Make DSA_generate_parameters, and fix a couple of bug

(including another problem in the s3_srvr.c state machine).
This commit is contained in:
Bodo Möller 2000-01-30 02:23:03 +00:00
parent 15701211b5
commit a87030a1ed
15 changed files with 186 additions and 139 deletions

43
CHANGES
View file

@ -4,6 +4,35 @@
Changes between 0.9.4 and 0.9.5 [xx XXX 2000] Changes between 0.9.4 and 0.9.5 [xx XXX 2000]
*) Bugfix: ssl3_send_server_key_exchange was not restartable
(the state was not changed to SSL3_ST_SW_KEY_EXCH_B, and because of
this the server could overwrite ephemeral keys that the client
has already seen).
[Bodo Moeller]
*) Turn DSA_is_prime into a macro that calls BN_is_prime,
using 50 iterations of the Rabin-Miller test.
DSA_generate_parameters now uses BN_is_prime_fasttest (with 50
iterations of the Rabin-Miller test as required by the appendix
to FIPS PUB 186[-1]) instead of DSA_is_prime.
As BN_is_prime_fasttest includes trial division, DSA parameter
generation becomes much faster.
This implies a change for the callback functions in DSA_is_prime
and DSA_generate_parameters: They are now called once for each
positive witness in the Rabin-Miller test, not just occasionally
in the inner loop; and the parameters to the callback function now
provide an iteration count for the outer loop rather than for the
current invocation of the inner loop.
[Bodo Moeller]
*) New functions BN_is_prime_fasttest that optionally does trial
division before starting the Rabin-Miller test and has
an additional BN_CTX * argument (whereas BN_is_prime always
has to allocate at least one BN_CTX).
[Bodo Moeller]
*) Fix for bug in CRL encoding. The validity dates weren't being handled *) Fix for bug in CRL encoding. The validity dates weren't being handled
as ASN1_TIME. as ASN1_TIME.
[Steve Henson] [Steve Henson]
@ -11,10 +40,6 @@
*) New -pkcs12 option to CA.pl script to write out a PKCS#12 file. *) New -pkcs12 option to CA.pl script to write out a PKCS#12 file.
[Steve Henson] [Steve Henson]
*) Use BN_prime_checks_size(BN_num_bits(w)) rounds of Miller-Rabin when
generating DSA primes.
[Ulf Möller]
*) New function BN_pseudo_rand(). *) New function BN_pseudo_rand().
[Ulf Möller] [Ulf Möller]
@ -41,7 +66,10 @@
*) Make BN_generate_prime() return NULL on error if ret!=NULL. *) Make BN_generate_prime() return NULL on error if ret!=NULL.
[Ulf Möller] [Ulf Möller]
*) Retain source code compatibility for BN_prime_checks macro. *) Retain source code compatibility for BN_prime_checks macro:
BN_is_prime(..., BN_prime_checks, ...) now uses
BN_prime_checks_for_size to determine the appropriate number of
Rabin-Miller iterations.
[Ulf Möller] [Ulf Möller]
*) Diffie-Hellman uses "safe" primes: DH_check() return code renamed to *) Diffie-Hellman uses "safe" primes: DH_check() return code renamed to
@ -114,10 +142,9 @@
*) Do more iterations of Rabin-Miller probable prime test (specifically, *) Do more iterations of Rabin-Miller probable prime test (specifically,
3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes 3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes
instead of only 2 for all lengths; see BN_prime_checks_size definition instead of only 2 for all lengths; see BN_prime_checks_for_size definition
in crypto/bn/bn_prime.c for the complete table). This guarantees a in crypto/bn/bn_prime.c for the complete table). This guarantees a
false-positive rate of at most 2^-80 (actually less because we are false-positive rate of at most 2^-80 for random input.
additionally doing trial division) for random input.
[Bodo Moeller] [Bodo Moeller]
*) Rewrite ssl3_read_n (ssl/s3_pkt.c) avoiding a couple of bugs. *) Rewrite ssl3_read_n (ssl/s3_pkt.c) avoiding a couple of bugs.

17
TABLE
View file

@ -663,6 +663,23 @@ $rc4_obj = asm/rx86-elf.o
$rmd160_obj = asm/rm86-elf.o $rmd160_obj = asm/rm86-elf.o
$rc5_obj = asm/r586-elf.o $rc5_obj = asm/r586-elf.o
*** debug-levitte-linux-elf
$cc = gcc
$cflags = -DRL_DEBUG -DREF_CHECK -DCRYPTO_MDEBUG -DNO_ASM -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -ggdb -g3 -m486 -pedantic -ansi -Wall -Wshadow -Wid-clash-31 -pipe
$unistd =
$thread_cflag = -D_REENTRANT
$lflags =
$bn_ops =
$bn_obj =
$des_obj =
$bf_obj =
$md5_obj =
$sha1_obj =
$cast_obj =
$rc4_obj =
$rmd160_obj =
$rc5_obj =
*** debug-linux-elf *** debug-linux-elf
$cc = gcc $cc = gcc
$cflags = -DREF_CHECK -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -m486 -Wall $cflags = -DREF_CHECK -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -m486 -Wall

View file

@ -292,7 +292,7 @@ typedef struct bn_recp_ctx_st
* of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996]; * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
* original paper: Damgaard, Landrock, Pomerance: Average case error estimates * original paper: Damgaard, Landrock, Pomerance: Average case error estimates
* for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */ * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */
#define BN_prime_checks_size(b) ((b) >= 1300 ? 2 : \ #define BN_prime_checks_for_size(b) ((b) >= 1300 ? 2 : \
(b) >= 850 ? 3 : \ (b) >= 850 ? 3 : \
(b) >= 650 ? 4 : \ (b) >= 650 ? 4 : \
(b) >= 550 ? 5 : \ (b) >= 550 ? 5 : \
@ -406,6 +406,10 @@ BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,BIGNUM *add,
BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg); BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg);
int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int,void *), int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int,void *),
BN_CTX *ctx,void *cb_arg); BN_CTX *ctx,void *cb_arg);
int BN_is_prime_fasttest(BIGNUM *p,int nchecks,
void (*callback)(int,int,void *),
BN_CTX *ctx,BN_CTX *ctx2,void *cb_arg,
int do_trial_division);
void ERR_load_BN_strings(void ); void ERR_load_BN_strings(void );
BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w); BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);

View file

@ -84,7 +84,7 @@ BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, BIGNUM *add,
int found=0; int found=0;
int i,j,c1=0; int i,j,c1=0;
BN_CTX *ctx; BN_CTX *ctx;
int checks = BN_prime_checks_size(bits); int checks = BN_prime_checks_for_size(bits);
ctx=BN_CTX_new(); ctx=BN_CTX_new();
if (ctx == NULL) goto err; if (ctx == NULL) goto err;
@ -154,10 +154,12 @@ err:
return(found ? rnd : NULL); return(found ? rnd : NULL);
} }
int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *), int BN_is_prime_fasttest(BIGNUM *a, int checks,
BN_CTX *ctx_passed, void *cb_arg) void (*callback)(int,int,void *),
BN_CTX *ctx_passed, BN_CTX *ctx2_passed, void *cb_arg,
int do_trial_division)
{ {
int i,j,c2=0,ret= -1; int i,j,ret= -1;
BIGNUM *check; BIGNUM *check;
BN_CTX *ctx=NULL,*ctx2=NULL; BN_CTX *ctx=NULL,*ctx2=NULL;
BN_MONT_CTX *mont=NULL; BN_MONT_CTX *mont=NULL;
@ -165,17 +167,25 @@ int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *),
if (checks == BN_prime_checks) if (checks == BN_prime_checks)
{ {
int bits = BN_num_bits(a); int bits = BN_num_bits(a);
checks = BN_prime_checks_size(bits); checks = BN_prime_checks_for_size(bits);
} }
if (!BN_is_odd(a)) if (!BN_is_odd(a))
return(0); return(0);
if (do_trial_division)
for (i = 1; i < NUMPRIMES; i++)
if (BN_mod_word(a, primes[i]) == 0)
return 0;
if (ctx_passed != NULL) if (ctx_passed != NULL)
ctx=ctx_passed; ctx=ctx_passed;
else else
if ((ctx=BN_CTX_new()) == NULL) goto err; if ((ctx=BN_CTX_new()) == NULL) goto err;
if (ctx2_passed != NULL)
ctx2=ctx2_passed;
else
if ((ctx2=BN_CTX_new()) == NULL) goto err;
if ((ctx2=BN_CTX_new()) == NULL) goto err;
if ((mont=BN_MONT_CTX_new()) == NULL) goto err; if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
check= &(ctx->bn[ctx->tos++]); check= &(ctx->bn[ctx->tos++]);
@ -185,7 +195,9 @@ int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *),
for (i=0; i<checks; i++) for (i=0; i<checks; i++)
{ {
if (!BN_pseudo_rand(check,BN_num_bits(a)-1,0,0)) goto err; if (!BN_pseudo_rand(check,BN_num_bits(a),0,0)) goto err;
if (BN_cmp(check, a) >= 0)
BN_sub(check, check, a);
j=witness(check,a,ctx,ctx2,mont); j=witness(check,a,ctx,ctx2,mont);
if (j == -1) goto err; if (j == -1) goto err;
if (j) if (j)
@ -193,20 +205,26 @@ int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *),
ret=0; ret=0;
goto err; goto err;
} }
if (callback != NULL) callback(1,c2++,cb_arg); if (callback != NULL) callback(1,i,cb_arg);
} }
ret=1; ret=1;
err: err:
ctx->tos--; ctx->tos--;
if ((ctx_passed == NULL) && (ctx != NULL)) if ((ctx_passed == NULL) && (ctx != NULL))
BN_CTX_free(ctx); BN_CTX_free(ctx);
if (ctx2 != NULL) if ((ctx2_passed == NULL) && (ctx2 != NULL))
BN_CTX_free(ctx2); BN_CTX_free(ctx2);
if (mont != NULL) BN_MONT_CTX_free(mont); if (mont != NULL) BN_MONT_CTX_free(mont);
return(ret); return(ret);
} }
int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *),
BN_CTX *ctx_passed, void *cb_arg)
{
return BN_is_prime_fasttest(a, checks, callback, ctx_passed, NULL, cb_arg, 0);
}
static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx, BN_CTX *ctx2, static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx, BN_CTX *ctx2,
BN_MONT_CTX *mont) BN_MONT_CTX *mont)
{ {
@ -274,7 +292,7 @@ err:
static int probable_prime(BIGNUM *rnd, int bits) static int probable_prime(BIGNUM *rnd, int bits)
{ {
int i; int i;
MS_STATIC BN_ULONG mods[NUMPRIMES]; BN_ULONG mods[NUMPRIMES];
BN_ULONG delta,d; BN_ULONG delta,d;
again: again:

View file

@ -197,7 +197,11 @@ int DSAparams_print_fp(FILE *fp, DSA *x);
int DSA_print_fp(FILE *bp, DSA *x, int off); int DSA_print_fp(FILE *bp, DSA *x, int off);
#endif #endif
int DSA_is_prime(BIGNUM *q,void (*callback)(),void *cb_arg); #define DSS_prime_checks 50
/* Primality test according to FIPS PUB 186[-1], Appendix 2.1:
* 50 rounds of Rabin-Miller */
#define DSA_is_prime(n, callback, cb_arg) \
BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg)
#ifndef NO_DH #ifndef NO_DH
/* Convert DSA structure (key or just parameters) into DH structure /* Convert DSA structure (key or just parameters) into DH structure
@ -218,7 +222,6 @@ DH *DSA_dup_DH(DSA *r);
#define DSA_F_DSAPARAMS_PRINT_FP 101 #define DSA_F_DSAPARAMS_PRINT_FP 101
#define DSA_F_DSA_DO_SIGN 112 #define DSA_F_DSA_DO_SIGN 112
#define DSA_F_DSA_DO_VERIFY 113 #define DSA_F_DSA_DO_VERIFY 113
#define DSA_F_DSA_IS_PRIME 102
#define DSA_F_DSA_NEW 103 #define DSA_F_DSA_NEW 103
#define DSA_F_DSA_PRINT 104 #define DSA_F_DSA_PRINT 104
#define DSA_F_DSA_PRINT_FP 105 #define DSA_F_DSA_PRINT_FP 105

View file

@ -70,7 +70,6 @@ static ERR_STRING_DATA DSA_str_functs[]=
{ERR_PACK(0,DSA_F_DSAPARAMS_PRINT_FP,0), "DSAparams_print_fp"}, {ERR_PACK(0,DSA_F_DSAPARAMS_PRINT_FP,0), "DSAparams_print_fp"},
{ERR_PACK(0,DSA_F_DSA_DO_SIGN,0), "DSA_do_sign"}, {ERR_PACK(0,DSA_F_DSA_DO_SIGN,0), "DSA_do_sign"},
{ERR_PACK(0,DSA_F_DSA_DO_VERIFY,0), "DSA_do_verify"}, {ERR_PACK(0,DSA_F_DSA_DO_VERIFY,0), "DSA_do_verify"},
{ERR_PACK(0,DSA_F_DSA_IS_PRIME,0), "DSA_is_prime"},
{ERR_PACK(0,DSA_F_DSA_NEW,0), "DSA_new"}, {ERR_PACK(0,DSA_F_DSA_NEW,0), "DSA_new"},
{ERR_PACK(0,DSA_F_DSA_PRINT,0), "DSA_print"}, {ERR_PACK(0,DSA_F_DSA_PRINT,0), "DSA_print"},
{ERR_PACK(0,DSA_F_DSA_PRINT_FP,0), "DSA_print_fp"}, {ERR_PACK(0,DSA_F_DSA_PRINT_FP,0), "DSA_print_fp"},

View file

@ -59,12 +59,18 @@
#undef GENUINE_DSA #undef GENUINE_DSA
#ifdef GENUINE_DSA #ifdef GENUINE_DSA
/* Parameter generation follows the original release of FIPS PUB 186,
* Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */
#define HASH SHA #define HASH SHA
#else #else
/* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
* also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in
* FIPS PUB 180-1) */
#define HASH SHA1 #define HASH SHA1
#endif #endif
#ifndef NO_SHA #ifndef NO_SHA
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
#include "cryptlib.h" #include "cryptlib.h"
@ -74,8 +80,8 @@
#include <openssl/rand.h> #include <openssl/rand.h>
DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len,
int *counter_ret, unsigned long *h_ret, void (*callback)(), int *counter_ret, unsigned long *h_ret, void (*callback)(),
void *cb_arg) void *cb_arg)
{ {
int ok=0; int ok=0;
unsigned char seed[SHA_DIGEST_LENGTH]; unsigned char seed[SHA_DIGEST_LENGTH];
@ -86,19 +92,26 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len,
BN_MONT_CTX *mont=NULL; BN_MONT_CTX *mont=NULL;
int k,n=0,i,b,m=0; int k,n=0,i,b,m=0;
int counter=0; int counter=0;
BN_CTX *ctx=NULL,*ctx2=NULL; int r=0;
BN_CTX *ctx=NULL,*ctx2=NULL,*ctx3=NULL,*ctx4=NULL;
unsigned int h=2; unsigned int h=2;
DSA *ret=NULL; DSA *ret=NULL;
if (bits < 512) bits=512; if (bits < 512) bits=512;
bits=(bits+63)/64*64; bits=(bits+63)/64*64;
if (seed_len < 20) seed_in = NULL; if (seed_len < 20)
seed_in = NULL; /* seed buffer too small -- ignore */
if (seed_len > 20)
seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
* but our internal buffers are restricted to 160 bits*/
if ((seed_in != NULL) && (seed_len == 20)) if ((seed_in != NULL) && (seed_len == 20))
memcpy(seed,seed_in,seed_len); memcpy(seed,seed_in,seed_len);
if ((ctx=BN_CTX_new()) == NULL) goto err; if ((ctx=BN_CTX_new()) == NULL) goto err;
if ((ctx2=BN_CTX_new()) == NULL) goto err; if ((ctx2=BN_CTX_new()) == NULL) goto err;
if ((ctx3=BN_CTX_new()) == NULL) goto err;
if ((ctx4=BN_CTX_new()) == NULL) goto err;
if ((ret=DSA_new()) == NULL) goto err; if ((ret=DSA_new()) == NULL) goto err;
if ((mont=BN_MONT_CTX_new()) == NULL) goto err; if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
@ -116,18 +129,24 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len,
for (;;) for (;;)
{ {
for (;;) for (;;) /* find q */
{ {
int seed_is_random = 0;
/* step 1 */ /* step 1 */
if (callback != NULL) callback(0,m++,cb_arg); if (callback != NULL) callback(0,m++,cb_arg);
if (!seed_len) if (!seed_len)
{
RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH); RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH);
seed_is_random = 1;
}
else else
/* use random seed if 'seed_in' turns out to be bad */
seed_len=0; seed_len=0;
memcpy(buf,seed,SHA_DIGEST_LENGTH); memcpy(buf,seed,SHA_DIGEST_LENGTH);
memcpy(buf2,seed,SHA_DIGEST_LENGTH); memcpy(buf2,seed,SHA_DIGEST_LENGTH);
/* precompute "SEED + 1" for step 7: */
for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
{ {
buf[i]++; buf[i]++;
@ -146,7 +165,12 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len,
if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) goto err; if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) goto err;
/* step 4 */ /* step 4 */
if (BN_is_prime(q,BN_prime_checks,callback,NULL,cb_arg) > 0) break; r = BN_is_prime_fasttest(q, DSS_prime_checks, callback, ctx3, ctx4, cb_arg, seed_is_random);
if (r > 0)
break;
if (r != 0)
goto err;
/* do a callback call */ /* do a callback call */
/* step 5 */ /* step 5 */
} }
@ -156,16 +180,22 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len,
/* step 6 */ /* step 6 */
counter=0; counter=0;
/* "offset = 2" */
n=(bits-1)/160; n=(bits-1)/160;
b=(bits-1)-n*160; b=(bits-1)-n*160;
for (;;) for (;;)
{ {
if (callback != NULL && counter != 0)
callback(0,counter,cb_arg);
/* step 7 */ /* step 7 */
BN_zero(W); BN_zero(W);
/* now 'buf' contains "SEED + offset - 1" */
for (k=0; k<=n; k++) for (k=0; k<=n; k++)
{ {
/* obtain "SEED + offset + k" by incrementing: */
for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
{ {
buf[i]++; buf[i]++;
@ -196,17 +226,19 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len,
if (BN_cmp(p,test) >= 0) if (BN_cmp(p,test) >= 0)
{ {
/* step 11 */ /* step 11 */
if (BN_is_prime(p,BN_prime_checks,callback,NULL,cb_arg) > 0) r = BN_is_prime_fasttest(p, DSS_prime_checks, callback, ctx3, ctx4, cb_arg, 1);
goto end; if (r > 0)
goto end; /* found it */
if (r != 0)
goto err;
} }
/* step 13 */ /* step 13 */
counter++; counter++;
/* "offset = offset + n + 1" */
/* step 14 */ /* step 14 */
if (counter >= 4096) break; if (counter >= 4096) break;
if (callback != NULL) callback(0,counter,cb_arg);
} }
} }
end: end:
@ -247,90 +279,10 @@ err:
if (h_ret != NULL) *h_ret=h; if (h_ret != NULL) *h_ret=h;
} }
if (ctx != NULL) BN_CTX_free(ctx); if (ctx != NULL) BN_CTX_free(ctx);
if (ctx != NULL) BN_CTX_free(ctx2); if (ctx2 != NULL) BN_CTX_free(ctx2);
if (ctx3 != NULL) BN_CTX_free(ctx3);
if (ctx4 != NULL) BN_CTX_free(ctx4);
if (mont != NULL) BN_MONT_CTX_free(mont); if (mont != NULL) BN_MONT_CTX_free(mont);
return(ok?ret:NULL); return(ok?ret:NULL);
} }
int DSA_is_prime(BIGNUM *w, void (*callback)(), void *cb_arg)
{
int ok= -1,j,i,n;
BN_CTX *ctx=NULL,*ctx2=NULL;
BIGNUM *w_1,*b,*m,*z,*tmp,*mont_1;
int a;
BN_MONT_CTX *mont=NULL;
if (!BN_is_odd(w)) return(0);
if ((ctx=BN_CTX_new()) == NULL) goto err;
if ((ctx2=BN_CTX_new()) == NULL) goto err;
if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
m= &(ctx2->bn[2]);
b= &(ctx2->bn[3]);
z= &(ctx2->bn[4]);
w_1= &(ctx2->bn[5]);
tmp= &(ctx2->bn[6]);
mont_1= &(ctx2->bn[7]);
/* step 1 */
n=BN_prime_checks_size(BN_num_bits(w));
/* step 2 */
if (!BN_sub(w_1,w,BN_value_one())) goto err;
for (a=1; !BN_is_bit_set(w_1,a); a++)
;
if (!BN_rshift(m,w_1,a)) goto err;
BN_MONT_CTX_set(mont,w,ctx);
BN_to_montgomery(mont_1,BN_value_one(),mont,ctx);
BN_to_montgomery(w_1,w_1,mont,ctx);
for (i=1; i < n; i++)
{
/* step 3 */
if (!BN_pseudo_rand(b,BN_num_bits(w)-2/*-1*/,0,0))
goto err;
/* BN_set_word(b,0x10001L); */
/* step 4 */
j=0;
if (!BN_mod_exp_mont(z,b,m,w,ctx,mont)) goto err;
if (!BN_to_montgomery(z,z,mont,ctx)) goto err;
/* step 5 */
for (;;)
{
if (((j == 0) && (BN_cmp(z,mont_1) == 0)) ||
(BN_cmp(z,w_1) == 0))
break;
/* step 6 */
if ((j > 0) && (BN_cmp(z,mont_1) == 0))
{
ok=0;
goto err;
}
j++;
if (j >= a)
{
ok=0;
goto err;
}
if (!BN_mod_mul_montgomery(z,z,z,mont,ctx)) goto err;
if (callback != NULL) callback(1,j,cb_arg);
}
}
ok=1;
err:
if (ok == -1) DSAerr(DSA_F_DSA_IS_PRIME,ERR_R_BN_LIB);
BN_CTX_free(ctx);
BN_CTX_free(ctx2);
BN_MONT_CTX_free(mont);
return(ok);
}
#endif #endif

View file

@ -85,6 +85,9 @@ int main(int argc, char *argv[])
#endif #endif
static void MS_CALLBACK dsa_cb(int p, int n, char *arg); static void MS_CALLBACK dsa_cb(int p, int n, char *arg);
/* seed, out_p, out_q, out_g are taken from the updated Appendix 5 to
* FIPS PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1 */
static unsigned char seed[20]={ static unsigned char seed[20]={
0xd5,0x01,0x4e,0x4b,0x60,0xef,0x2b,0xa8,0xb6,0x21,0x1b,0x40, 0xd5,0x01,0x4e,0x4b,0x60,0xef,0x2b,0xa8,0xb6,0x21,0x1b,0x40,
0x62,0xba,0x32,0x24,0xe0,0x42,0x7d,0xd3, 0x62,0xba,0x32,0x24,0xe0,0x42,0x7d,0xd3,
@ -141,9 +144,8 @@ int main(int argc, char **argv)
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
BIO_printf(bio_err,"test generation of DSA parameters\n"); BIO_printf(bio_err,"test generation of DSA parameters\n");
BIO_printf(bio_err,"expect '.*' followed by 3 lines of '.'s and '+'s\n");
dsa=DSA_generate_parameters(512,seed,20,&counter,&h,dsa_cb, dsa=DSA_generate_parameters(512,seed,20,&counter,&h,dsa_cb,(char *)bio_err);
(char *)bio_err);
BIO_printf(bio_err,"seed\n"); BIO_printf(bio_err,"seed\n");
for (i=0; i<20; i+=4) for (i=0; i<20; i+=4)

View file

@ -63,7 +63,7 @@
extern "C" { extern "C" {
#endif #endif
#if defined(NO_SHA) || defined(NO_SHA0) || defined(NO_SHA1) #if defined(NO_SHA) || (defined(NO_SHA0) && defined(NO_SHA1))
#error SHA is disabled. #error SHA is disabled.
#endif #endif

View file

@ -20,14 +20,14 @@ for use in the DSA.
B<bits> is the length of the prime to be generated; the DSS allows a B<bits> is the length of the prime to be generated; the DSS allows a
maximum of 1024 bits. maximum of 1024 bits.
If B<seed> is NULL or B<seed_len> E<lt> 20, the primes will be If B<seed> is B<NULL> or B<seed_len> E<lt> 20, the primes will be
generated at random. Otherwise, the seed is used to generate generated at random. Otherwise, the seed is used to generate
them. If the given seed does not yield a prime q, a new random them. If the given seed does not yield a prime q, a new random
seed is chosen and placed at B<seed>. seed is chosen and placed at B<seed>.
DSA_generate_parameters() places the iteration count in DSA_generate_parameters() places the iteration count in
*B<counter_ret> and a counter used for finding a generator in *B<counter_ret> and a counter used for finding a generator in
*B<h_ret>, unless these are NULL. *B<h_ret>, unless these are B<NULL>.
A callback function may be used to provide feedback about the progress A callback function may be used to provide feedback about the progress
of the key generation. If B<callback> is not B<NULL>, it will be of the key generation. If B<callback> is not B<NULL>, it will be
@ -37,13 +37,15 @@ called as follows:
=item * =item *
When the the m-th candidate for q is generated, B<callback(0, m, When a candidate for q is generated, B<callback(0, m++, cb_arg)> is called
cb_arg)> is called. (m is 0 for the first candidate).
=item * =item *
B<callback(1, j++, cb_arg)> is called in the inner loop of the While a candidate for q is tested, B<callback(1, i, cb_arg)>
Miller-Rabin primality test. is called in the outer loop of the Miller-Rabin primality tests
(once for each witness that confirms that the candidate may be prime).
i is the loop counter (starting at 0).
=item * =item *
@ -52,10 +54,15 @@ B<callback(3, 0, cb_arg)> are called.
=item * =item *
While candidates for p are being tested, B<callback(1, j++, cb_arg)> Before a candidate for p (other than the first) is generated and tested,
is called in the inner loop of the Miller-Rabin primality test, then B<callback(0, counter, cb_arg)> is called.
B<callback(0, counter, cb_arg)> is called when the next candidate
is chosen. =item *
While a candidate for p is tested, B<callback(1, j++, cb_arg)>
is called in the outer loop of the Miller-Rabin primality test
(once for each witness that confirms that the candidate may be prime).
i is the loop counter (starting at 0).
=item * =item *
@ -70,15 +77,11 @@ When the generator has been found, B<callback(3, 1, cb_arg)> is called.
=head1 RETURN VALUE =head1 RETURN VALUE
DSA_generate_parameters() returns a pointer to the DSA structure, or DSA_generate_parameters() returns a pointer to the DSA structure, or
NULL if the parameter generation fails. The error codes can be B<NULL> if the parameter generation fails. The error codes can be
obtained by L<ERR_get_error(3)|ERR_get_error(3)>. obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
=head1 BUGS =head1 BUGS
The deterministic generation of p does not follow the NIST algorithm:
r0 is SHA1(s+k+1), but should be SHA1(s+j+k) with j_0=2,
j_counter=j_counter-1 + n + 1.
Seed lengths E<gt> 20 are not supported. Seed lengths E<gt> 20 are not supported.
=head1 SEE ALSO =head1 SEE ALSO
@ -90,5 +93,9 @@ L<DSA_free(3)|DSA_free(3)>
DSA_generate_parameters() appeared in SSLeay 0.8. The B<cb_arg> DSA_generate_parameters() appeared in SSLeay 0.8. The B<cb_arg>
argument was added in SSLeay 0.9.0. argument was added in SSLeay 0.9.0.
In versions up to OpenSSL 0.9.4, B<callback(1, ...)> was called
in the inner loop of the Miller-Rabin test whenever it reached the
squaring step (the parameters to B<callback> did not reveal how many
witnesses had been tested); since OpenSSL 0.9.5, B<callback(1, ...)>
is called as in BN_is_prime(3), i.e. once for each witness.
=cut =cut

View file

@ -135,6 +135,10 @@ echo test sslv2 via BIO pair
ssltest -bio_pair -ssl2 ssltest -bio_pair -ssl2
if errorlevel 1 goto done if errorlevel 1 goto done
echo test sslv2/sslv3 with 1024 bit DHE via BIO pair
ssltest -bio_pair -dhe1024 -v
if errorlevel 1 goto done
echo test sslv2 with server authentication via BIO pair echo test sslv2 with server authentication via BIO pair
ssltest -bio_pair -ssl2 -server_auth -CAfile cert.tmp ssltest -bio_pair -ssl2 -server_auth -CAfile cert.tmp
if errorlevel 1 goto done if errorlevel 1 goto done

View file

@ -963,6 +963,14 @@ static int ssl3_send_server_key_exchange(SSL *s)
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY); SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
goto f_err; goto f_err;
} }
if (s->s3->tmp.dh != NULL)
{
DH_free(dh);
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, SSL_R_INTERNAL_ERROR);
goto err;
}
if ((dh=DHparams_dup(dhp)) == NULL) if ((dh=DHparams_dup(dhp)) == NULL)
{ {
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB); SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
@ -1109,7 +1117,7 @@ static int ssl3_send_server_key_exchange(SSL *s)
s->init_off=0; s->init_off=0;
} }
/* SSL3_ST_SW_KEY_EXCH_B */ s->state = SSL3_ST_SW_KEY_EXCH_B;
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
f_err: f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al); ssl3_send_alert(s,SSL3_AL_FATAL,al);

View file

@ -197,12 +197,13 @@ test_verify:
../apps/openssl verify -CApath ../certs ../certs/*.pem ../apps/openssl verify -CApath ../certs ../certs/*.pem
test_dh: test_dh:
@echo "Generate as set of DH parameters" @echo "Generate a set of DH parameters"
./$(DHTEST) ./$(DHTEST)
test_dsa: test_dsa:
@echo "Generate as set of DSA parameters" @echo "Generate a set of DSA parameters"
./$(DSATEST) ./$(DSATEST)
./$(DSATEST) -app2_1
test_gen: test_gen:
@echo "Generate and verify a certificate request" @echo "Generate and verify a certificate request"

View file

@ -66,6 +66,9 @@ echo test sslv2/sslv3 via BIO pair
echo test sslv2/sslv3 w/o DHE via BIO pair echo test sslv2/sslv3 w/o DHE via BIO pair
./ssltest -bio_pair -no_dhe || exit 1 ./ssltest -bio_pair -no_dhe || exit 1
echo test sslv2/sslv3 with 1024bit DHE
./ssltest -bio_pair -dhe1024 -v || exit 1
echo test sslv2/sslv3 with server authentication echo test sslv2/sslv3 with server authentication
./ssltest -bio_pair -server_auth -CApath ../certs || exit 1 ./ssltest -bio_pair -server_auth -CApath ../certs || exit 1

View file

@ -2211,3 +2211,5 @@ sk_CRYPTO_EX_DATA_FUNCS_num 2235
sk_CRYPTO_EX_DATA_FUNCS_pop_free 2236 sk_CRYPTO_EX_DATA_FUNCS_pop_free 2236
sk_CRYPTO_EX_DATA_FUNCS_insert 2237 sk_CRYPTO_EX_DATA_FUNCS_insert 2237
sk_CRYPTO_EX_DATA_FUNCS_zero 2238 sk_CRYPTO_EX_DATA_FUNCS_zero 2238
BN_pseudo_rand 2239
BN_is_prime_fasttest 2240