/src/openssl/crypto/bn/bn_rand.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
4 | | * Licensed under the OpenSSL license (the "License"). You may not use |
5 | | * this file except in compliance with the License. You can obtain a copy |
6 | | * in the file LICENSE in the source distribution or at |
7 | | * https://www.openssl.org/source/license.html |
8 | | */ |
9 | | |
10 | | #include <stdio.h> |
11 | | #include <time.h> |
12 | | #include "internal/cryptlib.h" |
13 | | #include "bn_lcl.h" |
14 | | #include <openssl/rand.h> |
15 | | #include <openssl/sha.h> |
16 | | |
17 | | typedef enum bnrand_flag_e { |
18 | | NORMAL, TESTING, PRIVATE |
19 | | } BNRAND_FLAG; |
20 | | |
21 | | static int bnrand(BNRAND_FLAG flag, BIGNUM *rnd, int bits, int top, int bottom) |
22 | 0 | { |
23 | 0 | unsigned char *buf = NULL; |
24 | 0 | int b, ret = 0, bit, bytes, mask; |
25 | 0 |
|
26 | 0 | if (bits == 0) { |
27 | 0 | if (top != BN_RAND_TOP_ANY || bottom != BN_RAND_BOTTOM_ANY) |
28 | 0 | goto toosmall; |
29 | 0 | BN_zero(rnd); |
30 | 0 | return 1; |
31 | 0 | } |
32 | 0 | if (bits < 0 || (bits == 1 && top > 0)) |
33 | 0 | goto toosmall; |
34 | 0 | |
35 | 0 | bytes = (bits + 7) / 8; |
36 | 0 | bit = (bits - 1) % 8; |
37 | 0 | mask = 0xff << (bit + 1); |
38 | 0 |
|
39 | 0 | buf = OPENSSL_malloc(bytes); |
40 | 0 | if (buf == NULL) { |
41 | 0 | BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE); |
42 | 0 | goto err; |
43 | 0 | } |
44 | 0 |
|
45 | 0 | /* make a random number and set the top and bottom bits */ |
46 | 0 | b = flag == NORMAL ? RAND_bytes(buf, bytes) : RAND_priv_bytes(buf, bytes); |
47 | 0 | if (b <= 0) |
48 | 0 | goto err; |
49 | 0 | |
50 | 0 | if (flag == TESTING) { |
51 | 0 | /* |
52 | 0 | * generate patterns that are more likely to trigger BN library bugs |
53 | 0 | */ |
54 | 0 | int i; |
55 | 0 | unsigned char c; |
56 | 0 |
|
57 | 0 | for (i = 0; i < bytes; i++) { |
58 | 0 | if (RAND_bytes(&c, 1) <= 0) |
59 | 0 | goto err; |
60 | 0 | if (c >= 128 && i > 0) |
61 | 0 | buf[i] = buf[i - 1]; |
62 | 0 | else if (c < 42) |
63 | 0 | buf[i] = 0; |
64 | 0 | else if (c < 84) |
65 | 0 | buf[i] = 255; |
66 | 0 | } |
67 | 0 | } |
68 | 0 |
|
69 | 0 | if (top >= 0) { |
70 | 0 | if (top) { |
71 | 0 | if (bit == 0) { |
72 | 0 | buf[0] = 1; |
73 | 0 | buf[1] |= 0x80; |
74 | 0 | } else { |
75 | 0 | buf[0] |= (3 << (bit - 1)); |
76 | 0 | } |
77 | 0 | } else { |
78 | 0 | buf[0] |= (1 << bit); |
79 | 0 | } |
80 | 0 | } |
81 | 0 | buf[0] &= ~mask; |
82 | 0 | if (bottom) /* set bottom bit if requested */ |
83 | 0 | buf[bytes - 1] |= 1; |
84 | 0 | if (!BN_bin2bn(buf, bytes, rnd)) |
85 | 0 | goto err; |
86 | 0 | ret = 1; |
87 | 0 | err: |
88 | 0 | OPENSSL_clear_free(buf, bytes); |
89 | 0 | bn_check_top(rnd); |
90 | 0 | return ret; |
91 | 0 |
|
92 | 0 | toosmall: |
93 | 0 | BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL); |
94 | 0 | return 0; |
95 | 0 | } |
96 | | |
97 | | int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) |
98 | 0 | { |
99 | 0 | return bnrand(NORMAL, rnd, bits, top, bottom); |
100 | 0 | } |
101 | | |
102 | | int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom) |
103 | 0 | { |
104 | 0 | return bnrand(TESTING, rnd, bits, top, bottom); |
105 | 0 | } |
106 | | |
107 | | int BN_priv_rand(BIGNUM *rnd, int bits, int top, int bottom) |
108 | 0 | { |
109 | 0 | return bnrand(PRIVATE, rnd, bits, top, bottom); |
110 | 0 | } |
111 | | |
112 | | /* random number r: 0 <= r < range */ |
113 | | static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range) |
114 | 0 | { |
115 | 0 | int n; |
116 | 0 | int count = 100; |
117 | 0 |
|
118 | 0 | if (range->neg || BN_is_zero(range)) { |
119 | 0 | BNerr(BN_F_BNRAND_RANGE, BN_R_INVALID_RANGE); |
120 | 0 | return 0; |
121 | 0 | } |
122 | 0 |
|
123 | 0 | n = BN_num_bits(range); /* n > 0 */ |
124 | 0 |
|
125 | 0 | /* BN_is_bit_set(range, n - 1) always holds */ |
126 | 0 |
|
127 | 0 | if (n == 1) |
128 | 0 | BN_zero(r); |
129 | 0 | else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) { |
130 | 0 | /* |
131 | 0 | * range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer |
132 | 0 | * than range |
133 | 0 | */ |
134 | 0 | do { |
135 | 0 | if (!bnrand(flag, r, n + 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) |
136 | 0 | return 0; |
137 | 0 | |
138 | 0 | /* |
139 | 0 | * If r < 3*range, use r := r MOD range (which is either r, r - |
140 | 0 | * range, or r - 2*range). Otherwise, iterate once more. Since |
141 | 0 | * 3*range = 11..._2, each iteration succeeds with probability >= |
142 | 0 | * .75. |
143 | 0 | */ |
144 | 0 | if (BN_cmp(r, range) >= 0) { |
145 | 0 | if (!BN_sub(r, r, range)) |
146 | 0 | return 0; |
147 | 0 | if (BN_cmp(r, range) >= 0) |
148 | 0 | if (!BN_sub(r, r, range)) |
149 | 0 | return 0; |
150 | 0 | } |
151 | 0 | |
152 | 0 | if (!--count) { |
153 | 0 | BNerr(BN_F_BNRAND_RANGE, BN_R_TOO_MANY_ITERATIONS); |
154 | 0 | return 0; |
155 | 0 | } |
156 | 0 |
|
157 | 0 | } |
158 | 0 | while (BN_cmp(r, range) >= 0); |
159 | 0 | } else { |
160 | 0 | do { |
161 | 0 | /* range = 11..._2 or range = 101..._2 */ |
162 | 0 | if (!bnrand(flag, r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) |
163 | 0 | return 0; |
164 | 0 | |
165 | 0 | if (!--count) { |
166 | 0 | BNerr(BN_F_BNRAND_RANGE, BN_R_TOO_MANY_ITERATIONS); |
167 | 0 | return 0; |
168 | 0 | } |
169 | 0 | } |
170 | 0 | while (BN_cmp(r, range) >= 0); |
171 | 0 | } |
172 | 0 |
|
173 | 0 | bn_check_top(r); |
174 | 0 | return 1; |
175 | 0 | } |
176 | | |
177 | | int BN_rand_range(BIGNUM *r, const BIGNUM *range) |
178 | 0 | { |
179 | 0 | return bnrand_range(NORMAL, r, range); |
180 | 0 | } |
181 | | |
182 | | int BN_priv_rand_range(BIGNUM *r, const BIGNUM *range) |
183 | 0 | { |
184 | 0 | return bnrand_range(PRIVATE, r, range); |
185 | 0 | } |
186 | | |
187 | | int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) |
188 | 0 | { |
189 | 0 | return BN_rand(rnd, bits, top, bottom); |
190 | 0 | } |
191 | | |
192 | | int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) |
193 | 0 | { |
194 | 0 | return BN_rand_range(r, range); |
195 | 0 | } |
196 | | |
197 | | /* |
198 | | * BN_generate_dsa_nonce generates a random number 0 <= out < range. Unlike |
199 | | * BN_rand_range, it also includes the contents of |priv| and |message| in |
200 | | * the generation so that an RNG failure isn't fatal as long as |priv| |
201 | | * remains secret. This is intended for use in DSA and ECDSA where an RNG |
202 | | * weakness leads directly to private key exposure unless this function is |
203 | | * used. |
204 | | */ |
205 | | int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, |
206 | | const BIGNUM *priv, const unsigned char *message, |
207 | | size_t message_len, BN_CTX *ctx) |
208 | 0 | { |
209 | 0 | SHA512_CTX sha; |
210 | 0 | /* |
211 | 0 | * We use 512 bits of random data per iteration to ensure that we have at |
212 | 0 | * least |range| bits of randomness. |
213 | 0 | */ |
214 | 0 | unsigned char random_bytes[64]; |
215 | 0 | unsigned char digest[SHA512_DIGEST_LENGTH]; |
216 | 0 | unsigned done, todo; |
217 | 0 | /* We generate |range|+8 bytes of random output. */ |
218 | 0 | const unsigned num_k_bytes = BN_num_bytes(range) + 8; |
219 | 0 | unsigned char private_bytes[96]; |
220 | 0 | unsigned char *k_bytes; |
221 | 0 | int ret = 0; |
222 | 0 |
|
223 | 0 | k_bytes = OPENSSL_malloc(num_k_bytes); |
224 | 0 | if (k_bytes == NULL) |
225 | 0 | goto err; |
226 | 0 | |
227 | 0 | /* We copy |priv| into a local buffer to avoid exposing its length. */ |
228 | 0 | todo = sizeof(priv->d[0]) * priv->top; |
229 | 0 | if (todo > sizeof(private_bytes)) { |
230 | 0 | /* |
231 | 0 | * No reasonable DSA or ECDSA key should have a private key this |
232 | 0 | * large and we don't handle this case in order to avoid leaking the |
233 | 0 | * length of the private key. |
234 | 0 | */ |
235 | 0 | BNerr(BN_F_BN_GENERATE_DSA_NONCE, BN_R_PRIVATE_KEY_TOO_LARGE); |
236 | 0 | goto err; |
237 | 0 | } |
238 | 0 | memcpy(private_bytes, priv->d, todo); |
239 | 0 | memset(private_bytes + todo, 0, sizeof(private_bytes) - todo); |
240 | 0 |
|
241 | 0 | for (done = 0; done < num_k_bytes;) { |
242 | 0 | if (RAND_priv_bytes(random_bytes, sizeof(random_bytes)) != 1) |
243 | 0 | goto err; |
244 | 0 | SHA512_Init(&sha); |
245 | 0 | SHA512_Update(&sha, &done, sizeof(done)); |
246 | 0 | SHA512_Update(&sha, private_bytes, sizeof(private_bytes)); |
247 | 0 | SHA512_Update(&sha, message, message_len); |
248 | 0 | SHA512_Update(&sha, random_bytes, sizeof(random_bytes)); |
249 | 0 | SHA512_Final(digest, &sha); |
250 | 0 |
|
251 | 0 | todo = num_k_bytes - done; |
252 | 0 | if (todo > SHA512_DIGEST_LENGTH) |
253 | 0 | todo = SHA512_DIGEST_LENGTH; |
254 | 0 | memcpy(k_bytes + done, digest, todo); |
255 | 0 | done += todo; |
256 | 0 | } |
257 | 0 |
|
258 | 0 | if (!BN_bin2bn(k_bytes, num_k_bytes, out)) |
259 | 0 | goto err; |
260 | 0 | if (BN_mod(out, out, range, ctx) != 1) |
261 | 0 | goto err; |
262 | 0 | ret = 1; |
263 | 0 |
|
264 | 0 | err: |
265 | 0 | OPENSSL_free(k_bytes); |
266 | 0 | OPENSSL_cleanse(private_bytes, sizeof(private_bytes)); |
267 | 0 | return ret; |
268 | 0 | } |