Mercurial > dropbear
annotate dbrandom.c @ 1788:1fc0012b9c38
Fix handling of replies to global requests (#112)
The current code assumes that all global requests want / need a reply.
This isn't always true and the request itself indicates if it wants a
reply or not.
It causes a specific problem with [email protected] messages.
These are sent by OpenSSH after authentication to inform the client of
potential other host keys for the host. This can be used to add a new
type of host key or to rotate host keys.
The initial information message from the server is sent as a global
request, but with want_reply set to false. This means that the server
doesn't expect an answer to this message. Instead the client needs to
send a prove request as a reply if it wants to receive proof of
ownership for the host keys.
The bug doesn't cause any current problems with due to how OpenSSH
treats receiving the failure message. It instead treats it as a
keepalive message and further ignores it.
Arguably this is a protocol violation though of Dropbear and it is only
accidental that it doesn't cause a problem with OpenSSH.
The bug was found when adding host keys support to libssh, which is more
strict protocol wise and treats the unexpected failure message an error,
also see https://gitlab.com/libssh/libssh-mirror/-/merge_requests/145
for more information.
The fix here is to honor the want_reply flag in the global request and
to only send a reply if the other side expects a reply.
author | Dirkjan Bussink <d.bussink@gmail.com> |
---|---|
date | Thu, 10 Dec 2020 16:13:13 +0100 |
parents | 833bf9947603 |
children | 3f4cdf839a1a |
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" |
1347
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
30 #include "runopts.h" |
4
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 |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
52 /* Pass wantlen=0 to hash an entire file */ |
687 | 53 static int |
54 process_file(hash_state *hs, const char *filename, | |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
55 unsigned int wantlen, int prngd) { |
1701
6e5037ae2c1c
Fix warning for unused prngd branch
Matt Johnston <matt@ucc.asn.au>
parents:
1698
diff
changeset
|
56 int readfd = -1; |
687 | 57 unsigned int readcount; |
58 int ret = DROPBEAR_FAILURE; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
59 |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
60 if (prngd) { |
1499
2d450c1056e3
options: Complete the transition to numeric toggles (`#if')
Michael Witten <mfwitten@gmail.com>
parents:
1459
diff
changeset
|
61 #if DROPBEAR_USE_PRNGD |
687 | 62 readfd = connect_unix(filename); |
63 #endif | |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
64 } else { |
687 | 65 readfd = open(filename, O_RDONLY); |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
66 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
67 |
687 | 68 if (readfd < 0) { |
69 goto out; | |
70 } | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
71 |
687 | 72 readcount = 0; |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
73 while (wantlen == 0 || readcount < wantlen) { |
687 | 74 int readlen, wantread; |
811
5de524aec047
limit how much we read from rt_cache etc
Matt Johnston <matt@ucc.asn.au>
parents:
737
diff
changeset
|
75 unsigned char readbuf[4096]; |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
76 if (wantlen == 0) { |
694
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
77 wantread = sizeof(readbuf); |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
78 } else { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
79 wantread = MIN(sizeof(readbuf), wantlen-readcount); |
694
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
80 } |
687 | 81 |
1499
2d450c1056e3
options: Complete the transition to numeric toggles (`#if')
Michael Witten <mfwitten@gmail.com>
parents:
1459
diff
changeset
|
82 #if DROPBEAR_USE_PRNGD |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
83 if (prngd) { |
687 | 84 char egdcmd[2]; |
85 egdcmd[0] = 0x02; /* blocking read */ | |
86 egdcmd[1] = (unsigned char)wantread; | |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
87 if (write(readfd, egdcmd, 2) < 0) { |
687 | 88 dropbear_exit("Can't send command to egd"); |
89 } | |
90 } | |
91 #endif | |
92 readlen = read(readfd, readbuf, wantread); | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
93 if (readlen <= 0) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
94 if (readlen < 0 && errno == EINTR) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
95 continue; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
96 } |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
97 if (readlen == 0 && wantlen == 0) { |
687 | 98 /* whole file was read as requested */ |
99 break; | |
100 } | |
101 goto out; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
102 } |
687 | 103 sha1_process(hs, readbuf, readlen); |
104 readcount += readlen; | |
105 } | |
106 ret = DROPBEAR_SUCCESS; | |
107 out: | |
108 close(readfd); | |
109 return ret; | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
110 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
111 |
1459
06d52bcb8094
Pointer parameter could be declared as pointing to const
Francois Perrad <francois.perrad@gadz.org>
parents:
1401
diff
changeset
|
112 void addrandom(const unsigned char * buf, unsigned int len) |
687 | 113 { |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
114 hash_state hs; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
115 |
1558
2f64cb3d3007
- #if not #ifdef for DROPBEAR_FUZZ
Matt Johnston <matt@ucc.asn.au>
parents:
1511
diff
changeset
|
116 #if DROPBEAR_FUZZ |
1561
02b226c2675e
clean some fuzzing conditionals
Matt Johnston <matt@ucc.asn.au>
parents:
1558
diff
changeset
|
117 if (fuzz.fuzzing) { |
1347
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
118 return; |
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
119 } |
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
120 #endif |
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
121 |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
122 /* hash in the new seed data */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
123 sha1_init(&hs); |
687 | 124 /* existing state (zeroes on startup) */ |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
125 sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); |
687 | 126 |
127 /* new */ | |
128 sha1_process(&hs, buf, len); | |
129 sha1_done(&hs, hashpool); | |
130 } | |
131 | |
132 static void write_urandom() | |
133 { | |
1558
2f64cb3d3007
- #if not #ifdef for DROPBEAR_FUZZ
Matt Johnston <matt@ucc.asn.au>
parents:
1511
diff
changeset
|
134 #if DROPBEAR_FUZZ |
1561
02b226c2675e
clean some fuzzing conditionals
Matt Johnston <matt@ucc.asn.au>
parents:
1558
diff
changeset
|
135 if (fuzz.fuzzing) { |
1347
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
136 return; |
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
137 } |
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
138 #endif |
1499
2d450c1056e3
options: Complete the transition to numeric toggles (`#if')
Michael Witten <mfwitten@gmail.com>
parents:
1459
diff
changeset
|
139 #if !DROPBEAR_USE_PRNGD |
687 | 140 /* This is opportunistic, don't worry about failure */ |
141 unsigned char buf[INIT_SEED_SIZE]; | |
142 FILE *f = fopen(DROPBEAR_URANDOM_DEV, "w"); | |
737 | 143 if (!f) { |
144 return; | |
145 } | |
687 | 146 genrandom(buf, sizeof(buf)); |
147 fwrite(buf, sizeof(buf), 1, f); | |
148 fclose(f); | |
149 #endif | |
150 } | |
151 | |
1558
2f64cb3d3007
- #if not #ifdef for DROPBEAR_FUZZ
Matt Johnston <matt@ucc.asn.au>
parents:
1511
diff
changeset
|
152 #if DROPBEAR_FUZZ |
1757
517fb7b62438
Add some more variation to fuzzer random number generation
Matt Johnston <matt@ucc.asn.au>
parents:
1701
diff
changeset
|
153 void fuzz_seed(const unsigned char* dat, unsigned int len) { |
1774
833bf9947603
Fuzzing - get rid of "prefix" for streams
Matt Johnston <matt@ucc.asn.au>
parents:
1773
diff
changeset
|
154 hash_state hs; |
833bf9947603
Fuzzing - get rid of "prefix" for streams
Matt Johnston <matt@ucc.asn.au>
parents:
1773
diff
changeset
|
155 sha1_init(&hs); |
833bf9947603
Fuzzing - get rid of "prefix" for streams
Matt Johnston <matt@ucc.asn.au>
parents:
1773
diff
changeset
|
156 sha1_process(&hs, "fuzzfuzzfuzz", strlen("fuzzfuzzfuzz")); |
833bf9947603
Fuzzing - get rid of "prefix" for streams
Matt Johnston <matt@ucc.asn.au>
parents:
1773
diff
changeset
|
157 sha1_process(&hs, dat, len); |
833bf9947603
Fuzzing - get rid of "prefix" for streams
Matt Johnston <matt@ucc.asn.au>
parents:
1773
diff
changeset
|
158 sha1_done(&hs, hashpool); |
1347
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
159 counter = 0; |
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
160 donerandinit = 1; |
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
161 } |
1358
6b89eb92f872
glaring wrapfd problems fixed
Matt Johnston <matt@ucc.asn.au>
parents:
1357
diff
changeset
|
162 #endif |
1347
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
163 |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
164 |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
165 #ifdef HAVE_GETRANDOM |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
166 /* Reads entropy seed with getrandom(). |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
167 * May block if the kernel isn't ready. |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
168 * Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
169 static int process_getrandom(hash_state *hs) { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
170 char buf[INIT_SEED_SIZE]; |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
171 ssize_t ret; |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
172 |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
173 /* First try non-blocking so that we can warn about waiting */ |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
174 ret = getrandom(buf, sizeof(buf), GRND_NONBLOCK); |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
175 if (ret == -1) { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
176 if (errno == ENOSYS) { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
177 /* Old kernel */ |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
178 return DROPBEAR_FAILURE; |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
179 } |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
180 /* Other errors fall through to blocking getrandom() */ |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
181 TRACE(("first getrandom() failed: %d %s", errno, strerror(errno))) |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
182 if (errno == EAGAIN) { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
183 dropbear_log(LOG_WARNING, "Waiting for kernel randomness to be initialised..."); |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
184 } |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
185 } |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
186 |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
187 /* Wait blocking if needed. Loop in case we get EINTR */ |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
188 while (ret != sizeof(buf)) { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
189 ret = getrandom(buf, sizeof(buf), 0); |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
190 |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
191 if (ret == sizeof(buf)) { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
192 /* Success */ |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
193 break; |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
194 } |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
195 if (ret == -1 && errno == EINTR) { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
196 /* Try again. */ |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
197 continue; |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
198 } |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
199 if (ret >= 0) { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
200 TRACE(("Short read %zd from getrandom() shouldn't happen", ret)) |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
201 /* Try again? */ |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
202 continue; |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
203 } |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
204 |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
205 /* Unexpected problem, fall back to /dev/urandom */ |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
206 TRACE(("2nd getrandom() failed: %d %s", errno, strerror(errno))) |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
207 break; |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
208 } |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
209 |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
210 if (ret == sizeof(buf)) { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
211 /* Success, stir in the entropy */ |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
212 sha1_process(hs, (void*)buf, sizeof(buf)); |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
213 return DROPBEAR_SUCCESS; |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
214 } |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
215 |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
216 return DROPBEAR_FAILURE; |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
217 |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
218 } |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
219 #endif /* HAVE_GETRANDOM */ |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
220 |
687 | 221 /* Initialise the prng from /dev/urandom or prngd. This function can |
222 * be called multiple times */ | |
223 void seedrandom() { | |
224 | |
225 hash_state hs; | |
226 | |
227 pid_t pid; | |
228 struct timeval tv; | |
229 clock_t clockval; | |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
230 int urandom_seeded = 0; |
687 | 231 |
1558
2f64cb3d3007
- #if not #ifdef for DROPBEAR_FUZZ
Matt Johnston <matt@ucc.asn.au>
parents:
1511
diff
changeset
|
232 #if DROPBEAR_FUZZ |
1561
02b226c2675e
clean some fuzzing conditionals
Matt Johnston <matt@ucc.asn.au>
parents:
1558
diff
changeset
|
233 if (fuzz.fuzzing) { |
1347
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
234 return; |
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
235 } |
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
236 #endif |
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
237 |
687 | 238 /* hash in the new seed data */ |
239 sha1_init(&hs); | |
1347
b28624698130
copy over some fuzzing code from AFL branch
Matt Johnston <matt@ucc.asn.au>
parents:
1274
diff
changeset
|
240 |
687 | 241 /* existing state */ |
242 sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); | |
243 | |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
244 #ifdef HAVE_GETRANDOM |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
245 if (process_getrandom(&hs) == DROPBEAR_SUCCESS) { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
246 urandom_seeded = 1; |
687 | 247 } |
248 #endif | |
249 | |
1698
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
250 if (!urandom_seeded) { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
251 #if DROPBEAR_USE_PRNGD |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
252 if (process_file(&hs, DROPBEAR_PRNGD_SOCKET, INIT_SEED_SIZE, 1) |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
253 != DROPBEAR_SUCCESS) { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
254 dropbear_exit("Failure reading random device %s", |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
255 DROPBEAR_PRNGD_SOCKET); |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
256 urandom_seeded = 1; |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
257 } |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
258 #else |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
259 /* non-blocking random source (probably /dev/urandom) */ |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
260 if (process_file(&hs, DROPBEAR_URANDOM_DEV, INIT_SEED_SIZE, 0) |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
261 != DROPBEAR_SUCCESS) { |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
262 dropbear_exit("Failure reading random device %s", |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
263 DROPBEAR_URANDOM_DEV); |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
264 urandom_seeded = 1; |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
265 } |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
266 #endif |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
267 } /* urandom_seeded */ |
f966834f0f9c
Use Linux getrandom() to ensure random device is initialised
Matt Johnston <matt@ucc.asn.au>
parents:
1596
diff
changeset
|
268 |
694
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
269 /* 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
|
270 * Add more here for other platforms */ |
687 | 271 #ifdef __linux__ |
688
650c41a4909a
Add a few more files in /proc for Linux
Matt Johnston <matt@ucc.asn.au>
parents:
687
diff
changeset
|
272 /* 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
|
273 * for even local attackers to reproduce */ |
687 | 274 process_file(&hs, "/proc/timer_list", 0, 0); |
275 /* Might help on systems with wireless */ | |
276 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
|
277 |
694
c85bb68e1db6
add loadavg and entropy_avail as sources
Matt Johnston <matt@ucc.asn.au>
parents:
689
diff
changeset
|
278 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
|
279 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
|
280 |
811
5de524aec047
limit how much we read from rt_cache etc
Matt Johnston <matt@ucc.asn.au>
parents:
737
diff
changeset
|
281 /* 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
|
282 * 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
|
283 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
|
284 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
|
285 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
|
286 /* 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
|
287 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
|
288 process_file(&hs, "/proc/vmstat", 0, 0); |
687 | 289 #endif |
290 | |
291 pid = getpid(); | |
292 sha1_process(&hs, (void*)&pid, sizeof(pid)); | |
293 | |
857 | 294 /* gettimeofday() doesn't completely fill out struct timeval on |
295 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
|
296 memset(&tv, 0x0, sizeof(tv)); |
687 | 297 gettimeofday(&tv, NULL); |
298 sha1_process(&hs, (void*)&tv, sizeof(tv)); | |
299 | |
300 clockval = clock(); | |
301 sha1_process(&hs, (void*)&clockval, sizeof(clockval)); | |
302 | |
303 /* When a private key is read by the client or server it will | |
304 * be added to the hashpool - see runopts.c */ | |
305 | |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
306 sha1_done(&hs, hashpool); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
307 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
308 counter = 0; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
309 donerandinit = 1; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
310 |
687 | 311 /* Feed it all back into /dev/urandom - this might help if Dropbear |
312 * is running from inetd and gets new state each time */ | |
313 write_urandom(); | |
272
3be7ae2e8dfa
Only read /dev/random once when the program starts
Matt Johnston <matt@ucc.asn.au>
parents:
198
diff
changeset
|
314 } |
3be7ae2e8dfa
Only read /dev/random once when the program starts
Matt Johnston <matt@ucc.asn.au>
parents:
198
diff
changeset
|
315 |
4
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
316 /* return len bytes of pseudo-random data */ |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
317 void genrandom(unsigned char* buf, unsigned int len) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
318 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
319 hash_state hs; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
320 unsigned char hash[SHA1_HASH_SIZE]; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
321 unsigned int copylen; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
322 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
323 if (!donerandinit) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
324 dropbear_exit("seedrandom not done"); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
325 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
326 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
327 while (len > 0) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
328 sha1_init(&hs); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
329 sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
330 sha1_process(&hs, (void*)&counter, sizeof(counter)); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
331 sha1_done(&hs, hash); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
332 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
333 counter++; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
334 if (counter > MAX_COUNTER) { |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
335 seedrandom(); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
336 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
337 |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
338 copylen = MIN(len, SHA1_HASH_SIZE); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
339 memcpy(buf, hash, copylen); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
340 len -= copylen; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
341 buf += copylen; |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
342 } |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
343 m_burn(hash, sizeof(hash)); |
fe6bca95afa7
Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
344 } |
188
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
345 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
346 /* 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
|
347 * 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
|
348 * 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
|
349 * 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
|
350 * */ |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
351 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
|
352 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
353 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
|
354 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
|
355 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
|
356 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
357 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
|
358 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
359 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
|
360 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
|
361 len += 1; |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
362 } |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
363 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
364 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
|
365 do { |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
366 genrandom(randbuf, len); |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
367 /* 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
|
368 * MSB first.*/ |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
369 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
|
370 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
371 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
|
372 |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
373 /* 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
|
374 * 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
|
375 } 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
|
376 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
|
377 m_free(randbuf); |
c9483550701b
- refactored random mp_int generation and byte->mp_int code
Matt Johnston <matt@ucc.asn.au>
parents:
159
diff
changeset
|
378 } |