diff options
author | Ron Yorston <rmy@pobox.com> | 2023-01-11 08:20:11 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-01-11 08:20:11 +0000 |
commit | 4ea671b358ec15331a961be092a777c8a82d1642 (patch) | |
tree | db30ad8df0749c9b43b2beadb6005f65f9466487 | |
parent | 67fb94dea61e74da032a8f0c51fbf216ec47dadb (diff) | |
download | busybox-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.c | 42 | ||||
-rw-r--r-- | win32/sh_random.c | 28 |
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 | ||
22 | typedef struct { | 23 | typedef 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 | */ |
129 | static void get_entropy(isaac_t *t) | 122 | static 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 | */ |
17 | static void get_entropy(uint32_t state[2]) | 10 | static 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++); |