1 /* Copyright (C) 1995-1998 Eric Young ([email protected])
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young ([email protected]).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson ([email protected]).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young ([email protected])"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson ([email protected])"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.] */
56
57 #include <openssl/dh.h>
58
59 #include <string.h>
60
61 #include <openssl/bn.h>
62 #include <openssl/err.h>
63 #include <openssl/digest.h>
64 #include <openssl/mem.h>
65 #include <openssl/thread.h>
66
67 #include "../../internal.h"
68 #include "../bn/internal.h"
69 #include "../service_indicator/internal.h"
70 #include "internal.h"
71
72
DH_new(void)73 DH *DH_new(void) {
74 DH *dh = OPENSSL_zalloc(sizeof(DH));
75 if (dh == NULL) {
76 return NULL;
77 }
78
79 CRYPTO_MUTEX_init(&dh->method_mont_p_lock);
80 dh->references = 1;
81 return dh;
82 }
83
DH_free(DH * dh)84 void DH_free(DH *dh) {
85 if (dh == NULL) {
86 return;
87 }
88
89 if (!CRYPTO_refcount_dec_and_test_zero(&dh->references)) {
90 return;
91 }
92
93 BN_MONT_CTX_free(dh->method_mont_p);
94 BN_clear_free(dh->p);
95 BN_clear_free(dh->g);
96 BN_clear_free(dh->q);
97 BN_clear_free(dh->pub_key);
98 BN_clear_free(dh->priv_key);
99 CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock);
100
101 OPENSSL_free(dh);
102 }
103
DH_bits(const DH * dh)104 unsigned DH_bits(const DH *dh) { return BN_num_bits(dh->p); }
105
DH_get0_pub_key(const DH * dh)106 const BIGNUM *DH_get0_pub_key(const DH *dh) { return dh->pub_key; }
107
DH_get0_priv_key(const DH * dh)108 const BIGNUM *DH_get0_priv_key(const DH *dh) { return dh->priv_key; }
109
DH_get0_p(const DH * dh)110 const BIGNUM *DH_get0_p(const DH *dh) { return dh->p; }
111
DH_get0_q(const DH * dh)112 const BIGNUM *DH_get0_q(const DH *dh) { return dh->q; }
113
DH_get0_g(const DH * dh)114 const BIGNUM *DH_get0_g(const DH *dh) { return dh->g; }
115
DH_get0_key(const DH * dh,const BIGNUM ** out_pub_key,const BIGNUM ** out_priv_key)116 void DH_get0_key(const DH *dh, const BIGNUM **out_pub_key,
117 const BIGNUM **out_priv_key) {
118 if (out_pub_key != NULL) {
119 *out_pub_key = dh->pub_key;
120 }
121 if (out_priv_key != NULL) {
122 *out_priv_key = dh->priv_key;
123 }
124 }
125
DH_set0_key(DH * dh,BIGNUM * pub_key,BIGNUM * priv_key)126 int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) {
127 if (pub_key != NULL) {
128 BN_free(dh->pub_key);
129 dh->pub_key = pub_key;
130 }
131
132 if (priv_key != NULL) {
133 BN_free(dh->priv_key);
134 dh->priv_key = priv_key;
135 }
136
137 return 1;
138 }
139
DH_get0_pqg(const DH * dh,const BIGNUM ** out_p,const BIGNUM ** out_q,const BIGNUM ** out_g)140 void DH_get0_pqg(const DH *dh, const BIGNUM **out_p, const BIGNUM **out_q,
141 const BIGNUM **out_g) {
142 if (out_p != NULL) {
143 *out_p = dh->p;
144 }
145 if (out_q != NULL) {
146 *out_q = dh->q;
147 }
148 if (out_g != NULL) {
149 *out_g = dh->g;
150 }
151 }
152
DH_set0_pqg(DH * dh,BIGNUM * p,BIGNUM * q,BIGNUM * g)153 int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
154 if ((dh->p == NULL && p == NULL) ||
155 (dh->g == NULL && g == NULL)) {
156 return 0;
157 }
158
159 if (p != NULL) {
160 BN_free(dh->p);
161 dh->p = p;
162 }
163
164 if (q != NULL) {
165 BN_free(dh->q);
166 dh->q = q;
167 }
168
169 if (g != NULL) {
170 BN_free(dh->g);
171 dh->g = g;
172 }
173
174 // Invalidate the cached Montgomery parameters.
175 BN_MONT_CTX_free(dh->method_mont_p);
176 dh->method_mont_p = NULL;
177 return 1;
178 }
179
DH_set_length(DH * dh,unsigned priv_length)180 int DH_set_length(DH *dh, unsigned priv_length) {
181 dh->priv_length = priv_length;
182 return 1;
183 }
184
DH_generate_key(DH * dh)185 int DH_generate_key(DH *dh) {
186 boringssl_ensure_ffdh_self_test();
187
188 if (!dh_check_params_fast(dh)) {
189 return 0;
190 }
191
192 int ok = 0;
193 int generate_new_key = 0;
194 BN_CTX *ctx = NULL;
195 BIGNUM *pub_key = NULL, *priv_key = NULL, *priv_key_limit = NULL;
196
197 ctx = BN_CTX_new();
198 if (ctx == NULL) {
199 goto err;
200 }
201
202 if (dh->priv_key == NULL) {
203 priv_key = BN_new();
204 if (priv_key == NULL) {
205 goto err;
206 }
207 generate_new_key = 1;
208 } else {
209 priv_key = dh->priv_key;
210 }
211
212 if (dh->pub_key == NULL) {
213 pub_key = BN_new();
214 if (pub_key == NULL) {
215 goto err;
216 }
217 } else {
218 pub_key = dh->pub_key;
219 }
220
221 if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
222 dh->p, ctx)) {
223 goto err;
224 }
225
226 if (generate_new_key) {
227 if (dh->q) {
228 // Section 5.6.1.1.4 of SP 800-56A Rev3 generates a private key uniformly
229 // from [1, min(2^N-1, q-1)].
230 //
231 // Although SP 800-56A Rev3 now permits a private key length N,
232 // |dh->priv_length| historically was ignored when q is available. We
233 // continue to ignore it and interpret such a configuration as N = len(q).
234 if (!BN_rand_range_ex(priv_key, 1, dh->q)) {
235 goto err;
236 }
237 } else {
238 // If q is unspecified, we expect p to be a safe prime, with g generating
239 // the (p-1)/2 subgroup. So, we use q = (p-1)/2. (If g generates a smaller
240 // prime-order subgroup, q will still divide (p-1)/2.)
241 //
242 // We set N from |dh->priv_length|. Section 5.6.1.1.4 of SP 800-56A Rev3
243 // says to reject N > len(q), or N > num_bits(p) - 1. However, this logic
244 // originally aligned with PKCS#3, which allows num_bits(p). Instead, we
245 // clamp |dh->priv_length| before invoking the algorithm.
246
247 // Compute M = min(2^N, q).
248 priv_key_limit = BN_new();
249 if (priv_key_limit == NULL) {
250 goto err;
251 }
252 if (dh->priv_length == 0 || dh->priv_length >= BN_num_bits(dh->p) - 1) {
253 // M = q = (p - 1) / 2.
254 if (!BN_rshift1(priv_key_limit, dh->p)) {
255 goto err;
256 }
257 } else {
258 // M = 2^N.
259 if (!BN_set_bit(priv_key_limit, dh->priv_length)) {
260 goto err;
261 }
262 }
263
264 // Choose a private key uniformly from [1, M-1].
265 if (!BN_rand_range_ex(priv_key, 1, priv_key_limit)) {
266 goto err;
267 }
268 }
269 }
270
271 if (!BN_mod_exp_mont_consttime(pub_key, dh->g, priv_key, dh->p, ctx,
272 dh->method_mont_p)) {
273 goto err;
274 }
275
276 dh->pub_key = pub_key;
277 dh->priv_key = priv_key;
278 ok = 1;
279
280 err:
281 if (ok != 1) {
282 OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
283 }
284
285 if (dh->pub_key == NULL) {
286 BN_free(pub_key);
287 }
288 if (dh->priv_key == NULL) {
289 BN_free(priv_key);
290 }
291 BN_free(priv_key_limit);
292 BN_CTX_free(ctx);
293 return ok;
294 }
295
dh_compute_key(DH * dh,BIGNUM * out_shared_key,const BIGNUM * peers_key,BN_CTX * ctx)296 static int dh_compute_key(DH *dh, BIGNUM *out_shared_key,
297 const BIGNUM *peers_key, BN_CTX *ctx) {
298 if (!dh_check_params_fast(dh)) {
299 return 0;
300 }
301
302 if (dh->priv_key == NULL) {
303 OPENSSL_PUT_ERROR(DH, DH_R_NO_PRIVATE_VALUE);
304 return 0;
305 }
306
307 int check_result;
308 if (!DH_check_pub_key(dh, peers_key, &check_result) || check_result) {
309 OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY);
310 return 0;
311 }
312
313 int ret = 0;
314 BN_CTX_start(ctx);
315 BIGNUM *p_minus_1 = BN_CTX_get(ctx);
316
317 if (!p_minus_1 ||
318 !BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
319 dh->p, ctx)) {
320 goto err;
321 }
322
323 if (!BN_mod_exp_mont_consttime(out_shared_key, peers_key, dh->priv_key, dh->p,
324 ctx, dh->method_mont_p) ||
325 !BN_copy(p_minus_1, dh->p) ||
326 !BN_sub_word(p_minus_1, 1)) {
327 OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
328 goto err;
329 }
330
331 // This performs the check required by SP 800-56Ar3 section 5.7.1.1 step two.
332 if (BN_cmp_word(out_shared_key, 1) <= 0 ||
333 BN_cmp(out_shared_key, p_minus_1) == 0) {
334 OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY);
335 goto err;
336 }
337
338 ret = 1;
339
340 err:
341 BN_CTX_end(ctx);
342 return ret;
343 }
344
dh_compute_key_padded_no_self_test(unsigned char * out,const BIGNUM * peers_key,DH * dh)345 int dh_compute_key_padded_no_self_test(unsigned char *out,
346 const BIGNUM *peers_key, DH *dh) {
347 BN_CTX *ctx = BN_CTX_new();
348 if (ctx == NULL) {
349 return -1;
350 }
351 BN_CTX_start(ctx);
352
353 int dh_size = DH_size(dh);
354 int ret = -1;
355 BIGNUM *shared_key = BN_CTX_get(ctx);
356 if (shared_key &&
357 dh_compute_key(dh, shared_key, peers_key, ctx) &&
358 BN_bn2bin_padded(out, dh_size, shared_key)) {
359 ret = dh_size;
360 }
361
362 BN_CTX_end(ctx);
363 BN_CTX_free(ctx);
364 return ret;
365 }
366
DH_compute_key_padded(unsigned char * out,const BIGNUM * peers_key,DH * dh)367 int DH_compute_key_padded(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
368 boringssl_ensure_ffdh_self_test();
369
370 return dh_compute_key_padded_no_self_test(out, peers_key, dh);
371 }
372
DH_compute_key(unsigned char * out,const BIGNUM * peers_key,DH * dh)373 int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
374 boringssl_ensure_ffdh_self_test();
375
376 BN_CTX *ctx = BN_CTX_new();
377 if (ctx == NULL) {
378 return -1;
379 }
380 BN_CTX_start(ctx);
381
382 int ret = -1;
383 BIGNUM *shared_key = BN_CTX_get(ctx);
384 if (shared_key && dh_compute_key(dh, shared_key, peers_key, ctx)) {
385 // A |BIGNUM|'s byte count fits in |int|.
386 ret = (int)BN_bn2bin(shared_key, out);
387 }
388
389 BN_CTX_end(ctx);
390 BN_CTX_free(ctx);
391 return ret;
392 }
393
DH_compute_key_hashed(DH * dh,uint8_t * out,size_t * out_len,size_t max_out_len,const BIGNUM * peers_key,const EVP_MD * digest)394 int DH_compute_key_hashed(DH *dh, uint8_t *out, size_t *out_len,
395 size_t max_out_len, const BIGNUM *peers_key,
396 const EVP_MD *digest) {
397 *out_len = SIZE_MAX;
398
399 const size_t digest_len = EVP_MD_size(digest);
400 if (digest_len > max_out_len) {
401 return 0;
402 }
403
404 FIPS_service_indicator_lock_state();
405
406 int ret = 0;
407 const size_t dh_len = DH_size(dh);
408 uint8_t *shared_bytes = OPENSSL_malloc(dh_len);
409 unsigned out_len_unsigned;
410 if (!shared_bytes ||
411 // SP 800-56A is ambiguous about whether the output should be padded prior
412 // to revision three. But revision three, section C.1, awkwardly specifies
413 // padding to the length of p.
414 //
415 // Also, padded output avoids side-channels, so is always strongly
416 // advisable.
417 DH_compute_key_padded(shared_bytes, peers_key, dh) != (int)dh_len ||
418 !EVP_Digest(shared_bytes, dh_len, out, &out_len_unsigned, digest, NULL) ||
419 out_len_unsigned != digest_len) {
420 goto err;
421 }
422
423 *out_len = digest_len;
424 ret = 1;
425
426 err:
427 FIPS_service_indicator_unlock_state();
428 OPENSSL_free(shared_bytes);
429 return ret;
430 }
431
DH_size(const DH * dh)432 int DH_size(const DH *dh) { return BN_num_bytes(dh->p); }
433
DH_num_bits(const DH * dh)434 unsigned DH_num_bits(const DH *dh) { return BN_num_bits(dh->p); }
435
DH_up_ref(DH * dh)436 int DH_up_ref(DH *dh) {
437 CRYPTO_refcount_inc(&dh->references);
438 return 1;
439 }
440
DH_get_rfc7919_2048(void)441 DH *DH_get_rfc7919_2048(void) {
442 // This is the prime from https://tools.ietf.org/html/rfc7919#appendix-A.1,
443 // which is specifically approved for FIPS in appendix D of SP 800-56Ar3.
444 static const BN_ULONG kFFDHE2048Data[] = {
445 TOBN(0xffffffff, 0xffffffff), TOBN(0x886b4238, 0x61285c97),
446 TOBN(0xc6f34a26, 0xc1b2effa), TOBN(0xc58ef183, 0x7d1683b2),
447 TOBN(0x3bb5fcbc, 0x2ec22005), TOBN(0xc3fe3b1b, 0x4c6fad73),
448 TOBN(0x8e4f1232, 0xeef28183), TOBN(0x9172fe9c, 0xe98583ff),
449 TOBN(0xc03404cd, 0x28342f61), TOBN(0x9e02fce1, 0xcdf7e2ec),
450 TOBN(0x0b07a7c8, 0xee0a6d70), TOBN(0xae56ede7, 0x6372bb19),
451 TOBN(0x1d4f42a3, 0xde394df4), TOBN(0xb96adab7, 0x60d7f468),
452 TOBN(0xd108a94b, 0xb2c8e3fb), TOBN(0xbc0ab182, 0xb324fb61),
453 TOBN(0x30acca4f, 0x483a797a), TOBN(0x1df158a1, 0x36ade735),
454 TOBN(0xe2a689da, 0xf3efe872), TOBN(0x984f0c70, 0xe0e68b77),
455 TOBN(0xb557135e, 0x7f57c935), TOBN(0x85636555, 0x3ded1af3),
456 TOBN(0x2433f51f, 0x5f066ed0), TOBN(0xd3df1ed5, 0xd5fd6561),
457 TOBN(0xf681b202, 0xaec4617a), TOBN(0x7d2fe363, 0x630c75d8),
458 TOBN(0xcc939dce, 0x249b3ef9), TOBN(0xa9e13641, 0x146433fb),
459 TOBN(0xd8b9c583, 0xce2d3695), TOBN(0xafdc5620, 0x273d3cf1),
460 TOBN(0xadf85458, 0xa2bb4a9a), TOBN(0xffffffff, 0xffffffff),
461 };
462
463 BIGNUM *const ffdhe2048_p = BN_new();
464 BIGNUM *const ffdhe2048_q = BN_new();
465 BIGNUM *const ffdhe2048_g = BN_new();
466 DH *const dh = DH_new();
467
468 if (!ffdhe2048_p || !ffdhe2048_q || !ffdhe2048_g || !dh) {
469 goto err;
470 }
471
472 bn_set_static_words(ffdhe2048_p, kFFDHE2048Data,
473 OPENSSL_ARRAY_SIZE(kFFDHE2048Data));
474
475 if (!BN_rshift1(ffdhe2048_q, ffdhe2048_p) ||
476 !BN_set_word(ffdhe2048_g, 2) ||
477 !DH_set0_pqg(dh, ffdhe2048_p, ffdhe2048_q, ffdhe2048_g)) {
478 goto err;
479 }
480
481 return dh;
482
483 err:
484 BN_free(ffdhe2048_p);
485 BN_free(ffdhe2048_q);
486 BN_free(ffdhe2048_g);
487 DH_free(dh);
488 return NULL;
489 }
490