From 1013bcab9c4c3269c377ffc5c98508a6ef245df9 Mon Sep 17 00:00:00 2001 From: thorpej Date: Wed, 21 Jun 2000 19:46:16 +0000 Subject: [PATCH] Add cleaned up versions of des_set_random_generator_seed(), des_new_random_key(), and des_init_random_number_generator() from the crypto-us libdes. While I'm here, fix a serious bug in des_init_random_number_generator() whereby the accumlated data to be hashed was zero'd *before* actually being hashed. NOTE: The bug only affects people who are not using the rnd(4) in-kernel random number generator, and it is worth noting that the resulting keys are not always the same, but are likely easy to determine. --- lib/libcrypto/rnd_keys.c | 95 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 lib/libcrypto/rnd_keys.c diff --git a/lib/libcrypto/rnd_keys.c b/lib/libcrypto/rnd_keys.c new file mode 100644 index 000000000000..4c6b6cc7f8ee --- /dev/null +++ b/lib/libcrypto/rnd_keys.c @@ -0,0 +1,95 @@ +/* $NetBSD: rnd_keys.c,v 1.1 2000/06/21 19:46:16 thorpej Exp $ */ + +#include "des_locl.h" +#include +#include + +#include +#include + +#include + +void +des_set_random_generator_seed(des_cblock *seed) +{ + + des_random_seed(seed); +} + +/* + * Generate a sequence of random des keys + * using the random block sequence, fixup + * parity and skip weak keys. + */ +int +des_new_random_key(des_cblock *key) +{ + int urandom; + + again: + urandom = open("/dev/urandom", O_RDONLY); + + if (urandom < 0) + des_random_key(key); + else { + if (read(urandom, key, + sizeof(des_cblock)) != sizeof(des_cblock)) { + close(urandom); + des_random_key(key); + } else + close(urandom); + } + + /* random key must have odd parity and not be weak */ + des_set_odd_parity(key); + if (des_is_weak_key(key)) + goto again; + + return (0); +} + +/* + * des_init_random_number_generator: + * + * This routine takes a secret key possibly shared by a number of servers + * and uses it to generate a random number stream that is not shared by + * any of the other servers. It does this by using the current process id, + * host id, and the current time to the nearest second. The resulting + * stream seed is not useful information for cracking the secret key. + * Moreover, this routine keeps no copy of the secret key. + */ +void +des_init_random_number_generator(des_cblock *seed) +{ + u_int64_t seed_q; + des_cblock seed_new; + SHA1_CTX sha; + + u_char results[20]; + char hname[64], accum[512]; + + struct timeval when; + + SHA1Init(&sha); + + gethostname(hname, sizeof(hname - 1)); + gettimeofday(&when, NULL); + + memcpy(&seed_q, seed, sizeof(seed_q)); + + snprintf(accum, sizeof(accum), "%ld%ld%d%s%d%qd", + when.tv_sec, when.tv_usec, getpid(), hname, getuid(), + (long long) seed_q); + + SHA1Update(&sha, (u_char *) accum, strlen(accum)); + + memset(accum, 0, sizeof(accum)); + + SHA1Final(results, &sha); + + memcpy(seed_new, results, sizeof(seed_new)); + des_random_seed(&seed_new); + + memset(seed_new, 0, sizeof(seed_new)); + memset(results, 0, sizeof(results)); +}