Mercurial > dropbear
comparison libtomcrypt/src/prngs/rng_get_bytes.c @ 1471:6dba84798cd5
Update to libtomcrypt 1.18.1, merged with Dropbear changes
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 09 Feb 2018 21:44:05 +0800 |
parents | f849a5ca2efc |
children |
comparison
equal
deleted
inserted
replaced
1470:8bba51a55704 | 1471:6dba84798cd5 |
---|---|
3 * LibTomCrypt is a library that provides various cryptographic | 3 * LibTomCrypt is a library that provides various cryptographic |
4 * algorithms in a highly modular and flexible manner. | 4 * algorithms in a highly modular and flexible manner. |
5 * | 5 * |
6 * The library is free for all purposes without any express | 6 * The library is free for all purposes without any express |
7 * guarantee it works. | 7 * guarantee it works. |
8 * | |
9 * Tom St Denis, [email protected], http://libtom.org | |
10 */ | 8 */ |
11 #include "tomcrypt.h" | 9 #include "tomcrypt.h" |
12 | 10 |
13 /** | 11 #ifdef LTC_RNG_GET_BYTES |
12 /** | |
14 @file rng_get_bytes.c | 13 @file rng_get_bytes.c |
15 portable way to get secure random bits to feed a PRNG (Tom St Denis) | 14 portable way to get secure random bits to feed a PRNG (Tom St Denis) |
16 */ | 15 */ |
17 | 16 |
18 #ifdef LTC_DEVRANDOM | 17 #if defined(LTC_DEVRANDOM) && !defined(_WIN32) |
19 /* on *NIX read /dev/random */ | 18 /* on *NIX read /dev/random */ |
20 static unsigned long rng_nix(unsigned char *buf, unsigned long len, | 19 static unsigned long _rng_nix(unsigned char *buf, unsigned long len, |
21 void (*callback)(void)) | 20 void (*callback)(void)) |
22 { | 21 { |
23 #ifdef LTC_NO_FILE | 22 #ifdef LTC_NO_FILE |
23 LTC_UNUSED_PARAM(callback); | |
24 LTC_UNUSED_PARAM(buf); | |
25 LTC_UNUSED_PARAM(len); | |
24 return 0; | 26 return 0; |
25 #else | 27 #else |
26 FILE *f; | 28 FILE *f; |
27 unsigned long x; | 29 unsigned long x; |
28 #ifdef TRY_URANDOM_FIRST | 30 LTC_UNUSED_PARAM(callback); |
31 #ifdef LTC_TRY_URANDOM_FIRST | |
29 f = fopen("/dev/urandom", "rb"); | 32 f = fopen("/dev/urandom", "rb"); |
30 if (f == NULL) | 33 if (f == NULL) |
31 #endif /* TRY_URANDOM_FIRST */ | 34 #endif /* LTC_TRY_URANDOM_FIRST */ |
32 f = fopen("/dev/random", "rb"); | 35 f = fopen("/dev/random", "rb"); |
33 | 36 |
34 if (f == NULL) { | 37 if (f == NULL) { |
35 return 0; | 38 return 0; |
36 } | 39 } |
37 | 40 |
38 /* disable buffering */ | 41 /* disable buffering */ |
39 if (setvbuf(f, NULL, _IONBF, 0) != 0) { | 42 if (setvbuf(f, NULL, _IONBF, 0) != 0) { |
40 fclose(f); | 43 fclose(f); |
41 return 0; | 44 return 0; |
42 } | 45 } |
43 | 46 |
44 x = (unsigned long)fread(buf, 1, (size_t)len, f); | 47 x = (unsigned long)fread(buf, 1, (size_t)len, f); |
45 fclose(f); | 48 fclose(f); |
46 return x; | 49 return x; |
47 #endif /* LTC_NO_FILE */ | 50 #endif /* LTC_NO_FILE */ |
48 } | 51 } |
49 | 52 |
50 #endif /* LTC_DEVRANDOM */ | 53 #endif /* LTC_DEVRANDOM */ |
51 | 54 |
52 /* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */ | 55 #if !defined(_WIN32_WCE) |
53 #if defined(CLOCKS_PER_SEC) && !defined(WINCE) | |
54 | 56 |
55 #define ANSI_RNG | 57 #define ANSI_RNG |
56 | 58 |
57 static unsigned long rng_ansic(unsigned char *buf, unsigned long len, | 59 static unsigned long _rng_ansic(unsigned char *buf, unsigned long len, |
58 void (*callback)(void)) | 60 void (*callback)(void)) |
59 { | 61 { |
60 clock_t t1; | 62 clock_t t1; |
61 int l, acc, bits, a, b; | 63 int l, acc, bits, a, b; |
62 | |
63 if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) { | |
64 return 0; | |
65 } | |
66 | 64 |
67 l = len; | 65 l = len; |
68 bits = 8; | 66 bits = 8; |
69 acc = a = b = 0; | 67 acc = a = b = 0; |
70 while (len--) { | 68 while (len--) { |
74 t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1; | 72 t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1; |
75 t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1; | 73 t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1; |
76 } while (a == b); | 74 } while (a == b); |
77 acc = (acc << 1) | a; | 75 acc = (acc << 1) | a; |
78 } | 76 } |
79 *buf++ = acc; | 77 *buf++ = acc; |
80 acc = 0; | 78 acc = 0; |
81 bits = 8; | 79 bits = 8; |
82 } | 80 } |
83 acc = bits = a = b = 0; | |
84 return l; | 81 return l; |
85 } | 82 } |
86 | 83 |
87 #endif | 84 #endif |
88 | 85 |
89 /* Try the Microsoft CSP */ | 86 /* Try the Microsoft CSP */ |
90 #if defined(WIN32) || defined(WINCE) | 87 #if defined(_WIN32) || defined(_WIN32_WCE) |
91 #define _WIN32_WINNT 0x0400 | 88 #ifndef _WIN32_WINNT |
92 #ifdef WINCE | 89 #define _WIN32_WINNT 0x0400 |
90 #endif | |
91 #ifdef _WIN32_WCE | |
93 #define UNDER_CE | 92 #define UNDER_CE |
94 #define ARM | 93 #define ARM |
95 #endif | 94 #endif |
95 | |
96 #define WIN32_LEAN_AND_MEAN | |
96 #include <windows.h> | 97 #include <windows.h> |
97 #include <wincrypt.h> | 98 #include <wincrypt.h> |
98 | 99 |
99 static unsigned long rng_win32(unsigned char *buf, unsigned long len, | 100 static unsigned long _rng_win32(unsigned char *buf, unsigned long len, |
100 void (*callback)(void)) | 101 void (*callback)(void)) |
101 { | 102 { |
102 HCRYPTPROV hProv = 0; | 103 HCRYPTPROV hProv = 0; |
103 if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, | 104 LTC_UNUSED_PARAM(callback); |
104 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && | 105 if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, |
105 !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, | 106 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && |
107 !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, | |
106 CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) | 108 CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) |
107 return 0; | 109 return 0; |
108 | 110 |
109 if (CryptGenRandom(hProv, len, buf) == TRUE) { | 111 if (CryptGenRandom(hProv, len, buf) == TRUE) { |
110 CryptReleaseContext(hProv, 0); | 112 CryptReleaseContext(hProv, 0); |
121 Read the system RNG | 123 Read the system RNG |
122 @param out Destination | 124 @param out Destination |
123 @param outlen Length desired (octets) | 125 @param outlen Length desired (octets) |
124 @param callback Pointer to void function to act as "callback" when RNG is slow. This can be NULL | 126 @param callback Pointer to void function to act as "callback" when RNG is slow. This can be NULL |
125 @return Number of octets read | 127 @return Number of octets read |
126 */ | 128 */ |
127 unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen, | 129 unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen, |
128 void (*callback)(void)) | 130 void (*callback)(void)) |
129 { | 131 { |
130 unsigned long x; | 132 unsigned long x; |
131 | 133 |
132 LTC_ARGCHK(out != NULL); | 134 LTC_ARGCHK(out != NULL); |
133 | 135 |
134 #if defined(LTC_DEVRANDOM) | 136 #ifdef LTC_PRNG_ENABLE_LTC_RNG |
135 x = rng_nix(out, outlen, callback); if (x != 0) { return x; } | 137 if (ltc_rng) { |
138 x = ltc_rng(out, outlen, callback); | |
139 if (x != 0) { | |
140 return x; | |
141 } | |
142 } | |
136 #endif | 143 #endif |
137 #ifdef WIN32 | 144 |
138 x = rng_win32(out, outlen, callback); if (x != 0) { return x; } | 145 #if defined(_WIN32) || defined(_WIN32_WCE) |
146 x = _rng_win32(out, outlen, callback); if (x != 0) { return x; } | |
147 #elif defined(LTC_DEVRANDOM) | |
148 x = _rng_nix(out, outlen, callback); if (x != 0) { return x; } | |
139 #endif | 149 #endif |
140 #ifdef ANSI_RNG | 150 #ifdef ANSI_RNG |
141 x = rng_ansic(out, outlen, callback); if (x != 0) { return x; } | 151 x = _rng_ansic(out, outlen, callback); if (x != 0) { return x; } |
142 #endif | 152 #endif |
143 return 0; | 153 return 0; |
144 } | 154 } |
155 #endif /* #ifdef LTC_RNG_GET_BYTES */ | |
145 | 156 |
146 /* $Source$ */ | 157 /* ref: $Format:%D$ */ |
147 /* $Revision$ */ | 158 /* git commit: $Format:%H$ */ |
148 /* $Date$ */ | 159 /* commit time: $Format:%ai$ */ |