summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_prime.c
diff options
context:
space:
mode:
authorjsing <>2014-05-08 13:20:49 +0000
committerjsing <>2014-05-08 13:20:49 +0000
commit2e8879604fe3abbc2431ca79a4a923f1e87da75e (patch)
tree18398455223278c0cb2bd44f57e4499a4370f665 /src/lib/libcrypto/bn/bn_prime.c
parentf7d9a959949e5f3918c1cf2b27fb4cd7b62d07d5 (diff)
downloadopenbsd-2e8879604fe3abbc2431ca79a4a923f1e87da75e.tar.gz
openbsd-2e8879604fe3abbc2431ca79a4a923f1e87da75e.tar.bz2
openbsd-2e8879604fe3abbc2431ca79a4a923f1e87da75e.zip
Emergency knfectomie requested by tedu@.
Diffstat (limited to 'src/lib/libcrypto/bn/bn_prime.c')
-rw-r--r--src/lib/libcrypto/bn/bn_prime.c393
1 files changed, 209 insertions, 184 deletions
diff --git a/src/lib/libcrypto/bn/bn_prime.c b/src/lib/libcrypto/bn/bn_prime.c
index 7b25979dd1..7d4cab4acd 100644
--- a/src/lib/libcrypto/bn/bn_prime.c
+++ b/src/lib/libcrypto/bn/bn_prime.c
@@ -5,21 +5,21 @@
5 * This package is an SSL implementation written 5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com). 6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL. 7 * The implementation was written so as to conform with Netscapes SSL.
8 * 8 *
9 * This library is free for commercial and non-commercial use as long as 9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions 10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA, 11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms 13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 * 15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed. 17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution 18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used. 19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or 20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package. 21 * in documentation (online or textual) provided with the package.
22 * 22 *
23 * Redistribution and use in source and binary forms, with or without 23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions 24 * modification, are permitted provided that the following conditions
25 * are met: 25 * are met:
@@ -34,10 +34,10 @@
34 * Eric Young (eay@cryptsoft.com)" 34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library 35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-). 36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement: 38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 * 40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -49,7 +49,7 @@
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE. 51 * SUCH DAMAGE.
52 * 52 *
53 * The licence and distribution terms for any publically available version or 53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence 55 * copied and put under another distribution licence
@@ -63,7 +63,7 @@
63 * are met: 63 * are met:
64 * 64 *
65 * 1. Redistributions of source code must retain the above copyright 65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer. 66 * notice, this list of conditions and the following disclaimer.
67 * 67 *
68 * 2. Redistributions in binary form must reproduce the above copyright 68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in 69 * notice, this list of conditions and the following disclaimer in
@@ -127,22 +127,23 @@
127#include "bn_prime.h" 127#include "bn_prime.h"
128 128
129static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, 129static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
130 const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont); 130 const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont);
131static int probable_prime(BIGNUM *rnd, int bits); 131static int probable_prime(BIGNUM *rnd, int bits);
132static int probable_prime_dh(BIGNUM *rnd, int bits, 132static int probable_prime_dh(BIGNUM *rnd, int bits,
133 const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx); 133 const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
134static int probable_prime_dh_safe(BIGNUM *rnd, int bits, 134static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
135 const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx); 135 const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
136 136
137int BN_GENCB_call(BN_GENCB *cb, int a, int b) 137int
138 { 138BN_GENCB_call(BN_GENCB *cb, int a, int b)
139{
139 /* No callback means continue */ 140 /* No callback means continue */
140 if(!cb) return 1; 141 if (!cb)
141 switch(cb->ver) 142 return 1;
142 { 143 switch (cb->ver) {
143 case 1: 144 case 1:
144 /* Deprecated-style callbacks */ 145 /* Deprecated-style callbacks */
145 if(!cb->cb.cb_1) 146 if (!cb->cb.cb_1)
146 return 1; 147 return 1;
147 cb->cb.cb_1(a, b, cb->arg); 148 cb->cb.cb_1(a, b, cb->arg);
148 return 1; 149 return 1;
@@ -151,98 +152,101 @@ int BN_GENCB_call(BN_GENCB *cb, int a, int b)
151 return cb->cb.cb_2(a, b, cb); 152 return cb->cb.cb_2(a, b, cb);
152 default: 153 default:
153 break; 154 break;
154 } 155 }
155 /* Unrecognised callback type */ 156 /* Unrecognised callback type */
156 return 0; 157 return 0;
157 } 158}
158 159
159int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, 160int
160 const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) 161BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
161 { 162 const BIGNUM *rem, BN_GENCB *cb)
163{
162 BIGNUM *t; 164 BIGNUM *t;
163 int found=0; 165 int found = 0;
164 int i,j,c1=0; 166 int i, j, c1 = 0;
165 BN_CTX *ctx; 167 BN_CTX *ctx;
166 int checks = BN_prime_checks_for_size(bits); 168 int checks = BN_prime_checks_for_size(bits);
167 169
168 ctx=BN_CTX_new(); 170 ctx = BN_CTX_new();
169 if (ctx == NULL) goto err; 171 if (ctx == NULL)
172 goto err;
170 BN_CTX_start(ctx); 173 BN_CTX_start(ctx);
171 t = BN_CTX_get(ctx); 174 t = BN_CTX_get(ctx);
172 if(!t) goto err; 175 if (!t)
173loop: 176 goto err;
177loop:
174 /* make a random number and set the top and bottom bits */ 178 /* make a random number and set the top and bottom bits */
175 if (add == NULL) 179 if (add == NULL) {
176 { 180 if (!probable_prime(ret, bits))
177 if (!probable_prime(ret,bits)) goto err; 181 goto err;
178 } 182 } else {
179 else 183 if (safe) {
180 { 184 if (!probable_prime_dh_safe(ret, bits, add, rem, ctx))
181 if (safe) 185 goto err;
182 { 186 } else {
183 if (!probable_prime_dh_safe(ret,bits,add,rem,ctx)) 187 if (!probable_prime_dh(ret, bits, add, rem, ctx))
184 goto err;
185 }
186 else
187 {
188 if (!probable_prime_dh(ret,bits,add,rem,ctx))
189 goto err; 188 goto err;
190 }
191 } 189 }
190 }
192 /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */ 191 /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */
193 if(!BN_GENCB_call(cb, 0, c1++)) 192 if (!BN_GENCB_call(cb, 0, c1++))
194 /* aborted */ 193 /* aborted */
195 goto err; 194 goto err;
196 195
197 if (!safe) 196 if (!safe) {
198 { 197 i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb);
199 i=BN_is_prime_fasttest_ex(ret,checks,ctx,0,cb); 198 if (i == -1)
200 if (i == -1) goto err; 199 goto err;
201 if (i == 0) goto loop; 200 if (i == 0)
202 } 201 goto loop;
203 else 202 } else {
204 {
205 /* for "safe prime" generation, 203 /* for "safe prime" generation,
206 * check that (p-1)/2 is prime. 204 * check that (p-1)/2 is prime.
207 * Since a prime is odd, We just 205 * Since a prime is odd, We just
208 * need to divide by 2 */ 206 * need to divide by 2 */
209 if (!BN_rshift1(t,ret)) goto err; 207 if (!BN_rshift1(t, ret))
208 goto err;
210 209
211 for (i=0; i<checks; i++) 210 for (i = 0; i < checks; i++) {
212 { 211 j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb);
213 j=BN_is_prime_fasttest_ex(ret,1,ctx,0,cb); 212 if (j == -1)
214 if (j == -1) goto err; 213 goto err;
215 if (j == 0) goto loop; 214 if (j == 0)
215 goto loop;
216 216
217 j=BN_is_prime_fasttest_ex(t,1,ctx,0,cb); 217 j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb);
218 if (j == -1) goto err; 218 if (j == -1)
219 if (j == 0) goto loop; 219 goto err;
220 if (j == 0)
221 goto loop;
220 222
221 if(!BN_GENCB_call(cb, 2, c1-1)) 223 if (!BN_GENCB_call(cb, 2, c1 - 1))
222 goto err; 224 goto err;
223 /* We have a safe prime test pass */ 225 /* We have a safe prime test pass */
224 }
225 } 226 }
227 }
226 /* we have a prime :-) */ 228 /* we have a prime :-) */
227 found = 1; 229 found = 1;
230
228err: 231err:
229 if (ctx != NULL) 232 if (ctx != NULL) {
230 {
231 BN_CTX_end(ctx); 233 BN_CTX_end(ctx);
232 BN_CTX_free(ctx); 234 BN_CTX_free(ctx);
233 } 235 }
234 bn_check_top(ret); 236 bn_check_top(ret);
235 return found; 237 return found;
236 } 238}
237 239
238int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb) 240int
239 { 241BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb)
242{
240 return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb); 243 return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
241 } 244}
242 245
243int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, 246int
244 int do_trial_division, BN_GENCB *cb) 247BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
245 { 248 int do_trial_division, BN_GENCB *cb)
249{
246 int i, j, ret = -1; 250 int i, j, ret = -1;
247 int k; 251 int k;
248 BN_CTX *ctx = NULL; 252 BN_CTX *ctx = NULL;
@@ -252,7 +256,7 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
252 256
253 if (BN_cmp(a, BN_value_one()) <= 0) 257 if (BN_cmp(a, BN_value_one()) <= 0)
254 return 0; 258 return 0;
255 259
256 if (checks == BN_prime_checks) 260 if (checks == BN_prime_checks)
257 checks = BN_prime_checks_for_size(BN_num_bits(a)); 261 checks = BN_prime_checks_for_size(BN_num_bits(a));
258 262
@@ -260,48 +264,45 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
260 if (!BN_is_odd(a)) 264 if (!BN_is_odd(a))
261 /* a is even => a is prime if and only if a == 2 */ 265 /* a is even => a is prime if and only if a == 2 */
262 return BN_is_word(a, 2); 266 return BN_is_word(a, 2);
263 if (do_trial_division) 267 if (do_trial_division) {
264 {
265 for (i = 1; i < NUMPRIMES; i++) 268 for (i = 1; i < NUMPRIMES; i++)
266 if (BN_mod_word(a, primes[i]) == 0) 269 if (BN_mod_word(a, primes[i]) == 0)
267 return 0; 270 return 0;
268 if(!BN_GENCB_call(cb, 1, -1)) 271 if (!BN_GENCB_call(cb, 1, -1))
269 goto err; 272 goto err;
270 } 273 }
271 274
272 if (ctx_passed != NULL) 275 if (ctx_passed != NULL)
273 ctx = ctx_passed; 276 ctx = ctx_passed;
274 else 277 else if ((ctx = BN_CTX_new()) == NULL)
275 if ((ctx=BN_CTX_new()) == NULL) 278 goto err;
276 goto err;
277 BN_CTX_start(ctx); 279 BN_CTX_start(ctx);
278 280
279 /* A := abs(a) */ 281 /* A := abs(a) */
280 if (a->neg) 282 if (a->neg) {
281 {
282 BIGNUM *t; 283 BIGNUM *t;
283 if ((t = BN_CTX_get(ctx)) == NULL) goto err; 284 if ((t = BN_CTX_get(ctx)) == NULL)
285 goto err;
284 BN_copy(t, a); 286 BN_copy(t, a);
285 t->neg = 0; 287 t->neg = 0;
286 A = t; 288 A = t;
287 } 289 } else
288 else
289 A = a; 290 A = a;
290 A1 = BN_CTX_get(ctx); 291 A1 = BN_CTX_get(ctx);
291 A1_odd = BN_CTX_get(ctx); 292 A1_odd = BN_CTX_get(ctx);
292 check = BN_CTX_get(ctx); 293 check = BN_CTX_get(ctx);
293 if (check == NULL) goto err; 294 if (check == NULL)
295 goto err;
294 296
295 /* compute A1 := A - 1 */ 297 /* compute A1 := A - 1 */
296 if (!BN_copy(A1, A)) 298 if (!BN_copy(A1, A))
297 goto err; 299 goto err;
298 if (!BN_sub_word(A1, 1)) 300 if (!BN_sub_word(A1, 1))
299 goto err; 301 goto err;
300 if (BN_is_zero(A1)) 302 if (BN_is_zero(A1)) {
301 {
302 ret = 0; 303 ret = 0;
303 goto err; 304 goto err;
304 } 305 }
305 306
306 /* write A1 as A1_odd * 2^k */ 307 /* write A1 as A1_odd * 2^k */
307 k = 1; 308 k = 1;
@@ -316,9 +317,8 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
316 goto err; 317 goto err;
317 if (!BN_MONT_CTX_set(mont, A, ctx)) 318 if (!BN_MONT_CTX_set(mont, A, ctx))
318 goto err; 319 goto err;
319 320
320 for (i = 0; i < checks; i++) 321 for (i = 0; i < checks; i++) {
321 {
322 if (!BN_pseudo_rand_range(check, A1)) 322 if (!BN_pseudo_rand_range(check, A1))
323 goto err; 323 goto err;
324 if (!BN_add_word(check, 1)) 324 if (!BN_add_word(check, 1))
@@ -326,40 +326,41 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
326 /* now 1 <= check < A */ 326 /* now 1 <= check < A */
327 327
328 j = witness(check, A, A1, A1_odd, k, ctx, mont); 328 j = witness(check, A, A1, A1_odd, k, ctx, mont);
329 if (j == -1) goto err; 329 if (j == -1)
330 if (j)
331 {
332 ret=0;
333 goto err; 330 goto err;
334 } 331 if (j) {
335 if(!BN_GENCB_call(cb, 1, i)) 332 ret = 0;
336 goto err; 333 goto err;
337 } 334 }
338 ret=1; 335 if (!BN_GENCB_call(cb, 1, i))
336 goto err;
337 }
338 ret = 1;
339
339err: 340err:
340 if (ctx != NULL) 341 if (ctx != NULL) {
341 {
342 BN_CTX_end(ctx); 342 BN_CTX_end(ctx);
343 if (ctx_passed == NULL) 343 if (ctx_passed == NULL)
344 BN_CTX_free(ctx); 344 BN_CTX_free(ctx);
345 } 345 }
346 if (mont != NULL) 346 if (mont != NULL)
347 BN_MONT_CTX_free(mont); 347 BN_MONT_CTX_free(mont);
348 348
349 return(ret); 349 return (ret);
350 } 350}
351 351
352static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, 352static int
353 const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont) 353witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, const BIGNUM *a1_odd,
354 { 354 int k, BN_CTX *ctx, BN_MONT_CTX *mont)
355 if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */ 355{
356 if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont))
357 /* w := w^a1_odd mod a */
356 return -1; 358 return -1;
357 if (BN_is_one(w)) 359 if (BN_is_one(w))
358 return 0; /* probably prime */ 360 return 0; /* probably prime */
359 if (BN_cmp(w, a1) == 0) 361 if (BN_cmp(w, a1) == 0)
360 return 0; /* w == -1 (mod a), 'a' is probably prime */ 362 return 0; /* w == -1 (mod a), 'a' is probably prime */
361 while (--k) 363 while (--k) {
362 {
363 if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */ 364 if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
364 return -1; 365 return -1;
365 if (BN_is_one(w)) 366 if (BN_is_one(w))
@@ -367,128 +368,152 @@ static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
367 * have been == -1 (mod 'a') */ 368 * have been == -1 (mod 'a') */
368 if (BN_cmp(w, a1) == 0) 369 if (BN_cmp(w, a1) == 0)
369 return 0; /* w == -1 (mod a), 'a' is probably prime */ 370 return 0; /* w == -1 (mod a), 'a' is probably prime */
370 } 371 }
371 /* If we get here, 'w' is the (a-1)/2-th power of the original 'w', 372 /* 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 */ 373 * and it is neither -1 nor +1 -- so 'a' cannot be prime */
373 bn_check_top(w); 374 bn_check_top(w);
374 return 1; 375 return 1;
375 } 376}
376 377
377static int probable_prime(BIGNUM *rnd, int bits) 378static int
378 { 379probable_prime(BIGNUM *rnd, int bits)
380{
379 int i; 381 int i;
380 prime_t mods[NUMPRIMES]; 382 prime_t mods[NUMPRIMES];
381 BN_ULONG delta,maxdelta; 383 BN_ULONG delta, maxdelta;
382 384
383again: 385again:
384 if (!BN_rand(rnd,bits,1,1)) return(0); 386 if (!BN_rand(rnd, bits, 1, 1))
387 return (0);
385 /* we now have a random number 'rand' to test. */ 388 /* we now have a random number 'rand' to test. */
386 for (i=1; i<NUMPRIMES; i++) 389 for (i = 1; i < NUMPRIMES; i++)
387 mods[i]=(prime_t)BN_mod_word(rnd,(BN_ULONG)primes[i]); 390 mods[i] = (prime_t)BN_mod_word(rnd, (BN_ULONG)primes[i]);
388 maxdelta=BN_MASK2 - primes[NUMPRIMES-1]; 391 maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
389 delta=0; 392 delta = 0;
390 loop: for (i=1; i<NUMPRIMES; i++) 393loop:
391 { 394 for (i = 1; i < NUMPRIMES; i++) {
392 /* check that rnd is not a prime and also 395 /* check that rnd is not a prime and also
393 * that gcd(rnd-1,primes) == 1 (except for 2) */ 396 * that gcd(rnd-1,primes) == 1 (except for 2) */
394 if (((mods[i]+delta)%primes[i]) <= 1) 397 if (((mods[i] + delta) % primes[i]) <= 1) {
395 { 398 delta += 2;
396 delta+=2; 399 if (delta > maxdelta)
397 if (delta > maxdelta) goto again; 400 goto again;
398 goto loop; 401 goto loop;
399 }
400 } 402 }
401 if (!BN_add_word(rnd,delta)) return(0);
402 bn_check_top(rnd);
403 return(1);
404 } 403 }
405 404 if (!BN_add_word(rnd, delta))
406static int probable_prime_dh(BIGNUM *rnd, int bits, 405 return (0);
407 const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx) 406 bn_check_top(rnd);
408 { 407 return (1);
409 int i,ret=0; 408}
409
410static int
411probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem,
412 BN_CTX *ctx)
413{
414 int i, ret = 0;
410 BIGNUM *t1; 415 BIGNUM *t1;
411 416
412 BN_CTX_start(ctx); 417 BN_CTX_start(ctx);
413 if ((t1 = BN_CTX_get(ctx)) == NULL) goto err; 418 if ((t1 = BN_CTX_get(ctx)) == NULL)
419 goto err;
414 420
415 if (!BN_rand(rnd,bits,0,1)) goto err; 421 if (!BN_rand(rnd, bits, 0, 1))
422 goto err;
416 423
417 /* we need ((rnd-rem) % add) == 0 */ 424 /* we need ((rnd-rem) % add) == 0 */
418 425
419 if (!BN_mod(t1,rnd,add,ctx)) goto err; 426 if (!BN_mod(t1, rnd, add, ctx))
420 if (!BN_sub(rnd,rnd,t1)) goto err; 427 goto err;
421 if (rem == NULL) 428 if (!BN_sub(rnd, rnd, t1))
422 { if (!BN_add_word(rnd,1)) goto err; } 429 goto err;
423 else 430 if (rem == NULL) {
424 { if (!BN_add(rnd,rnd,rem)) goto err; } 431 if (!BN_add_word(rnd, 1))
432 goto err;
433 } else {
434 if (!BN_add(rnd, rnd, rem))
435 goto err;
436 }
425 437
426 /* we now have a random number 'rand' to test. */ 438 /* we now have a random number 'rand' to test. */
427 439
428 loop: for (i=1; i<NUMPRIMES; i++) 440loop:
429 { 441 for (i = 1; i < NUMPRIMES; i++) {
430 /* check that rnd is a prime */ 442 /* check that rnd is a prime */
431 if (BN_mod_word(rnd,(BN_ULONG)primes[i]) <= 1) 443 if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) {
432 { 444 if (!BN_add(rnd, rnd, add))
433 if (!BN_add(rnd,rnd,add)) goto err; 445 goto err;
434 goto loop; 446 goto loop;
435 }
436 } 447 }
437 ret=1; 448 }
449 ret = 1;
450
438err: 451err:
439 BN_CTX_end(ctx); 452 BN_CTX_end(ctx);
440 bn_check_top(rnd); 453 bn_check_top(rnd);
441 return(ret); 454 return (ret);
442 } 455}
443 456
444static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, 457static int
445 const BIGNUM *rem, BN_CTX *ctx) 458probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
446 { 459 const BIGNUM *rem, BN_CTX *ctx)
447 int i,ret=0; 460{
448 BIGNUM *t1,*qadd,*q; 461 int i, ret = 0;
462 BIGNUM *t1, *qadd, *q;
449 463
450 bits--; 464 bits--;
451 BN_CTX_start(ctx); 465 BN_CTX_start(ctx);
452 t1 = BN_CTX_get(ctx); 466 t1 = BN_CTX_get(ctx);
453 q = BN_CTX_get(ctx); 467 q = BN_CTX_get(ctx);
454 qadd = BN_CTX_get(ctx); 468 qadd = BN_CTX_get(ctx);
455 if (qadd == NULL) goto err; 469 if (qadd == NULL)
470 goto err;
471
472 if (!BN_rshift1(qadd, padd))
473 goto err;
456 474
457 if (!BN_rshift1(qadd,padd)) goto err; 475 if (!BN_rand(q, bits, 0, 1))
458 476 goto err;
459 if (!BN_rand(q,bits,0,1)) goto err;
460 477
461 /* we need ((rnd-rem) % add) == 0 */ 478 /* we need ((rnd-rem) % add) == 0 */
462 if (!BN_mod(t1,q,qadd,ctx)) goto err; 479 if (!BN_mod(t1, q,qadd, ctx))
463 if (!BN_sub(q,q,t1)) goto err; 480 goto err;
464 if (rem == NULL) 481 if (!BN_sub(q, q, t1))
465 { if (!BN_add_word(q,1)) goto err; } 482 goto err;
466 else 483 if (rem == NULL) {
467 { 484 if (!BN_add_word(q, 1))
468 if (!BN_rshift1(t1,rem)) goto err; 485 goto err;
469 if (!BN_add(q,q,t1)) goto err; 486 } else {
470 } 487 if (!BN_rshift1(t1, rem))
488 goto err;
489 if (!BN_add(q, q, t1))
490 goto err;
491 }
471 492
472 /* we now have a random number 'rand' to test. */ 493 /* we now have a random number 'rand' to test. */
473 if (!BN_lshift1(p,q)) goto err; 494 if (!BN_lshift1(p, q))
474 if (!BN_add_word(p,1)) goto err; 495 goto err;
496 if (!BN_add_word(p, 1))
497 goto err;
475 498
476 loop: for (i=1; i<NUMPRIMES; i++) 499loop:
477 { 500 for (i = 1; i < NUMPRIMES; i++) {
478 /* check that p and q are prime */ 501 /* check that p and q are prime */
479 /* check that for p and q 502 /* check that for p and q
480 * gcd(p-1,primes) == 1 (except for 2) */ 503 * gcd(p-1,primes) == 1 (except for 2) */
481 if ( (BN_mod_word(p,(BN_ULONG)primes[i]) == 0) || 504 if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) ||
482 (BN_mod_word(q,(BN_ULONG)primes[i]) == 0)) 505 (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) {
483 { 506 if (!BN_add(p, p, padd))
484 if (!BN_add(p,p,padd)) goto err; 507 goto err;
485 if (!BN_add(q,q,qadd)) goto err; 508 if (!BN_add(q, q, qadd))
509 goto err;
486 goto loop; 510 goto loop;
487 }
488 } 511 }
489 ret=1; 512 }
513 ret = 1;
514
490err: 515err:
491 BN_CTX_end(ctx); 516 BN_CTX_end(ctx);
492 bn_check_top(p); 517 bn_check_top(p);
493 return(ret); 518 return (ret);
494 } 519}