Coverage Report

Created: 2026-10-13 06:57

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