aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-01-11 08:20:11 +0000
committerRon Yorston <rmy@pobox.com>2023-01-11 08:20:11 +0000
commit4ea671b358ec15331a961be092a777c8a82d1642 (patch)
treedb30ad8df0749c9b43b2beadb6005f65f9466487
parent67fb94dea61e74da032a8f0c51fbf216ec47dadb (diff)
downloadbusybox-w32-4ea671b358ec15331a961be092a777c8a82d1642.tar.gz
busybox-w32-4ea671b358ec15331a961be092a777c8a82d1642.tar.bz2
busybox-w32-4ea671b358ec15331a961be092a777c8a82d1642.zip
win32: improve seeding of PRNGs
busybox-w32 provides two PRNG implementations which are used in the emulation of /dev/urandom. The ad hoc method of seeding them has been replaced by calls to RtlGenRandom. The documentation for RtlGenRandom indicates it has been deprecated in favour of CryptGenRandom. The documentation for the latter indicates it has been deprecated in favour of the 'Cryptography Next Generation APIs'. Nonetheless, RtlGenRandom remains available in every version of Windows since XP. In the unlikely event that RtlGenRandom fails simply use the current time as the seed. Saves 192 bytes in the default configuration.
-rw-r--r--win32/isaac.c42
-rw-r--r--win32/sh_random.c28
2 files changed, 10 insertions, 60 deletions
diff --git a/win32/isaac.c b/win32/isaac.c
index 6b174b69e..19b96de94 100644
--- a/win32/isaac.c
+++ b/win32/isaac.c
@@ -18,6 +18,7 @@ You may use this code in any way you wish, and it is free. No warrantee.
18 public domain. 18 public domain.
19*/ 19*/
20#include "libbb.h" 20#include "libbb.h"
21#include <ntsecapi.h>
21 22
22typedef struct { 23typedef struct {
23 /* external results */ 24 /* external results */
@@ -113,14 +114,6 @@ static void randinit(isaac_t *t, int flag)
113 isaac(t); /* fill in the first set of results */ 114 isaac(t); /* fill in the first set of results */
114} 115}
115 116
116/* call 'fn' to put data in 'dt' then copy it to generator state */
117#define GET_DATA(fn, dt) \
118 fn(&dt); \
119 u = (uint32_t *)&dt; \
120 for (j=0; j<sizeof(dt)/sizeof(uint32_t); ++j) { \
121 t->randrsl[i++ % 256] = *u++; \
122 }
123
124/* 117/*
125 * Stuff a few bytes of random-ish data into the generator state. 118 * Stuff a few bytes of random-ish data into the generator state.
126 * This is unlikely to be very robust: don't rely on it for 119 * This is unlikely to be very robust: don't rely on it for
@@ -128,37 +121,14 @@ static void randinit(isaac_t *t, int flag)
128 */ 121 */
129static void get_entropy(isaac_t *t) 122static void get_entropy(isaac_t *t)
130{ 123{
131 int i, j; 124 if (!RtlGenRandom(t->randrsl, sizeof(uint32_t)*256))
132 FILETIME tm; 125 GetSystemTimeAsFileTime((FILETIME *)t->randrsl);
133 MEMORYSTATUS ms;
134 SYSTEM_INFO si;
135 LARGE_INTEGER pc;
136 uint32_t *u;
137 char *env, *s;
138 unsigned char *p;
139
140 i = 0;
141 t->randrsl[i++] = (uint32_t)GetProcessId(GetCurrentProcess());
142 t->randrsl[i++] = (uint32_t)GetCurrentThreadId();
143 t->randrsl[i++] = (uint32_t)GetTickCount();
144
145 GET_DATA(GetSystemTimeAsFileTime, tm)
146 GET_DATA(GlobalMemoryStatus, ms)
147 GET_DATA(GetSystemInfo, si)
148 GET_DATA(QueryPerformanceCounter, pc)
149
150 env = GetEnvironmentStringsA();
151
152 /* environment ends with two nuls */
153 p = (unsigned char *)t->randrsl;
154 i *= sizeof(uint32_t);
155 for (s=env; *s || *(s+1); ++s)
156 p[i++ % (256 * sizeof(uint32_t))] ^= *s;
157
158 FreeEnvironmentStringsA(env);
159 126
160#if 0 127#if 0
161 { 128 {
129 unsigned char *p = (unsigned char *)t->randrsl;
130 int j;
131
162 for (j=0; j<256; ++j) { 132 for (j=0; j<256; ++j) {
163 fprintf(stderr, "%02x", p[j]); 133 fprintf(stderr, "%02x", p[j]);
164 if ((j&31) == 31) { 134 if ((j&31) == 31) {
diff --git a/win32/sh_random.c b/win32/sh_random.c
index 912793269..32ce135c8 100644
--- a/win32/sh_random.c
+++ b/win32/sh_random.c
@@ -1,14 +1,7 @@
1#include "libbb.h" 1#include "libbb.h"
2#include <ntsecapi.h>
2#include "../shell/random.h" 3#include "../shell/random.h"
3 4
4/* call 'fn' to put data in 'dt' then copy it to generator state */
5#define GET_DATA(fn, dt) \
6 fn(&dt); \
7 u = (uint32_t *)&dt; \
8 for (j=0; j<sizeof(dt)/sizeof(uint32_t); ++j) { \
9 state[i++%2] ^= *u++; \
10 }
11
12/* 5/*
13 * Obtain a few bytes of random-ish data to initialise the generator. 6 * Obtain a few bytes of random-ish data to initialise the generator.
14 * This is unlikely to be very robust: don't rely on it for 7 * This is unlikely to be very robust: don't rely on it for
@@ -16,26 +9,13 @@
16 */ 9 */
17static void get_entropy(uint32_t state[2]) 10static void get_entropy(uint32_t state[2])
18{ 11{
19 int i, j; 12 if (!RtlGenRandom(state, sizeof(state[0])*2))
20 FILETIME tm; 13 GetSystemTimeAsFileTime((FILETIME *)state);
21 MEMORYSTATUS ms;
22 SYSTEM_INFO si;
23 LARGE_INTEGER pc;
24 uint32_t *u;
25
26 i = 0;
27 state[i++%2] ^= (uint32_t)GetProcessId(GetCurrentProcess());
28 state[i++%2] ^= (uint32_t)GetCurrentThreadId();
29 state[i++%2] ^= (uint32_t)GetTickCount();
30
31 GET_DATA(GetSystemTimeAsFileTime, tm)
32 GET_DATA(GlobalMemoryStatus, ms)
33 GET_DATA(GetSystemInfo, si)
34 GET_DATA(QueryPerformanceCounter, pc)
35 14
36#if 0 15#if 0
37 { 16 {
38 unsigned char *p = (unsigned char *)state; 17 unsigned char *p = (unsigned char *)state;
18 int j;
39 19
40 for (j=0; j<8; ++j) { 20 for (j=0; j<8; ++j) {
41 fprintf(stderr, "%02x", *p++); 21 fprintf(stderr, "%02x", *p++);