X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/aff51935734441207923b8e59fbc3644fc4e7d2c..HEAD:/moduli.c diff --git a/moduli.c b/moduli.c index ae71b250..f737cb3f 100644 --- a/moduli.c +++ b/moduli.c @@ -1,4 +1,4 @@ -/* $OpenBSD: moduli.c,v 1.2 2003/11/21 11:57:03 djm Exp $ */ +/* $OpenBSD: moduli.c,v 1.21 2008/06/26 09:19:40 djm Exp $ */ /* * Copyright 1994 Phil Karn * Copyright 1996-1998, 2003 William Allen Simpson @@ -38,90 +38,87 @@ */ #include "includes.h" -#include "moduli.h" -#include "xmalloc.h" -#include "log.h" -#include +#include +#include +#include -/* - * Debugging defines - */ +#include +#include +#include +#include +#include -/* define DEBUG_LARGE 1 */ -/* define DEBUG_SMALL 1 */ -/* define DEBUG_TEST 1 */ +#include "xmalloc.h" +#include "dh.h" +#include "log.h" /* * File output defines */ /* need line long enough for largest moduli plus headers */ -#define QLINESIZE (100+8192) +#define QLINESIZE (100+8192) -/* Type: decimal. - * Specifies the internal structure of the prime modulus. - */ -#define QTYPE_UNKNOWN (0) -#define QTYPE_UNSTRUCTURED (1) -#define QTYPE_SAFE (2) -#define QTYPE_SCHNOOR (3) -#define QTYPE_SOPHIE_GERMAINE (4) -#define QTYPE_STRONG (5) - -/* Tests: decimal (bit field). - * Specifies the methods used in checking for primality. - * Usually, more than one test is used. - */ -#define QTEST_UNTESTED (0x00) -#define QTEST_COMPOSITE (0x01) -#define QTEST_SIEVE (0x02) -#define QTEST_MILLER_RABIN (0x04) -#define QTEST_JACOBI (0x08) -#define QTEST_ELLIPTIC (0x10) - -/* Size: decimal. +/* + * Size: decimal. * Specifies the number of the most significant bit (0 to M). - ** WARNING: internally, usually 1 to N. + * WARNING: internally, usually 1 to N. */ -#define QSIZE_MINIMUM (511) +#define QSIZE_MINIMUM (511) /* * Prime sieving defines */ /* Constant: assuming 8 bit bytes and 32 bit words */ -#define SHIFT_BIT (3) -#define SHIFT_BYTE (2) -#define SHIFT_WORD (SHIFT_BIT+SHIFT_BYTE) -#define SHIFT_MEGABYTE (20) -#define SHIFT_MEGAWORD (SHIFT_MEGABYTE-SHIFT_BYTE) +#define SHIFT_BIT (3) +#define SHIFT_BYTE (2) +#define SHIFT_WORD (SHIFT_BIT+SHIFT_BYTE) +#define SHIFT_MEGABYTE (20) +#define SHIFT_MEGAWORD (SHIFT_MEGABYTE-SHIFT_BYTE) + +/* + * Using virtual memory can cause thrashing. This should be the largest + * number that is supported without a large amount of disk activity -- + * that would increase the run time from hours to days or weeks! + */ +#define LARGE_MINIMUM (8UL) /* megabytes */ + +/* + * Do not increase this number beyond the unsigned integer bit size. + * Due to a multiple of 4, it must be LESS than 128 (yielding 2**30 bits). + */ +#define LARGE_MAXIMUM (127UL) /* megabytes */ /* * Constant: when used with 32-bit integers, the largest sieve prime * has to be less than 2**32. */ -#define SMALL_MAXIMUM (0xffffffffUL) +#define SMALL_MAXIMUM (0xffffffffUL) /* Constant: can sieve all primes less than 2**32, as 65537**2 > 2**32-1. */ -#define TINY_NUMBER (1UL<<16) +#define TINY_NUMBER (1UL<<16) /* Ensure enough bit space for testing 2*q. */ -#define TEST_MAXIMUM (1UL<<16) -#define TEST_MINIMUM (QSIZE_MINIMUM + 1) -/* real TEST_MINIMUM (1UL << (SHIFT_WORD - TEST_POWER)) */ -#define TEST_POWER (3) /* 2**n, n < SHIFT_WORD */ +#define TEST_MAXIMUM (1UL<<16) +#define TEST_MINIMUM (QSIZE_MINIMUM + 1) +/* real TEST_MINIMUM (1UL << (SHIFT_WORD - TEST_POWER)) */ +#define TEST_POWER (3) /* 2**n, n < SHIFT_WORD */ /* bit operations on 32-bit words */ -#define BIT_CLEAR(a,n) ((a)[(n)>>SHIFT_WORD] &= ~(1L << ((n) & 31))) -#define BIT_SET(a,n) ((a)[(n)>>SHIFT_WORD] |= (1L << ((n) & 31))) -#define BIT_TEST(a,n) ((a)[(n)>>SHIFT_WORD] & (1L << ((n) & 31))) +#define BIT_CLEAR(a,n) ((a)[(n)>>SHIFT_WORD] &= ~(1L << ((n) & 31))) +#define BIT_SET(a,n) ((a)[(n)>>SHIFT_WORD] |= (1L << ((n) & 31))) +#define BIT_TEST(a,n) ((a)[(n)>>SHIFT_WORD] & (1L << ((n) & 31))) /* * Prime testing defines */ +/* Minimum number of primality tests to perform */ +#define TRIAL_MINIMUM (4) + /* * Sieving data (XXX - move to struct) */ @@ -137,6 +134,8 @@ static u_int32_t *LargeSieve, largewords, largetries, largenumbers; static u_int32_t largebits, largememory; /* megabytes */ static BIGNUM *largebase; +int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); +int prime_test(FILE *, FILE *, u_int32_t, u_int32_t); /* * print moduli out in consistent form, @@ -151,7 +150,7 @@ qfileout(FILE * ofile, u_int32_t otype, u_int32_t otests, u_int32_t otries, time(&time_now); gtm = gmtime(&time_now); - + res = fprintf(ofile, "%04d%02d%02d%02d%02d%02d %u %u %u %u %x ", gtm->tm_year + 1900, gtm->tm_mon + 1, gtm->tm_mday, gtm->tm_hour, gtm->tm_min, gtm->tm_sec, @@ -178,7 +177,7 @@ sieve_large(u_int32_t s) { u_int32_t r, u; - debug2("sieve_large %u", s); + debug3("sieve_large %u", s); largetries++; /* r = largebase mod s */ r = BN_mod_word(largebase, s); @@ -227,22 +226,30 @@ sieve_large(u_int32_t s) } /* - * list candidates for Sophie-Germaine primes (where q = (p-1)/2) + * list candidates for Sophie-Germain primes (where q = (p-1)/2) * to standard output. * The list is checked against small known primes (less than 2**30). */ int -gen_candidates(FILE *out, int memory, int power, BIGNUM *start) +gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start) { BIGNUM *q; u_int32_t j, r, s, t; u_int32_t smallwords = TINY_NUMBER >> 6; u_int32_t tinywords = TINY_NUMBER >> 6; time_t time_start, time_stop; - int i, ret = 0; + u_int32_t i; + int ret = 0; largememory = memory; + if (memory != 0 && + (memory < LARGE_MINIMUM || memory > LARGE_MAXIMUM)) { + error("Invalid memory amount (min %ld, max %ld)", + LARGE_MINIMUM, LARGE_MAXIMUM); + return (-1); + } + /* * Set power to the length in bits of the prime to be generated. * This is changed to 1 less than the desired safe prime moduli p. @@ -284,21 +291,10 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start) largewords = (largememory << SHIFT_MEGAWORD); } - TinySieve = calloc(tinywords, sizeof(u_int32_t)); - if (TinySieve == NULL) { - error("Insufficient memory for tiny sieve: need %u bytes", - tinywords << SHIFT_BYTE); - exit(1); - } + TinySieve = xcalloc(tinywords, sizeof(u_int32_t)); tinybits = tinywords << SHIFT_WORD; - SmallSieve = calloc(smallwords, sizeof(u_int32_t)); - if (SmallSieve == NULL) { - error("Insufficient memory for small sieve: need %u bytes", - smallwords << SHIFT_BYTE); - xfree(TinySieve); - exit(1); - } + SmallSieve = xcalloc(smallwords, sizeof(u_int32_t)); smallbits = smallwords << SHIFT_WORD; /* @@ -312,20 +308,26 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start) /* validation check: count the number of primes tried */ largetries = 0; - q = BN_new(); + if ((q = BN_new()) == NULL) + fatal("BN_new failed"); /* * Generate random starting point for subprime search, or use * specified parameter. */ - largebase = BN_new(); - if (start == NULL) - BN_rand(largebase, power, 1, 1); - else - BN_copy(largebase, start); + if ((largebase = BN_new()) == NULL) + fatal("BN_new failed"); + if (start == NULL) { + if (BN_rand(largebase, power, 1, 1) == 0) + fatal("BN_rand failed"); + } else { + if (BN_copy(largebase, start) == NULL) + fatal("BN_copy: failed"); + } /* ensure odd */ - BN_set_bit(largebase, 0); + if (BN_set_bit(largebase, 0) == 0) + fatal("BN_set_bit: failed"); time(&time_start); @@ -355,8 +357,8 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start) * fencepost errors, the last pass is skipped. */ for (smallbase = TINY_NUMBER + 3; - smallbase < (SMALL_MAXIMUM - TINY_NUMBER); - smallbase += TINY_NUMBER) { + smallbase < (SMALL_MAXIMUM - TINY_NUMBER); + smallbase += TINY_NUMBER) { for (i = 0; i < tinybits; i++) { if (BIT_TEST(TinySieve, i)) continue; /* 2*i+3 is composite */ @@ -409,10 +411,13 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start) continue; /* Definitely composite, skip */ debug2("test q = largebase+%u", 2 * j); - BN_set_word(q, 2 * j); - BN_add(q, q, largebase); - if (qfileout(out, QTYPE_SOPHIE_GERMAINE, QTEST_SIEVE, - largetries, (power - 1) /* MSB */, (0), q) == -1) { + if (BN_set_word(q, 2 * j) == 0) + fatal("BN_set_word failed"); + if (BN_add(q, q, largebase) == 0) + fatal("BN_add failed"); + if (qfileout(out, MODULI_TYPE_SOPHIE_GERMAIN, + MODULI_TESTS_SIEVE, largetries, + (power - 1) /* MSB */, (0), q) == -1) { ret = -1; break; } @@ -438,8 +443,7 @@ gen_candidates(FILE *out, int memory, int power, BIGNUM *start) * The result is a list of so-call "safe" primes */ int -prime_test(FILE *in, FILE *out, u_int32_t trials, - u_int32_t generator_wanted) +prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) { BIGNUM *q, *p, *a; BN_CTX *ctx; @@ -449,22 +453,28 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, time_t time_start, time_stop; int res; + if (trials < TRIAL_MINIMUM) { + error("Minimum primality trials is %d", TRIAL_MINIMUM); + return (-1); + } + time(&time_start); - p = BN_new(); - q = BN_new(); - ctx = BN_CTX_new(); + if ((p = BN_new()) == NULL) + fatal("BN_new failed"); + if ((q = BN_new()) == NULL) + fatal("BN_new failed"); + if ((ctx = BN_CTX_new()) == NULL) + fatal("BN_CTX_new failed"); debug2("%.24s Final %u Miller-Rabin trials (%x generator)", ctime(&time_start), trials, generator_wanted); res = 0; lp = xmalloc(QLINESIZE + 1); - while (fgets(lp, QLINESIZE, in) != NULL) { - int ll = strlen(lp); - + while (fgets(lp, QLINESIZE + 1, in) != NULL) { count_in++; - if (ll < 14 || *lp == '!' || *lp == '#') { + if (strlen(lp) < 14 || *lp == '!' || *lp == '#') { debug2("%10u: comment or short line", count_in); continue; } @@ -479,10 +489,11 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, /* tests */ in_tests = strtoul(cp, &cp, 10); - if (in_tests & QTEST_COMPOSITE) { + if (in_tests & MODULI_TESTS_COMPOSITE) { debug2("%10u: known composite", count_in); continue; } + /* tries */ in_tries = strtoul(cp, &cp, 10); @@ -497,22 +508,34 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, /* modulus (hex) */ switch (in_type) { - case QTYPE_SOPHIE_GERMAINE: - debug2("%10u: (%u) Sophie-Germaine", count_in, in_type); + case MODULI_TYPE_SOPHIE_GERMAIN: + debug2("%10u: (%u) Sophie-Germain", count_in, in_type); a = q; - BN_hex2bn(&a, cp); + if (BN_hex2bn(&a, cp) == 0) + fatal("BN_hex2bn failed"); /* p = 2*q + 1 */ - BN_lshift(p, q, 1); - BN_add_word(p, 1); + if (BN_lshift(p, q, 1) == 0) + fatal("BN_lshift failed"); + if (BN_add_word(p, 1) == 0) + fatal("BN_add_word failed"); in_size += 1; generator_known = 0; break; - default: + case MODULI_TYPE_UNSTRUCTURED: + case MODULI_TYPE_SAFE: + case MODULI_TYPE_SCHNORR: + case MODULI_TYPE_STRONG: + case MODULI_TYPE_UNKNOWN: debug2("%10u: (%u)", count_in, in_type); a = p; - BN_hex2bn(&a, cp); + if (BN_hex2bn(&a, cp) == 0) + fatal("BN_hex2bn failed"); /* q = (p-1) / 2 */ - BN_rshift(q, p, 1); + if (BN_rshift(q, p, 1) == 0) + fatal("BN_rshift failed"); + break; + default: + debug2("Unknown prime type"); break; } @@ -520,7 +543,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, * due to earlier inconsistencies in interpretation, check * the proposed bit size. */ - if (BN_num_bits(p) != (in_size + 1)) { + if ((u_int32_t)BN_num_bits(p) != (in_size + 1)) { debug2("%10u: bit size %u mismatch", count_in, in_size); continue; } @@ -529,10 +552,11 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, continue; } - if (in_tests & QTEST_MILLER_RABIN) + if (in_tests & MODULI_TESTS_MILLER_RABIN) in_tries += trials; else in_tries = trials; + /* * guess unknown generator */ @@ -544,9 +568,8 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, else { u_int32_t r = BN_mod_word(p, 10); - if (r == 3 || r == 7) { + if (r == 3 || r == 7) generator_known = 5; - } } } /* @@ -559,6 +582,15 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, continue; } + /* + * Primes with no known generator are useless for DH, so + * skip those. + */ + if (generator_known == 0) { + debug2("%10u: no known generator", count_in); + continue; + } + count_possible++; /* @@ -569,11 +601,11 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, * vast majority of composite q's. */ if (BN_is_prime(q, 1, NULL, ctx, NULL) <= 0) { - debug2("%10u: q failed first possible prime test", + debug("%10u: q failed first possible prime test", count_in); continue; } - + /* * q is possibly prime, so go ahead and really make sure * that p is prime. If it is, then we can go back and do @@ -582,7 +614,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, * doesn't hurt to specify a high iteration count. */ if (!BN_is_prime(p, trials, NULL, ctx, NULL)) { - debug2("%10u: p is not prime", count_in); + debug("%10u: p is not prime", count_in); continue; } debug("%10u: p is almost certainly prime", count_in); @@ -594,7 +626,8 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, } debug("%10u: q is almost certainly prime", count_in); - if (qfileout(out, QTYPE_SAFE, (in_tests | QTEST_MILLER_RABIN), + if (qfileout(out, MODULI_TYPE_SAFE, + in_tests | MODULI_TESTS_MILLER_RABIN, in_tries, in_size, generator_known, p)) { res = -1; break;