1/* $NetBSD: ornd_keys.c,v 1.3 2008/12/28 23:20:03 christos Exp $ */ 2 3#include "des_locl.h" 4#include <sys/time.h> 5#include <sys/types.h> 6 7#include <fcntl.h> 8#include <unistd.h> 9 10#include <sha1.h> 11 12void 13des_set_random_generator_seed(des_cblock *seed) 14{ 15 16 des_random_seed(seed); 17} 18 19/* 20 * Generate a sequence of random des keys 21 * using the random block sequence, fixup 22 * parity and skip weak keys. 23 */ 24int 25des_new_random_key(des_cblock *key) 26{ 27 int urandom; 28 29 again: 30 urandom = open("/dev/urandom", O_RDONLY); 31 32 if (urandom < 0) 33 des_random_key(key); 34 else { 35 if (read(urandom, key, 36 sizeof(des_cblock)) != sizeof(des_cblock)) { 37 close(urandom); 38 des_random_key(key); 39 } else 40 close(urandom); 41 } 42 43 /* random key must have odd parity and not be weak */ 44 des_set_odd_parity(key); 45 if (des_is_weak_key(key)) 46 goto again; 47 48 return (0); 49} 50 51/* 52 * des_init_random_number_generator: 53 * 54 * This routine takes a secret key possibly shared by a number of servers 55 * and uses it to generate a random number stream that is not shared by 56 * any of the other servers. It does this by using the current process id, 57 * host id, and the current time to the nearest second. The resulting 58 * stream seed is not useful information for cracking the secret key. 59 * Moreover, this routine keeps no copy of the secret key. 60 */ 61void 62des_init_random_number_generator(des_cblock *seed) 63{ 64 u_int64_t seed_q; 65 des_cblock seed_new; 66 SHA1_CTX sha; 67 68 u_char results[20]; 69 char hname[64], accum[512]; 70 71 struct timeval when; 72 73 SHA1Init(&sha); 74 75 gethostname(hname, sizeof(hname) - 1); 76 gettimeofday(&when, NULL); 77 78 memcpy(&seed_q, seed, sizeof(seed_q)); 79 80 snprintf(accum, sizeof(accum), "%lld%ld%d%s%d%lld", 81 (long long)when.tv_sec, (long)when.tv_usec, getpid(), hname, 82 getuid(), (long long)seed_q); 83 84 SHA1Update(&sha, (u_char *) accum, strlen(accum)); 85 86 memset(accum, 0, sizeof(accum)); 87 88 SHA1Final(results, &sha); 89 90 memcpy(seed_new, results, sizeof(seed_new)); 91 des_random_seed(&seed_new); 92 93 memset(seed_new, 0, sizeof(seed_new)); 94 memset(results, 0, sizeof(results)); 95} 96