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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
37 static unsigned char hashpool[SHA1_HASH_SIZE] = {0};
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
53 static int
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
57 unsigned int readcount;
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
62 readfd = connect_unix(filename);
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
68 if (readfd < 0) {
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
69 goto out;
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
70 }
4
fe6bca95afa7 Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
71
687
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
84 char egdcmd[2];
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
85 egdcmd[0] = 0x02; /* blocking read */
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
88 dropbear_exit("Can't send command to egd");
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
89 }
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
90 }
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
91 #endif
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
98 /* whole file was read as requested */
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
99 break;
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
100 }
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
101 goto out;
4
fe6bca95afa7 Makefile.in contains updated files required
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
102 }
687
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
103 sha1_process(hs, readbuf, readlen);
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
104 readcount += readlen;
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
105 }
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
106 ret = DROPBEAR_SUCCESS;
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
107 out:
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
108 close(readfd);
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
126
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
127 /* new */
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
128 sha1_process(&hs, buf, len);
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
129 sha1_done(&hs, hashpool);
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
130 }
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
131
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
132 static void write_urandom()
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
140 /* This is opportunistic, don't worry about failure */
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
141 unsigned char buf[INIT_SEED_SIZE];
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
142 FILE *f = fopen(DROPBEAR_URANDOM_DEV, "w");
737
7deb6fda1319 fix tabs
Matt Johnston <matt@ucc.asn.au>
parents: 735
diff changeset
143 if (!f) {
7deb6fda1319 fix tabs
Matt Johnston <matt@ucc.asn.au>
parents: 735
diff changeset
144 return;
7deb6fda1319 fix tabs
Matt Johnston <matt@ucc.asn.au>
parents: 735
diff changeset
145 }
687
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
146 genrandom(buf, sizeof(buf));
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
147 fwrite(buf, sizeof(buf), 1, f);
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
148 fclose(f);
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
149 #endif
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
150 }
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
221 /* Initialise the prng from /dev/urandom or prngd. This function can
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
222 * be called multiple times */
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
223 void seedrandom() {
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
224
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
225 hash_state hs;
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
226
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
227 pid_t pid;
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
228 struct timeval tv;
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
238 /* hash in the new seed data */
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
241 /* existing state */
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
242 sha1_process(&hs, (void*)hashpool, sizeof(hashpool));
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
247 }
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
248 #endif
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
274 process_file(&hs, "/proc/timer_list", 0, 0);
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
275 /* Might help on systems with wireless */
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
289 #endif
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
290
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
291 pid = getpid();
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
292 sha1_process(&hs, (void*)&pid, sizeof(pid));
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
293
857
c19acba28590 use oldstyle comments
Matt Johnston <matt@ucc.asn.au>
parents: 855
diff changeset
294 /* gettimeofday() doesn't completely fill out struct timeval on
c19acba28590 use oldstyle comments
Matt Johnston <matt@ucc.asn.au>
parents: 855
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
297 gettimeofday(&tv, NULL);
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
298 sha1_process(&hs, (void*)&tv, sizeof(tv));
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
299
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
300 clockval = clock();
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
301 sha1_process(&hs, (void*)&clockval, sizeof(clockval));
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
302
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
303 /* When a private key is read by the client or server it will
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
304 * be added to the hashpool - see runopts.c */
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
311 /* Feed it all back into /dev/urandom - this might help if Dropbear
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
312 * is running from inetd and gets new state each time */
167fdc091c05 Improve RNG seeding.
Matt Johnston <matt@ucc.asn.au>
parents: 602
diff changeset
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 }