-
Notifications
You must be signed in to change notification settings - Fork 3
/
u_random.c
69 lines (55 loc) · 1.58 KB
/
u_random.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "deconz/u_assert.h"
#include "deconz/u_random.h"
/* support multiple implementations, select first available at runtime */
extern U_rand_bytes_fp U_InitRandBytesOpenssl(void);
extern U_rand_bytes_fp U_InitRandBytesGetEntropy(void);
static U_rand_bytes_fp rand_bytes_impl;
/* rudimentary test if it works */
static void test_rand_implementation(unsigned char *buf, unsigned bufsize)
{
unsigned i;
unsigned c;
if (!rand_bytes_impl)
return;
for (i = 0; i < bufsize; i++)
buf[i] = 1;
rand_bytes_impl(buf, bufsize);
for (c = 0, i = 0; i < bufsize; i++)
c += buf[i];
U_ASSERT(c != bufsize && "rand_bytes implementation suspicious");
if (c == bufsize)
rand_bytes_impl = 0;
}
int U_RandomBytes(unsigned char *buf, unsigned bufsize)
{
U_ASSERT(buf);
if (!buf || bufsize == 0)
return 0;
if (!rand_bytes_impl)
{
/*
* Try to find a working implementation of OS or 3rd party library
* high entropy random bytes function.
*/
#ifdef PL_UNIX
if (!rand_bytes_impl)
{
rand_bytes_impl = U_InitRandBytesGetEntropy();
test_rand_implementation(buf, bufsize);
}
#endif
#ifdef HAS_OPENSSL
if (!rand_bytes_impl)
{
rand_bytes_impl = U_InitRandBytesOpenssl();
test_rand_implementation(buf, bufsize);
}
#endif
if (!rand_bytes_impl)
goto no_impl;
}
return rand_bytes_impl(buf, bufsize);
no_impl:
U_ASSERT(0 && "no rand_bytes implementation available");
return 0;
}