Mercurial > dropbear
comparison dbrandom.c @ 1916:3f4cdf839a1a
Make SHA1 optional, implement SHA256 fingerprints
SHA256 is always compiled and only enable SHA1 when needed. Fingerprints
are always SHA256: base64 format, md5 and sha1 are removed. dbrandom now
uses sha256 its hash function.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 30 Mar 2022 11:44:04 +0800 |
parents | 833bf9947603 |
children |
comparison
equal
deleted
inserted
replaced
1915:13cb8cc1b0e4 | 1916:3f4cdf839a1a |
---|---|
32 /* this is used to generate unique output from the same hashpool */ | 32 /* this is used to generate unique output from the same hashpool */ |
33 static uint32_t counter = 0; | 33 static uint32_t counter = 0; |
34 /* the max value for the counter, so it won't integer overflow */ | 34 /* the max value for the counter, so it won't integer overflow */ |
35 #define MAX_COUNTER (1<<30) | 35 #define MAX_COUNTER (1<<30) |
36 | 36 |
37 static unsigned char hashpool[SHA1_HASH_SIZE] = {0}; | 37 static unsigned char hashpool[SHA256_HASH_SIZE] = {0}; |
38 static int donerandinit = 0; | 38 static int donerandinit = 0; |
39 | 39 |
40 #define INIT_SEED_SIZE 32 /* 256 bits */ | 40 #define INIT_SEED_SIZE 32 /* 256 bits */ |
41 | 41 |
42 /* The basic setup is we read some data from /dev/(u)random or prngd and hash it | 42 /* The basic setup is we read some data from /dev/(u)random or prngd and hash it |
98 /* whole file was read as requested */ | 98 /* whole file was read as requested */ |
99 break; | 99 break; |
100 } | 100 } |
101 goto out; | 101 goto out; |
102 } | 102 } |
103 sha1_process(hs, readbuf, readlen); | 103 sha256_process(hs, readbuf, readlen); |
104 readcount += readlen; | 104 readcount += readlen; |
105 } | 105 } |
106 ret = DROPBEAR_SUCCESS; | 106 ret = DROPBEAR_SUCCESS; |
107 out: | 107 out: |
108 close(readfd); | 108 close(readfd); |
118 return; | 118 return; |
119 } | 119 } |
120 #endif | 120 #endif |
121 | 121 |
122 /* hash in the new seed data */ | 122 /* hash in the new seed data */ |
123 sha1_init(&hs); | 123 sha256_init(&hs); |
124 /* existing state (zeroes on startup) */ | 124 /* existing state (zeroes on startup) */ |
125 sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); | 125 sha256_process(&hs, (void*)hashpool, sizeof(hashpool)); |
126 | 126 |
127 /* new */ | 127 /* new */ |
128 sha1_process(&hs, buf, len); | 128 sha256_process(&hs, buf, len); |
129 sha1_done(&hs, hashpool); | 129 sha256_done(&hs, hashpool); |
130 } | 130 } |
131 | 131 |
132 static void write_urandom() | 132 static void write_urandom() |
133 { | 133 { |
134 #if DROPBEAR_FUZZ | 134 #if DROPBEAR_FUZZ |
150 } | 150 } |
151 | 151 |
152 #if DROPBEAR_FUZZ | 152 #if DROPBEAR_FUZZ |
153 void fuzz_seed(const unsigned char* dat, unsigned int len) { | 153 void fuzz_seed(const unsigned char* dat, unsigned int len) { |
154 hash_state hs; | 154 hash_state hs; |
155 sha1_init(&hs); | 155 sha256_init(&hs); |
156 sha1_process(&hs, "fuzzfuzzfuzz", strlen("fuzzfuzzfuzz")); | 156 sha256_process(&hs, "fuzzfuzzfuzz", strlen("fuzzfuzzfuzz")); |
157 sha1_process(&hs, dat, len); | 157 sha256_process(&hs, dat, len); |
158 sha1_done(&hs, hashpool); | 158 sha256_done(&hs, hashpool); |
159 counter = 0; | 159 counter = 0; |
160 donerandinit = 1; | 160 donerandinit = 1; |
161 } | 161 } |
162 #endif | 162 #endif |
163 | 163 |
207 break; | 207 break; |
208 } | 208 } |
209 | 209 |
210 if (ret == sizeof(buf)) { | 210 if (ret == sizeof(buf)) { |
211 /* Success, stir in the entropy */ | 211 /* Success, stir in the entropy */ |
212 sha1_process(hs, (void*)buf, sizeof(buf)); | 212 sha256_process(hs, (void*)buf, sizeof(buf)); |
213 return DROPBEAR_SUCCESS; | 213 return DROPBEAR_SUCCESS; |
214 } | 214 } |
215 | 215 |
216 return DROPBEAR_FAILURE; | 216 return DROPBEAR_FAILURE; |
217 | 217 |
219 #endif /* HAVE_GETRANDOM */ | 219 #endif /* HAVE_GETRANDOM */ |
220 | 220 |
221 /* Initialise the prng from /dev/urandom or prngd. This function can | 221 /* Initialise the prng from /dev/urandom or prngd. This function can |
222 * be called multiple times */ | 222 * be called multiple times */ |
223 void seedrandom() { | 223 void seedrandom() { |
224 | |
225 hash_state hs; | 224 hash_state hs; |
226 | 225 |
227 pid_t pid; | 226 pid_t pid; |
228 struct timeval tv; | 227 struct timeval tv; |
229 clock_t clockval; | 228 clock_t clockval; |
234 return; | 233 return; |
235 } | 234 } |
236 #endif | 235 #endif |
237 | 236 |
238 /* hash in the new seed data */ | 237 /* hash in the new seed data */ |
239 sha1_init(&hs); | 238 sha256_init(&hs); |
240 | 239 |
241 /* existing state */ | 240 /* existing state */ |
242 sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); | 241 sha256_process(&hs, (void*)hashpool, sizeof(hashpool)); |
243 | 242 |
244 #ifdef HAVE_GETRANDOM | 243 #ifdef HAVE_GETRANDOM |
245 if (process_getrandom(&hs) == DROPBEAR_SUCCESS) { | 244 if (process_getrandom(&hs) == DROPBEAR_SUCCESS) { |
246 urandom_seeded = 1; | 245 urandom_seeded = 1; |
247 } | 246 } |
287 process_file(&hs, "/proc/net/rt_cache", 4096, 0); | 286 process_file(&hs, "/proc/net/rt_cache", 4096, 0); |
288 process_file(&hs, "/proc/vmstat", 0, 0); | 287 process_file(&hs, "/proc/vmstat", 0, 0); |
289 #endif | 288 #endif |
290 | 289 |
291 pid = getpid(); | 290 pid = getpid(); |
292 sha1_process(&hs, (void*)&pid, sizeof(pid)); | 291 sha256_process(&hs, (void*)&pid, sizeof(pid)); |
293 | 292 |
294 /* gettimeofday() doesn't completely fill out struct timeval on | 293 /* gettimeofday() doesn't completely fill out struct timeval on |
295 OS X (10.8.3), avoid valgrind warnings by clearing it first */ | 294 OS X (10.8.3), avoid valgrind warnings by clearing it first */ |
296 memset(&tv, 0x0, sizeof(tv)); | 295 memset(&tv, 0x0, sizeof(tv)); |
297 gettimeofday(&tv, NULL); | 296 gettimeofday(&tv, NULL); |
298 sha1_process(&hs, (void*)&tv, sizeof(tv)); | 297 sha256_process(&hs, (void*)&tv, sizeof(tv)); |
299 | 298 |
300 clockval = clock(); | 299 clockval = clock(); |
301 sha1_process(&hs, (void*)&clockval, sizeof(clockval)); | 300 sha256_process(&hs, (void*)&clockval, sizeof(clockval)); |
302 | 301 |
303 /* When a private key is read by the client or server it will | 302 /* When a private key is read by the client or server it will |
304 * be added to the hashpool - see runopts.c */ | 303 * be added to the hashpool - see runopts.c */ |
305 | 304 |
306 sha1_done(&hs, hashpool); | 305 sha256_done(&hs, hashpool); |
307 | 306 |
308 counter = 0; | 307 counter = 0; |
309 donerandinit = 1; | 308 donerandinit = 1; |
310 | 309 |
311 /* Feed it all back into /dev/urandom - this might help if Dropbear | 310 /* Feed it all back into /dev/urandom - this might help if Dropbear |
315 | 314 |
316 /* return len bytes of pseudo-random data */ | 315 /* return len bytes of pseudo-random data */ |
317 void genrandom(unsigned char* buf, unsigned int len) { | 316 void genrandom(unsigned char* buf, unsigned int len) { |
318 | 317 |
319 hash_state hs; | 318 hash_state hs; |
320 unsigned char hash[SHA1_HASH_SIZE]; | 319 unsigned char hash[SHA256_HASH_SIZE]; |
321 unsigned int copylen; | 320 unsigned int copylen; |
322 | 321 |
323 if (!donerandinit) { | 322 if (!donerandinit) { |
324 dropbear_exit("seedrandom not done"); | 323 dropbear_exit("seedrandom not done"); |
325 } | 324 } |
326 | 325 |
327 while (len > 0) { | 326 while (len > 0) { |
328 sha1_init(&hs); | 327 sha256_init(&hs); |
329 sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); | 328 sha256_process(&hs, (void*)hashpool, sizeof(hashpool)); |
330 sha1_process(&hs, (void*)&counter, sizeof(counter)); | 329 sha256_process(&hs, (void*)&counter, sizeof(counter)); |
331 sha1_done(&hs, hash); | 330 sha256_done(&hs, hash); |
332 | 331 |
333 counter++; | 332 counter++; |
334 if (counter > MAX_COUNTER) { | 333 if (counter > MAX_COUNTER) { |
335 seedrandom(); | 334 seedrandom(); |
336 } | 335 } |
337 | 336 |
338 copylen = MIN(len, SHA1_HASH_SIZE); | 337 copylen = MIN(len, SHA256_HASH_SIZE); |
339 memcpy(buf, hash, copylen); | 338 memcpy(buf, hash, copylen); |
340 len -= copylen; | 339 len -= copylen; |
341 buf += copylen; | 340 buf += copylen; |
342 } | 341 } |
343 m_burn(hash, sizeof(hash)); | 342 m_burn(hash, sizeof(hash)); |