Coverage Report

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