aboutsummaryrefslogtreecommitdiff
path: root/win32/sh_random.c
diff options
context:
space:
mode:
Diffstat (limited to 'win32/sh_random.c')
-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}