diff options
Diffstat (limited to 'cipher/rndw32.c')
-rw-r--r-- | cipher/rndw32.c | 292 |
1 files changed, 12 insertions, 280 deletions
diff --git a/cipher/rndw32.c b/cipher/rndw32.c index f58d45866..87aa20878 100644 --- a/cipher/rndw32.c +++ b/cipher/rndw32.c @@ -1,5 +1,5 @@ /* rndw32.c - W32 entropy gatherer - * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + * Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. * Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-1999 * * This file is part of GnuPG. @@ -60,6 +60,9 @@ */ #include <config.h> + +#ifdef USE_RNDW32 + #include <stdio.h> #include <stdlib.h> #include <assert.h> @@ -74,230 +77,13 @@ #include "types.h" #include "util.h" -#include "dynload.h" - -/* We do not use the netropy DLL anymore because a standalone program is - * easier to maintain and */ -/*#define USE_ENTROPY_DLL*/ +#include "algorithms.h" - - -#ifdef IS_MODULE - #define _(a) (a) -#else - #include "i18n.h" -#endif +#include "i18n.h" static int debug_me; -#ifdef USE_ENTROPY_DLL - -#define WIN32_SLOW_SEEDER 0 -#define WIN32_FAST_SEEDER 1 - -#define PCP_SUCCESS 0 -#define PCP_NULL_POINTER 1 -#define PCP_SEEDER_FAILED 2 -#define PCP_SEEDER_NO_MEM 3 -#define PCP_SEEDER_TOO_SMALL 4 -#define PCP_DLL_LOAD_FAILED 5 -#define PCP_UNKNOWN_PLATFORM 6 -#define PCP_ERROR_VERSION 7 -#define PCP_DLL_FUNC 8 -#define PCP_UNKNOWN_SEEDER_TYPE 9 - - -/**************** - * We sometimes get a SEEDER_TOO_SMALL error, in which case we increment - * the internal buffer by SEEDER_INC_CHUNK until we reach MAX_SEEDER_SIZE - * MAX_SEEDER_SIZE is used as an arbitrary limit to protect against - * bugs in Winseed. - */ -#define MAX_SEEDER_SIZE 500000 -#define SEEDER_INC_CHUNK 50000 - - -typedef void *WIN32_SEEDER; - -static WIN32_SEEDER (WINAPI *create_instance)( byte type, unsigned int *reason); -static void (WINAPI *delete_instance)( WIN32_SEEDER that ); -static unsigned int (WINAPI *get_internal_seed_size)( WIN32_SEEDER that ); -static void (WINAPI *set_internal_seed_size)( WIN32_SEEDER that, - unsigned int new_size); -static unsigned int (WINAPI *get_expected_seed_size)( WIN32_SEEDER that); -static unsigned int (WINAPI *get_seed)( WIN32_SEEDER that, byte *buffer, - unsigned int *desired_length); - -static WIN32_SEEDER slow_seeder, fast_seeder; -static byte *entropy_buffer; -static size_t entropy_buffer_size; - -/**************** - * Load and initialize the winseed DLL - * NOTE: winseed is not part of the GnuPG distribution. It should be available - * at the GNU crypto FTP server site. - * We do not load the DLL on demand to have a better control over the - * location of the library. - */ -static void -load_and_init_winseed( void ) -{ - HANDLE hInstance; - void *addr; - unsigned int reason = 0; - unsigned int n1, n2; - const char *dllname; - - dllname = read_w32_registry_string( "HKEY_LOCAL_MACHINE", - "Software\\GNU\\GnuPG", - "EntropyDLL" ); - if( !dllname ) - dllname = "c:/gnupg/entropy.dll"; - - hInstance = LoadLibrary( dllname ); - if( !hInstance ) - goto failure; - if( !(addr = GetProcAddress( hInstance, "WS_create_instance" )) ) - goto failure; - create_instance = addr; - if( !(addr = GetProcAddress( hInstance, "WS_delete_instance" )) ) - goto failure; - delete_instance = addr; - if( !(addr = GetProcAddress( hInstance, "WS_get_internal_seed_size" )) ) - goto failure; - get_internal_seed_size = addr; - if( !(addr = GetProcAddress( hInstance, "WS_set_internal_seed_size" )) ) - goto failure; - set_internal_seed_size = addr; - if( !(addr = GetProcAddress( hInstance, "WS_get_expected_seed_size" )) ) - goto failure; - get_expected_seed_size = addr; - if( !(addr = GetProcAddress( hInstance, "WS_get_seed" )) ) - goto failure; - get_seed = addr; - - /* we have all the functions - init the system */ - slow_seeder = create_instance( WIN32_SLOW_SEEDER, &reason); - if( !slow_seeder ) { - g10_log_fatal("error creating winseed slow seeder: rc=%u\n", reason ); - goto failure; - } - fast_seeder = create_instance( WIN32_FAST_SEEDER, &reason); - if( !fast_seeder ) { - g10_log_fatal("error creating winseed fast seeder: rc=%u\n", reason ); - goto failure; - } - n1 = get_internal_seed_size( slow_seeder ); - /*g10_log_info("slow buffer size=%u\n", n1);*/ - n2 = get_internal_seed_size( fast_seeder ); - /*g10_log_info("fast buffer size=%u\n", n2);*/ - - entropy_buffer_size = n1 > n2? n1: n2; - entropy_buffer = m_alloc( entropy_buffer_size ); - /*g10_log_info("using a buffer of size=%u\n", entropy_buffer_size );*/ - - return; - - failure: - g10_log_fatal("error loading winseed DLL `%s'\n", dllname ); -} - - - - - -/* Note: we always use the highest level. - * TO boost the performance we may want to add some - * additional code for level 1 - */ -static int -gather_random( void (*add)(const void*, size_t, int), int requester, - size_t length, int level ) -{ - unsigned int result; - unsigned int nbytes; - - if( !level ) - return 0; - - if( !slow_seeder ) - load_and_init_winseed(); - - /* Our estimation on how much entropy we should use is very vague. - * Winseed delivers some amount of entropy on each slow poll and - * we add it to our random pool. Depending on the required quality - * level we adjust the requested length so that for higher quality - * we make sure to add more entropy to our pool. However, as we don't - * like to waste any entropy collected by winseed, we always add - * at least everything we got from winseed. - */ - if( level > 1 ) - length *= 100; - else if( level > 0 ) - length *= 10; - - for(;;) { - nbytes = entropy_buffer_size; - result = get_seed( slow_seeder, entropy_buffer, &nbytes); - if( result == PCP_SEEDER_TOO_SMALL ) { - unsigned int n1 = get_internal_seed_size( slow_seeder ); - - if( n1 > MAX_SEEDER_SIZE ) { - g10_log_fatal("rndw32: internal seeder problem (size=%u)\n", - n1); - return -1; /* actually never reached */ - } - n1 += SEEDER_INC_CHUNK; - set_internal_seed_size( slow_seeder, n1 ); - if( n1 > entropy_buffer_size ) { - entropy_buffer_size = n1; - entropy_buffer = m_realloc( entropy_buffer, - entropy_buffer_size ); - } - continue; - } - - - if( result ) { - g10_log_fatal("rndw32: get_seed(slow) failed: rc=%u\n", result); - return -1; /* actually never reached */ - } - /*g10_log_info("rndw32: slow poll level %d, need %u, got %u\n", - level, (unsigned int)length, (unsigned int)nbytes );*/ - (*add)( entropy_buffer, nbytes, requester ); - if( length <= nbytes ) - return 0; /* okay */ - length -= nbytes; - } -} - -static int -gather_random_fast( void (*add)(const void*, size_t, int), int requester ) -{ - unsigned int result; - unsigned int nbytes; - - if( !fast_seeder ) - load_and_init_winseed(); - - /* winseed delivers a constant ammount of entropy for a fast - * poll. We can simply use this and add it to the pool; no need - * a loop like it is used in the slow poll */ - nbytes = entropy_buffer_size; - result = get_seed( fast_seeder, entropy_buffer, &nbytes); - if( result ) { - g10_log_fatal("rndw32: get_seed(fast) failed: rc=%u\n", result); - return -1; /* actually never reached */ - } - /*g10_log_info("rndw32: fast poll got %u\n", (unsigned int)nbytes );*/ - (*add)( entropy_buffer, nbytes, requester ); - return 0; -} - -#else /* !USE_ENTROPY_DLL */ -/* This is the new code which does not require the entropy.dll */ - /* * Definitions which are missing from the current GNU Windows32Api */ @@ -731,9 +517,9 @@ slow_gatherer_windowsNT( void (*add)(const void*, size_t, int), int requester ) } -static int -gather_random( void (*add)(const void*, size_t, int), int requester, - size_t length, int level ) +int +rndw32_gather_random (void (*add)(const void*, size_t, int), int requester, + size_t length, int level ) { static int is_initialized; static int is_windowsNT, has_toolhelp; @@ -783,8 +569,8 @@ gather_random( void (*add)(const void*, size_t, int), int requester, -static int -gather_random_fast( void (*add)(const void*, size_t, int), int requester ) +int +rndw32_gather_random_fast( void (*add)(const void*, size_t, int), int requester ) { static int addedFixedItems = 0; @@ -915,58 +701,4 @@ gather_random_fast( void (*add)(const void*, size_t, int), int requester ) } - - - -#endif /* !USE_ENTROPY_DLL */ - - -#ifndef IS_MODULE -static -#endif -const char * const gnupgext_version = "RNDW32 ($Revision$)"; - -static struct { - int class; - int version; - void *func; -} func_table[] = { - { 40, 1, gather_random }, - { 41, 1, gather_random_fast }, -}; - - -#ifndef IS_MODULE -static -#endif -void * -gnupgext_enum_func( int what, int *sequence, int *class, int *vers ) -{ - void *ret; - int i = *sequence; - - debug_me = !!getenv("DEBUG_RNDW32"); - - do { - if ( i >= DIM(func_table) || i < 0 ) { - return NULL; - } - *class = func_table[i].class; - *vers = func_table[i].version; - ret = func_table[i].func; - i++; - } while ( what && what != *class ); - - *sequence = i; - return ret; -} - -#ifndef IS_MODULE -void -rndw32_constructor(void) -{ - register_internal_cipher_extension( gnupgext_version, - gnupgext_enum_func ); -} -#endif - +#endif /*USE_RNDW32*/ |