summaryrefslogtreecommitdiff
path: root/random
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2010-03-24 15:51:37 +0000
committerWerner Koch <wk@gnupg.org>2010-03-24 15:51:37 +0000
commit0e13f6709d8fa7e593c09180da75f21af943a14a (patch)
tree6fb3dfeb82f293ad341a44908a1c6ddceded8703 /random
parentadaaf899d13a6ebc180d63b7c84b20995eadc197 (diff)
downloadlibgcrypt-0e13f6709d8fa7e593c09180da75f21af943a14a.tar.gz
Added an entropy gatherer for W32CE.
Diffstat (limited to 'random')
-rw-r--r--random/ChangeLog9
-rw-r--r--random/Makefile.am3
-rw-r--r--random/rand-internal.h9
-rw-r--r--random/random-csprng.c10
-rw-r--r--random/rndw32.c32
-rw-r--r--random/rndw32ce.c193
6 files changed, 226 insertions, 30 deletions
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 <wk@g10code.com>
+
+ * 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 <wk@g10code.com>
* 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*/
@@ -1159,6 +1164,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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <windows.h>
+#include <wincrypt.h>
+
+#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);
+ }
+
+}