• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright 1995-2016 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 <openssl/dh.h>
11
12#include <string.h>
13
14#include <openssl/bn.h>
15#include <openssl/digest.h>
16#include <openssl/err.h>
17#include <openssl/mem.h>
18#include <openssl/thread.h>
19
20#include "../../internal.h"
21#include "../bn/internal.h"
22#include "../service_indicator/internal.h"
23#include "internal.h"
24
25
26DH *DH_new(void) {
27  DH *dh = reinterpret_cast<DH *>(OPENSSL_zalloc(sizeof(DH)));
28  if (dh == NULL) {
29    return NULL;
30  }
31
32  CRYPTO_MUTEX_init(&dh->method_mont_p_lock);
33  dh->references = 1;
34  return dh;
35}
36
37void DH_free(DH *dh) {
38  if (dh == NULL) {
39    return;
40  }
41
42  if (!CRYPTO_refcount_dec_and_test_zero(&dh->references)) {
43    return;
44  }
45
46  BN_MONT_CTX_free(dh->method_mont_p);
47  BN_clear_free(dh->p);
48  BN_clear_free(dh->g);
49  BN_clear_free(dh->q);
50  BN_clear_free(dh->pub_key);
51  BN_clear_free(dh->priv_key);
52  CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock);
53
54  OPENSSL_free(dh);
55}
56
57unsigned DH_bits(const DH *dh) { return BN_num_bits(dh->p); }
58
59const BIGNUM *DH_get0_pub_key(const DH *dh) { return dh->pub_key; }
60
61const BIGNUM *DH_get0_priv_key(const DH *dh) { return dh->priv_key; }
62
63const BIGNUM *DH_get0_p(const DH *dh) { return dh->p; }
64
65const BIGNUM *DH_get0_q(const DH *dh) { return dh->q; }
66
67const BIGNUM *DH_get0_g(const DH *dh) { return dh->g; }
68
69void DH_get0_key(const DH *dh, const BIGNUM **out_pub_key,
70                 const BIGNUM **out_priv_key) {
71  if (out_pub_key != NULL) {
72    *out_pub_key = dh->pub_key;
73  }
74  if (out_priv_key != NULL) {
75    *out_priv_key = dh->priv_key;
76  }
77}
78
79int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) {
80  if (pub_key != NULL) {
81    BN_free(dh->pub_key);
82    dh->pub_key = pub_key;
83  }
84
85  if (priv_key != NULL) {
86    BN_free(dh->priv_key);
87    dh->priv_key = priv_key;
88  }
89
90  return 1;
91}
92
93void DH_get0_pqg(const DH *dh, const BIGNUM **out_p, const BIGNUM **out_q,
94                 const BIGNUM **out_g) {
95  if (out_p != NULL) {
96    *out_p = dh->p;
97  }
98  if (out_q != NULL) {
99    *out_q = dh->q;
100  }
101  if (out_g != NULL) {
102    *out_g = dh->g;
103  }
104}
105
106int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
107  if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL)) {
108    return 0;
109  }
110
111  if (p != NULL) {
112    BN_free(dh->p);
113    dh->p = p;
114  }
115
116  if (q != NULL) {
117    BN_free(dh->q);
118    dh->q = q;
119  }
120
121  if (g != NULL) {
122    BN_free(dh->g);
123    dh->g = g;
124  }
125
126  // Invalidate the cached Montgomery parameters.
127  BN_MONT_CTX_free(dh->method_mont_p);
128  dh->method_mont_p = NULL;
129  return 1;
130}
131
132int DH_set_length(DH *dh, unsigned priv_length) {
133  dh->priv_length = priv_length;
134  return 1;
135}
136
137int DH_generate_key(DH *dh) {
138  boringssl_ensure_ffdh_self_test();
139
140  if (!dh_check_params_fast(dh)) {
141    return 0;
142  }
143
144  int ok = 0;
145  int generate_new_key = 0;
146  BN_CTX *ctx = NULL;
147  BIGNUM *pub_key = NULL, *priv_key = NULL, *priv_key_limit = NULL;
148
149  ctx = BN_CTX_new();
150  if (ctx == NULL) {
151    goto err;
152  }
153
154  if (dh->priv_key == NULL) {
155    priv_key = BN_new();
156    if (priv_key == NULL) {
157      goto err;
158    }
159    generate_new_key = 1;
160  } else {
161    priv_key = dh->priv_key;
162  }
163
164  if (dh->pub_key == NULL) {
165    pub_key = BN_new();
166    if (pub_key == NULL) {
167      goto err;
168    }
169  } else {
170    pub_key = dh->pub_key;
171  }
172
173  if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
174                              dh->p, ctx)) {
175    goto err;
176  }
177
178  if (generate_new_key) {
179    if (dh->q) {
180      // Section 5.6.1.1.4 of SP 800-56A Rev3 generates a private key uniformly
181      // from [1, min(2^N-1, q-1)].
182      //
183      // Although SP 800-56A Rev3 now permits a private key length N,
184      // |dh->priv_length| historically was ignored when q is available. We
185      // continue to ignore it and interpret such a configuration as N = len(q).
186      if (!BN_rand_range_ex(priv_key, 1, dh->q)) {
187        goto err;
188      }
189    } else {
190      // If q is unspecified, we expect p to be a safe prime, with g generating
191      // the (p-1)/2 subgroup. So, we use q = (p-1)/2. (If g generates a smaller
192      // prime-order subgroup, q will still divide (p-1)/2.)
193      //
194      // We set N from |dh->priv_length|. Section 5.6.1.1.4 of SP 800-56A Rev3
195      // says to reject N > len(q), or N > num_bits(p) - 1. However, this logic
196      // originally aligned with PKCS#3, which allows num_bits(p). Instead, we
197      // clamp |dh->priv_length| before invoking the algorithm.
198
199      // Compute M = min(2^N, q).
200      priv_key_limit = BN_new();
201      if (priv_key_limit == NULL) {
202        goto err;
203      }
204      if (dh->priv_length == 0 || dh->priv_length >= BN_num_bits(dh->p) - 1) {
205        // M = q = (p - 1) / 2.
206        if (!BN_rshift1(priv_key_limit, dh->p)) {
207          goto err;
208        }
209      } else {
210        // M = 2^N.
211        if (!BN_set_bit(priv_key_limit, dh->priv_length)) {
212          goto err;
213        }
214      }
215
216      // Choose a private key uniformly from [1, M-1].
217      if (!BN_rand_range_ex(priv_key, 1, priv_key_limit)) {
218        goto err;
219      }
220    }
221  }
222
223  if (!BN_mod_exp_mont_consttime(pub_key, dh->g, priv_key, dh->p, ctx,
224                                 dh->method_mont_p)) {
225    goto err;
226  }
227
228  dh->pub_key = pub_key;
229  dh->priv_key = priv_key;
230  ok = 1;
231
232err:
233  if (ok != 1) {
234    OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
235  }
236
237  if (dh->pub_key == NULL) {
238    BN_free(pub_key);
239  }
240  if (dh->priv_key == NULL) {
241    BN_free(priv_key);
242  }
243  BN_free(priv_key_limit);
244  BN_CTX_free(ctx);
245  return ok;
246}
247
248static int dh_compute_key(DH *dh, BIGNUM *out_shared_key,
249                          const BIGNUM *peers_key, BN_CTX *ctx) {
250  if (!dh_check_params_fast(dh)) {
251    return 0;
252  }
253
254  if (dh->priv_key == NULL) {
255    OPENSSL_PUT_ERROR(DH, DH_R_NO_PRIVATE_VALUE);
256    return 0;
257  }
258
259  int check_result;
260  if (!DH_check_pub_key(dh, peers_key, &check_result) || check_result) {
261    OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY);
262    return 0;
263  }
264
265  int ret = 0;
266  BN_CTX_start(ctx);
267  BIGNUM *p_minus_1 = BN_CTX_get(ctx);
268
269  if (!p_minus_1 ||
270      !BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
271                              dh->p, ctx)) {
272    goto err;
273  }
274
275  if (!BN_mod_exp_mont_consttime(out_shared_key, peers_key, dh->priv_key, dh->p,
276                                 ctx, dh->method_mont_p) ||
277      !BN_copy(p_minus_1, dh->p) || !BN_sub_word(p_minus_1, 1)) {
278    OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
279    goto err;
280  }
281
282  // This performs the check required by SP 800-56Ar3 section 5.7.1.1 step two.
283  if (BN_cmp_word(out_shared_key, 1) <= 0 ||
284      BN_cmp(out_shared_key, p_minus_1) == 0) {
285    OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY);
286    goto err;
287  }
288
289  ret = 1;
290
291err:
292  BN_CTX_end(ctx);
293  return ret;
294}
295
296int dh_compute_key_padded_no_self_test(unsigned char *out,
297                                       const BIGNUM *peers_key, DH *dh) {
298  BN_CTX *ctx = BN_CTX_new();
299  if (ctx == NULL) {
300    return -1;
301  }
302  BN_CTX_start(ctx);
303
304  int dh_size = DH_size(dh);
305  int ret = -1;
306  BIGNUM *shared_key = BN_CTX_get(ctx);
307  if (shared_key && dh_compute_key(dh, shared_key, peers_key, ctx) &&
308      BN_bn2bin_padded(out, dh_size, shared_key)) {
309    ret = dh_size;
310  }
311
312  BN_CTX_end(ctx);
313  BN_CTX_free(ctx);
314  return ret;
315}
316
317int DH_compute_key_padded(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
318  boringssl_ensure_ffdh_self_test();
319
320  return dh_compute_key_padded_no_self_test(out, peers_key, dh);
321}
322
323int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
324  boringssl_ensure_ffdh_self_test();
325
326  BN_CTX *ctx = BN_CTX_new();
327  if (ctx == NULL) {
328    return -1;
329  }
330  BN_CTX_start(ctx);
331
332  int ret = -1;
333  BIGNUM *shared_key = BN_CTX_get(ctx);
334  if (shared_key && dh_compute_key(dh, shared_key, peers_key, ctx)) {
335    // A |BIGNUM|'s byte count fits in |int|.
336    ret = (int)BN_bn2bin(shared_key, out);
337  }
338
339  BN_CTX_end(ctx);
340  BN_CTX_free(ctx);
341  return ret;
342}
343
344int DH_compute_key_hashed(DH *dh, uint8_t *out, size_t *out_len,
345                          size_t max_out_len, const BIGNUM *peers_key,
346                          const EVP_MD *digest) {
347  *out_len = SIZE_MAX;
348
349  const size_t digest_len = EVP_MD_size(digest);
350  if (digest_len > max_out_len) {
351    return 0;
352  }
353
354  FIPS_service_indicator_lock_state();
355
356  int ret = 0;
357  const size_t dh_len = DH_size(dh);
358  uint8_t *shared_bytes = reinterpret_cast<uint8_t *>(OPENSSL_malloc(dh_len));
359  unsigned out_len_unsigned;
360  if (!shared_bytes ||
361      // SP 800-56A is ambiguous about whether the output should be padded prior
362      // to revision three. But revision three, section C.1, awkwardly specifies
363      // padding to the length of p.
364      //
365      // Also, padded output avoids side-channels, so is always strongly
366      // advisable.
367      DH_compute_key_padded(shared_bytes, peers_key, dh) != (int)dh_len ||
368      !EVP_Digest(shared_bytes, dh_len, out, &out_len_unsigned, digest, NULL) ||
369      out_len_unsigned != digest_len) {
370    goto err;
371  }
372
373  *out_len = digest_len;
374  ret = 1;
375
376err:
377  FIPS_service_indicator_unlock_state();
378  OPENSSL_free(shared_bytes);
379  return ret;
380}
381
382int DH_size(const DH *dh) { return BN_num_bytes(dh->p); }
383
384unsigned DH_num_bits(const DH *dh) { return BN_num_bits(dh->p); }
385
386int DH_up_ref(DH *dh) {
387  CRYPTO_refcount_inc(&dh->references);
388  return 1;
389}
390
391DH *DH_get_rfc7919_2048(void) {
392  // This is the prime from https://tools.ietf.org/html/rfc7919#appendix-A.1,
393  // which is specifically approved for FIPS in appendix D of SP 800-56Ar3.
394  static const BN_ULONG kFFDHE2048Data[] = {
395      TOBN(0xffffffff, 0xffffffff), TOBN(0x886b4238, 0x61285c97),
396      TOBN(0xc6f34a26, 0xc1b2effa), TOBN(0xc58ef183, 0x7d1683b2),
397      TOBN(0x3bb5fcbc, 0x2ec22005), TOBN(0xc3fe3b1b, 0x4c6fad73),
398      TOBN(0x8e4f1232, 0xeef28183), TOBN(0x9172fe9c, 0xe98583ff),
399      TOBN(0xc03404cd, 0x28342f61), TOBN(0x9e02fce1, 0xcdf7e2ec),
400      TOBN(0x0b07a7c8, 0xee0a6d70), TOBN(0xae56ede7, 0x6372bb19),
401      TOBN(0x1d4f42a3, 0xde394df4), TOBN(0xb96adab7, 0x60d7f468),
402      TOBN(0xd108a94b, 0xb2c8e3fb), TOBN(0xbc0ab182, 0xb324fb61),
403      TOBN(0x30acca4f, 0x483a797a), TOBN(0x1df158a1, 0x36ade735),
404      TOBN(0xe2a689da, 0xf3efe872), TOBN(0x984f0c70, 0xe0e68b77),
405      TOBN(0xb557135e, 0x7f57c935), TOBN(0x85636555, 0x3ded1af3),
406      TOBN(0x2433f51f, 0x5f066ed0), TOBN(0xd3df1ed5, 0xd5fd6561),
407      TOBN(0xf681b202, 0xaec4617a), TOBN(0x7d2fe363, 0x630c75d8),
408      TOBN(0xcc939dce, 0x249b3ef9), TOBN(0xa9e13641, 0x146433fb),
409      TOBN(0xd8b9c583, 0xce2d3695), TOBN(0xafdc5620, 0x273d3cf1),
410      TOBN(0xadf85458, 0xa2bb4a9a), TOBN(0xffffffff, 0xffffffff),
411  };
412
413  BIGNUM *const ffdhe2048_p = BN_new();
414  BIGNUM *const ffdhe2048_q = BN_new();
415  BIGNUM *const ffdhe2048_g = BN_new();
416  DH *const dh = DH_new();
417
418  if (!ffdhe2048_p || !ffdhe2048_q || !ffdhe2048_g || !dh) {
419    goto err;
420  }
421
422  bn_set_static_words(ffdhe2048_p, kFFDHE2048Data,
423                      OPENSSL_ARRAY_SIZE(kFFDHE2048Data));
424
425  if (!BN_rshift1(ffdhe2048_q, ffdhe2048_p) || !BN_set_word(ffdhe2048_g, 2) ||
426      !DH_set0_pqg(dh, ffdhe2048_p, ffdhe2048_q, ffdhe2048_g)) {
427    goto err;
428  }
429
430  return dh;
431
432err:
433  BN_free(ffdhe2048_p);
434  BN_free(ffdhe2048_q);
435  BN_free(ffdhe2048_g);
436  DH_free(dh);
437  return NULL;
438}
439