Home | History | Annotate | Line # | Download | only in libcrypto
      1 /*	$NetBSD: rnd_keys.c,v 1.1 2025/07/17 14:25:26 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 
     12 void
     13 des_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  */
     24 int
     25 des_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  */
     61 void
     62 des_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), "%ld%ld%d%s%d%lld",
     81 	    when.tv_sec, when.tv_usec, getpid(), hname, getuid(),
     82 	    (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