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$ */