]> granicus.if.org Git - libexpat/commitdiff
Make win32 stdlib.h define rand_s(), add writeRandomBytes_rand_s().
authorDavid Loffredo <loffredo@steptools.com>
Wed, 7 Aug 2019 03:19:48 +0000 (23:19 -0400)
committerSebastian Pipping <sebastian@pipping.org>
Wed, 7 Aug 2019 17:42:16 +0000 (19:42 +0200)
Signed-off-by: David Loffredo <loffredo@steptools.com>
expat/lib/xmlparse.c

index e89a2afddacb30511088dc03bf41c85c62c9b2d8..50c61a87863ebf41a2c18d68944857f6f594881f 100644 (file)
 #  define _GNU_SOURCE 1 /* syscall prototype */
 #endif
 
+#ifdef _WIN32
+/* force stdlib to define rand_s() */
+#  define _CRT_RAND_S
+#endif
+
 #include <stddef.h>
 #include <string.h> /* memset(), memcpy() */
 #include <assert.h>
@@ -729,6 +734,31 @@ writeRandomBytes_arc4random(void *target, size_t count) {
 
 #ifdef _WIN32
 
+/* Obtain entropy on Windows using the rand_s() function which
+ * generates cryptographically secure random numbers.  Internally it
+ * uses RtlGenRandom API which is present in Windows XP and later.
+ */
+static int
+writeRandomBytes_rand_s(void *target, size_t count) {
+  size_t bytesWrittenTotal = 0;
+
+  while (bytesWrittenTotal < count) {
+    unsigned int random32 = 0;
+    size_t i = 0;
+
+    if (rand_s(&random32))
+      return 0; /* failure */
+
+    for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
+         i++, bytesWrittenTotal++) {
+      const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
+      ((uint8_t *)target)[bytesWrittenTotal] = random8;
+    }
+  }
+  return 1; /* success */
+}
+
+
 typedef BOOLEAN(APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);
 HMODULE _Expat_LoadLibrary(LPCTSTR filename); /* see loadlibrary.c */