aboutsummaryrefslogtreecommitdiff
path: root/win32/sh_random.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-03-22 14:58:29 +0000
committerRon Yorston <rmy@pobox.com>2018-03-22 15:11:41 +0000
commit6cff8357023adb4d5c9daa027522f883f3905f4c (patch)
tree50964ae864ec3325c2413facaa8efc3a3104f3a6 /win32/sh_random.c
parentbe9b9ed64e658889229e18e3d089df27d8b724c3 (diff)
downloadbusybox-w32-6cff8357023adb4d5c9daa027522f883f3905f4c.tar.gz
busybox-w32-6cff8357023adb4d5c9daa027522f883f3905f4c.tar.bz2
busybox-w32-6cff8357023adb4d5c9daa027522f883f3905f4c.zip
win32: allow use of shell's PRNG for /dev/urandom
Allow either ISAAC or the shell's built-in pseudo-random number generator to be used for /dev/urandom. The latter is smaller so it's the default.
Diffstat (limited to '')
-rw-r--r--win32/sh_random.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/win32/sh_random.c b/win32/sh_random.c
new file mode 100644
index 000000000..2948e4a55
--- /dev/null
+++ b/win32/sh_random.c
@@ -0,0 +1,76 @@
1#include "libbb.h"
2#include "../shell/random.h"
3
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/*
13 * 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
15 * anything that needs to be secure.
16 */
17static void get_entropy(uint32_t state[2])
18{
19 int i, j;
20 SYSTEMTIME tm;
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)GetCurrentProcessId();
28 state[i++%2] ^= (uint32_t)GetCurrentThreadId();
29 state[i++%2] ^= (uint32_t)GetTickCount();
30
31 GET_DATA(GetLocalTime, tm)
32 GET_DATA(GlobalMemoryStatus, ms)
33 GET_DATA(GetSystemInfo, si)
34 GET_DATA(QueryPerformanceCounter, pc)
35
36#if 0
37 {
38 unsigned char *p = (unsigned char *)state;
39
40 for (j=0; j<8; ++j) {
41 fprintf(stderr, "%02x", *p++);
42 if ((j&3) == 3) {
43 fprintf(stderr, " ");
44 }
45 }
46 fprintf(stderr, "\n");
47 }
48#endif
49}
50
51ssize_t get_random_bytes(void *buf, ssize_t count)
52{
53 static random_t rnd;
54 ssize_t save_count = count;
55 uint32_t value;
56 unsigned char *ptr = (unsigned char *)&value;
57
58 if (buf == NULL || count < 0) {
59 errno = EINVAL;
60 return -1;
61 }
62
63 if (UNINITED_RANDOM_T(&rnd)) {
64 uint32_t state[2] = {0, 0};
65
66 get_entropy(state);
67 INIT_RANDOM_T(&rnd, state[0] ? state[0] : 1, state[1]);
68 }
69
70 for (;count > 0; buf+=4, count-=4) {
71 value = full_random(&rnd);
72 memcpy(buf, ptr, count >= 4 ? 4 : count);
73 }
74
75 return save_count;
76}