summaryrefslogtreecommitdiff
path: root/moduli.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2011-10-18 16:05:19 +1100
committerDamien Miller <djm@mindrot.org>2011-10-18 16:05:19 +1100
commit390d0561fccfba5e2e97105f75b70b32aab59578 (patch)
treec1baadb7c116489ef2a6260d06fac81d66208c3e /moduli.c
parentd3e6990c4ca1e6c8ad9e66f5e57a2b4545dbc940 (diff)
- dtucker@cvs.openbsd.org 2011/10/16 11:02:46
[moduli.c ssh-keygen.1 ssh-keygen.c] Add optional checkpoints for moduli screening. feedback & ok deraadt
Diffstat (limited to 'moduli.c')
-rw-r--r--moduli.c69
1 files changed, 66 insertions, 3 deletions
diff --git a/moduli.c b/moduli.c
index 2964a8b3d..f734d1c28 100644
--- a/moduli.c
+++ b/moduli.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: moduli.c,v 1.22 2010/11/10 01:33:07 djm Exp $ */ 1/* $OpenBSD: moduli.c,v 1.23 2011/10/16 11:02:46 dtucker Exp $ */
2/* 2/*
3 * Copyright 1994 Phil Karn <karn@qualcomm.com> 3 * Copyright 1994 Phil Karn <karn@qualcomm.com>
4 * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com> 4 * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com>
@@ -49,6 +49,7 @@
49#include <string.h> 49#include <string.h>
50#include <stdarg.h> 50#include <stdarg.h>
51#include <time.h> 51#include <time.h>
52#include <unistd.h>
52 53
53#include "xmalloc.h" 54#include "xmalloc.h"
54#include "dh.h" 55#include "dh.h"
@@ -137,7 +138,7 @@ static u_int32_t largebits, largememory; /* megabytes */
137static BIGNUM *largebase; 138static BIGNUM *largebase;
138 139
139int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); 140int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
140int prime_test(FILE *, FILE *, u_int32_t, u_int32_t); 141int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *);
141 142
142/* 143/*
143 * print moduli out in consistent form, 144 * print moduli out in consistent form,
@@ -438,6 +439,52 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start)
438 return (ret); 439 return (ret);
439} 440}
440 441
442static void
443write_checkpoint(char *cpfile, u_int32_t lineno)
444{
445 FILE *fp;
446 char tmpfile[MAXPATHLEN];
447 int r;
448
449 r = snprintf(tmpfile, sizeof(tmpfile), "%s.XXXXXXXXXX", cpfile);
450 if (r == -1 || r >= MAXPATHLEN) {
451 logit("write_checkpoint: temp pathname too long");
452 return;
453 }
454 if ((r = mkstemp(tmpfile)) == -1) {
455 logit("mkstemp(%s): %s", tmpfile, strerror(errno));
456 return;
457 }
458 if ((fp = fdopen(r, "w")) == NULL) {
459 logit("write_checkpoint: fdopen: %s", strerror(errno));
460 close(r);
461 return;
462 }
463 if (fprintf(fp, "%lu\n", (unsigned long)lineno) > 0 && fclose(fp) == 0
464 && rename(tmpfile, cpfile) == 0)
465 debug3("wrote checkpoint line %lu to '%s'",
466 (unsigned long)lineno, cpfile);
467 else
468 logit("failed to write to checkpoint file '%s': %s", cpfile,
469 strerror(errno));
470}
471
472static unsigned long
473read_checkpoint(char *cpfile)
474{
475 FILE *fp;
476 unsigned long lineno = 0;
477
478 if ((fp = fopen(cpfile, "r")) == NULL)
479 return 0;
480 if (fscanf(fp, "%lu\n", &lineno) < 1)
481 logit("Failed to load checkpoint from '%s'", cpfile);
482 else
483 logit("Loaded checkpoint from '%s' line %lu", cpfile, lineno);
484 fclose(fp);
485 return lineno;
486}
487
441/* 488/*
442 * perform a Miller-Rabin primality test 489 * perform a Miller-Rabin primality test
443 * on the list of candidates 490 * on the list of candidates
@@ -445,13 +492,15 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start)
445 * The result is a list of so-call "safe" primes 492 * The result is a list of so-call "safe" primes
446 */ 493 */
447int 494int
448prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) 495prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted,
496 char *checkpoint_file)
449{ 497{
450 BIGNUM *q, *p, *a; 498 BIGNUM *q, *p, *a;
451 BN_CTX *ctx; 499 BN_CTX *ctx;
452 char *cp, *lp; 500 char *cp, *lp;
453 u_int32_t count_in = 0, count_out = 0, count_possible = 0; 501 u_int32_t count_in = 0, count_out = 0, count_possible = 0;
454 u_int32_t generator_known, in_tests, in_tries, in_type, in_size; 502 u_int32_t generator_known, in_tests, in_tries, in_type, in_size;
503 unsigned long last_processed = 0;
455 time_t time_start, time_stop; 504 time_t time_start, time_stop;
456 int res; 505 int res;
457 506
@@ -472,10 +521,21 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
472 debug2("%.24s Final %u Miller-Rabin trials (%x generator)", 521 debug2("%.24s Final %u Miller-Rabin trials (%x generator)",
473 ctime(&time_start), trials, generator_wanted); 522 ctime(&time_start), trials, generator_wanted);
474 523
524 if (checkpoint_file != NULL)
525 last_processed = read_checkpoint(checkpoint_file);
526
475 res = 0; 527 res = 0;
476 lp = xmalloc(QLINESIZE + 1); 528 lp = xmalloc(QLINESIZE + 1);
477 while (fgets(lp, QLINESIZE + 1, in) != NULL) { 529 while (fgets(lp, QLINESIZE + 1, in) != NULL) {
478 count_in++; 530 count_in++;
531 if (checkpoint_file != NULL) {
532 if (count_in <= last_processed) {
533 debug3("skipping line %u, before checkpoint",
534 count_in);
535 continue;
536 }
537 write_checkpoint(checkpoint_file, count_in);
538 }
479 if (strlen(lp) < 14 || *lp == '!' || *lp == '#') { 539 if (strlen(lp) < 14 || *lp == '!' || *lp == '#') {
480 debug2("%10u: comment or short line", count_in); 540 debug2("%10u: comment or short line", count_in);
481 continue; 541 continue;
@@ -644,6 +704,9 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
644 BN_free(q); 704 BN_free(q);
645 BN_CTX_free(ctx); 705 BN_CTX_free(ctx);
646 706
707 if (checkpoint_file != NULL)
708 unlink(checkpoint_file);
709
647 logit("%.24s Found %u safe primes of %u candidates in %ld seconds", 710 logit("%.24s Found %u safe primes of %u candidates in %ld seconds",
648 ctime(&time_stop), count_out, count_possible, 711 ctime(&time_stop), count_out, count_possible,
649 (long) (time_stop - time_start)); 712 (long) (time_stop - time_start));