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