static int fdt_add_bignum(void *blob, int noffset, const char *prop_name, BIGNUM *num, int num_bits) { int nwords = num_bits / 32; int size; uint32_t *buf, *ptr; BIGNUM *tmp, *big2, *big32, *big2_32; BN_CTX *ctx; int ret; tmp = BN_new(); big2 = BN_new(); big32 = BN_new(); big2_32 = BN_new(); if (!tmp || !big2 || !big32 || !big2_32) { fprintf(stderr, "Out of memory (bignum)\n"); return -ENOMEM; } ctx = BN_CTX_new(); if (!tmp) { fprintf(stderr, "Out of memory (bignum context)\n"); return -ENOMEM; } BN_set_word(big2, 2L); BN_set_word(big32, 32L); BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */ size = nwords * sizeof(uint32_t); buf = malloc(size); if (!buf) { fprintf(stderr, "Out of memory (%d bytes)\n", size); return -ENOMEM; } /* Write out modulus as big endian array of integers */ for (ptr = buf + nwords - 1; ptr >= buf; ptr--) { BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */ *ptr = cpu_to_fdt32(BN_get_word(tmp)); BN_rshift(num, num, 32); /* N = N/B */ } /* We try signing with successively increasing size values, so this * might fail several times */ ret = fdt_setprop(blob, noffset, prop_name, buf, size); if (ret) return -FDT_ERR_NOSPACE; free(buf); BN_free(tmp); BN_free(big2); BN_free(big32); BN_free(big2_32); return ret; }
static int fdt_add_bignum(void *blob, int noffset, const char *prop_name, BIGNUM *num, int num_bits) { int nwords = num_bits / 32; int size; uint32_t *buf, *ptr; BIGNUM *tmp, *big2, *big32, *big2_32; BN_CTX *ctx; int ret; tmp = BN_new(); big2 = BN_new(); big32 = BN_new(); big2_32 = BN_new(); if (!tmp || !big2 || !big32 || !big2_32) { fprintf(stderr, "Out of memory (bignum)\n"); return -ENOMEM; } ctx = BN_CTX_new(); if (!tmp) { fprintf(stderr, "Out of memory (bignum context)\n"); return -ENOMEM; } BN_set_word(big2, 2L); BN_set_word(big32, 32L); BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */ size = nwords * sizeof(uint32_t); buf = malloc(size); if (!buf) { fprintf(stderr, "Out of memory (%d bytes)\n", size); return -ENOMEM; } /* Write out modulus as big endian array of integers */ for (ptr = buf + nwords - 1; ptr >= buf; ptr--) { BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */ *ptr = cpu_to_fdt32(BN_get_word(tmp)); BN_rshift(num, num, 32); /* N = N/B */ } ret = fdt_setprop(blob, noffset, prop_name, buf, size); if (ret) { fprintf(stderr, "Failed to write public key to FIT\n"); return -ENOSPC; } free(buf); BN_free(tmp); BN_free(big2); BN_free(big32); BN_free(big2_32); return ret; }
static int probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx) { int i, ret = 0; BIGNUM *t1; BN_CTX_start(ctx); if ((t1 = BN_CTX_get(ctx)) == NULL) { goto err; } if (!BN_rand(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) { goto err; } // we need ((rnd-rem) % add) == 0 if (!BN_mod(t1, rnd, add, ctx)) { goto err; } if (!BN_sub(rnd, rnd, t1)) { goto err; } if (rem == NULL) { if (!BN_add_word(rnd, 1)) { goto err; } } else { if (!BN_add(rnd, rnd, rem)) { goto err; } } // we now have a random number 'rand' to test. loop: for (i = 1; i < NUMPRIMES; i++) { // check that rnd is a prime BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]); if (mod == (BN_ULONG)-1) { goto err; } if (mod <= 1) { if (!BN_add(rnd, rnd, add)) { goto err; } goto loop; } } ret = 1; err: BN_CTX_end(ctx); return ret; }
/* calculate p-1 and q-1 */ void rsa_generate_additional_parameters(RSA *rsa) { BIGNUM *aux; BN_CTX *ctx; if ((aux = BN_new()) == NULL) fatal("rsa_generate_additional_parameters: BN_new failed"); if ((ctx = BN_CTX_new()) == NULL) fatal("rsa_generate_additional_parameters: BN_CTX_new failed"); if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || (BN_sub(aux, rsa->p, BN_value_one()) == 0) || (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) fatal("rsa_generate_additional_parameters: BN_sub/mod failed"); BN_clear_free(aux); BN_CTX_free(ctx); }
uint8_t sane_key(RSA *rsa) { // checks sanity of a RSA key (PKCS#1 v2.1) uint8_t sane = 1; BN_CTX *ctx = BN_CTX_new(); BN_CTX_start(ctx); BIGNUM *p1 = BN_CTX_get(ctx), // p - 1 *q1 = BN_CTX_get(ctx), // q - 1 *chk = BN_CTX_get(ctx), // storage to run checks with *gcd = BN_CTX_get(ctx), // GCD(p - 1, q - 1) *lambda = BN_CTX_get(ctx); // LCM(p - 1, q - 1) BN_sub(p1, rsa->p, BN_value_one()); // p - 1 BN_sub(q1, rsa->q, BN_value_one()); // q - 1 BN_gcd(gcd, p1, q1, ctx); // gcd(p - 1, q - 1) BN_lcm(lambda, p1, q1, gcd, ctx); // lambda(n) BN_gcd(chk, lambda, rsa->e, ctx); // check if e is coprime to lambda(n) if(!BN_is_one(chk)) sane = 0; // check if public exponent e is less than n - 1 BN_sub(chk, rsa->e, rsa->n); // subtract n from e to avoid checking BN_is_zero if(!chk->neg) sane = 0; BN_mod_inverse(rsa->d, rsa->e, lambda, ctx); // d BN_mod(rsa->dmp1, rsa->d, p1, ctx); // d mod (p - 1) BN_mod(rsa->dmq1, rsa->d, q1, ctx); // d mod (q - 1) BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx); // q ^ -1 mod p BN_CTX_end(ctx); BN_CTX_free(ctx); // this is excessive but you're better off safe than (very) sorry // in theory this should never be true unless I made a mistake ;) if((RSA_check_key(rsa) != 1) && sane) { fprintf(stderr, "WARNING: Key looked okay, but OpenSSL says otherwise!\n"); sane = 0; } return sane; }
int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) { /* like BN_mod, but returns non-negative remainder * (i.e., 0 <= r < |d| always holds) */ if (!(BN_mod(r,m,d,ctx))) return 0; if (!r->neg) return 1; /* now -|d| < r < 0, so we have to set r := r + |d| */ return (d->neg ? BN_sub : BN_add)(r, r, d); }
static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, const BIGNUM *rem, BN_CTX *ctx) { int i,ret=0; BIGNUM *t1,*qadd,*q; bits--; BN_CTX_start(ctx); t1 = BN_CTX_get(ctx); q = BN_CTX_get(ctx); qadd = BN_CTX_get(ctx); if (qadd == NULL) goto err; if (!BN_rshift1(qadd,padd)) goto err; if (!BN_rand(q,bits,0,1)) goto err; /* we need ((rnd-rem) % add) == 0 */ if (!BN_mod(t1,q,qadd,ctx)) goto err; if (!BN_sub(q,q,t1)) goto err; if (rem == NULL) { if (!BN_add_word(q,1)) goto err; } else { if (!BN_rshift1(t1,rem)) goto err; if (!BN_add(q,q,t1)) goto err; } /* we now have a random number 'rand' to test. */ if (!BN_lshift1(p,q)) goto err; if (!BN_add_word(p,1)) goto err; loop: for (i=1; i<NUMPRIMES; i++) { /* check that p and q are prime */ /* check that for p and q * gcd(p-1,primes) == 1 (except for 2) */ if ((BN_mod_word(p,(BN_ULONG)primes[i]) == 0) || (BN_mod_word(q,(BN_ULONG)primes[i]) == 0)) { if (!BN_add(p,p,padd)) goto err; if (!BN_add(q,q,qadd)) goto err; goto loop; } } ret=1; err: BN_CTX_end(ctx); bn_check_top(p); return(ret); }
BOOL rsautil_quickimport(RSA *rsa, BIGNUM *e_value, BIGNUM *p_value, BIGNUM *q_value, OPTIONAL BIGNUM *n_value) { BIGNUM *r0, *r1, *r2; BN_CTX *ctx; ctx = BN_CTX_new(); BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); r1 = BN_CTX_get(ctx); r2 = BN_CTX_get(ctx); rsa->n = BN_new(); rsa->d = BN_new(); rsa->e = BN_new(); rsa->p = BN_new(); rsa->q = BN_new(); rsa->dmp1 = BN_new(); rsa->dmq1 = BN_new(); rsa->iqmp = BN_new(); BN_copy(rsa->e, e_value); BN_copy(rsa->p, p_value); BN_copy(rsa->q, q_value); if(n_value) BN_copy(rsa->n, n_value); else BN_mul(rsa->n, rsa->p, rsa->q, ctx); BN_sub(r1, rsa->p, BN_value_one()); BN_sub(r2, rsa->q, BN_value_one()); BN_mul(r0, r1, r2, ctx); BN_mod_inverse(rsa->d, rsa->e, r0, ctx); BN_mod(rsa->dmp1, rsa->d, r1, ctx); BN_mod(rsa->dmq1, rsa->d, r2, ctx); BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx); BN_CTX_end(ctx); BN_CTX_free(ctx); return (RSA_check_key(rsa) == 1); }
/* calculate p-1 and q-1 */ static void rsa_generate_additional_parameters(RSA *rsa) { BIGNUM *aux = NULL; BN_CTX *ctx = NULL; if ((aux = BN_new()) == NULL) goto error; if ((ctx = BN_CTX_new()) == NULL) goto error; if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || (BN_sub(aux, rsa->p, BN_value_one()) == 0) || (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) goto error; error: if (aux) BN_clear_free(aux); if (ctx) BN_CTX_free(ctx); }
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) { BIGNUM Ri,*R; BN_init(&Ri); R= &(mont->RR); /* grab RR as a temp */ BN_copy(&(mont->N),mod); /* Set N */ { BIGNUM tmod; BN_ULONG buf[2]; mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; if (!(BN_zero(R))) goto err; if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */ buf[0]=mod->d[0]; /* tmod = N mod word size */ buf[1]=0; tmod.d=buf; tmod.top=1; tmod.dmax=2; tmod.neg=mod->neg; /* Ri = R^-1 mod N*/ if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL) goto err; /* R*Ri */ if (!(BN_lshift(&Ri,&Ri,BN_BITS2))) goto err; if (!BN_is_zero(&Ri)) { if (!BN_sub_word(&Ri,1)) goto err; } else /* if N mod word size == 1 */ /* Ri-- (mod word size) */ { if (!BN_set_word(&Ri,BN_MASK2)) goto err; } /* Ni = (R*Ri-1)/N, keep only least significant word: */ if (!(BN_div(&Ri,NULL,&Ri,&tmod,ctx))) goto err; mont->n0=Ri.d[0]; BN_free(&Ri); } /* setup RR for conversions */ if (!(BN_zero(&(mont->RR)))) goto err; if (!(BN_set_bit(&(mont->RR),mont->ri*2))) goto err; if (!(BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx))) goto err; return(1); err: return(0); }
/* given the password(string), use SHA1 to hash it and return the result mod q */ static void hashpassword(BIGNUM *hash_result, const char *password, BN_CTX *ctx, const BIGNUM *q) { SHA_CTX sha; size_t length = strlen(password); BIGNUM *hash_bn = BN_new(); unsigned char digest[SHA_DIGEST_LENGTH]; SHA1_Init(&sha); SHA1_Update(&sha, password, length); SHA1_Final(digest, &sha); BN_bin2bn(digest, SHA_DIGEST_LENGTH, hash_bn); BN_mod(hash_result, hash_bn, q, ctx); }
bool android_pubkey_encode(const RSA* key, uint8_t* key_buffer, size_t size) { RSAPublicKey* key_struct = (RSAPublicKey*)key_buffer; bool ret = false; BN_CTX* ctx = BN_CTX_new(); BIGNUM* r32 = BN_new(); BIGNUM* n0inv = BN_new(); BIGNUM* rr = BN_new(); if (sizeof(RSAPublicKey) > size || RSA_size(key) != ANDROID_PUBKEY_MODULUS_SIZE) { goto cleanup; } // Store the modulus size. key_struct->modulus_size_words = ANDROID_PUBKEY_MODULUS_SIZE_WORDS; // Compute and store n0inv = -1 / N[0] mod 2^32. if (!ctx || !r32 || !n0inv || !BN_set_bit(r32, 32) || !BN_mod(n0inv, key->n, r32, ctx) || !BN_mod_inverse(n0inv, n0inv, r32, ctx) || !BN_sub(n0inv, r32, n0inv)) { goto cleanup; } key_struct->n0inv = (uint32_t)BN_get_word(n0inv); // Store the modulus. if (!android_pubkey_encode_bignum(key->n, key_struct->modulus)) { goto cleanup; } // Compute and store rr = (2^(rsa_size)) ^ 2 mod N. if (!ctx || !rr || !BN_set_bit(rr, ANDROID_PUBKEY_MODULUS_SIZE * 8) || !BN_mod_sqr(rr, rr, key->n, ctx) || !android_pubkey_encode_bignum(rr, key_struct->rr)) { goto cleanup; } // Store the exponent. key_struct->exponent = (uint32_t)BN_get_word(key->e); ret = true; cleanup: BN_free(rr); BN_free(n0inv); BN_free(r32); BN_CTX_free(ctx); return ret; }
jstring Java_ch_ethz_inf_vs_talosmodule_cryptoalg_PaillierPrivNative_decryptpart(JNIEnv *env, jobject javaThis, jstring j_ciphertext, jstring j_p2, jstring j_a, jstring j_pinv, jstring j_two_p, jstring j_p, jstring j_hp) { BIGNUM *ciphertext, *p2, *a, *pinv, *two_p, *p, *hp; jstring* res; BIGNUM *temp = BN_new(); BIGNUM *temp_2 = BN_new(); BN_CTX *ctx = BN_CTX_new(); ciphertext = convert_to_bignum(env, j_ciphertext); p2 = convert_to_bignum(env, j_p2); a = convert_to_bignum(env, j_a); pinv = convert_to_bignum(env, j_pinv); two_p = convert_to_bignum(env, j_two_p); p = convert_to_bignum(env, j_p); hp = convert_to_bignum(env, j_hp); // temp = ciphertext % p2 BN_mod(temp, ciphertext, p2, ctx); // temp = g^(plaintext + n*r) % n2 BN_mod_exp(temp, temp, a, p2, ctx); Lfast(temp_2, temp, pinv, two_p, p); //temp = g^(plaintext + n*r) % n2 BN_mod_mul(temp, temp_2, hp, p, ctx); res = BN_to_jstring(env, temp); BN_CTX_free(ctx); BN_free(ciphertext); BN_free(p2); BN_free(a); BN_free(pinv); BN_free(two_p); BN_free(p); BN_free(hp); BN_free(temp); BN_free(temp_2); return res; }
int paillier_encrypt(BIGNUM *c, const BIGNUM *m, const pubKey *key, BN_CTX *ctx) { int ret = 1; BN_CTX_start(ctx); BIGNUM *r = BN_CTX_get(ctx); BIGNUM *tmp1 = BN_CTX_get(ctx); BIGNUM *tmp2 = BN_CTX_get(ctx); // 1. Let m be the message to be encrypted where m E Zn if (BN_cmp(m, key->n) >= 0) { fprintf(stderr, "Message not in Zn"); goto end; } // 2. Select random r where r E Zn* do { if (!BN_rand(r, DEFAULT_KEY_LEN, 0, 0)) goto end; } while (BN_is_zero(r)); if (!BN_mod(r, r, key->n, ctx)) goto end; // 3. Compute ciperthext as c = g^m*r^n mod n^2 if (!BN_mod_exp(tmp1, key->g, m, key->n2, ctx)) goto end; if (!BN_mod_exp(tmp2, r, key->n, key->n2, ctx)) goto end; if (!BN_mod_mul(c, tmp1, tmp2, key->n2, ctx)) goto end; ret = 0; end: if (ret) { ERR_load_crypto_strings(); fprintf(stderr, "Error ecnrypting: %s", ERR_error_string(ERR_get_error(), NULL)); } BN_CTX_end(ctx); return ret; }
//old BIGNUM *Egcd(const BIGNUM *n, const BIGNUM *m, BIGNUM *x, BIGNUM *y) { //print_bn("n", n); //print_bn("m", m); BIGNUM *value = BN_new(); BIGNUM *temp = BN_new(); BIGNUM *t1 = BN_new(); BIGNUM *t2 = BN_new(); BIGNUM *new_m = BN_new(); BN_CTX *ctx = BN_CTX_new(); if (BN_is_zero(m)) { BN_set_word(x, 1); BN_set_word(y, 0); value = BN_dup(n); //print_bn("x", x); //print_bn("y", y); return value; } BN_mod(new_m, n, m, ctx); //printf("called once\n"); value = BN_dup(Egcd(m, new_m, x, y)); print_bn("n", n); print_bn("m", m); print_bn("old_x", x); print_bn("old_y", y); temp = BN_dup(x); x = BN_dup(y); /* y = temp - (n/m) * y */ BN_div(t1, NULL, n, m, ctx); BN_mul(t2, t1, y, ctx); BN_sub(y, temp, t2); print_bn("x", x); print_bn("y", y); return value; }
BIGNUM * auth_rsa_generate_challenge(Key *key) { BIGNUM *challenge; BN_CTX *ctx; if ((challenge = BN_new()) == NULL) fatal("auth_rsa_generate_challenge: BN_new() failed"); /* Generate a random challenge. */ BN_rand(challenge, 256, 0, 0); if ((ctx = BN_CTX_new()) == NULL) fatal("auth_rsa_generate_challenge: BN_CTX_new() failed"); BN_mod(challenge, challenge, key->rsa->n, ctx); BN_CTX_free(ctx); return challenge; }
static int probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx) { int i, ret = 0; BIGNUM *t1; BN_CTX_start(ctx); if ((t1 = BN_CTX_get(ctx)) == NULL) goto err; if (!BN_rand(rnd, bits, 0, 1)) goto err; /* we need ((rnd-rem) % add) == 0 */ if (!BN_mod(t1, rnd, add, ctx)) goto err; if (!BN_sub(rnd, rnd, t1)) goto err; if (rem == NULL) { if (!BN_add_word(rnd, 1)) goto err; } else { if (!BN_add(rnd, rnd, rem)) goto err; } /* we now have a random number 'rand' to test. */ loop: for (i = 1; i < NUMPRIMES; i++) { /* check that rnd is a prime */ if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) { if (!BN_add(rnd, rnd, add)) goto err; goto loop; } } ret = 1; err: BN_CTX_end(ctx); bn_check_top(rnd); return (ret); }
qint32 CryptoUtils::checkDHParams (BIGNUM *p, qint32 g) { if (g < 2 || g > 7) { return -1; } BIGNUM t; BN_init (&t); BIGNUM dh_g; BN_init (&dh_g); Utils::ensure (BN_set_word (&dh_g, 4 * g)); Utils::ensure (BN_mod (&t, p, &dh_g, BN_ctx)); qint32 x = BN_get_word (&t); Q_ASSERT(x >= 0 && x < 4 * g); BN_free (&dh_g); switch (g) { case 2: if (x != 7) { return -1; } break; case 3: if (x % 3 != 2 ) { return -1; } break; case 4: break; case 5: if (x % 5 != 1 && x % 5 != 4) { return -1; } break; case 6: if (x != 19 && x != 23) { return -1; } break; case 7: if (x % 7 != 3 && x % 7 != 5 && x % 7 != 6) { return -1; } break; } if (!checkPrime (p)) { return -1; } BIGNUM b; BN_init (&b); Utils::ensure (BN_set_word (&b, 2)); Utils::ensure (BN_div (&t, 0, p, &b, BN_ctx)); if (!checkPrime (&t)) { return -1; } BN_free (&b); BN_free (&t); return 0; }
int test_mod(BIO *bp, BN_CTX *ctx) { BIGNUM *a,*b,*c,*d,*e; int i; a=BN_new(); b=BN_new(); c=BN_new(); d=BN_new(); e=BN_new(); BN_bntest_rand(a,1024,0,0); /**/ for (i=0; i<num0; i++) { BN_bntest_rand(b,450+i*10,0,0); /**/ a->neg=rand_neg(); b->neg=rand_neg(); BN_mod(c,a,b,ctx);/**/ if (bp != NULL) { if (!results) { BN_print(bp,a); BIO_puts(bp," % "); BN_print(bp,b); BIO_puts(bp," - "); } BN_print(bp,c); BIO_puts(bp,"\n"); } BN_div(d,e,a,b,ctx); BN_sub(e,e,c); if(!BN_is_zero(e)) { fprintf(stderr,"Modulo test failed!\n"); return 0; } } BN_free(a); BN_free(b); BN_free(c); BN_free(d); BN_free(e); return(1); }
/* Output: username, bytes_A, len_A, Astr */ const char * srp_user_start_authentication(SRPUser *usr) { BN_CTX *ctx = BN_CTX_new(); BN_mod_exp(usr->A, usr->ng->g, usr->a, usr->ng->N, ctx); BIGNUM *modCheck = BN_new(); BN_mod(modCheck, usr->A, usr->ng->N, ctx); BN_free(modCheck); BN_CTX_free(ctx); int len_A = BN_num_bytes(usr->A); unsigned char *bytes_A = malloc(len_A); BN_bn2bin(usr->A, bytes_A); usr->bytes_A = bytes_A; usr->Astr = convert_to_lower(BN_bn2hex(usr->A)); free(bytes_A); return usr->Astr; }
EC_POINT *embed(const polypseud_ctx *ctx, const unsigned char *data, const size_t len) { BIGNUM *t1 = BN_bin2bn(data, len, NULL); BIGNUM *x = BN_new(); BN_mod(x, t1, ctx->p, ctx->bn_ctx); EC_POINT *point = EC_POINT_new(ctx->ec_group); unsigned char counter = 0; int success = 0; while(!success) { success = EC_POINT_set_compressed_coordinates_GFp(ctx->ec_group, point, x, 1, ctx->bn_ctx); if(!success) { if(counter == 0) { BN_lshift(x, x, 8); } BN_add(x, x, BN_value_one()); } } BN_free(x); BN_free(t1); return point; }
private_key private_key::generate_from_seed( const fc::sha256& seed, const fc::sha256& offset ) { ssl_bignum z; BN_bin2bn((unsigned char*)&offset, sizeof(offset), z); ec_group group(EC_GROUP_new_by_curve_name(NID_secp256k1)); bn_ctx ctx(BN_CTX_new()); ssl_bignum order; EC_GROUP_get_order(group, order, ctx); // secexp = (seed + z) % order ssl_bignum secexp; BN_bin2bn((unsigned char*)&seed, sizeof(seed), secexp); BN_add(secexp, secexp, z); BN_mod(secexp, secexp, order, ctx); fc::sha256 secret; assert(BN_num_bytes(secexp) <= int64_t(sizeof(secret))); auto shift = sizeof(secret) - BN_num_bytes(secexp); BN_bn2bin(secexp, ((unsigned char*)&secret)+shift); return regenerate( secret ); }
int compute_scalar_element(REQUEST *request, pwd_session_t *session, BN_CTX *bn_ctx) { BIGNUM *mask = NULL; int ret = -1; MEM(session->private_value = BN_new()); MEM(session->my_element = EC_POINT_new(session->group)); MEM(session->my_scalar = BN_new()); MEM(mask = BN_new()); if (BN_rand_range(session->private_value, session->order) != 1) { REDEBUG("Unable to get randomness for private_value"); goto error; } if (BN_rand_range(mask, session->order) != 1) { REDEBUG("Unable to get randomness for mask"); goto error; } BN_add(session->my_scalar, session->private_value, mask); BN_mod(session->my_scalar, session->my_scalar, session->order, bn_ctx); if (!EC_POINT_mul(session->group, session->my_element, NULL, session->pwe, mask, bn_ctx)) { REDEBUG("Server element allocation failed"); goto error; } if (!EC_POINT_invert(session->group, session->my_element, bn_ctx)) { REDEBUG("Server element inversion failed"); goto error; } ret = 0; error: BN_clear_free(mask); return ret; }
static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g, BN_CTX *ctx) { BIGNUM *rem = NULL; if (BN_num_bits(p) != nmod) return 0; if (BN_num_bits(q) != 160) return 0; if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1) return 0; if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1) return 0; rem = BN_new(); if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem) || (BN_cmp(g, BN_value_one()) <= 0) || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem)) { BN_free(rem); return 0; } /* Todo: check g */ BN_free(rem); return 1; }
static void bmod(void) { struct number *a, *b; struct number *r; u_int scale; BN_CTX *ctx; a = pop_number(); if (a == NULL) { return; } b = pop_number(); if (b == NULL) { push_number(a); return; } r = new_number(); scale = max(a->scale, b->scale); r->scale = max(b->scale, a->scale + bmachine.scale); if (BN_is_zero(a->number)) warnx("remainder by zero"); else { normalize(a, scale); normalize(b, scale + bmachine.scale); ctx = BN_CTX_new(); bn_checkp(ctx); bn_check(BN_mod(r->number, b->number, a->number, ctx)); BN_CTX_free(ctx); } push_number(r); free_number(a); free_number(b); }
int compute_scalar_element (pwd_session_t *sess, BN_CTX *bnctx) { BIGNUM *mask = NULL; int ret = -1; if (((sess->private_value = BN_new()) == NULL) || ((sess->my_element = EC_POINT_new(sess->group)) == NULL) || ((sess->my_scalar = BN_new()) == NULL) || ((mask = BN_new()) == NULL)) { DEBUG2("server scalar allocation failed"); goto fail; } BN_rand_range(sess->private_value, sess->order); BN_rand_range(mask, sess->order); BN_add(sess->my_scalar, sess->private_value, mask); BN_mod(sess->my_scalar, sess->my_scalar, sess->order, bnctx); if (!EC_POINT_mul(sess->group, sess->my_element, NULL, sess->pwe, mask, bnctx)) { DEBUG2("server element allocation failed"); goto fail; } if (!EC_POINT_invert(sess->group, sess->my_element, bnctx)) { DEBUG2("server element inversion failed"); goto fail; } ret = 0; fail: BN_free(mask); return ret; }
static int get_key_bignum(BIGNUM *num, int num_bits, uint32_t *key_mod) { BIGNUM *tmp, *big2, *big32, *big2_32; BN_CTX *ctx; int ret; tmp = BN_new(); big2 = BN_new(); big32 = BN_new(); big2_32 = BN_new(); if (!tmp || !big2 || !big32 || !big2_32) { fprintf(stderr, "Out of memory (bignum)\n"); return -1; } ctx = BN_CTX_new(); if (!tmp) { fprintf(stderr, "Out of memory (bignum context)\n"); return -1; } BN_set_word(big2, 2L); BN_set_word(big32, 32L); BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */ for (ret = 0; ret <= 63; ret++) { BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */ key_mod[ret] = htonl(BN_get_word(tmp)); BN_rshift(num, num, 32); /* N = N/B */ } BN_free(tmp); BN_free(big2); BN_free(big32); BN_free(big2_32); return 0; }
int CREDLIB_mod_hash( BIGNUM* r, BIGNUM* n, BIGNUM* n2, byte* out, int out_len, BIGNUM* m, BN_CTX* ctx ) { EXCEPTION; SHA_CTX sha1; byte hash[ SHA_DIGEST_LENGTH ]; byte* dat = NULL; int dat_len_s, req_len, alt_len; int* dat_len=&dat_len_s; if ( !m || !r || !ctx ) { THROW( CREDLIB_NULL_PTR ); } if ( !n && !n2 && !out ) { THROW( CREDLIB_NULL_PTR ); } /* no input! */ SHA1_Init( &sha1 ); req_len = ( n ? CREDLIB_calc_bn( n ) : 0 ) + ( n2 ? CREDLIB_calc_bn( n2 ) : 0 ); if ( req_len > 0 ) { TRY( CREDLIB_out( &dat, &dat_len, &alt_len, req_len ) ); TRYIO_start( dat ); /* use serialization system to n||n2 to prevent ambiguity */ if ( n ) { TRYIO( CREDLIB_write_bn( ptr, n ) ); } if ( n2 ) { TRYIO( CREDLIB_write_bn( ptr, n2 ) ); } SHA1_Update( &sha1, dat, TRYIO_len( dat ) ); } if ( out ) { SHA1_Update( &sha1, out, out_len ); } SHA1_Final( hash, &sha1 ); CREDLIB_free( dat ); TRYM( BN_bin2bn( hash, SHA_DIGEST_LENGTH, r ) ); TRYM( BN_mod( r, r, m, ctx ) ); cleanup: return ret; }
int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { int ok = 0; unsigned char seed[SHA256_DIGEST_LENGTH]; unsigned char md[SHA256_DIGEST_LENGTH]; unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH]; BIGNUM *r0, *W, *X, *c, *test; BIGNUM *g = NULL, *q = NULL, *p = NULL; BN_MONT_CTX *mont = NULL; int i, k, n = 0, m = 0, qsize = qbits >> 3; int counter = 0; int r = 0; BN_CTX *ctx = NULL; unsigned int h = 2; if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && qsize != SHA256_DIGEST_LENGTH) /* invalid q size */ return 0; if (evpmd == NULL) /* use SHA1 as default */ evpmd = EVP_sha1(); if (bits < 512) bits = 512; bits = (bits + 63) / 64 * 64; /* * NB: seed_len == 0 is special case: copy generated seed to * seed_in if it is not NULL. */ if (seed_len && seed_len < (size_t)qsize) seed_in = NULL; /* seed buffer too small -- ignore */ /* * App. 2.2 of FIPS PUB 186 allows larger SEED, * but our internal buffers are restricted to 160 bits */ if (seed_len > (size_t)qsize) seed_len = qsize; if (seed_in != NULL) memcpy(seed, seed_in, seed_len); if ((ctx=BN_CTX_new()) == NULL) goto err; if ((mont=BN_MONT_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); g = BN_CTX_get(ctx); W = BN_CTX_get(ctx); q = BN_CTX_get(ctx); X = BN_CTX_get(ctx); c = BN_CTX_get(ctx); p = BN_CTX_get(ctx); test = BN_CTX_get(ctx); if (!BN_lshift(test, BN_value_one(), bits - 1)) goto err; for (;;) { for (;;) { /* find q */ int seed_is_random; /* step 1 */ if (!BN_GENCB_call(cb, 0, m++)) goto err; if (!seed_len) { RAND_pseudo_bytes(seed, qsize); seed_is_random = 1; } else { seed_is_random = 0; /* use random seed if 'seed_in' turns out to be bad */ seed_len = 0; } memcpy(buf, seed, qsize); memcpy(buf2, seed, qsize); /* precompute "SEED + 1" for step 7: */ for (i = qsize - 1; i >= 0; i--) { buf[i]++; if (buf[i] != 0) break; } /* step 2 */ if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL)) goto err; if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) goto err; for (i = 0; i < qsize; i++) md[i] ^= buf2[i]; /* step 3 */ md[0] |= 0x80; md[qsize - 1] |= 0x01; if (!BN_bin2bn(md, qsize, q)) goto err; /* step 4 */ r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, seed_is_random, cb); if (r > 0) break; if (r != 0) goto err; /* do a callback call */ /* step 5 */ } if (!BN_GENCB_call(cb, 2, 0)) goto err; if (!BN_GENCB_call(cb, 3, 0)) goto err; /* step 6 */ counter = 0; /* "offset = 2" */ n = (bits - 1) / 160; for (;;) { if (counter != 0 && !BN_GENCB_call(cb, 0, counter)) goto err; /* step 7 */ BN_zero(W); /* now 'buf' contains "SEED + offset - 1" */ for (k = 0; k <= n; k++) { /* obtain "SEED + offset + k" by incrementing: */ for (i = qsize - 1; i >= 0; i--) { buf[i]++; if (buf[i] != 0) break; } if (!EVP_Digest(buf, qsize, md ,NULL, evpmd, NULL)) goto err; /* step 8 */ if (!BN_bin2bn(md, qsize, r0)) goto err; if (!BN_lshift(r0, r0, (qsize << 3) * k)) goto err; if (!BN_add(W, W, r0)) goto err; } /* more of step 8 */ if (!BN_mask_bits(W, bits - 1)) goto err; if (!BN_copy(X, W)) goto err; if (!BN_add(X, X, test)) goto err; /* step 9 */ if (!BN_lshift1(r0, q)) goto err; if (!BN_mod(c, X, r0, ctx)) goto err; if (!BN_sub(r0, c, BN_value_one())) goto err; if (!BN_sub(p, X, r0)) goto err; /* step 10 */ if (BN_cmp(p, test) >= 0) { /* step 11 */ r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); if (r > 0) goto end; /* found it */ if (r != 0) goto err; } /* step 13 */ counter++; /* "offset = offset + n + 1" */ /* step 14 */ if (counter >= 4096) break; } } end: if (!BN_GENCB_call(cb, 2, 1)) goto err; /* We now need to generate g */ /* Set r0=(p-1)/q */ if (!BN_sub(test, p, BN_value_one())) goto err; if (!BN_div(r0, NULL, test, q, ctx)) goto err; if (!BN_set_word(test, h)) goto err; if (!BN_MONT_CTX_set(mont, p, ctx)) goto err; for (;;) { /* g=test^r0%p */ if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) goto err; if (!BN_is_one(g)) break; if (!BN_add(test, test, BN_value_one())) goto err; h++; } if (!BN_GENCB_call(cb, 3, 1)) goto err; ok = 1; err: if (ok) { if (ret->p) BN_free(ret->p); if (ret->q) BN_free(ret->q); if (ret->g) BN_free(ret->g); ret->p = BN_dup(p); ret->q = BN_dup(q); ret->g = BN_dup(g); if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { ok = 0; goto err; } if (counter_ret != NULL) *counter_ret = counter; if (h_ret != NULL) *h_ret = h; if (seed_out) memcpy(seed_out, seed, qsize); } if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (mont != NULL) BN_MONT_CTX_free(mont); return ok; }
static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { BIGNUM *r1,*m1,*vrfy; BIGNUM local_dmp1, local_dmq1; BIGNUM *dmp1, *dmq1; int ret=0; BN_CTX_start(ctx); r1 = BN_CTX_get(ctx); m1 = BN_CTX_get(ctx); vrfy = BN_CTX_get(ctx); MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); if (!BN_mod(r1,I,rsa->q,ctx)) goto err; if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME)) { dmq1 = &local_dmq1; BN_with_flags(dmq1, rsa->dmq1, BN_FLG_EXP_CONSTTIME); } else dmq1 = rsa->dmq1; if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx, rsa->_method_mod_q)) goto err; if (!BN_mod(r1,I,rsa->p,ctx)) goto err; if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME)) { dmp1 = &local_dmp1; BN_with_flags(dmp1, rsa->dmp1, BN_FLG_EXP_CONSTTIME); } else dmp1 = rsa->dmp1; if (!rsa->meth->bn_mod_exp(r0,r1,dmp1,rsa->p,ctx, rsa->_method_mod_p)) goto err; if (!BN_sub(r0,r0,m1)) goto err; /* This will help stop the size of r0 increasing, which does * affect the multiply if it optimised for a power of 2 size */ if (BN_is_negative(r0)) if (!BN_add(r0,r0,rsa->p)) goto err; if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err; if (!BN_mod(r0,r1,rsa->p,ctx)) goto err; /* If p < q it is occasionally possible for the correction of * adding 'p' if r0 is negative above to leave the result still * negative. This can break the private key operations: the following * second correction should *always* correct this rare occurrence. * This will *never* happen with OpenSSL generated keys because * they ensure p > q [steve] */ if (BN_is_negative(r0)) if (!BN_add(r0,r0,rsa->p)) goto err; if (!BN_mul(r1,r0,rsa->q,ctx)) goto err; if (!BN_add(r0,r1,m1)) goto err; if (rsa->e && rsa->n) { if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err; /* If 'I' was greater than (or equal to) rsa->n, the operation * will be equivalent to using 'I mod n'. However, the result of * the verify will *always* be less than 'n' so we don't check * for absolute equality, just congruency. */ if (!BN_sub(vrfy, vrfy, I)) goto err; if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err; if (BN_is_negative(vrfy)) if (!BN_add(vrfy, vrfy, rsa->n)) goto err; if (!BN_is_zero(vrfy)) { /* 'I' and 'vrfy' aren't congruent mod n. Don't leak * miscalculated CRT output, just do a raw (slower) * mod_exp and return that instead. */ BIGNUM local_d; BIGNUM *d = NULL; if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME)) { d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME); } else d = rsa->d; if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx, rsa->_method_mod_n)) goto err; } } ret=1; err: BN_CTX_end(ctx); return(ret); }