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