X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=crypto%2Fbn%2Fbn_prime.c;h=7b25979dd1c450324eaf08a5574fb3ba0a9b92b7;hb=5711dd8eacf9e3c97fec97389e95cc84601d3f88;hp=5bfc0b682be598c32e52ab65d7ee98dae6cef60b;hpb=983495c4b215b7418dc3470fa8bc9c919c09c683;p=openssl.git diff --git a/crypto/bn/bn_prime.c b/crypto/bn/bn_prime.c index 5bfc0b682b..7b25979dd1 100644 --- a/crypto/bn/bn_prime.c +++ b/crypto/bn/bn_prime.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -115,6 +115,11 @@ #include "bn_lcl.h" #include +/* NB: these functions have been "upgraded", the deprecated versions (which are + * compatibility wrappers using these functions) are in bn_depr.c. + * - Geoff + */ + /* The quick sieve algorithm approach to weeding out primes is * Philip Zimmermann's, as implemented in PGP. I have had a read of * his comments and implemented my own version. @@ -129,12 +134,32 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, static int probable_prime_dh_safe(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx); -BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, - const BIGNUM *add, const BIGNUM *rem, - void (*callback)(int,int,void *), void *cb_arg) +int BN_GENCB_call(BN_GENCB *cb, int a, int b) + { + /* No callback means continue */ + if(!cb) return 1; + switch(cb->ver) + { + case 1: + /* Deprecated-style callbacks */ + if(!cb->cb.cb_1) + return 1; + cb->cb.cb_1(a, b, cb->arg); + return 1; + case 2: + /* New-style callbacks */ + return cb->cb.cb_2(a, b, cb); + default: + break; + } + /* Unrecognised callback type */ + return 0; + } + +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) { - BIGNUM *rnd=NULL; - BIGNUM t; + BIGNUM *t; int found=0; int i,j,c1=0; BN_CTX *ctx; @@ -142,38 +167,36 @@ BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, ctx=BN_CTX_new(); if (ctx == NULL) goto err; - if (ret == NULL) - { - if ((rnd=BN_new()) == NULL) goto err; - } - else - rnd=ret; - BN_init(&t); + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if(!t) goto err; loop: /* make a random number and set the top and bottom bits */ if (add == NULL) { - if (!probable_prime(rnd,bits)) goto err; + if (!probable_prime(ret,bits)) goto err; } else { if (safe) { - if (!probable_prime_dh_safe(rnd,bits,add,rem,ctx)) + if (!probable_prime_dh_safe(ret,bits,add,rem,ctx)) goto err; } else { - if (!probable_prime_dh(rnd,bits,add,rem,ctx)) + if (!probable_prime_dh(ret,bits,add,rem,ctx)) goto err; } } - /* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */ - if (callback != NULL) callback(0,c1++,cb_arg); + /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */ + if(!BN_GENCB_call(cb, 0, c1++)) + /* aborted */ + goto err; if (!safe) { - i=BN_is_prime_fasttest(rnd,checks,callback,ctx,cb_arg,0); + i=BN_is_prime_fasttest_ex(ret,checks,ctx,0,cb); if (i == -1) goto err; if (i == 0) goto loop; } @@ -183,41 +206,42 @@ loop: * check that (p-1)/2 is prime. * Since a prime is odd, We just * need to divide by 2 */ - if (!BN_rshift1(&t,rnd)) goto err; + if (!BN_rshift1(t,ret)) goto err; for (i=0; i a is prime if and only if a == 2 */ + return BN_is_word(a, 2); if (do_trial_division) { for (i = 1; i < NUMPRIMES; i++) if (BN_mod_word(a, primes[i]) == 0) return 0; - if (callback != NULL) callback(1, -1, cb_arg); + if(!BN_GENCB_call(cb, 1, -1)) + goto err; } if (ctx_passed != NULL) @@ -306,7 +332,8 @@ int BN_is_prime_fasttest(const BIGNUM *a, int checks, ret=0; goto err; } - if (callback != NULL) callback(1,i,cb_arg); + if(!BN_GENCB_call(cb, 1, i)) + goto err; } ret=1; err: @@ -343,20 +370,22 @@ static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, } /* If we get here, 'w' is the (a-1)/2-th power of the original 'w', * and it is neither -1 nor +1 -- so 'a' cannot be prime */ + bn_check_top(w); return 1; } static int probable_prime(BIGNUM *rnd, int bits) { int i; - BN_ULONG mods[NUMPRIMES]; - BN_ULONG delta,d; + prime_t mods[NUMPRIMES]; + BN_ULONG delta,maxdelta; again: if (!BN_rand(rnd,bits,1,1)) return(0); /* we now have a random number 'rand' to test. */ for (i=1; i maxdelta) goto again; goto loop; } } if (!BN_add_word(rnd,delta)) return(0); + bn_check_top(rnd); return(1); } @@ -411,6 +437,7 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, ret=1; err: BN_CTX_end(ctx); + bn_check_top(rnd); return(ret); } @@ -462,5 +489,6 @@ static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, ret=1; err: BN_CTX_end(ctx); + bn_check_top(p); return(ret); }