Mercurial > dropbear
comparison random.c @ 347:381834084475 debug-unrandom
be sure not to include uninitialised buffers in the unrandom number
generator
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 04 Aug 2006 17:37:45 +0000 |
parents | 959c66ccf1b5 |
children | e66eec4dcba7 |
comparison
equal
deleted
inserted
replaced
346:ed24dfc44904 | 347:381834084475 |
---|---|
36 | 36 |
37 static unsigned char hashpool[SHA1_HASH_SIZE]; | 37 static unsigned char hashpool[SHA1_HASH_SIZE]; |
38 | 38 |
39 #define INIT_SEED_SIZE 32 /* 256 bits */ | 39 #define INIT_SEED_SIZE 32 /* 256 bits */ |
40 | 40 |
41 static void readrand(unsigned char* buf, unsigned int buflen); | |
42 | |
43 /* The basic setup is we read some data from /dev/(u)random or prngd and hash it | |
44 * into hashpool. To read data, we hash together current hashpool contents, | |
45 * and a counter. We feed more data in by hashing the current pool and new | |
46 * data into the pool. | |
47 * | |
48 * It is important to ensure that counter doesn't wrap around before we | |
49 * feed in new entropy. | |
50 * | |
51 */ | |
52 | |
53 static void readrand(unsigned char* buf, unsigned int buflen) { | |
54 | |
55 static int already_blocked = 0; | |
56 int readfd; | |
57 unsigned int readpos; | |
58 int readlen; | |
59 #ifdef DROPBEAR_PRNGD_SOCKET | |
60 struct sockaddr_un egdsock; | |
61 char egdcmd[2]; | |
62 #endif | |
63 | |
64 #ifdef DROPBEAR_RANDOM_DEV | |
65 readfd = open(DROPBEAR_RANDOM_DEV, O_RDONLY); | |
66 if (readfd < 0) { | |
67 dropbear_exit("couldn't open random device"); | |
68 } | |
69 #endif | |
70 | |
71 #ifdef DROPBEAR_PRNGD_SOCKET | |
72 memset((void*)&egdsock, 0x0, sizeof(egdsock)); | |
73 egdsock.sun_family = AF_UNIX; | |
74 strlcpy(egdsock.sun_path, DROPBEAR_PRNGD_SOCKET, | |
75 sizeof(egdsock.sun_path)); | |
76 | |
77 readfd = socket(PF_UNIX, SOCK_STREAM, 0); | |
78 if (readfd < 0) { | |
79 dropbear_exit("couldn't open random device"); | |
80 } | |
81 /* todo - try various common locations */ | |
82 if (connect(readfd, (struct sockaddr*)&egdsock, | |
83 sizeof(struct sockaddr_un)) < 0) { | |
84 dropbear_exit("couldn't open random device"); | |
85 } | |
86 | |
87 if (buflen > 255) | |
88 dropbear_exit("can't request more than 255 bytes from egd"); | |
89 egdcmd[0] = 0x02; /* blocking read */ | |
90 egdcmd[1] = (unsigned char)buflen; | |
91 if (write(readfd, egdcmd, 2) < 0) | |
92 dropbear_exit("can't send command to egd"); | |
93 #endif | |
94 | |
95 /* read the actual random data */ | |
96 | |
97 close (readfd); | |
98 } | |
99 | |
100 /* initialise the prng from /dev/(u)random or prngd */ | 41 /* initialise the prng from /dev/(u)random or prngd */ |
101 void seedrandom() { | 42 void seedrandom() { |
102 | |
103 unsigned char readbuf[INIT_SEED_SIZE]; | |
104 | |
105 hash_state hs; | |
106 | 43 |
107 /* initialise so that things won't warn about | 44 /* initialise so that things won't warn about |
108 * hashing an undefined buffer */ | 45 * hashing an undefined buffer */ |
109 if (!donerandinit) { | 46 m_burn(hashpool, sizeof(hashpool)); |
110 m_burn(hashpool, sizeof(hashpool)); | |
111 } | |
112 | |
113 /* get the seed data */ | |
114 readrand(readbuf, sizeof(readbuf)); | |
115 | |
116 /* hash in the new seed data */ | |
117 sha1_init(&hs); | |
118 sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); | |
119 sha1_process(&hs, (void*)readbuf, sizeof(readbuf)); | |
120 sha1_done(&hs, hashpool); | |
121 | 47 |
122 counter = 0; | 48 counter = 0; |
123 donerandinit = 1; | 49 donerandinit = 1; |
124 } | 50 } |
125 | 51 |