Coverage Report

Created: 2026-10-23 07:11

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
346
{
56
346
  return moduli_filename ? moduli_filename : _PATH_DH_MODULI;
57
346
}
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
173
{
160
173
  FILE *f;
161
173
  char *line = NULL;
162
173
  size_t linesize = 0;
163
173
  int best, bestcount, which, linenum;
164
173
  struct dhgroup dhg;
165
166
173
  if ((f = fopen(get_moduli_filename(), "r")) == NULL) {
167
173
    logit("WARNING: could not open %s (%s), using fixed modulus",
168
173
        get_moduli_filename(), strerror(errno));
169
173
    return (dh_new_group_fallback(max));
170
173
  }
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.06k
{
237
2.06k
  int i;
238
2.06k
  int n = BN_num_bits(dh_pub);
239
2.06k
  int bits_set = 0;
240
2.06k
  BIGNUM *tmp;
241
2.06k
  const BIGNUM *dh_p;
242
243
2.06k
  DH_get0_pqg(dh, &dh_p, NULL, NULL);
244
245
2.06k
  if (BN_is_negative(dh_pub)) {
246
0
    logit("invalid public DH value: negative");
247
0
    return 0;
248
0
  }
249
2.06k
  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.06k
  if ((tmp = BN_new()) == NULL) {
255
0
    error_f("BN_new failed");
256
0
    return 0;
257
0
  }
258
2.06k
  if (!BN_sub(tmp, dh_p, BN_value_one()) ||
259
2.06k
      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.05k
  BN_clear_free(tmp);
265
266
3.43M
  for (i = 0; i <= n; i++)
267
3.43M
    if (BN_is_bit_set(dh_pub, i))
268
1.66M
      bits_set++;
269
2.05k
  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.05k
  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.05k
  return 1;
280
2.05k
}
281
282
int
283
dh_gen_key(DH *dh, int need)
284
1.67k
{
285
1.67k
  int pbits;
286
1.67k
  const BIGNUM *dh_p, *pub_key;
287
288
1.67k
  DH_get0_pqg(dh, &dh_p, NULL, NULL);
289
290
1.67k
  if (need < 0 || dh_p == NULL ||
291
1.67k
      (pbits = BN_num_bits(dh_p)) <= 0 ||
292
1.67k
      need > INT_MAX / 2 || 2 * need > pbits)
293
0
    return SSH_ERR_INVALID_ARGUMENT;
294
1.67k
  if (need < 256)
295
1.38k
    need = 256;
296
  /*
297
   * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
298
   * so double requested need here.
299
   */
300
1.67k
  if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
301
0
    return SSH_ERR_LIBCRYPTO_ERROR;
302
303
1.67k
  if (DH_generate_key(dh) == 0)
304
19
    return SSH_ERR_LIBCRYPTO_ERROR;
305
1.65k
  DH_get0_key(dh, &pub_key, NULL);
306
1.65k
  if (!dh_pub_is_valid(dh, pub_key))
307
2
    return SSH_ERR_INVALID_FORMAT;
308
1.65k
  return 0;
309
1.65k
}
310
311
DH *
312
dh_new_group_asc(const char *gen, const char *modulus)
313
1.62k
{
314
1.62k
  DH *dh;
315
1.62k
  BIGNUM *dh_p = NULL, *dh_g = NULL;
316
317
1.62k
  if ((dh = DH_new()) == NULL)
318
0
    return NULL;
319
1.62k
  if (BN_hex2bn(&dh_p, modulus) == 0 ||
320
1.62k
      BN_hex2bn(&dh_g, gen) == 0)
321
0
    goto fail;
322
1.62k
  if (!DH_set0_pqg(dh, dh_p, NULL, dh_g))
323
0
    goto fail;
324
1.62k
  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.62k
}
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
51
{
339
51
  DH *dh;
340
341
51
  if ((dh = DH_new()) == NULL)
342
0
    return NULL;
343
51
  if (!DH_set0_pqg(dh, modulus, NULL, gen)) {
344
0
    DH_free(dh);
345
0
    return NULL;
346
0
  }
347
348
51
  return dh;
349
51
}
350
351
/* rfc2409 "Second Oakley Group" (1024 bits) */
352
DH *
353
dh_new_group1(void)
354
1.45k
{
355
1.45k
  static char *gen = "2", *group1 =
356
1.45k
      "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
357
1.45k
      "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
358
1.45k
      "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
359
1.45k
      "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
360
1.45k
      "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
361
1.45k
      "FFFFFFFF" "FFFFFFFF";
362
363
1.45k
  return (dh_new_group_asc(gen, group1));
364
1.45k
}
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
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
173
{
473
173
  debug3_f("requested max size %d", max);
474
173
  if (max < 3072) {
475
7
    debug3("using 2k bit group 14");
476
7
    return dh_new_group14();
477
166
  } else if (max < 6144) {
478
10
    debug3("using 4k bit group 16");
479
10
    return dh_new_group16();
480
10
  }
481
156
  debug3("using 8k bit group 18");
482
156
  return dh_new_group18();
483
173
}
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.12k
{
495
1.12k
  if (bits <= 112)
496
0
    return 2048;
497
1.12k
  if (bits <= 128)
498
844
    return 3072;
499
279
  if (bits <= 192)
500
104
    return 7680;
501
175
  return 8192;
502
279
}
503
504
#endif /* WITH_OPENSSL */