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.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/win32/sh_random.c b/win32/sh_random.c
new file mode 100644
index 000000000..10e942e80
--- /dev/null
+++ b/win32/sh_random.c
@@ -0,0 +1,59 @@
1#include "libbb.h"
2#include <ntsecapi.h>
3#include "../shell/random.h"
4
5/*
6 * Obtain a few bytes of random-ish data to initialise the generator.
7 * This is unlikely to be very robust: don't rely on it for
8 * anything that needs to be secure.
9 */
10static void get_entropy(uint32_t state[2])
11{
12#if defined(__MINGW64_VERSION_MAJOR) && \
13 (__MINGW64_VERSION_MAJOR >= 7 || defined(__MINGW64__))
14 if (!RtlGenRandom(state, sizeof(state[0])*2))
15#endif
16 GetSystemTimeAsFileTime((FILETIME *)state);
17
18#if 0
19 {
20 unsigned char *p = (unsigned char *)state;
21 int j;
22
23 for (j=0; j<8; ++j) {
24 fprintf(stderr, "%02x", *p++);
25 if ((j&3) == 3) {
26 fprintf(stderr, " ");
27 }
28 }
29 fprintf(stderr, "\n");
30 }
31#endif
32}
33
34ssize_t get_random_bytes(void *buf, ssize_t count)
35{
36 static random_t rnd;
37 ssize_t save_count = count;
38 uint32_t value;
39 unsigned char *ptr = (unsigned char *)&value;
40
41 if (buf == NULL || count < 0) {
42 errno = EINVAL;
43 return -1;
44 }
45
46 if (UNINITED_RANDOM_T(&rnd)) {
47 uint32_t state[2] = {0, 0};
48
49 get_entropy(state);
50 INIT_RANDOM_T(&rnd, state[0] ? state[0] : 1, state[1]);
51 }
52
53 for (;count > 0; buf+=4, count-=4) {
54 value = full_random(&rnd);
55 memcpy(buf, ptr, count >= 4 ? 4 : count);
56 }
57
58 return save_count;
59}