summary refs log tree commit diff stats
path: root/libotr/libgcrypt-1.8.7/random/rndw32ce.c
diff options
context:
space:
mode:
Diffstat (limited to 'libotr/libgcrypt-1.8.7/random/rndw32ce.c')
-rw-r--r--libotr/libgcrypt-1.8.7/random/rndw32ce.c199
1 files changed, 199 insertions, 0 deletions
diff --git a/libotr/libgcrypt-1.8.7/random/rndw32ce.c b/libotr/libgcrypt-1.8.7/random/rndw32ce.c
new file mode 100644
index 0000000..b485eef
--- /dev/null
+++ b/libotr/libgcrypt-1.8.7/random/rndw32ce.c
@@ -0,0 +1,199 @@
+/* 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 size_t filler_used;
+static size_t filler_length;
+static unsigned char *filler_buffer;
+
+static void
+filler (const void *data, size_t datalen, enum random_origins dummy)
+{
+  (void)dummy;
+  if (filler_used + datalen > filler_length)
+    datalen = filler_length - filler_used;
+  memcpy (filler_buffer + filler_used, data, datalen);
+  filler_used += datalen;
+}
+
+
+static void
+fillup_buffer (unsigned char *buffer, size_t length)
+{
+  filler_used = 0;
+  filler_length = length;
+  filler_buffer = buffer;
+
+  while (filler_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);
+  }
+
+}