From 0e13f6709d8fa7e593c09180da75f21af943a14a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 Mar 2010 15:51:37 +0000 Subject: Added an entropy gatherer for W32CE. --- random/ChangeLog | 9 +++ random/Makefile.am | 3 +- random/rand-internal.h | 9 +++ random/random-csprng.c | 10 ++- random/rndw32.c | 32 +------- random/rndw32ce.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 226 insertions(+), 30 deletions(-) create mode 100644 random/rndw32ce.c (limited to 'random') diff --git a/random/ChangeLog b/random/ChangeLog index 76fa5ec7..2fa2b81d 100644 --- a/random/ChangeLog +++ b/random/ChangeLog @@ -1,3 +1,12 @@ +2010-03-24 Werner Koch + + * rndw32.c: Revert all changes from 2010-01-21. + + * rndw32ce.c: New. + * Makefile.am (EXTRA_librandom_la_SOURCES): Add it. + * random-csprng.c (getfnc_gather_random) + (getfnc_fast_random_poll) [USE_RNDW32CE]: Use rndw32ce. + 2010-01-21 Werner Koch * rndw32.c (read_mbm_data) [W32CE]: Do not build. diff --git a/random/Makefile.am b/random/Makefile.am index 336109a6..2058d563 100644 --- a/random/Makefile.am +++ b/random/Makefile.am @@ -46,4 +46,5 @@ EXTRA_librandom_la_SOURCES = \ rndlinux.c \ rndegd.c \ rndunix.c \ -rndw32.c +rndw32.c \ +rndw32ce.c diff --git a/random/rand-internal.h b/random/rand-internal.h index 534d8284..2cce9065 100644 --- a/random/rand-internal.h +++ b/random/rand-internal.h @@ -123,6 +123,15 @@ void _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, enum random_origins), enum random_origins origin ); +/*-- rndw32ce.c --*/ +int _gcry_rndw32ce_gather_random (void (*add) (const void *, size_t, + enum random_origins), + enum random_origins origin, + size_t length, int level); +void _gcry_rndw32ce_gather_random_fast (void (*add)(const void*, size_t, + enum random_origins), + enum random_origins origin ); + /*-- 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 fbc4230e..9ad39513 100644 --- a/random/random-csprng.c +++ b/random/random-csprng.c @@ -1,6 +1,6 @@ /* random-csprng.c - CSPRNG style random number generator (libgcrypt classic) * Copyright (C) 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008 Free Software Foundation, Inc. + * 2007, 2008, 2010 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -1144,6 +1144,11 @@ getfnc_gather_random (void))(void (*)(const void*, size_t, return fnc; #endif +#if USE_RNDW32CE + fnc = _gcry_rndw32ce_gather_random; + return fnc; +#endif + log_fatal (_("no entropy gathering module detected\n")); return NULL; /*NOTREACHED*/ @@ -1158,6 +1163,9 @@ getfnc_fast_random_poll (void))( void (*)(const void*, size_t, { #if USE_RNDW32 return _gcry_rndw32_gather_random_fast; +#endif +#if USE_RNDW32CE + return _gcry_rndw32ce_gather_random_fast; #endif return NULL; } diff --git a/random/rndw32.c b/random/rndw32.c index 4511ceeb..49dff3cc 100644 --- a/random/rndw32.c +++ b/random/rndw32.c @@ -329,7 +329,6 @@ read_system_rng (void (*add)(const void*, size_t, enum random_origins), /* Read data from MBM. This communicates via shared memory, so all we need to do is map a file and read the data out. */ -#ifndef HAVE_W32CE_SYSTEM static void read_mbm_data (void (*add)(const void*, size_t, enum random_origins), enum random_origins requester) @@ -352,7 +351,6 @@ read_mbm_data (void (*add)(const void*, size_t, enum random_origins), CloseHandle (hMBMData); } } -#endif /*!HAVE_W32CE_SYSTEM*/ /* Fallback method using the registry to poll the statistics. */ @@ -559,9 +557,7 @@ slow_gatherer ( void (*add)(const void*, size_t, enum random_origins), } read_system_rng ( add, requester ); -#ifndef HAVE_W32CE_SYSTEM read_mbm_data ( add, requester ); -#endif /* Get network statistics. Note: Both NT Workstation and NT Server by default will be running both the workstation and server services. The @@ -779,13 +775,8 @@ _gcry_rndw32_gather_random (void (*add)(const void*, size_t, OSVERSIONINFO osvi = { sizeof( osvi ) }; GetVersionEx( &osvi ); -#ifdef HAVE_W32CE_SYSTEM - if (osvi.dwPlatformId != VER_PLATFORM_WIN32_CE) - log_fatal ("can only run on a Windows CE platform\n" ); -#else if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) log_fatal ("can only run on a Windows NT platform\n" ); -#endif system_is_w2000 = (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0); init_system_rng (); is_initialized = 1; @@ -831,28 +822,23 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, memcpy (bufptr, &along, sizeof (along) ); \ bufptr += sizeof (along); \ } while (0) -#ifdef HAVE_W32CE_SYSTEM -# define ADD_NO_CE(f) -#else -# define ADD_NO_CE(f) ADD(f) -#endif ADD ( GetActiveWindow ()); ADD ( GetCapture ()); ADD ( GetClipboardOwner ()); - ADD_NO_CE ( GetClipboardViewer ()); + ADD ( GetClipboardViewer ()); ADD ( GetCurrentProcess ()); ADD ( GetCurrentProcessId ()); ADD ( GetCurrentThread ()); ADD ( GetCurrentThreadId ()); ADD ( GetDesktopWindow ()); ADD ( GetFocus ()); - ADD_NO_CE ( GetInputState ()); + ADD ( GetInputState ()); ADD ( GetMessagePos ()); - ADD_NO_CE ( GetMessageTime ()); + ADD ( GetMessageTime ()); ADD ( GetOpenClipboardWindow ()); ADD ( GetProcessHeap ()); - ADD_NO_CE ( GetProcessWindowStation ()); + ADD ( GetProcessWindowStation ()); ADD ( GetQueueStatus (QS_ALLEVENTS)); ADD ( GetTickCount ()); @@ -898,15 +884,9 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, (*add) ( &kernelTime, sizeof (kernelTime), origin ); (*add) ( &userTime, sizeof (userTime), origin ); -#ifdef HAVE_W32CE_SYSTEM - handle = GetCurrentThread (); - GetThreadTimes (handle, &creationTime, &exitTime, - &kernelTime, &userTime); -#else handle = GetCurrentProcess (); GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime); -#endif (*add) ( &creationTime, sizeof (creationTime), origin ); (*add) ( &exitTime, sizeof (exitTime), origin ); (*add) ( &kernelTime, sizeof (kernelTime), origin ); @@ -914,20 +894,17 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, /* Get the minimum and maximum working set size for the current process. */ -#ifndef HAVE_W32CE_SYSTEM GetProcessWorkingSetSize (handle, &minimumWorkingSetSize, &maximumWorkingSetSize); (*add) ( &minimumWorkingSetSize, sizeof (minimumWorkingSetSize), origin ); (*add) ( &maximumWorkingSetSize, sizeof (maximumWorkingSetSize), origin ); -#endif /*!HAVE_W32CE_SYSTEM*/ } /* The following are fixed for the lifetime of the process so we only * add them once */ -#ifndef HAVE_W32CE_SYSTEM if (!addedFixedItems) { STARTUPINFO startupInfo; @@ -940,7 +917,6 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, (*add) ( &startupInfo, sizeof (STARTUPINFO), origin ); addedFixedItems = 1; } -#endif /*!HAVE_W32CE_SYSTEM*/ /* The performance of QPC varies depending on the architecture it's running on and on the OS, the MS documentation is vague about the diff --git a/random/rndw32ce.c b/random/rndw32ce.c new file mode 100644 index 00000000..12239602 --- /dev/null +++ b/random/rndw32ce.c @@ -0,0 +1,193 @@ +/* rndw32ce.c - W32CE entropy gatherer + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "types.h" +#include "g10lib.h" +#include "rand-internal.h" + + +/* The Microsoft docs say that it is suggested to see the buffer with + some extra random. We do this, despite that it is a questionable + suggestion as the OS as better means of collecting entropy than an + application. */ +static void +fillup_buffer (unsigned char *buffer, size_t length) +{ + size_t used = 0; + + /* This code uses gcc anyway, thus we can use a nested function. */ + void filler (const void *data, size_t datalen, enum random_origins dummy) + { + (void)dummy; + if (used + datalen > length) + datalen = length - used; + memcpy (buffer+used, data, datalen); + used += datalen; + } + + while (used < length) + _gcry_rndw32ce_gather_random_fast (filler, 0); +} + + + +int +_gcry_rndw32ce_gather_random (void (*add)(const void*, size_t, + enum random_origins), + enum random_origins origin, + size_t length, int level ) +{ + HCRYPTPROV prov; + unsigned char buffer [256]; + DWORD buflen; + + if (!level) + return 0; + + /* Note that LENGTH is not really important because the caller + checks the returned lengths and calls this function until it + feels that enough entropy has been gathered. */ + + buflen = sizeof buffer; + if (length+8 < buflen) + buflen = length+8; /* Return a bit more than requested. */ + + if (!CryptAcquireContext (&prov, NULL, NULL, PROV_RSA_FULL, + (CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) ) + log_debug ("CryptAcquireContext failed: rc=%d\n", (int)GetLastError ()); + else + { + fillup_buffer (buffer, buflen); + if (!CryptGenRandom (prov, buflen, buffer)) + log_debug ("CryptGenRandom(%d) failed: rc=%d\n", + (int)buflen, (int)GetLastError ()); + else + (*add) (buffer, buflen, origin); + CryptReleaseContext (prov, 0); + wipememory (buffer, sizeof buffer); + } + + return 0; +} + + + +void +_gcry_rndw32ce_gather_random_fast (void (*add)(const void*, size_t, + enum random_origins), + enum random_origins origin) +{ + + /* Add word sized values. */ + { +# define ADD(t,f) do { \ + t along = (f); \ + memcpy (bufptr, &along, sizeof (along)); \ + bufptr += sizeof (along); \ + } while (0) + unsigned char buffer[20*sizeof(ulong)], *bufptr; + + bufptr = buffer; + ADD (HWND, GetActiveWindow ()); + ADD (HWND, GetCapture ()); + ADD (HWND, GetClipboardOwner ()); + ADD (HANDLE, GetCurrentProcess ()); + ADD (DWORD, GetCurrentProcessId ()); + ADD (HANDLE, GetCurrentThread ()); + ADD (DWORD, GetCurrentThreadId ()); + ADD (HWND, GetDesktopWindow ()); + ADD (HWND, GetFocus ()); + ADD (DWORD, GetMessagePos ()); + ADD (HWND, GetOpenClipboardWindow ()); + ADD (HWND, GetProcessHeap ()); + ADD (DWORD, GetQueueStatus (QS_ALLEVENTS)); + ADD (DWORD, GetTickCount ()); + + gcry_assert ( bufptr-buffer < sizeof (buffer) ); + (*add) ( buffer, bufptr-buffer, origin ); +# undef ADD + } + + /* Get multiword system information: Current caret position, current + mouse cursor position. */ + { + POINT point; + + GetCaretPos (&point); + (*add) ( &point, sizeof (point), origin ); + GetCursorPos (&point); + (*add) ( &point, sizeof (point), origin ); + } + + /* Get percent of memory in use, bytes of physical memory, bytes of + free physical memory, bytes in paging file, free bytes in paging + file, user bytes of address space, and free user bytes. */ + { + MEMORYSTATUS memoryStatus; + + memoryStatus.dwLength = sizeof (MEMORYSTATUS); + GlobalMemoryStatus (&memoryStatus); + (*add) ( &memoryStatus, sizeof (memoryStatus), origin ); + } + + + /* Get thread and process creation time, exit time, time in kernel + mode, and time in user mode in 100ns intervals. */ + { + HANDLE handle; + FILETIME creationTime, exitTime, kernelTime, userTime; + + handle = GetCurrentThread (); + GetThreadTimes (handle, &creationTime, &exitTime, + &kernelTime, &userTime); + (*add) ( &creationTime, sizeof (creationTime), origin ); + (*add) ( &exitTime, sizeof (exitTime), origin ); + (*add) ( &kernelTime, sizeof (kernelTime), origin ); + (*add) ( &userTime, sizeof (userTime), origin ); + + handle = GetCurrentThread (); + GetThreadTimes (handle, &creationTime, &exitTime, + &kernelTime, &userTime); + (*add) ( &creationTime, sizeof (creationTime), origin ); + (*add) ( &exitTime, sizeof (exitTime), origin ); + (*add) ( &kernelTime, sizeof (kernelTime), origin ); + (*add) ( &userTime, sizeof (userTime), origin ); + + } + + + /* In case the OEM provides a high precision timer get this. If + none is available the default implementation returns the + GetTickCount. */ + { + LARGE_INTEGER performanceCount; + + if (QueryPerformanceCounter (&performanceCount)) + (*add) (&performanceCount, sizeof (performanceCount), origin); + } + +} -- cgit v1.2.1