aboutsummaryrefslogtreecommitdiff
path: root/win32
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
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 'win32')
-rw-r--r--win32/Kbuild11
-rw-r--r--win32/sh_random.c76
2 files changed, 82 insertions, 5 deletions
diff --git a/win32/Kbuild b/win32/Kbuild
index 00950e0f7..f8c8fb5af 100644
--- a/win32/Kbuild
+++ b/win32/Kbuild
@@ -7,18 +7,19 @@ lib-y:=
7lib-$(CONFIG_PLATFORM_MINGW32) += env.o 7lib-$(CONFIG_PLATFORM_MINGW32) += env.o
8lib-$(CONFIG_PLATFORM_MINGW32) += fnmatch.o 8lib-$(CONFIG_PLATFORM_MINGW32) += fnmatch.o
9lib-$(CONFIG_PLATFORM_MINGW32) += fsync.o 9lib-$(CONFIG_PLATFORM_MINGW32) += fsync.o
10lib-$(CONFIG_PLATFORM_MINGW32) += inet_pton.o
10lib-$(CONFIG_PLATFORM_MINGW32) += ioctl.o 11lib-$(CONFIG_PLATFORM_MINGW32) += ioctl.o
11lib-$(CONFIG_PLATFORM_MINGW32) += isaac.o 12lib-$(CONFIG_FEATURE_PRNG_ISAAC) += isaac.o
12lib-$(CONFIG_PLATFORM_MINGW32) += mingw.o 13lib-$(CONFIG_PLATFORM_MINGW32) += mingw.o
13lib-$(CONFIG_PLATFORM_MINGW32) += process.o 14lib-$(CONFIG_PLATFORM_MINGW32) += process.o
14lib-$(CONFIG_PLATFORM_MINGW32) += regex.o 15lib-$(CONFIG_PLATFORM_MINGW32) += mntent.o
15lib-$(CONFIG_PLATFORM_MINGW32) += net.o 16lib-$(CONFIG_PLATFORM_MINGW32) += net.o
16lib-$(CONFIG_PLATFORM_MINGW32) += inet_pton.o
17lib-$(CONFIG_PLATFORM_MINGW32) += poll.o 17lib-$(CONFIG_PLATFORM_MINGW32) += poll.o
18lib-$(CONFIG_PLATFORM_MINGW32) += select.o
19lib-$(CONFIG_PLATFORM_MINGW32) += popen.o 18lib-$(CONFIG_PLATFORM_MINGW32) += popen.o
19lib-$(CONFIG_PLATFORM_MINGW32) += regex.o
20lib-$(CONFIG_PLATFORM_MINGW32) += select.o
21lib-$(CONFIG_FEATURE_PRNG_SHELL) += sh_random.o
20lib-$(CONFIG_PLATFORM_MINGW32) += statfs.o 22lib-$(CONFIG_PLATFORM_MINGW32) += statfs.o
21lib-$(CONFIG_PLATFORM_MINGW32) += mntent.o
22lib-$(CONFIG_PLATFORM_MINGW32) += strptime.o 23lib-$(CONFIG_PLATFORM_MINGW32) += strptime.o
23lib-$(CONFIG_PLATFORM_MINGW32) += system.o 24lib-$(CONFIG_PLATFORM_MINGW32) += system.o
24lib-$(CONFIG_PLATFORM_MINGW32) += termios.o 25lib-$(CONFIG_PLATFORM_MINGW32) += termios.o
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}