summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_prime.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bn/bn_prime.c')
-rw-r--r--src/lib/libcrypto/bn/bn_prime.c114
1 files changed, 70 insertions, 44 deletions
diff --git a/src/lib/libcrypto/bn/bn_prime.c b/src/lib/libcrypto/bn/bn_prime.c
index f422172f16..7b25979dd1 100644
--- a/src/lib/libcrypto/bn/bn_prime.c
+++ b/src/lib/libcrypto/bn/bn_prime.c
@@ -115,6 +115,11 @@
115#include "bn_lcl.h" 115#include "bn_lcl.h"
116#include <openssl/rand.h> 116#include <openssl/rand.h>
117 117
118/* NB: these functions have been "upgraded", the deprecated versions (which are
119 * compatibility wrappers using these functions) are in bn_depr.c.
120 * - Geoff
121 */
122
118/* The quick sieve algorithm approach to weeding out primes is 123/* The quick sieve algorithm approach to weeding out primes is
119 * Philip Zimmermann's, as implemented in PGP. I have had a read of 124 * Philip Zimmermann's, as implemented in PGP. I have had a read of
120 * his comments and implemented my own version. 125 * his comments and implemented my own version.
@@ -129,51 +134,69 @@ static int probable_prime_dh(BIGNUM *rnd, int bits,
129static int probable_prime_dh_safe(BIGNUM *rnd, int bits, 134static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
130 const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx); 135 const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
131 136
132BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, 137int BN_GENCB_call(BN_GENCB *cb, int a, int b)
133 const BIGNUM *add, const BIGNUM *rem, 138 {
134 void (*callback)(int,int,void *), void *cb_arg) 139 /* No callback means continue */
140 if(!cb) return 1;
141 switch(cb->ver)
142 {
143 case 1:
144 /* Deprecated-style callbacks */
145 if(!cb->cb.cb_1)
146 return 1;
147 cb->cb.cb_1(a, b, cb->arg);
148 return 1;
149 case 2:
150 /* New-style callbacks */
151 return cb->cb.cb_2(a, b, cb);
152 default:
153 break;
154 }
155 /* Unrecognised callback type */
156 return 0;
157 }
158
159int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
160 const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb)
135 { 161 {
136 BIGNUM *rnd=NULL; 162 BIGNUM *t;
137 BIGNUM t;
138 int found=0; 163 int found=0;
139 int i,j,c1=0; 164 int i,j,c1=0;
140 BN_CTX *ctx; 165 BN_CTX *ctx;
141 int checks = BN_prime_checks_for_size(bits); 166 int checks = BN_prime_checks_for_size(bits);
142 167
143 BN_init(&t);
144 ctx=BN_CTX_new(); 168 ctx=BN_CTX_new();
145 if (ctx == NULL) goto err; 169 if (ctx == NULL) goto err;
146 if (ret == NULL) 170 BN_CTX_start(ctx);
147 { 171 t = BN_CTX_get(ctx);
148 if ((rnd=BN_new()) == NULL) goto err; 172 if(!t) goto err;
149 }
150 else
151 rnd=ret;
152loop: 173loop:
153 /* make a random number and set the top and bottom bits */ 174 /* make a random number and set the top and bottom bits */
154 if (add == NULL) 175 if (add == NULL)
155 { 176 {
156 if (!probable_prime(rnd,bits)) goto err; 177 if (!probable_prime(ret,bits)) goto err;
157 } 178 }
158 else 179 else
159 { 180 {
160 if (safe) 181 if (safe)
161 { 182 {
162 if (!probable_prime_dh_safe(rnd,bits,add,rem,ctx)) 183 if (!probable_prime_dh_safe(ret,bits,add,rem,ctx))
163 goto err; 184 goto err;
164 } 185 }
165 else 186 else
166 { 187 {
167 if (!probable_prime_dh(rnd,bits,add,rem,ctx)) 188 if (!probable_prime_dh(ret,bits,add,rem,ctx))
168 goto err; 189 goto err;
169 } 190 }
170 } 191 }
171 /* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */ 192 /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */
172 if (callback != NULL) callback(0,c1++,cb_arg); 193 if(!BN_GENCB_call(cb, 0, c1++))
194 /* aborted */
195 goto err;
173 196
174 if (!safe) 197 if (!safe)
175 { 198 {
176 i=BN_is_prime_fasttest(rnd,checks,callback,ctx,cb_arg,0); 199 i=BN_is_prime_fasttest_ex(ret,checks,ctx,0,cb);
177 if (i == -1) goto err; 200 if (i == -1) goto err;
178 if (i == 0) goto loop; 201 if (i == 0) goto loop;
179 } 202 }
@@ -183,41 +206,42 @@ loop:
183 * check that (p-1)/2 is prime. 206 * check that (p-1)/2 is prime.
184 * Since a prime is odd, We just 207 * Since a prime is odd, We just
185 * need to divide by 2 */ 208 * need to divide by 2 */
186 if (!BN_rshift1(&t,rnd)) goto err; 209 if (!BN_rshift1(t,ret)) goto err;
187 210
188 for (i=0; i<checks; i++) 211 for (i=0; i<checks; i++)
189 { 212 {
190 j=BN_is_prime_fasttest(rnd,1,callback,ctx,cb_arg,0); 213 j=BN_is_prime_fasttest_ex(ret,1,ctx,0,cb);
191 if (j == -1) goto err; 214 if (j == -1) goto err;
192 if (j == 0) goto loop; 215 if (j == 0) goto loop;
193 216
194 j=BN_is_prime_fasttest(&t,1,callback,ctx,cb_arg,0); 217 j=BN_is_prime_fasttest_ex(t,1,ctx,0,cb);
195 if (j == -1) goto err; 218 if (j == -1) goto err;
196 if (j == 0) goto loop; 219 if (j == 0) goto loop;
197 220
198 if (callback != NULL) callback(2,c1-1,cb_arg); 221 if(!BN_GENCB_call(cb, 2, c1-1))
222 goto err;
199 /* We have a safe prime test pass */ 223 /* We have a safe prime test pass */
200 } 224 }
201 } 225 }
202 /* we have a prime :-) */ 226 /* we have a prime :-) */
203 found = 1; 227 found = 1;
204err: 228err:
205 if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd); 229 if (ctx != NULL)
206 BN_free(&t); 230 {
207 if (ctx != NULL) BN_CTX_free(ctx); 231 BN_CTX_end(ctx);
208 return(found ? rnd : NULL); 232 BN_CTX_free(ctx);
233 }
234 bn_check_top(ret);
235 return found;
209 } 236 }
210 237
211int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int,int,void *), 238int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb)
212 BN_CTX *ctx_passed, void *cb_arg)
213 { 239 {
214 return BN_is_prime_fasttest(a, checks, callback, ctx_passed, cb_arg, 0); 240 return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
215 } 241 }
216 242
217int BN_is_prime_fasttest(const BIGNUM *a, int checks, 243int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
218 void (*callback)(int,int,void *), 244 int do_trial_division, BN_GENCB *cb)
219 BN_CTX *ctx_passed, void *cb_arg,
220 int do_trial_division)
221 { 245 {
222 int i, j, ret = -1; 246 int i, j, ret = -1;
223 int k; 247 int k;
@@ -236,13 +260,13 @@ int BN_is_prime_fasttest(const BIGNUM *a, int checks,
236 if (!BN_is_odd(a)) 260 if (!BN_is_odd(a))
237 /* a is even => a is prime if and only if a == 2 */ 261 /* a is even => a is prime if and only if a == 2 */
238 return BN_is_word(a, 2); 262 return BN_is_word(a, 2);
239
240 if (do_trial_division) 263 if (do_trial_division)
241 { 264 {
242 for (i = 1; i < NUMPRIMES; i++) 265 for (i = 1; i < NUMPRIMES; i++)
243 if (BN_mod_word(a, primes[i]) == 0) 266 if (BN_mod_word(a, primes[i]) == 0)
244 return 0; 267 return 0;
245 if (callback != NULL) callback(1, -1, cb_arg); 268 if(!BN_GENCB_call(cb, 1, -1))
269 goto err;
246 } 270 }
247 271
248 if (ctx_passed != NULL) 272 if (ctx_passed != NULL)
@@ -308,7 +332,8 @@ int BN_is_prime_fasttest(const BIGNUM *a, int checks,
308 ret=0; 332 ret=0;
309 goto err; 333 goto err;
310 } 334 }
311 if (callback != NULL) callback(1,i,cb_arg); 335 if(!BN_GENCB_call(cb, 1, i))
336 goto err;
312 } 337 }
313 ret=1; 338 ret=1;
314err: 339err:
@@ -345,20 +370,22 @@ static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
345 } 370 }
346 /* If we get here, 'w' is the (a-1)/2-th power of the original 'w', 371 /* If we get here, 'w' is the (a-1)/2-th power of the original 'w',
347 * and it is neither -1 nor +1 -- so 'a' cannot be prime */ 372 * and it is neither -1 nor +1 -- so 'a' cannot be prime */
373 bn_check_top(w);
348 return 1; 374 return 1;
349 } 375 }
350 376
351static int probable_prime(BIGNUM *rnd, int bits) 377static int probable_prime(BIGNUM *rnd, int bits)
352 { 378 {
353 int i; 379 int i;
354 BN_ULONG mods[NUMPRIMES]; 380 prime_t mods[NUMPRIMES];
355 BN_ULONG delta,d; 381 BN_ULONG delta,maxdelta;
356 382
357again: 383again:
358 if (!BN_rand(rnd,bits,1,1)) return(0); 384 if (!BN_rand(rnd,bits,1,1)) return(0);
359 /* we now have a random number 'rand' to test. */ 385 /* we now have a random number 'rand' to test. */
360 for (i=1; i<NUMPRIMES; i++) 386 for (i=1; i<NUMPRIMES; i++)
361 mods[i]=BN_mod_word(rnd,(BN_ULONG)primes[i]); 387 mods[i]=(prime_t)BN_mod_word(rnd,(BN_ULONG)primes[i]);
388 maxdelta=BN_MASK2 - primes[NUMPRIMES-1];
362 delta=0; 389 delta=0;
363 loop: for (i=1; i<NUMPRIMES; i++) 390 loop: for (i=1; i<NUMPRIMES; i++)
364 { 391 {
@@ -366,16 +393,13 @@ again:
366 * that gcd(rnd-1,primes) == 1 (except for 2) */ 393 * that gcd(rnd-1,primes) == 1 (except for 2) */
367 if (((mods[i]+delta)%primes[i]) <= 1) 394 if (((mods[i]+delta)%primes[i]) <= 1)
368 { 395 {
369 d=delta;
370 delta+=2; 396 delta+=2;
371 /* perhaps need to check for overflow of 397 if (delta > maxdelta) goto again;
372 * delta (but delta can be up to 2^32)
373 * 21-May-98 eay - added overflow check */
374 if (delta < d) goto again;
375 goto loop; 398 goto loop;
376 } 399 }
377 } 400 }
378 if (!BN_add_word(rnd,delta)) return(0); 401 if (!BN_add_word(rnd,delta)) return(0);
402 bn_check_top(rnd);
379 return(1); 403 return(1);
380 } 404 }
381 405
@@ -413,6 +437,7 @@ static int probable_prime_dh(BIGNUM *rnd, int bits,
413 ret=1; 437 ret=1;
414err: 438err:
415 BN_CTX_end(ctx); 439 BN_CTX_end(ctx);
440 bn_check_top(rnd);
416 return(ret); 441 return(ret);
417 } 442 }
418 443
@@ -464,5 +489,6 @@ static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
464 ret=1; 489 ret=1;
465err: 490err:
466 BN_CTX_end(ctx); 491 BN_CTX_end(ctx);
492 bn_check_top(p);
467 return(ret); 493 return(ret);
468 } 494 }