Coverage Report

Created: 2026-10-17 06:40

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
348
{
56
348
  return moduli_filename ? moduli_filename : _PATH_DH_MODULI;
57
348
}
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
174
{
160
174
  FILE *f;
161
174
  char *line = NULL;
162
174
  size_t linesize = 0;
163
174
  int best, bestcount, which, linenum;
164
174
  struct dhgroup dhg;
165
166
174
  if ((f = fopen(get_moduli_filename(), "r")) == NULL) {
167
174
    logit("WARNING: could not open %s (%s), using fixed modulus",
168
174
        get_moduli_filename(), strerror(errno));
169
174
    return (dh_new_group_fallback(max));
170
174
  }
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.03k
{
237
2.03k
  int i;
238
2.03k
  int n = BN_num_bits(dh_pub);
239
2.03k
  int bits_set = 0;
240
2.03k
  BIGNUM *tmp;
241
2.03k
  const BIGNUM *dh_p;
242
243
2.03k
  DH_get0_pqg(dh, &dh_p, NULL, NULL);
244
245
2.03k
  if (BN_is_negative(dh_pub)) {
246
0
    logit("invalid public DH value: negative");
247
0
    return 0;
248
0
  }
249
2.03k
  if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */
250
4
    logit("invalid public DH value: <= 1");
251
4
    return 0;
252
4
  }
253
254
2.02k
  if ((tmp = BN_new()) == NULL) {
255
0
    error_f("BN_new failed");
256
0
    return 0;
257
0
  }
258
2.02k
  if (!BN_sub(tmp, dh_p, BN_value_one()) ||
259
2.02k
      BN_cmp(dh_pub, tmp) != -1) {   /* pub_exp > p-2 */
260
3
    BN_clear_free(tmp);
261
3
    logit("invalid public DH value: >= p-1");
262
3
    return 0;
263
3
  }
264
2.02k
  BN_clear_free(tmp);
265
266
3.45M
  for (i = 0; i <= n; i++)
267
3.45M
    if (BN_is_bit_set(dh_pub, i))
268
1.67M
      bits_set++;
269
2.02k
  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.02k
  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.02k
  return 1;
280
2.02k
}
281
282
int
283
dh_gen_key(DH *dh, int need)
284
1.64k
{
285
1.64k
  int pbits;
286
1.64k
  const BIGNUM *dh_p, *pub_key;
287
288
1.64k
  DH_get0_pqg(dh, &dh_p, NULL, NULL);
289
290
1.64k
  if (need < 0 || dh_p == NULL ||
291
1.64k
      (pbits = BN_num_bits(dh_p)) <= 0 ||
292
1.64k
      need > INT_MAX / 2 || 2 * need > pbits)
293
0
    return SSH_ERR_INVALID_ARGUMENT;
294
1.64k
  if (need < 256)
295
1.34k
    need = 256;
296
  /*
297
   * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
298
   * so double requested need here.
299
   */
300
1.64k
  if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
301
0
    return SSH_ERR_LIBCRYPTO_ERROR;
302
303
1.64k
  if (DH_generate_key(dh) == 0)
304
18
    return SSH_ERR_LIBCRYPTO_ERROR;
305
1.62k
  DH_get0_key(dh, &pub_key, NULL);
306
1.62k
  if (!dh_pub_is_valid(dh, pub_key))
307
2
    return SSH_ERR_INVALID_FORMAT;
308
1.62k
  return 0;
309
1.62k
}
310
311
DH *
312
dh_new_group_asc(const char *gen, const char *modulus)
313
1.59k
{
314
1.59k
  DH *dh;
315
1.59k
  BIGNUM *dh_p = NULL, *dh_g = NULL;
316
317
1.59k
  if ((dh = DH_new()) == NULL)
318
0
    return NULL;
319
1.59k
  if (BN_hex2bn(&dh_p, modulus) == 0 ||
320
1.59k
      BN_hex2bn(&dh_g, gen) == 0)
321
0
    goto fail;
322
1.59k
  if (!DH_set0_pqg(dh, dh_p, NULL, dh_g))
323
0
    goto fail;
324
1.59k
  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.59k
}
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
53
{
339
53
  DH *dh;
340
341
53
  if ((dh = DH_new()) == NULL)
342
0
    return NULL;
343
53
  if (!DH_set0_pqg(dh, modulus, NULL, gen)) {
344
0
    DH_free(dh);
345
0
    return NULL;
346
0
  }
347
348
53
  return dh;
349
53
}
350
351
/* rfc2409 "Second Oakley Group" (1024 bits) */
352
DH *
353
dh_new_group1(void)
354
1.41k
{
355
1.41k
  static char *gen = "2", *group1 =
356
1.41k
      "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
357
1.41k
      "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
358
1.41k
      "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
359
1.41k
      "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
360
1.41k
      "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
361
1.41k
      "FFFFFFFF" "FFFFFFFF";
362
363
1.41k
  return (dh_new_group_asc(gen, group1));
364
1.41k
}
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
11
{
390
11
  static char *gen = "2", *group16 =
391
11
      "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
392
11
      "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
393
11
      "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
394
11
      "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
395
11
      "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
396
11
      "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
397
11
      "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
398
11
      "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
399
11
      "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
400
11
      "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
401
11
      "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
402
11
      "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
403
11
      "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
404
11
      "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
405
11
      "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
406
11
      "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
407
11
      "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
408
11
      "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
409
11
      "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
410
11
      "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
411
11
      "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
412
11
      "FFFFFFFF" "FFFFFFFF";
413
414
11
  return (dh_new_group_asc(gen, group16));
415
11
}
416
417
/* rfc3526 group 18 "8192-bit MODP Group" */
418
DH *
419
dh_new_group18(void)
420
156
{
421
156
  static char *gen = "2", *group18 =
422
156
      "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
423
156
      "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
424
156
      "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
425
156
      "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
426
156
      "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
427
156
      "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
428
156
      "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
429
156
      "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
430
156
      "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
431
156
      "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
432
156
      "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
433
156
      "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
434
156
      "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
435
156
      "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
436
156
      "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
437
156
      "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
438
156
      "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
439
156
      "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
440
156
      "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
441
156
      "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
442
156
      "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
443
156
      "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
444
156
      "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
445
156
      "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
446
156
      "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
447
156
      "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
448
156
      "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
449
156
      "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
450
156
      "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
451
156
      "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
452
156
      "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
453
156
      "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
454
156
      "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
455
156
      "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
456
156
      "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
457
156
      "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
458
156
      "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
459
156
      "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
460
156
      "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
461
156
      "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
462
156
      "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
463
156
      "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
464
156
      "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
465
466
156
  return (dh_new_group_asc(gen, group18));
467
156
}
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
174
{
473
174
  debug3_f("requested max size %d", max);
474
174
  if (max < 3072) {
475
7
    debug3("using 2k bit group 14");
476
7
    return dh_new_group14();
477
167
  } else if (max < 6144) {
478
11
    debug3("using 4k bit group 16");
479
11
    return dh_new_group16();
480
11
  }
481
156
  debug3("using 8k bit group 18");
482
156
  return dh_new_group18();
483
174
}
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.11k
{
495
1.11k
  if (bits <= 112)
496
0
    return 2048;
497
1.11k
  if (bits <= 128)
498
834
    return 3072;
499
276
  if (bits <= 192)
500
104
    return 7680;
501
172
  return 8192;
502
276
}
503
504
#endif /* WITH_OPENSSL */