1/* 2 * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. 3 * 4 * The contents of this file constitute Original Code as defined in and are 5 * subject to the Apple Public Source License Version 1.2 (the 'License'). 6 * You may not use this file except in compliance with the License. Please obtain 7 * a copy of the License at http://www.apple.com/publicsource and read it before 8 * using this file. 9 * 10 * This Original Code and all software distributed under the License are 11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS 12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT 13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the 15 * specific language governing rights and limitations under the License. 16 */ 17 18 19/* crypto/bn/bn_prime.c */ 20/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 21 * All rights reserved. 22 * 23 * This package is an SSL implementation written 24 * by Eric Young (eay@cryptsoft.com). 25 * The implementation was written so as to conform with Netscapes SSL. 26 * 27 * This library is free for commercial and non-commercial use as long as 28 * the following conditions are aheared to. The following conditions 29 * apply to all code found in this distribution, be it the RC4, RSA, 30 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 31 * included with this distribution is covered by the same copyright terms 32 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 33 * 34 * Copyright remains Eric Young's, and as such any Copyright notices in 35 * the code are not to be removed. 36 * If this package is used in a product, Eric Young should be given attribution 37 * as the author of the parts of the library used. 38 * This can be in the form of a textual message at program startup or 39 * in documentation (online or textual) provided with the package. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. All advertising materials mentioning features or use of this software 50 * must display the following acknowledgement: 51 * "This product includes cryptographic software written by 52 * Eric Young (eay@cryptsoft.com)" 53 * The word 'cryptographic' can be left out if the rouines from the library 54 * being used are not cryptographic related :-). 55 * 4. If you include any Windows specific code (or a derivative thereof) from 56 * the apps directory (application code) you must include an acknowledgement: 57 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 58 * 59 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * SUCH DAMAGE. 70 * 71 * The licence and distribution terms for any publically available version or 72 * derivative of this code cannot be changed. i.e. this code cannot simply be 73 * copied and put under another distribution licence 74 * [including the GNU Public Licence.] 75 */ 76/* ==================================================================== 77 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 78 * 79 * Redistribution and use in source and binary forms, with or without 80 * modification, are permitted provided that the following conditions 81 * are met: 82 * 83 * 1. Redistributions of source code must retain the above copyright 84 * notice, this list of conditions and the following disclaimer. 85 * 86 * 2. Redistributions in binary form must reproduce the above copyright 87 * notice, this list of conditions and the following disclaimer in 88 * the documentation and/or other materials provided with the 89 * distribution. 90 * 91 * 3. All advertising materials mentioning features or use of this 92 * software must display the following acknowledgment: 93 * "This product includes software developed by the OpenSSL Project 94 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 95 * 96 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 97 * endorse or promote products derived from this software without 98 * prior written permission. For written permission, please contact 99 * openssl-core@openssl.org. 100 * 101 * 5. Products derived from this software may not be called "OpenSSL" 102 * nor may "OpenSSL" appear in their names without prior written 103 * permission of the OpenSSL Project. 104 * 105 * 6. Redistributions of any form whatsoever must retain the following 106 * acknowledgment: 107 * "This product includes software developed by the OpenSSL Project 108 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 109 * 110 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 111 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 112 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 113 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 114 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 115 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 116 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 117 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 118 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 119 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 120 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 121 * OF THE POSSIBILITY OF SUCH DAMAGE. 122 * ==================================================================== 123 * 124 * This product includes cryptographic software written by Eric Young 125 * (eay@cryptsoft.com). This product includes software written by Tim 126 * Hudson (tjh@cryptsoft.com). 127 * 128 */ 129 130#include <stdio.h> 131#include <time.h> 132#include "cryptlib.h" 133#include "bn_lcl.h" 134#include <openssl/rand.h> 135 136/* The quick sieve algorithm approach to weeding out primes is 137 * Philip Zimmermann's, as implemented in PGP. I have had a read of 138 * his comments and implemented my own version. 139 */ 140#include "bn_prime.h" 141 142static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, 143 const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont); 144static int probable_prime(BIGNUM *rnd, int bits); 145static int probable_prime_dh(BIGNUM *rnd, int bits, 146 BIGNUM *add, BIGNUM *rem, BN_CTX *ctx); 147static int probable_prime_dh_safe(BIGNUM *rnd, int bits, 148 BIGNUM *add, BIGNUM *rem, BN_CTX *ctx); 149 150BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, BIGNUM *add, 151 BIGNUM *rem, void (*callback)(int,int,void *), void *cb_arg) 152 { 153 BIGNUM *rnd=NULL; 154 BIGNUM t; 155 int found=0; 156 int i,j,c1=0; 157 BN_CTX *ctx; 158 int checks = BN_prime_checks_for_size(bits); 159 160 ctx=BN_CTX_new(); 161 if (ctx == NULL) goto err; 162 if (ret == NULL) 163 { 164 if ((rnd=BN_new()) == NULL) goto err; 165 } 166 else 167 rnd=ret; 168 BN_init(&t); 169loop: 170 /* make a random number and set the top and bottom bits */ 171 if (add == NULL) 172 { 173 if (!probable_prime(rnd,bits)) goto err; 174 } 175 else 176 { 177 if (safe) 178 { 179 if (!probable_prime_dh_safe(rnd,bits,add,rem,ctx)) 180 goto err; 181 } 182 else 183 { 184 if (!probable_prime_dh(rnd,bits,add,rem,ctx)) 185 goto err; 186 } 187 } 188 /* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */ 189 if (callback != NULL) callback(0,c1++,cb_arg); 190 191 if (!safe) 192 { 193 i=BN_is_prime_fasttest(rnd,checks,callback,ctx,cb_arg,0); 194 if (i == -1) goto err; 195 if (i == 0) goto loop; 196 } 197 else 198 { 199 /* for "safe prime" generation, 200 * check that (p-1)/2 is prime. 201 * Since a prime is odd, We just 202 * need to divide by 2 */ 203 if (!BN_rshift1(&t,rnd)) goto err; 204 205 for (i=0; i<checks; i++) 206 { 207 j=BN_is_prime_fasttest(rnd,1,callback,ctx,cb_arg,0); 208 if (j == -1) goto err; 209 if (j == 0) goto loop; 210 211 j=BN_is_prime_fasttest(&t,1,callback,ctx,cb_arg,0); 212 if (j == -1) goto err; 213 if (j == 0) goto loop; 214 215 if (callback != NULL) callback(2,c1-1,cb_arg); 216 /* We have a safe prime test pass */ 217 } 218 } 219 /* we have a prime :-) */ 220 found = 1; 221err: 222 if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd); 223 BN_free(&t); 224 if (ctx != NULL) BN_CTX_free(ctx); 225 return(found ? rnd : NULL); 226 } 227 228int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int,int,void *), 229 BN_CTX *ctx_passed, void *cb_arg) 230 { 231 return BN_is_prime_fasttest(a, checks, callback, ctx_passed, cb_arg, 0); 232 } 233 234int BN_is_prime_fasttest(const BIGNUM *a, int checks, 235 void (*callback)(int,int,void *), 236 BN_CTX *ctx_passed, void *cb_arg, 237 int do_trial_division) 238 { 239 int i, j, ret = -1; 240 int k; 241 BN_CTX *ctx = NULL; 242 BIGNUM *A1, *A1_odd, *check; /* taken from ctx */ 243 BN_MONT_CTX *mont = NULL; 244 const BIGNUM *A = NULL; 245 246 if (checks == BN_prime_checks) 247 checks = BN_prime_checks_for_size(BN_num_bits(a)); 248 249 /* first look for small factors */ 250 if (!BN_is_odd(a)) 251 return(0); 252 if (do_trial_division) 253 { 254 for (i = 1; i < NUMPRIMES; i++) 255 if (BN_mod_word(a, primes[i]) == 0) 256 return 0; 257 if (callback != NULL) callback(1, -1, cb_arg); 258 } 259 260 if (ctx_passed != NULL) 261 ctx = ctx_passed; 262 else 263 if ((ctx=BN_CTX_new()) == NULL) 264 goto err; 265 BN_CTX_start(ctx); 266 267 /* A := abs(a) */ 268 if (a->neg) 269 { 270 BIGNUM *t; 271 if ((t = BN_CTX_get(ctx)) == NULL) goto err; 272 BN_copy(t, a); 273 t->neg = 0; 274 A = t; 275 } 276 else 277 A = a; 278 A1 = BN_CTX_get(ctx); 279 A1_odd = BN_CTX_get(ctx); 280 check = BN_CTX_get(ctx); 281 if (check == NULL) goto err; 282 283 /* compute A1 := A - 1 */ 284 if (!BN_copy(A1, A)) 285 goto err; 286 if (!BN_sub_word(A1, 1)) 287 goto err; 288 if (BN_is_zero(A1)) 289 { 290 ret = 0; 291 goto err; 292 } 293 294 /* write A1 as A1_odd * 2^k */ 295 k = 1; 296 while (!BN_is_bit_set(A1, k)) 297 k++; 298 if (!BN_rshift(A1_odd, A1, k)) 299 goto err; 300 301 /* Montgomery setup for computations mod A */ 302 mont = BN_MONT_CTX_new(); 303 if (mont == NULL) 304 goto err; 305 if (!BN_MONT_CTX_set(mont, A, ctx)) 306 goto err; 307 308 for (i = 0; i < checks; i++) 309 { 310 if (!BN_pseudo_rand(check, BN_num_bits(A1), 0, 0)) 311 goto err; 312 if (BN_cmp(check, A1) >= 0) 313 if (!BN_sub(check, check, A1)) 314 goto err; 315 if (!BN_add_word(check, 1)) 316 goto err; 317 /* now 1 <= check < A */ 318 319 j = witness(check, A, A1, A1_odd, k, ctx, mont); 320 if (j == -1) goto err; 321 if (j) 322 { 323 ret=0; 324 goto err; 325 } 326 if (callback != NULL) callback(1,i,cb_arg); 327 } 328 ret=1; 329err: 330 if (ctx != NULL) 331 { 332 BN_CTX_end(ctx); 333 if (ctx_passed == NULL) 334 BN_CTX_free(ctx); 335 } 336 if (mont != NULL) 337 BN_MONT_CTX_free(mont); 338 339 return(ret); 340 } 341 342static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, 343 const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont) 344 { 345 if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */ 346 return -1; 347 if (BN_is_one(w)) 348 return 0; /* probably prime */ 349 if (BN_cmp(w, a1) == 0) 350 return 0; /* w == -1 (mod a), 'a' is probably prime */ 351 while (--k) 352 { 353 if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */ 354 return -1; 355 if (BN_is_one(w)) 356 return 1; /* 'a' is composite, otherwise a previous 'w' would 357 * have been == -1 (mod 'a') */ 358 if (BN_cmp(w, a1) == 0) 359 return 0; /* w == -1 (mod a), 'a' is probably prime */ 360 } 361 /* If we get here, 'w' is the (a-1)/2-th power of the original 'w', 362 * and it is neither -1 nor +1 -- so 'a' cannot be prime */ 363 return 1; 364 } 365 366static int probable_prime(BIGNUM *rnd, int bits) 367 { 368 int i; 369 BN_ULONG mods[NUMPRIMES]; 370 BN_ULONG delta,d; 371 372again: 373 if (!BN_rand(rnd,bits,1,1)) return(0); 374 /* we now have a random number 'rand' to test. */ 375 for (i=1; i<NUMPRIMES; i++) 376 mods[i]=BN_mod_word(rnd,(BN_ULONG)primes[i]); 377 delta=0; 378 loop: for (i=1; i<NUMPRIMES; i++) 379 { 380 /* check that rnd is not a prime and also 381 * that gcd(rnd-1,primes) == 1 (except for 2) */ 382 if (((mods[i]+delta)%primes[i]) <= 1) 383 { 384 d=delta; 385 delta+=2; 386 /* perhaps need to check for overflow of 387 * delta (but delta can be up to 2^32) 388 * 21-May-98 eay - added overflow check */ 389 if (delta < d) goto again; 390 goto loop; 391 } 392 } 393 if (!BN_add_word(rnd,delta)) return(0); 394 return(1); 395 } 396 397static int probable_prime_dh(BIGNUM *rnd, int bits, BIGNUM *add, BIGNUM *rem, 398 BN_CTX *ctx) 399 { 400 int i,ret=0; 401 BIGNUM *t1; 402 403 BN_CTX_start(ctx); 404 if ((t1 = BN_CTX_get(ctx)) == NULL) goto err; 405 406 if (!BN_rand(rnd,bits,0,1)) goto err; 407 408 /* we need ((rnd-rem) % add) == 0 */ 409 410 if (!BN_mod(t1,rnd,add,ctx)) goto err; 411 if (!BN_sub(rnd,rnd,t1)) goto err; 412 if (rem == NULL) 413 { if (!BN_add_word(rnd,1)) goto err; } 414 else 415 { if (!BN_add(rnd,rnd,rem)) goto err; } 416 417 /* we now have a random number 'rand' to test. */ 418 419 loop: for (i=1; i<NUMPRIMES; i++) 420 { 421 /* check that rnd is a prime */ 422 if (BN_mod_word(rnd,(BN_ULONG)primes[i]) <= 1) 423 { 424 if (!BN_add(rnd,rnd,add)) goto err; 425 goto loop; 426 } 427 } 428 ret=1; 429err: 430 BN_CTX_end(ctx); 431 return(ret); 432 } 433 434static int probable_prime_dh_safe(BIGNUM *p, int bits, BIGNUM *padd, 435 BIGNUM *rem, BN_CTX *ctx) 436 { 437 int i,ret=0; 438 BIGNUM *t1,*qadd,*q; 439 440 bits--; 441 BN_CTX_start(ctx); 442 t1 = BN_CTX_get(ctx); 443 q = BN_CTX_get(ctx); 444 qadd = BN_CTX_get(ctx); 445 if (qadd == NULL) goto err; 446 447 if (!BN_rshift1(qadd,padd)) goto err; 448 449 if (!BN_rand(q,bits,0,1)) goto err; 450 451 /* we need ((rnd-rem) % add) == 0 */ 452 if (!BN_mod(t1,q,qadd,ctx)) goto err; 453 if (!BN_sub(q,q,t1)) goto err; 454 if (rem == NULL) 455 { if (!BN_add_word(q,1)) goto err; } 456 else 457 { 458 if (!BN_rshift1(t1,rem)) goto err; 459 if (!BN_add(q,q,t1)) goto err; 460 } 461 462 /* we now have a random number 'rand' to test. */ 463 if (!BN_lshift1(p,q)) goto err; 464 if (!BN_add_word(p,1)) goto err; 465 466 loop: for (i=1; i<NUMPRIMES; i++) 467 { 468 /* check that p and q are prime */ 469 /* check that for p and q 470 * gcd(p-1,primes) == 1 (except for 2) */ 471 if ( (BN_mod_word(p,(BN_ULONG)primes[i]) == 0) || 472 (BN_mod_word(q,(BN_ULONG)primes[i]) == 0)) 473 { 474 if (!BN_add(p,p,padd)) goto err; 475 if (!BN_add(q,q,qadd)) goto err; 476 goto loop; 477 } 478 } 479 ret=1; 480err: 481 BN_CTX_end(ctx); 482 return(ret); 483 } 484