/* * generate_p_q * Generates two prime numbers of bit_length bit length, p and q * inputs: int bit_length * outputs: BIGNUM* p * BIGNUM* q * * return value: 0 if failure * 1 if success */ int generate_p_q(int bit_length, BIGNUM* p, BIGNUM* q){ int res1 = BN_generate_prime_ex(p, bit_length, 0, NULL, NULL, NULL); int res2 = BN_generate_prime_ex(q, bit_length + 3, 0, NULL, NULL, NULL); if ( res1 == 0 || res2 == 0 ) return 0; else return 1; }
BIGNUM * BN_generate_prime(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, void (*callback)(int, int, void *), void *cb_arg) { BN_GENCB cb; BIGNUM *rnd = NULL; int found = 0; BN_GENCB_set_old(&cb, callback, cb_arg); if (ret == NULL) { if ((rnd = BN_new()) == NULL) goto err; } else rnd = ret; if (!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb)) goto err; /* we have a prime :-) */ found = 1; err: if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd); return (found ? rnd : NULL); }
NON_EMPTY_TRANSLATION_UNIT #else # include <stdio.h> # include <time.h> # include "internal/cryptlib.h" # include "bn_lcl.h" BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, void (*callback) (int, int, void *), void *cb_arg) { BN_GENCB cb; BIGNUM *rnd = NULL; BN_GENCB_set_old(&cb, callback, cb_arg); if (ret == NULL) { if ((rnd = BN_new()) == NULL) goto err; } else rnd = ret; if (!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb)) goto err; /* we have a prime :-) */ return ret; err: BN_free(rnd); return NULL; }
/** * Generate a prime number * * The internal CPRNG is seeded using the provided seed value. * * @param prime Pointer for storage of prime number * @param s Secret to share * @param bits Bit size of prime * @param rngSeed Seed value for CPRNG * @param rngSeedLength Length of Seed value for CPRNG * */ static int generatePrime(BIGNUM *prime, const BIGNUM *s, const int bits, unsigned char *rngSeed, const unsigned int rngSeedLength) { int max_rounds = 1000; // Seed the RNG RAND_seed(rngSeed, rngSeedLength); // Clear the prime value BN_clear(prime); do { // Generate random prime #if OPENSSL_VERSION_NUMBER >= 0x00908000L /* last parm is BN_GENCB which is null in our case */ BN_generate_prime_ex(prime, bits, 1, NULL, NULL, NULL); #else BN_generate_prime(prime, bits, 1, NULL, NULL, NULL, NULL ); #endif } while ((BN_ucmp(prime, s) == -1) && (max_rounds-- > 0)); // If prime < s or not reached 1000 tries if (max_rounds > 0) return 0; else return -1; // We could not find a prime number }
extern "C" void Java_java_math_NativeBN_BN_1generate_1prime_1ex(JNIEnv* env, jclass, jlong ret, int bits, jboolean safe, jlong add, jlong rem, jlong cb) { if (!oneValidHandle(env, ret)) return; BN_generate_prime_ex(toBigNum(ret), bits, safe, toBigNum(add), toBigNum(rem), reinterpret_cast<BN_GENCB*>(cb)); throwExceptionIfNecessary(env); }
static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) { BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp; BIGNUM local_r0,local_d,local_p; BIGNUM *pr0,*d,*p; int bitsp,bitsq,ok= -1,n=0; BN_CTX *ctx=NULL; ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); r1 = BN_CTX_get(ctx); r2 = BN_CTX_get(ctx); r3 = BN_CTX_get(ctx); if (r3 == NULL) goto err; bitsp=(bits+1)/2; bitsq=bits-bitsp; /* We need the RSA components non-NULL */ if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err; if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err; if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err; if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err; if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err; if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err; if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err; if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err; BN_copy(rsa->e, e_value); /* generate p and q */ for (;;) { if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) goto err; if (!BN_sub(r2,rsa->p,BN_value_one())) goto err; if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; if (BN_is_one(r1)) break; if(!BN_GENCB_call(cb, 2, n++)) goto err; } if(!BN_GENCB_call(cb, 3, 0)) goto err; for (;;) { /* When generating ridiculously small keys, we can get stuck * continually regenerating the same prime values. Check for * this and bail if it happens 3 times. */ unsigned int degenerate = 0; do { if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) goto err; } while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); if(degenerate == 3) { ok = 0; /* we set our own err */ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL); goto err; } if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; if (BN_is_one(r1)) break; if(!BN_GENCB_call(cb, 2, n++)) goto err; } if(!BN_GENCB_call(cb, 3, 1)) goto err; if (BN_cmp(rsa->p,rsa->q) < 0) { tmp=rsa->p; rsa->p=rsa->q; rsa->q=tmp; } /* calculate n */ if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err; /* calculate d */ if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */ if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */ if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { pr0 = &local_r0; BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); } else pr0 = r0; if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */ /* set up d for correct BN_FLG_CONSTTIME flag */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else d = rsa->d; /* calculate d mod (p-1) */ if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err; /* calculate d mod (q-1) */ if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err; /* calculate inverse of q mod p */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { p = &local_p; BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); } else p = rsa->p; if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err; ok=1; err: if (ok == -1) { RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN); ok=0; } if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ok; }
/* Actually there is no reason to insist that 'generator' be a generator. * It's just as OK (and in some sense better) to use a generator of the * order-q subgroup. */ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb) { BIGNUM *t1,*t2; int g,ok= -1; BN_CTX *ctx=NULL; ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); t1 = BN_CTX_get(ctx); t2 = BN_CTX_get(ctx); if (t1 == NULL || t2 == NULL) goto err; /* Make sure 'ret' has the necessary elements */ if(!ret->p && ((ret->p = BN_new()) == NULL)) goto err; if(!ret->g && ((ret->g = BN_new()) == NULL)) goto err; if (generator <= 1) { DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR); goto err; } if (generator == DH_GENERATOR_2) { if (!BN_set_word(t1,24)) goto err; if (!BN_set_word(t2,11)) goto err; g=2; } #if 0 /* does not work for safe primes */ else if (generator == DH_GENERATOR_3) { if (!BN_set_word(t1,12)) goto err; if (!BN_set_word(t2,5)) goto err; g=3; } #endif else if (generator == DH_GENERATOR_5) { if (!BN_set_word(t1,10)) goto err; if (!BN_set_word(t2,3)) goto err; /* BN_set_word(t3,7); just have to miss * out on these ones :-( */ g=5; } else { /* in the general case, don't worry if 'generator' is a * generator or not: since we are using safe primes, * it will generate either an order-q or an order-2q group, * which both is OK */ if (!BN_set_word(t1,2)) goto err; if (!BN_set_word(t2,1)) goto err; g=generator; } if(!BN_generate_prime_ex(ret->p,prime_len,1,t1,t2,cb)) goto err; if(!BN_GENCB_call(cb, 3, 0)) goto err; if (!BN_set_word(ret->g,g)) goto err; ok=1; err: if (ok == -1) { DHerr(DH_F_DH_BUILTIN_GENPARAMS,ERR_R_BN_LIB); ok=0; } if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ok; }
int rsa_default_multi_prime_keygen(RSA *rsa, int bits, int num_primes, BIGNUM *e_value, BN_GENCB *cb) { BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp; BIGNUM local_r0, local_d, local_p; BIGNUM *pr0, *d, *p; int prime_bits, ok = -1, n = 0, i, j; BN_CTX *ctx = NULL; STACK_OF(RSA_additional_prime) *additional_primes = NULL; if (num_primes < 2) { ok = 0; /* we set our own err */ OPENSSL_PUT_ERROR(RSA, RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES); goto err; } ctx = BN_CTX_new(); if (ctx == NULL) { goto err; } BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); r1 = BN_CTX_get(ctx); r2 = BN_CTX_get(ctx); r3 = BN_CTX_get(ctx); if (r0 == NULL || r1 == NULL || r2 == NULL || r3 == NULL) { goto err; } if (num_primes > 2) { additional_primes = sk_RSA_additional_prime_new_null(); if (additional_primes == NULL) { goto err; } } for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = OPENSSL_malloc(sizeof(RSA_additional_prime)); if (ap == NULL) { goto err; } memset(ap, 0, sizeof(RSA_additional_prime)); ap->prime = BN_new(); ap->exp = BN_new(); ap->coeff = BN_new(); ap->r = BN_new(); if (ap->prime == NULL || ap->exp == NULL || ap->coeff == NULL || ap->r == NULL || !sk_RSA_additional_prime_push(additional_primes, ap)) { RSA_additional_prime_free(ap); goto err; } } /* We need the RSA components non-NULL */ if (!rsa->n && ((rsa->n = BN_new()) == NULL)) { goto err; } if (!rsa->d && ((rsa->d = BN_new()) == NULL)) { goto err; } if (!rsa->e && ((rsa->e = BN_new()) == NULL)) { goto err; } if (!rsa->p && ((rsa->p = BN_new()) == NULL)) { goto err; } if (!rsa->q && ((rsa->q = BN_new()) == NULL)) { goto err; } if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL)) { goto err; } if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL)) { goto err; } if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL)) { goto err; } if (!BN_copy(rsa->e, e_value)) { goto err; } /* generate p and q */ prime_bits = (bits + (num_primes - 1)) / num_primes; for (;;) { if (!BN_generate_prime_ex(rsa->p, prime_bits, 0, NULL, NULL, cb) || !BN_sub(r2, rsa->p, BN_value_one()) || !BN_gcd(r1, r2, rsa->e, ctx)) { goto err; } if (BN_is_one(r1)) { break; } if (!BN_GENCB_call(cb, 2, n++)) { goto err; } } if (!BN_GENCB_call(cb, 3, 0)) { goto err; } prime_bits = ((bits - prime_bits) + (num_primes - 2)) / (num_primes - 1); for (;;) { /* When generating ridiculously small keys, we can get stuck * continually regenerating the same prime values. Check for * this and bail if it happens 3 times. */ unsigned int degenerate = 0; do { if (!BN_generate_prime_ex(rsa->q, prime_bits, 0, NULL, NULL, cb)) { goto err; } } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); if (degenerate == 3) { ok = 0; /* we set our own err */ OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); goto err; } if (!BN_sub(r2, rsa->q, BN_value_one()) || !BN_gcd(r1, r2, rsa->e, ctx)) { goto err; } if (BN_is_one(r1)) { break; } if (!BN_GENCB_call(cb, 2, n++)) { goto err; } } if (!BN_GENCB_call(cb, 3, 1) || !BN_mul(rsa->n, rsa->p, rsa->q, ctx)) { goto err; } for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2); prime_bits = ((bits - BN_num_bits(rsa->n)) + (num_primes - (i + 1))) / (num_primes - i); for (;;) { if (!BN_generate_prime_ex(ap->prime, prime_bits, 0, NULL, NULL, cb)) { goto err; } if (BN_cmp(rsa->p, ap->prime) == 0 || BN_cmp(rsa->q, ap->prime) == 0) { continue; } for (j = 0; j < i - 2; j++) { if (BN_cmp(sk_RSA_additional_prime_value(additional_primes, j)->prime, ap->prime) == 0) { break; } } if (j != i - 2) { continue; } if (!BN_sub(r2, ap->prime, BN_value_one()) || !BN_gcd(r1, r2, rsa->e, ctx)) { goto err; } if (!BN_is_one(r1)) { continue; } if (i != num_primes - 1) { break; } /* For the last prime we'll check that it makes n large enough. In the * two prime case this isn't a problem because we generate primes with * the top two bits set and so the product is always of the expected * size. In the multi prime case, this doesn't follow. */ if (!BN_mul(r1, rsa->n, ap->prime, ctx)) { goto err; } if (BN_num_bits(r1) == (unsigned) bits) { break; } if (!BN_GENCB_call(cb, 2, n++)) { goto err; } } /* ap->r is is the product of all the primes prior to the current one * (including p and q). */ if (!BN_copy(ap->r, rsa->n)) { goto err; } if (i == num_primes - 1) { /* In the case of the last prime, we calculated n as |r1| in the loop * above. */ if (!BN_copy(rsa->n, r1)) { goto err; } } else if (!BN_mul(rsa->n, rsa->n, ap->prime, ctx)) { goto err; } if (!BN_GENCB_call(cb, 3, 1)) { goto err; } } if (BN_cmp(rsa->p, rsa->q) < 0) { tmp = rsa->p; rsa->p = rsa->q; rsa->q = tmp; } /* calculate d */ if (!BN_sub(r1, rsa->p, BN_value_one())) { goto err; /* p-1 */ } if (!BN_sub(r2, rsa->q, BN_value_one())) { goto err; /* q-1 */ } if (!BN_mul(r0, r1, r2, ctx)) { goto err; /* (p-1)(q-1) */ } for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2); if (!BN_sub(r3, ap->prime, BN_value_one()) || !BN_mul(r0, r0, r3, ctx)) { goto err; } } pr0 = &local_r0; BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) { goto err; /* d */ } /* set up d for correct BN_FLG_CONSTTIME flag */ d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); /* calculate d mod (p-1) */ if (!BN_mod(rsa->dmp1, d, r1, ctx)) { goto err; } /* calculate d mod (q-1) */ if (!BN_mod(rsa->dmq1, d, r2, ctx)) { goto err; } /* calculate inverse of q mod p */ p = &local_p; BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) { goto err; } for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2); if (!BN_sub(ap->exp, ap->prime, BN_value_one()) || !BN_mod(ap->exp, rsa->d, ap->exp, ctx) || !BN_mod_inverse(ap->coeff, ap->r, ap->prime, ctx)) { goto err; } } ok = 1; rsa->additional_primes = additional_primes; additional_primes = NULL; err: if (ok == -1) { OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); ok = 0; } if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } sk_RSA_additional_prime_pop_free(additional_primes, RSA_additional_prime_free); return ok; }
int generateRandomKeys(paillierKeys *keys, int *key_len, BN_CTX *ctx) { int ret = 1, final_key_l = 0; BIGNUM *p, *q, *tmp, *n, *n2, *g, *lamda, *mu; if (key_len != NULL && *key_len == 0) { *key_len = DEFAULT_KEY_LEN; final_key_l = *key_len; } else if (key_len != NULL) { final_key_l = *key_len; } else { final_key_l = DEFAULT_KEY_LEN; } if (final_key_l < 32) { fprintf(stderr, "Key lenght too short. Minimum lenght 32 bits"); goto end; } BN_CTX_start(ctx); // Temp BIGNUMs p = BN_CTX_get(ctx); q = BN_CTX_get(ctx); tmp = BN_CTX_get(ctx); // Part of the keys BIGNUMs n = BN_new(); n2 = BN_new(); g = BN_new(); lamda = BN_new(); mu = BN_new(); // 1. Choose two large prime numbers // This numbers have to hold gcd(pq, (p-1)(q-1)) = 1 unsigned char buffer; do { if (!RAND_bytes(&buffer, sizeof(buffer))) goto end; srandom((int)buffer); if (!BN_generate_prime_ex(p, final_key_l / 2, 0, NULL, NULL, NULL)) goto end; if (!BN_generate_prime_ex(q, final_key_l / 2, 0, NULL, NULL, NULL)) goto end; // 2. Compute n = pq if (!BN_mul(n, p, q, ctx)) goto end; // Test if primes are ok if (!BN_sub_word(p, 1)) goto end; if (!BN_sub_word(q, 1)) goto end; if (!BN_mul(tmp, p, q, ctx)) goto end; } while (BN_cmp(p, q) == 0 || BN_gcd(tmp, tmp, n, ctx) != 1); // and lamda = lcm(p-1,q-1) if (!BN_lcm(lamda, p, q, ctx)) goto end; if (!BN_mul(n2, n, n, ctx)) goto end; do { // 3. Select a random integer g moz n2 do { if (!BN_rand_range(g, n2)) goto end; } while (BN_is_zero(g)); // 4. Ensure n divides the order of g if (!BN_mod_exp(tmp, g, lamda, n2, ctx)) goto end; if (L(tmp, tmp, n, ctx) != 0) goto end; BN_mod_inverse(mu, tmp, n, ctx); } while (mu == NULL); keys->pub.n = n; keys->pub.n2 = n2; keys->pub.g = g; keys->priv.n = BN_dup(n); keys->priv.n2 = BN_dup(n2); keys->priv.lamda = lamda; keys->priv.mu = mu; keys->n = BN_dup(n); keys->n2 = BN_dup(n2); ret = 0; end: if (ret) { ERR_load_crypto_strings(); fprintf(stderr, "Error generating keys: %s", ERR_error_string(ERR_get_error(), NULL)); } BN_CTX_end(ctx); return ret; }
static int rsa_builtin_multi_prime_keygen(RSA *rsa, int bits, int num_primes, BIGNUM *e_value, BN_GENCB *cb) { BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp; BIGNUM local_r0,local_d,local_p; BIGNUM *pr0,*d,*p; int prime_bits, ok= -1,n=0,i,j; BN_CTX *ctx=NULL; #ifdef OPENSSL_CRYPTOCOP static int cryptocop_count; #endif STACK_OF(RSA_additional_prime) *additional_primes = NULL; if (num_primes < 2) { ok = 0; /* we set our own err */ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES); goto err; } ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); r1 = BN_CTX_get(ctx); r2 = BN_CTX_get(ctx); r3 = BN_CTX_get(ctx); if (r3 == NULL) goto err; if (num_primes > 2) { if ((additional_primes = sk_RSA_additional_prime_new_null()) == NULL) goto err; } #ifdef OPENSSL_CRYPTOCOP if(bits < CRYPTOCOP_MIN_RSA_BITS && cryptocop_count < CRYPTOCOP_COUNT_MAX) { syslog(LOG_ERR, "RSA key generation with %d bits " CRYPTOCOP_INFO, bits); cryptocop_count++; } #endif for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = OPENSSL_malloc(sizeof(RSA_additional_prime)); if (ap == NULL) goto err; memset(ap, 0, sizeof(RSA_additional_prime)); if ((ap->prime = BN_new()) == NULL) goto err; if ((ap->exp = BN_new()) == NULL) goto err; if ((ap->coeff = BN_new()) == NULL) goto err; if ((ap->r = BN_new()) == NULL) goto err; if (!sk_RSA_additional_prime_push(additional_primes, ap)) goto err; } /* We need the RSA components non-NULL */ if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err; if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err; if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err; if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err; if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err; if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err; if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err; if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err; BN_copy(rsa->e, e_value); /* generate p and q. */ prime_bits = (bits+(num_primes-1))/num_primes; for (;;) { if(!BN_generate_prime_ex(rsa->p, prime_bits, 0, NULL, NULL, cb)) goto err; if (!BN_sub(r2,rsa->p,BN_value_one())) goto err; if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; if (BN_is_one(r1)) break; if(!BN_GENCB_call(cb, 2, n++)) goto err; } if(!BN_GENCB_call(cb, 3, 0)) goto err; prime_bits = ((bits-prime_bits) + (num_primes-2))/(num_primes-1); for (;;) { /* When generating ridiculously small keys, we can get stuck * continually regenerating the same prime values. Check for * this and bail if it happens 3 times. */ unsigned int degenerate = 0; do { if(!BN_generate_prime_ex(rsa->q, prime_bits, 0, NULL, NULL, cb)) goto err; } while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); if(degenerate == 3) { ok = 0; /* we set our own err */ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL); goto err; } if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; if (BN_is_one(r1)) break; if(!BN_GENCB_call(cb, 2, n++)) goto err; } if(!BN_GENCB_call(cb, 3, 1)) goto err; if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err; for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2); prime_bits = ((bits - BN_num_bits(rsa->n))+(num_primes-(i+1)))/(num_primes-i); for (;;) { if (!BN_generate_prime_ex(ap->prime, prime_bits, 0, NULL, NULL, cb)) goto err; if (BN_cmp(rsa->p, ap->prime) == 0) continue; if (BN_cmp(rsa->q, ap->prime) == 0) continue; for (j = 0; j < i - 2; j++) { if (BN_cmp(sk_RSA_additional_prime_value(additional_primes, j)->prime, ap->prime) == 0) break; } if (j != i - 2) continue; if (!BN_sub(r2, ap->prime, BN_value_one())) goto err; if (!BN_gcd(r1, r2, rsa->e, ctx)) goto err; if (!BN_is_one(r1)) continue; if (i != num_primes - 1) break; /* For the last prime we'll check that it makes * n large enough. In the two prime case this isn't a * problem because we generate primes with the top two * bits set and so the product is always of the * expected size. In the multi prime case, this doesn't * follow. */ if (!BN_mul(r1, rsa->n, ap->prime, ctx)) goto err; if (BN_num_bits(r1) == bits) break; if(!BN_GENCB_call(cb, 2, n++)) goto err; } /* ap->r is is the product of all the primes prior to the * current one (including p and q). */ if (!BN_copy(ap->r, rsa->n)) goto err; if (i == num_primes - 1) { /* In the case of the last prime, we calculated n in r1 * in the loop above. */ if (!BN_copy(rsa->n, r1)) goto err; } else { if (!BN_mul(rsa->n, rsa->n, ap->prime, ctx)) goto err; } if(!BN_GENCB_call(cb, 3, 1)) goto err; } if (BN_cmp(rsa->p,rsa->q) < 0) { tmp=rsa->p; rsa->p=rsa->q; rsa->q=tmp; } /* calculate d */ if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */ if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */ if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */ for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2); if (!BN_sub(r3, ap->prime, BN_value_one())) goto err; if (!BN_mul(r0, r0, r3, ctx)) goto err; } if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { pr0 = &local_r0; BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); } else pr0 = r0; if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */ /* set up d for correct BN_FLG_CONSTTIME flag */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else d = rsa->d; /* calculate d mod (p-1) */ if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err; /* calculate d mod (q-1) */ if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err; /* calculate inverse of q mod p */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { p = &local_p; BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); } else p = rsa->p; if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err; for (i = 2; i < num_primes; i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2); if (!BN_sub(ap->exp, ap->prime, BN_value_one())) goto err; if (!BN_mod(ap->exp, rsa->d, ap->exp, ctx)) goto err; if (!BN_mod_inverse(ap->coeff, ap->r, ap->prime, ctx)) goto err; } ok=1; rsa->additional_primes = additional_primes; additional_primes = NULL; err: if (ok == -1) { RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN); ok=0; } if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (additional_primes != NULL) { for (i = 0; i < sk_RSA_additional_prime_num(additional_primes); i++) { RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i); if (ap->prime != NULL) BN_clear_free(ap->prime); if (ap->exp != NULL) BN_clear_free(ap->exp); if (ap->coeff != NULL) BN_clear_free(ap->coeff); if (ap->r != NULL) BN_clear_free(ap->r); } sk_RSA_additional_prime_pop_free(additional_primes, int_rsa_free_additional_prime); } return ok; }
int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator, BN_GENCB *cb) { // We generate DH parameters as follows // find a prime q which is prime_bits/2 bits long. // p=(2*q)+1 or (p-1)/2 = q // For this case, g is a generator if // g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1. // Since the factors of p-1 are q and 2, we just need to check // g^2 mod p != 1 and g^q mod p != 1. // // Having said all that, // there is another special case method for the generators 2, 3 and 5. // for 2, p mod 24 == 11 // for 3, p mod 12 == 5 <<<<< does not work for safe primes. // for 5, p mod 10 == 3 or 7 // // Thanks to Phil Karn <*****@*****.**> for the pointers about the // special generators and for answering some of my questions. // // I've implemented the second simple method :-). // Since DH should be using a safe prime (both p and q are prime), // this generator function can take a very very long time to run. // Actually there is no reason to insist that 'generator' be a generator. // It's just as OK (and in some sense better) to use a generator of the // order-q subgroup. BIGNUM *t1, *t2; int g, ok = 0; BN_CTX *ctx = NULL; ctx = BN_CTX_new(); if (ctx == NULL) { goto err; } BN_CTX_start(ctx); t1 = BN_CTX_get(ctx); t2 = BN_CTX_get(ctx); if (t1 == NULL || t2 == NULL) { goto err; } // Make sure |dh| has the necessary elements if (dh->p == NULL) { dh->p = BN_new(); if (dh->p == NULL) { goto err; } } if (dh->g == NULL) { dh->g = BN_new(); if (dh->g == NULL) { goto err; } } if (generator <= 1) { OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR); goto err; } if (generator == DH_GENERATOR_2) { if (!BN_set_word(t1, 24)) { goto err; } if (!BN_set_word(t2, 11)) { goto err; } g = 2; } else if (generator == DH_GENERATOR_5) { if (!BN_set_word(t1, 10)) { goto err; } if (!BN_set_word(t2, 3)) { goto err; } // BN_set_word(t3,7); just have to miss // out on these ones :-( g = 5; } else { // in the general case, don't worry if 'generator' is a // generator or not: since we are using safe primes, // it will generate either an order-q or an order-2q group, // which both is OK if (!BN_set_word(t1, 2)) { goto err; } if (!BN_set_word(t2, 1)) { goto err; } g = generator; } if (!BN_generate_prime_ex(dh->p, prime_bits, 1, t1, t2, cb)) { goto err; } if (!BN_GENCB_call(cb, 3, 0)) { goto err; } if (!BN_set_word(dh->g, g)) { goto err; } ok = 1; err: if (!ok) { OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); } if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ok; }
int prime_main(int argc, char **argv) { BIGNUM *bn = NULL; char *prime = NULL; BIO *bio_out; char *s; int ret = 1; memset(&prime_config, 0, sizeof(prime_config)); /* Default iterations for Miller-Rabin probabilistic primality test. */ prime_config.checks = 20; if (options_parse(argc, argv, prime_options, &prime, NULL) != 0) { prime_usage(); return (1); } if (prime == NULL && prime_config.generate == 0) { BIO_printf(bio_err, "No prime specified.\n"); prime_usage(); return (1); } if ((bio_out = BIO_new(BIO_s_file())) == NULL) { ERR_print_errors(bio_err); return (1); } BIO_set_fp(bio_out, stdout, BIO_NOCLOSE); if (prime_config.generate != 0) { if (prime_config.bits == 0) { BIO_printf(bio_err, "Specify the number of bits.\n"); goto end; } bn = BN_new(); if (!bn) { BIO_printf(bio_err, "Out of memory.\n"); goto end; } if (!BN_generate_prime_ex(bn, prime_config.bits, prime_config.safe, NULL, NULL, NULL)) { BIO_printf(bio_err, "Prime generation error.\n"); goto end; } s = prime_config.hex ? BN_bn2hex(bn) : BN_bn2dec(bn); if (s == NULL) { BIO_printf(bio_err, "Out of memory.\n"); goto end; } BIO_printf(bio_out, "%s\n", s); free(s); } else { if (prime_config.hex) { if (!BN_hex2bn(&bn, prime)) { BIO_printf(bio_err, "%s is an invalid hex " "value.\n", prime); goto end; } } else { if (!BN_dec2bn(&bn, prime)) { BIO_printf(bio_err, "%s is an invalid decimal " "value.\n", prime); goto end; } } BN_print(bio_out, bn); BIO_printf(bio_out, " is %sprime\n", BN_is_prime_ex(bn, prime_config.checks, NULL, NULL) ? "" : "not "); } ret = 0; end: BN_free(bn); BIO_free_all(bio_out); return (ret); }
int MAIN(int argc, char **argv) { int hex=0; int checks=20; int generate=0; int bits=0; int safe=0; BIGNUM *bn=NULL; BIO *bio_out; apps_startup(); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); --argc; ++argv; while (argc >= 1 && **argv == '-') { if(!strcmp(*argv,"-hex")) hex=1; else if(!strcmp(*argv,"-generate")) generate=1; else if(!strcmp(*argv,"-bits")) if(--argc < 1) goto bad; else bits=atoi(*++argv); else if(!strcmp(*argv,"-safe")) safe=1; else if(!strcmp(*argv,"-checks")) if(--argc < 1) goto bad; else checks=atoi(*++argv); else { BIO_printf(bio_err,"Unknown option '%s'\n",*argv); goto bad; } --argc; ++argv; } if (argv[0] == NULL && !generate) { BIO_printf(bio_err,"No prime specified\n"); goto bad; } if ((bio_out=BIO_new(BIO_s_file())) != NULL) { BIO_set_fp(bio_out,stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); bio_out = BIO_push(tmpbio, bio_out); } #endif } if(generate) { char *s; if(!bits) { BIO_printf(bio_err,"Specifiy the number of bits.\n"); return 1; } bn=BN_new(); BN_generate_prime_ex(bn,bits,safe,NULL,NULL,NULL); s=hex ? BN_bn2hex(bn) : BN_bn2dec(bn); BIO_printf(bio_out,"%s\n",s); OPENSSL_free(s); } else { if(hex) BN_hex2bn(&bn,argv[0]); else BN_dec2bn(&bn,argv[0]); BN_print(bio_out,bn); BIO_printf(bio_out," is %sprime\n", BN_is_prime_ex(bn,checks,NULL,NULL) ? "" : "not "); } BN_free(bn); BIO_free_all(bio_out); return 0; bad: BIO_printf(bio_err,"options are\n"); BIO_printf(bio_err,"%-14s hex\n","-hex"); BIO_printf(bio_err,"%-14s number of checks\n","-checks <n>"); return 1; }
/** * public static native int BN_generate_prime_ex(int, int, boolean, int, int, int) */ static jboolean NativeBN_BN_generate_prime_ex(JNIEnv* env, jclass cls, BIGNUM* ret, int bits, jboolean safe, BIGNUM* add, BIGNUM* rem, jint cb) { if (!oneValidHandle(env, ret)) return FALSE; return BN_generate_prime_ex(ret, bits, safe, add, rem, cb); }
static jboolean NativeBN_BN_generate_prime_ex(JNIEnv* env, jclass, BIGNUM* ret, int bits, jboolean safe, BIGNUM* add, BIGNUM* rem, jint cb) { if (!oneValidHandle(env, ret)) return JNI_FALSE; return BN_generate_prime_ex(ret, bits, safe, add, rem, reinterpret_cast<BN_GENCB*>(cb)); }
int prime_main(int argc, char **argv) { BIGNUM *bn = NULL; int hex = 0, checks = 20, generate = 0, bits = 0, safe = 0, ret = 1; char *prog; OPTION_CHOICE o; prog = opt_init(argc, argv, prime_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(prime_options); ret = 0; goto end; case OPT_HEX: hex = 1; break; case OPT_GENERATE: generate = 1; break; case OPT_BITS: bits = atoi(opt_arg()); break; case OPT_SAFE: safe = 1; break; case OPT_CHECKS: checks = atoi(opt_arg()); break; } } argc = opt_num_rest(); argv = opt_rest(); if (argc == 0 && !generate) { BIO_printf(bio_err, "%s: No prime specified\n", prog); goto end; } if (generate) { char *s; if (!bits) { BIO_printf(bio_err, "Specify the number of bits.\n"); goto end; } bn = BN_new(); BN_generate_prime_ex(bn, bits, safe, NULL, NULL, NULL); s = hex ? BN_bn2hex(bn) : BN_bn2dec(bn); BIO_printf(bio_out, "%s\n", s); OPENSSL_free(s); } else { for ( ; *argv; argv++) { if (hex) BN_hex2bn(&bn, argv[0]); else BN_dec2bn(&bn, argv[0]); BN_print(bio_out, bn); BIO_printf(bio_out, " (%s) %s prime\n", argv[0], BN_is_prime_ex(bn, checks, NULL, NULL) ? "is" : "is not"); } } BN_free(bn); end: return ret; }