Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tomcrypt/src/prngs/rng_get_bytes.c
5971 views
1
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2
*
3
* LibTomCrypt is a library that provides various cryptographic
4
* algorithms in a highly modular and flexible manner.
5
*
6
* The library is free for all purposes without any express
7
* guarantee it works.
8
*/
9
#include "tomcrypt.h"
10
11
#ifdef LTC_RNG_GET_BYTES
12
/**
13
@file rng_get_bytes.c
14
portable way to get secure random bits to feed a PRNG (Tom St Denis)
15
*/
16
17
#if defined(LTC_DEVRANDOM) && !defined(_WIN32)
18
/* on *NIX read /dev/random */
19
static unsigned long _rng_nix(unsigned char *buf, unsigned long len,
20
void (*callback)(void))
21
{
22
#ifdef LTC_NO_FILE
23
LTC_UNUSED_PARAM(callback);
24
LTC_UNUSED_PARAM(buf);
25
LTC_UNUSED_PARAM(len);
26
return 0;
27
#else
28
FILE *f;
29
unsigned long x;
30
LTC_UNUSED_PARAM(callback);
31
#ifdef LTC_TRY_URANDOM_FIRST
32
f = fopen("/dev/urandom", "rb");
33
if (f == NULL)
34
#endif /* LTC_TRY_URANDOM_FIRST */
35
f = fopen("/dev/random", "rb");
36
37
if (f == NULL) {
38
return 0;
39
}
40
41
/* disable buffering */
42
if (setvbuf(f, NULL, _IONBF, 0) != 0) {
43
fclose(f);
44
return 0;
45
}
46
47
x = (unsigned long)fread(buf, 1, (size_t)len, f);
48
fclose(f);
49
return x;
50
#endif /* LTC_NO_FILE */
51
}
52
53
#endif /* LTC_DEVRANDOM */
54
55
#if !defined(_WIN32_WCE)
56
57
#define ANSI_RNG
58
59
static unsigned long _rng_ansic(unsigned char *buf, unsigned long len,
60
void (*callback)(void))
61
{
62
clock_t t1;
63
int l, acc, bits, a, b;
64
65
l = len;
66
bits = 8;
67
acc = a = b = 0;
68
while (len--) {
69
if (callback != NULL) callback();
70
while (bits--) {
71
do {
72
t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1;
73
t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1;
74
} while (a == b);
75
acc = (acc << 1) | a;
76
}
77
*buf++ = acc;
78
acc = 0;
79
bits = 8;
80
}
81
return l;
82
}
83
84
#endif
85
86
/* Try the Microsoft CSP */
87
#if defined(_WIN32) || defined(_WIN32_WCE)
88
#ifndef _WIN32_WINNT
89
#define _WIN32_WINNT 0x0400
90
#endif
91
#ifdef _WIN32_WCE
92
#define UNDER_CE
93
#define ARM
94
#endif
95
96
#define WIN32_LEAN_AND_MEAN
97
#include <windows.h>
98
#include <ntsecapi.h>
99
100
static unsigned long _rng_win32(unsigned char *buf, unsigned long len,
101
void (*callback)(void))
102
{
103
LTC_UNUSED_PARAM(callback);
104
RtlGenRandom(buf, len);
105
return len;
106
}
107
108
#endif /* WIN32 */
109
110
/**
111
Read the system RNG
112
@param out Destination
113
@param outlen Length desired (octets)
114
@param callback Pointer to void function to act as "callback" when RNG is slow. This can be NULL
115
@return Number of octets read
116
*/
117
unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen,
118
void (*callback)(void))
119
{
120
unsigned long x;
121
122
LTC_ARGCHK(out != NULL);
123
124
#ifdef LTC_PRNG_ENABLE_LTC_RNG
125
if (ltc_rng) {
126
x = ltc_rng(out, outlen, callback);
127
if (x != 0) {
128
return x;
129
}
130
}
131
#endif
132
133
#if defined(_WIN32) || defined(_WIN32_WCE)
134
x = _rng_win32(out, outlen, callback); if (x != 0) { return x; }
135
#elif defined(LTC_DEVRANDOM)
136
x = _rng_nix(out, outlen, callback); if (x != 0) { return x; }
137
#endif
138
#ifdef ANSI_RNG
139
x = _rng_ansic(out, outlen, callback); if (x != 0) { return x; }
140
#endif
141
return 0;
142
}
143
#endif /* #ifdef LTC_RNG_GET_BYTES */
144
145