xref: /netbsd-src/crypto/external/bsd/openssl/lib/libcrypto/rnd_keys.c (revision 4840a75dea5149532eae7e7c2860c9fc563e1f88)
1 /*	$NetBSD: rnd_keys.c,v 1.2 2014/03/27 16:26:22 apb 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
des_set_random_generator_seed(des_cblock * seed)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
des_new_random_key(des_cblock * key)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
des_init_random_number_generator(des_cblock * seed)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