Coverage Report

Created: 2026-02-24 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssh/dh.c
Line
Count
Source
1
/* $OpenBSD: dh.c,v 1.76 2026/02/08 19:54:31 dtucker Exp $ */
2
/*
3
 * Copyright (c) 2000 Niels Provos.  All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
#include "includes.h"
27
28
#ifdef WITH_OPENSSL
29
#include "openbsd-compat/openssl-compat.h"
30
31
#include <errno.h>
32
#include <stdarg.h>
33
#include <stdio.h>
34
#include <stdlib.h>
35
#include <string.h>
36
#include <limits.h>
37
38
#include <openssl/bn.h>
39
#include <openssl/dh.h>
40
41
#include "dh.h"
42
#include "pathnames.h"
43
#include "log.h"
44
#include "misc.h"
45
#include "ssherr.h"
46
47
static const char *moduli_filename;
48
49
void dh_set_moduli_file(const char *filename)
50
0
{
51
0
  moduli_filename = filename;
52
0
}
53
54
static const char * get_moduli_filename(void)
55
402
{
56
402
  return moduli_filename ? moduli_filename : _PATH_DH_MODULI;
57
402
}
58
59
static int
60
parse_prime(int linenum, char *line, struct dhgroup *dhg)
61
0
{
62
0
  char *cp, *arg;
63
0
  char *strsize, *gen, *prime;
64
0
  const char *errstr = NULL;
65
0
  long long n;
66
67
0
  dhg->p = dhg->g = NULL;
68
0
  cp = line;
69
0
  if ((arg = strdelim(&cp)) == NULL)
70
0
    return 0;
71
  /* Ignore leading whitespace */
72
0
  if (*arg == '\0')
73
0
    arg = strdelim(&cp);
74
0
  if (!arg || !*arg || *arg == '#')
75
0
    return 0;
76
77
  /* time */
78
0
  if (cp == NULL || *arg == '\0')
79
0
    goto truncated;
80
0
  arg = strsep(&cp, " "); /* type */
81
0
  if (cp == NULL || *arg == '\0')
82
0
    goto truncated;
83
  /* Ensure this is a safe prime */
84
0
  n = strtonum(arg, 0, 5, &errstr);
85
0
  if (errstr != NULL || n != MODULI_TYPE_SAFE) {
86
0
    error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE);
87
0
    goto fail;
88
0
  }
89
0
  arg = strsep(&cp, " "); /* tests */
90
0
  if (cp == NULL || *arg == '\0')
91
0
    goto truncated;
92
  /* Ensure prime has been tested and is not composite */
93
0
  n = strtonum(arg, 0, 0x1f, &errstr);
94
0
  if (errstr != NULL ||
95
0
      (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) {
96
0
    error("moduli:%d: invalid moduli tests flag", linenum);
97
0
    goto fail;
98
0
  }
99
0
  arg = strsep(&cp, " "); /* tries */
100
0
  if (cp == NULL || *arg == '\0')
101
0
    goto truncated;
102
0
  n = strtonum(arg, 0, 1<<30, &errstr);
103
0
  if (errstr != NULL || n == 0) {
104
0
    error("moduli:%d: invalid primality trial count", linenum);
105
0
    goto fail;
106
0
  }
107
0
  strsize = strsep(&cp, " "); /* size */
108
0
  if (cp == NULL || *strsize == '\0' ||
109
0
      (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
110
0
      errstr) {
111
0
    error("moduli:%d: invalid prime length", linenum);
112
0
    goto fail;
113
0
  }
114
  /* The whole group is one bit larger */
115
0
  dhg->size++;
116
0
  gen = strsep(&cp, " "); /* gen */
117
0
  if (cp == NULL || *gen == '\0')
118
0
    goto truncated;
119
0
  prime = strsep(&cp, " "); /* prime */
120
0
  if (cp != NULL || *prime == '\0') {
121
0
 truncated:
122
0
    error("moduli:%d: truncated", linenum);
123
0
    goto fail;
124
0
  }
125
126
0
  if ((dhg->g = BN_new()) == NULL ||
127
0
      (dhg->p = BN_new()) == NULL) {
128
0
    error("parse_prime: BN_new failed");
129
0
    goto fail;
130
0
  }
131
0
  if (BN_hex2bn(&dhg->g, gen) == 0) {
132
0
    error("moduli:%d: could not parse generator value", linenum);
133
0
    goto fail;
134
0
  }
135
0
  if (BN_hex2bn(&dhg->p, prime) == 0) {
136
0
    error("moduli:%d: could not parse prime value", linenum);
137
0
    goto fail;
138
0
  }
139
0
  if (BN_num_bits(dhg->p) != dhg->size) {
140
0
    error("moduli:%d: prime has wrong size: actual %d listed %d",
141
0
        linenum, BN_num_bits(dhg->p), dhg->size - 1);
142
0
    goto fail;
143
0
  }
144
0
  if (BN_cmp(dhg->g, BN_value_one()) <= 0) {
145
0
    error("moduli:%d: generator is invalid", linenum);
146
0
    goto fail;
147
0
  }
148
0
  return 1;
149
150
0
 fail:
151
0
  BN_clear_free(dhg->g);
152
0
  BN_clear_free(dhg->p);
153
0
  dhg->g = dhg->p = NULL;
154
0
  return 0;
155
0
}
156
157
DH *
158
choose_dh(int min, int wantbits, int max)
159
201
{
160
201
  FILE *f;
161
201
  char *line = NULL;
162
201
  size_t linesize = 0;
163
201
  int best, bestcount, which, linenum;
164
201
  struct dhgroup dhg;
165
166
201
  if ((f = fopen(get_moduli_filename(), "r")) == NULL) {
167
201
    logit("WARNING: could not open %s (%s), using fixed modulus",
168
201
        get_moduli_filename(), strerror(errno));
169
201
    return (dh_new_group_fallback(max));
170
201
  }
171
172
0
  linenum = 0;
173
0
  best = bestcount = 0;
174
0
  while (getline(&line, &linesize, f) != -1) {
175
0
    linenum++;
176
0
    if (!parse_prime(linenum, line, &dhg))
177
0
      continue;
178
0
    BN_clear_free(dhg.g);
179
0
    BN_clear_free(dhg.p);
180
181
0
    if (dhg.size > max || dhg.size < min)
182
0
      continue;
183
184
0
    if ((dhg.size > wantbits && dhg.size < best) ||
185
0
        (dhg.size > best && best < wantbits)) {
186
0
      best = dhg.size;
187
0
      bestcount = 0;
188
0
    }
189
0
    if (dhg.size == best)
190
0
      bestcount++;
191
0
  }
192
0
  free(line);
193
0
  line = NULL;
194
0
  linesize = 0;
195
0
  rewind(f);
196
197
0
  if (bestcount == 0) {
198
0
    fclose(f);
199
0
    logit("WARNING: no suitable primes (size %d/%d/%d) in %s",
200
0
        min, wantbits, max, get_moduli_filename());
201
0
    return NULL;
202
0
  }
203
0
  which = arc4random_uniform(bestcount);
204
205
0
  linenum = 0;
206
0
  bestcount = 0;
207
0
  while (getline(&line, &linesize, f) != -1) {
208
0
    linenum++;
209
0
    if (!parse_prime(linenum, line, &dhg))
210
0
      continue;
211
0
    if ((dhg.size > max || dhg.size < min) ||
212
0
        dhg.size != best ||
213
0
        bestcount++ != which) {
214
0
      BN_clear_free(dhg.g);
215
0
      BN_clear_free(dhg.p);
216
0
      continue;
217
0
    }
218
0
    break;
219
0
  }
220
0
  free(line);
221
0
  line = NULL;
222
0
  fclose(f);
223
0
  if (bestcount != which + 1) {
224
0
    logit("WARNING: selected prime disappeared in %s, giving up",
225
0
        get_moduli_filename());
226
0
    return (dh_new_group_fallback(max));
227
0
  }
228
229
0
  return (dh_new_group(dhg.g, dhg.p));
230
0
}
231
232
/* diffie-hellman-groupN-sha1 */
233
234
int
235
dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
236
2.25k
{
237
2.25k
  int i;
238
2.25k
  int n = BN_num_bits(dh_pub);
239
2.25k
  int bits_set = 0;
240
2.25k
  BIGNUM *tmp;
241
2.25k
  const BIGNUM *dh_p;
242
243
2.25k
  DH_get0_pqg(dh, &dh_p, NULL, NULL);
244
245
2.25k
  if (BN_is_negative(dh_pub)) {
246
0
    logit("invalid public DH value: negative");
247
0
    return 0;
248
0
  }
249
2.25k
  if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */
250
3
    logit("invalid public DH value: <= 1");
251
3
    return 0;
252
3
  }
253
254
2.24k
  if ((tmp = BN_new()) == NULL) {
255
0
    error_f("BN_new failed");
256
0
    return 0;
257
0
  }
258
2.24k
  if (!BN_sub(tmp, dh_p, BN_value_one()) ||
259
2.24k
      BN_cmp(dh_pub, tmp) != -1) {   /* pub_exp > p-2 */
260
2
    BN_clear_free(tmp);
261
2
    logit("invalid public DH value: >= p-1");
262
2
    return 0;
263
2
  }
264
2.24k
  BN_clear_free(tmp);
265
266
3.80M
  for (i = 0; i <= n; i++)
267
3.80M
    if (BN_is_bit_set(dh_pub, i))
268
1.84M
      bits_set++;
269
2.24k
  debug2("bits set: %d/%d", bits_set, BN_num_bits(dh_p));
270
271
  /*
272
   * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
273
   */
274
2.24k
  if (bits_set < 4) {
275
3
    logit("invalid public DH value (%d/%d)",
276
3
        bits_set, BN_num_bits(dh_p));
277
3
    return 0;
278
3
  }
279
2.24k
  return 1;
280
2.24k
}
281
282
int
283
dh_gen_key(DH *dh, int need)
284
1.82k
{
285
1.82k
  int pbits;
286
1.82k
  const BIGNUM *dh_p, *pub_key;
287
288
1.82k
  DH_get0_pqg(dh, &dh_p, NULL, NULL);
289
290
1.82k
  if (need < 0 || dh_p == NULL ||
291
1.82k
      (pbits = BN_num_bits(dh_p)) <= 0 ||
292
1.82k
      need > INT_MAX / 2 || 2 * need > pbits)
293
0
    return SSH_ERR_INVALID_ARGUMENT;
294
1.82k
  if (need < 256)
295
1.48k
    need = 256;
296
  /*
297
   * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
298
   * so double requested need here.
299
   */
300
1.82k
  if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
301
0
    return SSH_ERR_LIBCRYPTO_ERROR;
302
303
1.82k
  if (DH_generate_key(dh) == 0)
304
18
    return SSH_ERR_LIBCRYPTO_ERROR;
305
1.80k
  DH_get0_key(dh, &pub_key, NULL);
306
1.80k
  if (!dh_pub_is_valid(dh, pub_key))
307
2
    return SSH_ERR_INVALID_FORMAT;
308
1.80k
  return 0;
309
1.80k
}
310
311
DH *
312
dh_new_group_asc(const char *gen, const char *modulus)
313
1.77k
{
314
1.77k
  DH *dh;
315
1.77k
  BIGNUM *dh_p = NULL, *dh_g = NULL;
316
317
1.77k
  if ((dh = DH_new()) == NULL)
318
0
    return NULL;
319
1.77k
  if (BN_hex2bn(&dh_p, modulus) == 0 ||
320
1.77k
      BN_hex2bn(&dh_g, gen) == 0)
321
0
    goto fail;
322
1.77k
  if (!DH_set0_pqg(dh, dh_p, NULL, dh_g))
323
0
    goto fail;
324
1.77k
  return dh;
325
0
 fail:
326
0
  DH_free(dh);
327
0
  BN_clear_free(dh_p);
328
0
  BN_clear_free(dh_g);
329
0
  return NULL;
330
1.77k
}
331
332
/*
333
 * This just returns the group, we still need to generate the exchange
334
 * value.
335
 */
336
DH *
337
dh_new_group(BIGNUM *gen, BIGNUM *modulus)
338
47
{
339
47
  DH *dh;
340
341
47
  if ((dh = DH_new()) == NULL)
342
0
    return NULL;
343
47
  if (!DH_set0_pqg(dh, modulus, NULL, gen)) {
344
0
    DH_free(dh);
345
0
    return NULL;
346
0
  }
347
348
47
  return dh;
349
47
}
350
351
/* rfc2409 "Second Oakley Group" (1024 bits) */
352
DH *
353
dh_new_group1(void)
354
1.57k
{
355
1.57k
  static char *gen = "2", *group1 =
356
1.57k
      "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
357
1.57k
      "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
358
1.57k
      "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
359
1.57k
      "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
360
1.57k
      "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
361
1.57k
      "FFFFFFFF" "FFFFFFFF";
362
363
1.57k
  return (dh_new_group_asc(gen, group1));
364
1.57k
}
365
366
/* rfc3526 group 14 "2048-bit MODP Group" */
367
DH *
368
dh_new_group14(void)
369
7
{
370
7
  static char *gen = "2", *group14 =
371
7
      "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
372
7
      "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
373
7
      "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
374
7
      "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
375
7
      "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
376
7
      "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
377
7
      "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
378
7
      "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
379
7
      "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
380
7
      "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
381
7
      "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
382
383
7
  return (dh_new_group_asc(gen, group14));
384
7
}
385
386
/* rfc3526 group 16 "4096-bit MODP Group" */
387
DH *
388
dh_new_group16(void)
389
14
{
390
14
  static char *gen = "2", *group16 =
391
14
      "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
392
14
      "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
393
14
      "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
394
14
      "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
395
14
      "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
396
14
      "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
397
14
      "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
398
14
      "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
399
14
      "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
400
14
      "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
401
14
      "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
402
14
      "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
403
14
      "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
404
14
      "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
405
14
      "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
406
14
      "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
407
14
      "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
408
14
      "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
409
14
      "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
410
14
      "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
411
14
      "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
412
14
      "FFFFFFFF" "FFFFFFFF";
413
414
14
  return (dh_new_group_asc(gen, group16));
415
14
}
416
417
/* rfc3526 group 18 "8192-bit MODP Group" */
418
DH *
419
dh_new_group18(void)
420
180
{
421
180
  static char *gen = "2", *group18 =
422
180
      "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
423
180
      "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
424
180
      "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
425
180
      "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
426
180
      "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
427
180
      "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
428
180
      "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
429
180
      "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
430
180
      "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
431
180
      "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
432
180
      "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
433
180
      "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
434
180
      "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
435
180
      "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
436
180
      "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
437
180
      "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
438
180
      "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
439
180
      "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
440
180
      "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
441
180
      "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
442
180
      "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
443
180
      "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
444
180
      "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
445
180
      "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
446
180
      "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
447
180
      "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
448
180
      "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
449
180
      "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
450
180
      "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
451
180
      "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
452
180
      "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
453
180
      "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
454
180
      "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
455
180
      "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
456
180
      "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
457
180
      "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
458
180
      "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
459
180
      "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
460
180
      "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
461
180
      "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
462
180
      "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
463
180
      "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
464
180
      "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
465
466
180
  return (dh_new_group_asc(gen, group18));
467
180
}
468
469
/* Select fallback group used by DH-GEX if moduli file cannot be read. */
470
DH *
471
dh_new_group_fallback(int max)
472
201
{
473
201
  debug3_f("requested max size %d", max);
474
201
  if (max < 3072) {
475
7
    debug3("using 2k bit group 14");
476
7
    return dh_new_group14();
477
194
  } else if (max < 6144) {
478
14
    debug3("using 4k bit group 16");
479
14
    return dh_new_group16();
480
14
  }
481
180
  debug3("using 8k bit group 18");
482
180
  return dh_new_group18();
483
201
}
484
485
/*
486
 * Estimates the group order for a Diffie-Hellman group that has an
487
 * attack complexity approximately the same as O(2**bits).
488
 * Values from NIST Special Publication 800-57: Recommendation for Key
489
 * Management Part 1 (rev 3) limited by the recommended maximum value
490
 * from RFC4419 section 3.
491
 */
492
u_int
493
dh_estimate(int bits)
494
1.22k
{
495
1.22k
  if (bits <= 112)
496
0
    return 2048;
497
1.22k
  if (bits <= 128)
498
884
    return 3072;
499
339
  if (bits <= 192)
500
115
    return 7680;
501
224
  return 8192;
502
339
}
503
504
#endif /* WITH_OPENSSL */