Coverage Report

Created: 2025-12-08 07:01

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