
komh78 at gmail
Mar 9, 2012, 5:08 AM
Post #1 of 14
(660 views)
Permalink
|
|
[PATCH] Add OS/2 entropy gatherer
|
|
--- configure.ac | 20 ++++ doc/Makefile.am | 6 +- random/rand-internal.h | 6 + random/random-csprng.c | 5 + random/rndos2.c | 252 ++++++++++++++++++++++++++++++++++++++++++++++++ src/hmac256.c | 9 +- tests/fipsdrv.c | 4 + 7 files changed, 296 insertions(+), 6 deletions(-) create mode 100644 random/rndos2.c diff --git a/configure.ac b/configure.ac index cf4a082..1f0c27a 100644 --- a/configure.ac +++ b/configure.ac @@ -197,6 +197,7 @@ LIBGCRYPT_THREAD_MODULES="" print_egd_notice=no have_w32_system=no have_w32ce_system=no +have_os2_system=no have_pthread=no @@ -227,8 +228,10 @@ case "${host}" in i?86-emx-os2 | i?86-*-os2*emx) # OS/2 with the EMX environment ac_cv_have_dev_random=no + have_os2_system=yes AC_DEFINE(HAVE_DRIVE_LETTERS) AC_DEFINE(HAVE_DOSISH_SYSTEM) + LDFLAGS="$LDFLAGS -no-undefined -Zbin-files" ;; i?86-*-msdosdjgpp*) @@ -271,6 +274,11 @@ fi AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) AM_CONDITIONAL(HAVE_W32CE_SYSTEM, test "$have_w32ce_system" = yes) +if test "$have_os2_system" = yes; then + AC_DEFINE(HAVE_OS2_SYSTEM,1, [Defined if we run on an OS/2 API based system]) +fi +AM_CONDITIONAL(HAVE_OS2_SYSTEM, test "$have_os2_system" = yes) + # A printable OS Name is sometimes useful. @@ -882,6 +890,11 @@ if test "$random" = "default"; then # Windows random device. random_modules="w32" ;; + + *-emx-os2 | *-*-os2*emx) + # OS/2 random device. + random_modules="os2" + ;; *) # Build everything, allow to select at runtime. random_modules="$auto_random_modules" @@ -1190,6 +1203,13 @@ if test "$found" = "1" ; then [Defined if the WindowsCE specific RNG should be used.]) fi +LIST_MEMBER(os2, $random_modules) +if test "$found" = "1" ; then + GCRYPT_RANDOM="$GCRYPT_RANDOM rndos2.lo" + AC_DEFINE(USE_RNDOS2, 1, + [Defined if the OS/2 specific RNG should be used.]) +fi + AC_SUBST([GCRYPT_CIPHERS]) AC_SUBST([GCRYPT_PUBKEY_CIPHERS]) AC_SUBST([GCRYPT_DIGESTS]) diff --git a/doc/Makefile.am b/doc/Makefile.am index a6bd2ae..451d42f 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -24,7 +24,7 @@ EXTRA_DIST = README.apichanges HACKING \ yat2m.c DISTCLEANFILES = gcrypt.cps yat2m-stamp.tmp yat2m-stamp $(myman_pages) -CLEANFILES = yat2m +CLEANFILES = yat2m$(EXEEXT) BUILT_SOURCES = libgcrypt-modules.eps fips-fsm.eps \ libgcrypt-modules.png fips-fsm.png \ @@ -41,7 +41,7 @@ myman_pages = hmac256.1 man_MANS = $(myman_pages) -yat2m: yat2m.c +yat2m$(EXEEXT): yat2m.c $(CC_FOR_BUILD) -o $@ $(srcdir)/yat2m.c .fig.png: @@ -64,7 +64,7 @@ yat2m-stamp: $(myman_sources) `test -f '$$file' || echo '$(srcdir)/'`$$file ; done @mv -f yat2m-stamp.tmp $@ -yat2m-stamp: yat2m +yat2m-stamp: yat2m$(EXEEXT) $(myman_pages) : yat2m-stamp @if test -f $@; then :; else \ diff --git a/random/rand-internal.h b/random/rand-internal.h index a04a2d4..5b2b3be 100644 --- a/random/rand-internal.h +++ b/random/rand-internal.h @@ -132,6 +132,12 @@ void _gcry_rndw32ce_gather_random_fast (void (*add)(const void*, size_t, enum random_origins), enum random_origins origin ); +/*-- rndos2.c --*/ +int _gcry_rndos2_gather_random (void (*add) (const void *, size_t, + enum random_origins), + enum random_origins origin, + size_t length, int level); + /*-- rndhw.c --*/ int _gcry_rndhw_failed_p (void); void _gcry_rndhw_poll_fast (void (*add)(const void*, size_t, diff --git a/random/random-csprng.c b/random/random-csprng.c index 50357d1..e22d873 100644 --- a/random/random-csprng.c +++ b/random/random-csprng.c @@ -1151,6 +1151,11 @@ getfnc_gather_random (void))(void (*)(const void*, size_t, return fnc; #endif +#if USE_RNDOS2 + fnc = _gcry_rndos2_gather_random; + return fnc; +#endif + log_fatal (_("no entropy gathering module detected\n")); return NULL; /*NOTREACHED*/ diff --git a/random/rndos2.c b/random/rndos2.c new file mode 100644 index 0000000..4e1589f --- /dev/null +++ b/random/rndos2.c @@ -0,0 +1,252 @@ +/* rndos2.c - OS/2 entropy gatherer + * Copyright (C) 2012 KO Myung-Hun <komh [at] chollian> + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#define INCL_DOS +#define INCL_DOSERRORS +#include <os2.h> + +#include <stdio.h> +#include <stdlib.h> + +#include <sys/ioctl.h> +#include <net/if.h> + +#include "types.h" +#include "g10lib.h" +#include "rand-internal.h" + +#define ADD( buf, bufsize, origin, remain ) \ + do { \ + int n = ( bufsize ) < ( remain ) ? ( bufsize ) : ( remain ); \ + add( buf, n, origin ); \ + ( remain ) -= n; \ + } while( 0 ) + +#define BUF_SIZE_REQUESTER ( sizeof( unsigned long ) * 30 ) +#define BUF_SIZE_SERVER ( sizeof( unsigned long ) * 17 ) +#define BUF_SIZE_IFMIB ( sizeof( struct ifmib )) +#define BUF_SIZE_CPUUTIL ( sizeof( ULONG ) * 8 ) +#define BUF_SIZE_SYS_STATE ( 64 * 1024 ) +#define BUF_SIZE_SYS_STATE_DELTA 4096 +#define BUF_SIZE_SYS_STATE_MARGIN 1024 + +static HMODULE hmodNetApi32; +static HMODULE hmodTcpIp32; +static HMODULE hmodDosCalls; + +static unsigned APIENTRY ( *pfnNet32StatisticsGet2 )( + const unsigned char *, const unsigned char *, + unsigned long, unsigned long, unsigned long, + unsigned char *, unsigned long, + unsigned long * ); + +static int _System ( *pfnsocket )( int, int, int ); +static int _System ( *pfnos2_ioctl )( int, unsigned long, char *, int ); +static int _System ( *pfnsoclose )( int ); + +static APIRET APIENTRY ( *pfnDosPerfSysCall )( ULONG, ULONG, ULONG, ULONG ); +static APIRET APIENTRY ( *pfnDosQuerySysState )( ULONG, ULONG, PID, TID, PVOID, + ULONG ); + +int +_gcry_rndos2_gather_random( void ( *add )( const void *, size_t, + enum random_origins ), + enum random_origins origin, size_t length, + int level ) +{ + static BOOL fInit = FALSE; + static ULONG ulCpuCount = 1; + + unsigned char *buf; + ULONG rc; + + if( !level ) + return 0; + + /* We never block, assume level 2. */ + + if( !fInit ) + { + CHAR szFail[ 260 ]; + + hmodNetApi32 = NULLHANDLE; + if( !DosLoadModule( szFail, sizeof( szFail ), "netapi32", + &hmodNetApi32 )) + { + if( DosQueryProcAddr( hmodNetApi32, 125, NULL, + ( PFN * )&pfnNet32StatisticsGet2 )) + { + DosFreeModule( hmodNetApi32 ); + + hmodNetApi32 = NULLHANDLE; + } + } + + hmodTcpIp32 = NULLHANDLE; + if( !DosLoadModule( szFail, sizeof( szFail ), "tcpip32", + &hmodTcpIp32 )) + { + rc = DosQueryProcAddr( hmodTcpIp32, 16, NULL, + ( PFN * )&pfnsocket ); + + if( !rc ) + rc = DosQueryProcAddr( hmodTcpIp32, 17, NULL, + ( PFN * )&pfnsoclose ); + + if( !rc ) + rc = DosQueryProcAddr( hmodTcpIp32, 200, NULL, + ( PFN * )&pfnos2_ioctl ); + + if( rc ) + { + DosFreeModule( hmodTcpIp32 ); + + hmodTcpIp32 = NULLHANDLE; + } + } + + hmodDosCalls = NULLHANDLE; + if( !DosLoadModule( szFail, sizeof( szFail ), "doscalls", + &hmodDosCalls )) + { + if( DosQueryProcAddr( hmodDosCalls, 976, NULL, + ( PFN * )&pfnDosPerfSysCall )) + pfnDosPerfSysCall = NULL; + else + /* Query CPU count */ + pfnDosPerfSysCall( 0x41, 0, ( ULONG )&ulCpuCount, 0 ); + + if( DosQueryProcAddr( hmodDosCalls, 368, NULL, + ( PFN * )&pfnDosQuerySysState )) + pfnDosQuerySysState = NULL; + + if( !pfnDosPerfSysCall && !pfnDosQuerySysState ) + { + DosFreeModule( hmodDosCalls ); + + hmodDosCalls = NULLHANDLE; + } + } + + fInit = TRUE; + } + + while( length ) + { + if( hmodNetApi32 ) + { + ULONG ulAvail; + + buf = gcry_xmalloc( BUF_SIZE_REQUESTER ); + + if( !pfnNet32StatisticsGet2( NULL, "REQUESTER", 0, 0, 1, buf, + BUF_SIZE_REQUESTER, &ulAvail )) + ADD( buf, BUF_SIZE_REQUESTER, origin, length ); + + gcry_free( buf ); + + buf = gcry_xmalloc( BUF_SIZE_SERVER ); + + if( !pfnNet32StatisticsGet2( NULL, "SERVER", 0, 0, 1, buf, + BUF_SIZE_SERVER, &ulAvail )) + ADD( buf, BUF_SIZE_SERVER, origin, length ); + + gcry_free( buf ); + } + + if( hmodTcpIp32 ) + { + int s; + + s = pfnsocket( PF_INET, SOCK_RAW, 0 ); + + if( s != -1 ) + { + buf = gcry_xmalloc( BUF_SIZE_IFMIB ); + + if( !pfnos2_ioctl( s, SIOSTATIF, ( caddr_t )buf, + BUF_SIZE_IFMIB )) + ADD( buf, BUF_SIZE_IFMIB, origin, length ); + + gcry_free( buf ); + + pfnsoclose( s ); + } + } + + if( hmodDosCalls ) + { + if( pfnDosPerfSysCall ) + { + buf = gcry_xcalloc( ulCpuCount, BUF_SIZE_CPUUTIL ); + + /* Query CPU utilization snapshot */ + if( !pfnDosPerfSysCall( 0x63, ( ULONG )buf, 0, 0 )) + ADD( buf, BUF_SIZE_CPUUTIL * ulCpuCount, origin, length ); + + gcry_free( buf ); + } + + if( pfnDosQuerySysState ) + { + size_t bufSize = BUF_SIZE_SYS_STATE; + + /* Allocate additional memory because DosQuerySysState() + sometimes seems to overwrite to a memory boundary. */ + buf = gcry_xmalloc( bufSize + BUF_SIZE_SYS_STATE_MARGIN ); + + do + { + /* Query all the system information supported by OS */ + rc = DosQuerySysState( QS_SUPPORTED, 0, 0, 0, ( PCHAR )buf, + bufSize ); + if( rc == ERROR_BUFFER_OVERFLOW ) + { + bufSize += BUF_SIZE_SYS_STATE_DELTA; + gcry_free( buf ); + buf = gcry_xmalloc( bufSize + + BUF_SIZE_SYS_STATE_MARGIN ); + } + } while( rc == ERROR_BUFFER_OVERFLOW ); + + if( !rc ) + ADD( buf, bufSize, origin, length ); + + gcry_free( buf ); + } + } + +#define ADD_QSV( ord ) \ + do { \ + ULONG ulSV; \ + DosQuerySysInfo( ord, ord, &ulSV, sizeof( ulSV )); \ + ADD( &ulSV, sizeof( ulSV ), origin, length ); \ + } while( 0 ) + + /* Fail safe */ + ADD_QSV( QSV_MS_COUNT ); + ADD_QSV( QSV_TIME_LOW ); + ADD_QSV( QSV_TIME_HIGH ); + ADD_QSV( QSV_TOTAVAILMEM ); + ADD_QSV( QSV_FOREGROUND_FS_SESSION ); + ADD_QSV( QSV_FOREGROUND_PROCESS ); + } + + return 0; +} diff --git a/src/hmac256.c b/src/hmac256.c index 34def76..a887e99 100644 --- a/src/hmac256.c +++ b/src/hmac256.c @@ -52,7 +52,10 @@ #include <string.h> #include <assert.h> #include <errno.h> -#if defined(__WIN32) && defined(STANDALONE) +#if (defined(__WIN32) || defined(__OS2__)) && defined(STANDALONE) +# ifdef __OS2__ +# include <io.h> +# endif # include <fcntl.h> /* We need setmode(). */ #endif @@ -658,7 +661,7 @@ main (int argc, char **argv) int use_binary = 0; assert (sizeof (u32) == 4); -#ifdef __WIN32 +#if defined(__WIN32) || defined(__OS2__) setmode (fileno (stdin), O_BINARY); #endif @@ -707,7 +710,7 @@ main (int argc, char **argv) exit (1); } -#ifdef __WIN32 +#if defined(__WIN32) || defined(__OS2__) if (use_binary) setmode (fileno (stdout), O_BINARY); #endif diff --git a/tests/fipsdrv.c b/tests/fipsdrv.c index 2d4c362..d1be32d 100644 --- a/tests/fipsdrv.c +++ b/tests/fipsdrv.c @@ -29,6 +29,10 @@ #ifdef HAVE_W32_SYSTEM # include <fcntl.h> /* We need setmode(). */ #else +# ifdef HAVE_DOSISH_SYSTEM +# include <io.h> /* We need setmode(). */ +# include <fcntl.h> /* We need O_BINARY */ +# endif # include <signal.h> #endif #include <assert.h> -- 1.7.3.2 _______________________________________________ Gcrypt-devel mailing list Gcrypt-devel [at] gnupg http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
|