Mercurial > dropbear
annotate dbrandom.c @ 1306:34e6127ef02e
merge fixes from PuTTY import.c
toint() from misc.c
(revids are from hggit conversion)
changeset: 4620:60a336a6c85c
user: Simon Tatham <[email protected]>
date: Thu Feb 25 20:26:33 2016 +0000
files: import.c
description:
Fix potential segfaults in reading OpenSSH's ASN.1 key format.
The length coming back from ber_read_id_len might have overflowed, so
treat it as potentially negative. Also, while I'm here, accumulate it
inside ber_read_id_len as an unsigned, so as to avoid undefined
behaviour on integer overflow, and toint() it before return.
Thanks to Hanno Böck for spotting this, with the aid of AFL.
(cherry picked from commit 5b7833cd474a24ec098654dcba8cb9509f3bf2c1)
Conflicts:
import.c
(cherry-picker's note: resolving the conflict involved removing an
entire section of the original commit which fixed ECDSA code not
present on this branch)
changeset: 4619:9c6c638d98d8
user: Simon Tatham <[email protected]>
date: Sun Jul 14 10:45:54 2013 +0000
files: import.c ssh.c sshdss.c sshpubk.c sshrsa.c
description:
Tighten up a lot of casts from unsigned to int which are read by one
of the GET_32BIT macros and then used as length fields. Missing bounds
checks against zero have been added, and also I've introduced a helper
function toint() which casts from unsigned to int in such a way as to
avoid C undefined behaviour, since I'm not sure I trust compilers any
more to do the obviously sensible thing.
[originally from svn r9918]
changeset: 4618:3957829f24d3
user: Simon Tatham <[email protected]>
date: Mon Jul 08 22:36:04 2013 +0000
files: import.c sshdss.c sshrsa.c
description:
Add an assortment of extra safety checks.
[originally from svn r9896]
changeset: 4617:2cddee0bce12
user: Jacob Nevins <[email protected]>
date: Wed Dec 07 00:24:45 2005 +0000
files: import.c
description:
Institutional failure to memset() things pointed at rather than pointers.
Things should now be zeroed and memory not leaked. Spotted by Brant Thomsen.
[originally from svn r6476]
changeset: 4616:24ac78a9c71d
user: Simon Tatham <[email protected]>
date: Wed Feb 11 13:58:27 2004 +0000
files: import.c
description:
Jacob's last-minute testing found a couple of trivial bugs in
import.c, and my attempts to reproduce them in cmdgen found another
one there :-)
[originally from svn r3847]
changeset: 4615:088d39a73db0
user: Simon Tatham <[email protected]>
date: Thu Jan 22 18:52:49 2004 +0000
files: import.c
description:
Placate some gcc warnings.
[originally from svn r3761]
changeset: 4614:e4288bad4d93
parent: 1758:108b8924593d
user: Simon Tatham <[email protected]>
date: Fri Oct 03 21:21:23 2003 +0000
files: import.c
description:
My ASN.1 decoder returned wrong IDs for anything above 0x1E! Good
job it's never had to yet. Ahem.
[originally from svn r3479]
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 12 Jul 2016 23:00:01 +0800 |
parents | 9da3e7b4fe55 |
children | 750ec4ec4cbe b28624698130 |
rev | line source |
---|---|
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1 /* |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2 * Dropbear - a SSH2 server |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
3 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
4 * Copyright (c) 2002,2003 Matt Johnston |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
5 * All rights reserved. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
6 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
7 * Permission is hereby granted, free of charge, to any person obtaining a copy |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
8 * of this software and associated documentation files (the "Software"), to deal |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
9 * in the Software without restriction, including without limitation the rights |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
11 * copies of the Software, and to permit persons to whom the Software is |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
12 * furnished to do so, subject to the following conditions: |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
13 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
14 * The above copyright notice and this permission notice shall be included in |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
15 * all copies or substantial portions of the Software. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
16 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
23 * SOFTWARE. */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
24 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
25 #include "includes.h" |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
26 #include "buffer.h" |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
27 #include "dbutil.h" |
188
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
28 #include "bignum.h" |
858
220f55d540ae
rename random.h to dbrandom.h since some OSes have a system random.h
Matt Johnston <matt@ucc.asn.au>
parents:
857
diff
changeset
|
29 #include "dbrandom.h" |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
30 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
31 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
32 /* this is used to generate unique output from the same hashpool */ |
272
3be7ae2e8dfa
Only read /dev/random once when the program starts
Matt Johnston <matt@ucc.asn.au>
parents:
198
diff
changeset
|
33 static uint32_t counter = 0; |
298
7dad470ad4aa
minor cleanups for some warnings
Matt Johnston <matt@ucc.asn.au>
parents:
272
diff
changeset
|
34 /* the max value for the counter, so it won't integer overflow */ |
1274
9da3e7b4fe55
add parentheses to macro
Francois Perrad <francois.perrad@gadz.org>
parents:
1096
diff
changeset
|
35 #define MAX_COUNTER (1<<30) |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
36 |
687 | 37 static unsigned char hashpool[SHA1_HASH_SIZE] = {0}; |
38 static int donerandinit = 0; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
39 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
40 #define INIT_SEED_SIZE 32 /* 256 bits */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
41 |
149
ed9ca2a9705c
Cleaned up the random code, use /dev/random by default,
Matt Johnston <matt@ucc.asn.au>
parents:
70
diff
changeset
|
42 /* The basic setup is we read some data from /dev/(u)random or prngd and hash it |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
43 * into hashpool. To read data, we hash together current hashpool contents, |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
44 * and a counter. We feed more data in by hashing the current pool and new |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
45 * data into the pool. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
46 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
47 * It is important to ensure that counter doesn't wrap around before we |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
48 * feed in new entropy. |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
49 * |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
50 */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
51 |
687 | 52 /* Pass len=0 to hash an entire file */ |
53 static int | |
54 process_file(hash_state *hs, const char *filename, | |
55 unsigned int len, int prngd) | |
56 { | |
185
5ccad7634388
* warn if we seem to be blocking on /dev/random
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
57 static int already_blocked = 0; |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
58 int readfd; |
687 | 59 unsigned int readcount; |
60 int ret = DROPBEAR_FAILURE; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
61 |
149
ed9ca2a9705c
Cleaned up the random code, use /dev/random by default,
Matt Johnston <matt@ucc.asn.au>
parents:
70
diff
changeset
|
62 #ifdef DROPBEAR_PRNGD_SOCKET |
687 | 63 if (prngd) |
64 { | |
65 readfd = connect_unix(filename); | |
66 } | |
67 else | |
68 #endif | |
69 { | |
70 readfd = open(filename, O_RDONLY); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
71 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
72 |
687 | 73 if (readfd < 0) { |
74 goto out; | |
75 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
76 |
687 | 77 readcount = 0; |
694
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
78 while (len == 0 || readcount < len) |
687 | 79 { |
80 int readlen, wantread; | |
811
5de524aec047
limit how much we read from rt_cache etc
Matt Johnston <matt@ucc.asn.au>
parents:
737
diff
changeset
|
81 unsigned char readbuf[4096]; |
855
04ede40a529a
- Some fixes for old compilers like tru64 v4 from Daniel Richard G.
Matt Johnston <matt@ucc.asn.au>
parents:
843
diff
changeset
|
82 if (!already_blocked && !prngd) |
185
5ccad7634388
* warn if we seem to be blocking on /dev/random
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
83 { |
843
3a9ec98808c3
Fix shadowed "ret" variable
Matt Johnston <matt@ucc.asn.au>
parents:
835
diff
changeset
|
84 int res; |
855
04ede40a529a
- Some fixes for old compilers like tru64 v4 from Daniel Richard G.
Matt Johnston <matt@ucc.asn.au>
parents:
843
diff
changeset
|
85 struct timeval timeout; |
185
5ccad7634388
* warn if we seem to be blocking on /dev/random
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
86 fd_set read_fds; |
5ccad7634388
* warn if we seem to be blocking on /dev/random
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
87 |
855
04ede40a529a
- Some fixes for old compilers like tru64 v4 from Daniel Richard G.
Matt Johnston <matt@ucc.asn.au>
parents:
843
diff
changeset
|
88 timeout.tv_sec = 2; |
04ede40a529a
- Some fixes for old compilers like tru64 v4 from Daniel Richard G.
Matt Johnston <matt@ucc.asn.au>
parents:
843
diff
changeset
|
89 timeout.tv_usec = 0; |
04ede40a529a
- Some fixes for old compilers like tru64 v4 from Daniel Richard G.
Matt Johnston <matt@ucc.asn.au>
parents:
843
diff
changeset
|
90 |
185
5ccad7634388
* warn if we seem to be blocking on /dev/random
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
91 FD_ZERO(&read_fds); |
5ccad7634388
* warn if we seem to be blocking on /dev/random
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
92 FD_SET(readfd, &read_fds); |
843
3a9ec98808c3
Fix shadowed "ret" variable
Matt Johnston <matt@ucc.asn.au>
parents:
835
diff
changeset
|
93 res = select(readfd + 1, &read_fds, NULL, NULL, &timeout); |
3a9ec98808c3
Fix shadowed "ret" variable
Matt Johnston <matt@ucc.asn.au>
parents:
835
diff
changeset
|
94 if (res == 0) |
185
5ccad7634388
* warn if we seem to be blocking on /dev/random
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
95 { |
687 | 96 dropbear_log(LOG_WARNING, "Warning: Reading the randomness source '%s' seems to have blocked.\nYou may need to find a better entropy source.", filename); |
185
5ccad7634388
* warn if we seem to be blocking on /dev/random
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
97 already_blocked = 1; |
5ccad7634388
* warn if we seem to be blocking on /dev/random
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
98 } |
5ccad7634388
* warn if we seem to be blocking on /dev/random
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
99 } |
687 | 100 |
694
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
101 if (len == 0) |
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
102 { |
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
103 wantread = sizeof(readbuf); |
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
104 } |
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
105 else |
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
106 { |
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
107 wantread = MIN(sizeof(readbuf), len-readcount); |
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
108 } |
687 | 109 |
110 #ifdef DROPBEAR_PRNGD_SOCKET | |
111 if (prngd) | |
112 { | |
113 char egdcmd[2]; | |
114 egdcmd[0] = 0x02; /* blocking read */ | |
115 egdcmd[1] = (unsigned char)wantread; | |
116 if (write(readfd, egdcmd, 2) < 0) | |
117 { | |
118 dropbear_exit("Can't send command to egd"); | |
119 } | |
120 } | |
121 #endif | |
122 | |
123 readlen = read(readfd, readbuf, wantread); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
124 if (readlen <= 0) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
125 if (readlen < 0 && errno == EINTR) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
126 continue; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
127 } |
687 | 128 if (readlen == 0 && len == 0) |
129 { | |
130 /* whole file was read as requested */ | |
131 break; | |
132 } | |
133 goto out; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
134 } |
687 | 135 sha1_process(hs, readbuf, readlen); |
136 readcount += readlen; | |
137 } | |
138 ret = DROPBEAR_SUCCESS; | |
139 out: | |
140 close(readfd); | |
141 return ret; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
142 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
143 |
1096
a9e4d66ffb2c
Turn addrandom()'s buf argument into unsigned char *
Gaël PORTAY <gael.portay@gmail.com>
parents:
1013
diff
changeset
|
144 void addrandom(unsigned char * buf, unsigned int len) |
687 | 145 { |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
146 hash_state hs; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
147 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
148 /* hash in the new seed data */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
149 sha1_init(&hs); |
687 | 150 /* existing state (zeroes on startup) */ |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
151 sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); |
687 | 152 |
153 /* new */ | |
154 sha1_process(&hs, buf, len); | |
155 sha1_done(&hs, hashpool); | |
156 } | |
157 | |
158 static void write_urandom() | |
159 { | |
160 #ifndef DROPBEAR_PRNGD_SOCKET | |
161 /* This is opportunistic, don't worry about failure */ | |
162 unsigned char buf[INIT_SEED_SIZE]; | |
163 FILE *f = fopen(DROPBEAR_URANDOM_DEV, "w"); | |
737 | 164 if (!f) { |
165 return; | |
166 } | |
687 | 167 genrandom(buf, sizeof(buf)); |
168 fwrite(buf, sizeof(buf), 1, f); | |
169 fclose(f); | |
170 #endif | |
171 } | |
172 | |
173 /* Initialise the prng from /dev/urandom or prngd. This function can | |
174 * be called multiple times */ | |
175 void seedrandom() { | |
176 | |
177 hash_state hs; | |
178 | |
179 pid_t pid; | |
180 struct timeval tv; | |
181 clock_t clockval; | |
182 | |
183 /* hash in the new seed data */ | |
184 sha1_init(&hs); | |
185 /* existing state */ | |
186 sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); | |
187 | |
188 #ifdef DROPBEAR_PRNGD_SOCKET | |
189 if (process_file(&hs, DROPBEAR_PRNGD_SOCKET, INIT_SEED_SIZE, 1) | |
190 != DROPBEAR_SUCCESS) { | |
191 dropbear_exit("Failure reading random device %s", | |
192 DROPBEAR_PRNGD_SOCKET); | |
193 } | |
194 #else | |
195 /* non-blocking random source (probably /dev/urandom) */ | |
196 if (process_file(&hs, DROPBEAR_URANDOM_DEV, INIT_SEED_SIZE, 0) | |
197 != DROPBEAR_SUCCESS) { | |
198 dropbear_exit("Failure reading random device %s", | |
199 DROPBEAR_URANDOM_DEV); | |
200 } | |
201 #endif | |
202 | |
694
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
203 /* A few other sources to fall back on. |
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
204 * Add more here for other platforms */ |
687 | 205 #ifdef __linux__ |
688
650c41a4909a
Add a few more files in /proc for Linux
Matt Johnston <matt@ucc.asn.au>
parents:
687
diff
changeset
|
206 /* Seems to be a reasonable source of entropy from timers. Possibly hard |
650c41a4909a
Add a few more files in /proc for Linux
Matt Johnston <matt@ucc.asn.au>
parents:
687
diff
changeset
|
207 * for even local attackers to reproduce */ |
687 | 208 process_file(&hs, "/proc/timer_list", 0, 0); |
209 /* Might help on systems with wireless */ | |
210 process_file(&hs, "/proc/interrupts", 0, 0); | |
688
650c41a4909a
Add a few more files in /proc for Linux
Matt Johnston <matt@ucc.asn.au>
parents:
687
diff
changeset
|
211 |
694
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
212 process_file(&hs, "/proc/loadavg", 0, 0); |
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
213 process_file(&hs, "/proc/sys/kernel/random/entropy_avail", 0, 0); |
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
214 |
811
5de524aec047
limit how much we read from rt_cache etc
Matt Johnston <matt@ucc.asn.au>
parents:
737
diff
changeset
|
215 /* Mostly network visible but useful in some situations. |
5de524aec047
limit how much we read from rt_cache etc
Matt Johnston <matt@ucc.asn.au>
parents:
737
diff
changeset
|
216 * Limit size to avoid slowdowns on systems with lots of routes */ |
5de524aec047
limit how much we read from rt_cache etc
Matt Johnston <matt@ucc.asn.au>
parents:
737
diff
changeset
|
217 process_file(&hs, "/proc/net/netstat", 4096, 0); |
5de524aec047
limit how much we read from rt_cache etc
Matt Johnston <matt@ucc.asn.au>
parents:
737
diff
changeset
|
218 process_file(&hs, "/proc/net/dev", 4096, 0); |
5de524aec047
limit how much we read from rt_cache etc
Matt Johnston <matt@ucc.asn.au>
parents:
737
diff
changeset
|
219 process_file(&hs, "/proc/net/tcp", 4096, 0); |
688
650c41a4909a
Add a few more files in /proc for Linux
Matt Johnston <matt@ucc.asn.au>
parents:
687
diff
changeset
|
220 /* Also includes interface lo */ |
811
5de524aec047
limit how much we read from rt_cache etc
Matt Johnston <matt@ucc.asn.au>
parents:
737
diff
changeset
|
221 process_file(&hs, "/proc/net/rt_cache", 4096, 0); |
702
48e173a0c52b
Include /proc/vmstat as another random source
Matt Johnston <matt@ucc.asn.au>
parents:
698
diff
changeset
|
222 process_file(&hs, "/proc/vmstat", 0, 0); |
687 | 223 #endif |
224 | |
225 pid = getpid(); | |
226 sha1_process(&hs, (void*)&pid, sizeof(pid)); | |
227 | |
857 | 228 /* gettimeofday() doesn't completely fill out struct timeval on |
229 OS X (10.8.3), avoid valgrind warnings by clearing it first */ | |
714
84157e435c52
Make sure "struct timeval" is initialised on OS X to avoid valgrind warnings
Matt Johnston <matt@ucc.asn.au>
parents:
702
diff
changeset
|
230 memset(&tv, 0x0, sizeof(tv)); |
687 | 231 gettimeofday(&tv, NULL); |
232 sha1_process(&hs, (void*)&tv, sizeof(tv)); | |
233 | |
234 clockval = clock(); | |
235 sha1_process(&hs, (void*)&clockval, sizeof(clockval)); | |
236 | |
237 /* When a private key is read by the client or server it will | |
238 * be added to the hashpool - see runopts.c */ | |
239 | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
240 sha1_done(&hs, hashpool); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
241 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
242 counter = 0; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
243 donerandinit = 1; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
244 |
687 | 245 /* Feed it all back into /dev/urandom - this might help if Dropbear |
246 * is running from inetd and gets new state each time */ | |
247 write_urandom(); | |
272
3be7ae2e8dfa
Only read /dev/random once when the program starts
Matt Johnston <matt@ucc.asn.au>
parents:
198
diff
changeset
|
248 } |
3be7ae2e8dfa
Only read /dev/random once when the program starts
Matt Johnston <matt@ucc.asn.au>
parents:
198
diff
changeset
|
249 |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
250 /* return len bytes of pseudo-random data */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
251 void genrandom(unsigned char* buf, unsigned int len) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
252 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
253 hash_state hs; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
254 unsigned char hash[SHA1_HASH_SIZE]; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
255 unsigned int copylen; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
256 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
257 if (!donerandinit) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
258 dropbear_exit("seedrandom not done"); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
259 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
260 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
261 while (len > 0) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
262 sha1_init(&hs); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
263 sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
264 sha1_process(&hs, (void*)&counter, sizeof(counter)); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
265 sha1_done(&hs, hash); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
266 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
267 counter++; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
268 if (counter > MAX_COUNTER) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
269 seedrandom(); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
270 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
271 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
272 copylen = MIN(len, SHA1_HASH_SIZE); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
273 memcpy(buf, hash, copylen); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
274 len -= copylen; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
275 buf += copylen; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
276 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
277 m_burn(hash, sizeof(hash)); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
278 } |
188
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
279 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
280 /* Generates a random mp_int. |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
281 * max is a *mp_int specifying an upper bound. |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
282 * rand must be an initialised *mp_int for the result. |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
283 * the result rand satisfies: 0 < rand < max |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
284 * */ |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
285 void gen_random_mpint(mp_int *max, mp_int *rand) { |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
286 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
287 unsigned char *randbuf = NULL; |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
288 unsigned int len = 0; |
433
c216212001fc
Fix for -pedantic -ansi compilation, change // to /**/, plus some signedness
Matt Johnston <matt@ucc.asn.au>
parents:
405
diff
changeset
|
289 const unsigned char masks[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f}; |
188
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
290 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
291 const int size_bits = mp_count_bits(max); |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
292 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
293 len = size_bits / 8; |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
294 if ((size_bits % 8) != 0) { |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
295 len += 1; |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
296 } |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
297 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
298 randbuf = (unsigned char*)m_malloc(len); |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
299 do { |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
300 genrandom(randbuf, len); |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
301 /* Mask out the unrequired bits - mp_read_unsigned_bin expects |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
302 * MSB first.*/ |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
303 randbuf[0] &= masks[size_bits % 8]; |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
304 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
305 bytes_to_mp(rand, randbuf, len); |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
306 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
307 /* keep regenerating until we get one satisfying |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
308 * 0 < rand < max */ |
1013
a1e79ffa5862
Tighten validation of DH values. Odds of x==0 being generated are
Matt Johnston <matt@ucc.asn.au>
parents:
858
diff
changeset
|
309 } while (!(mp_cmp(rand, max) == MP_LT && mp_cmp_d(rand, 0) == MP_GT)); |
188
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
310 m_burn(randbuf, len); |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
311 m_free(randbuf); |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
312 } |