static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { BN_CTX *ctx; BIGNUM k,kq,*K,*kinv=NULL,*r=NULL; int ret=0; if (!dsa->p || !dsa->q || !dsa->g) { DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS); return 0; } BN_init(&k); BN_init(&kq); if (ctx_in == NULL) { if ((ctx=BN_CTX_new()) == NULL) goto err; } else ctx=ctx_in; if ((r=BN_new()) == NULL) goto err; /* Get random k */ do if (!BN_rand_range(&k, dsa->q)) goto err; while (BN_is_zero(&k)); if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { BN_set_flags(&k, BN_FLG_CONSTTIME); } if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p, CRYPTO_LOCK_DSA, dsa->p, ctx)) goto err; } /* Compute r = (g^k mod p) mod q */ if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { if (!BN_copy(&kq, &k)) goto err; /* We do not want timing information to leak the length of k, * so we compute g^k using an equivalent exponent of fixed length. * * (This is a kludge that we need because the BN_mod_exp_mont() * does not let us specify the desired timing behaviour.) */ if (!BN_add(&kq, &kq, dsa->q)) goto err; if (BN_num_bits(&kq) <= BN_num_bits(dsa->q)) { if (!BN_add(&kq, &kq, dsa->q)) goto err; } K = &kq; } else { K = &k; } if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,K,dsa->p,ctx, (BN_MONT_CTX *)dsa->method_mont_p)) goto err; if (!BN_mod(r,r,dsa->q,ctx)) goto err; /* Compute part of 's = inv(k) (m + xr) mod q' */ if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err; if (*kinvp != NULL) BN_clear_free(*kinvp); *kinvp=kinv; kinv=NULL; if (*rp != NULL) BN_clear_free(*rp); *rp=r; ret=1; err: if (!ret) { DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB); if (kinv != NULL) BN_clear_free(kinv); if (r != NULL) BN_clear_free(r); } if (ctx_in == NULL) BN_CTX_free(ctx); if (kinv != NULL) BN_clear_free(kinv); BN_clear_free(&k); BN_clear_free(&kq); return(ret); }
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey) { int ret = -1, i; BN_CTX *ctx; BIGNUM *order, *u1, *u2, *m, *X; EC_POINT *point = NULL; const EC_GROUP *group; const EC_POINT *pub_key; /* check input values */ if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS); return -1; } ctx = BN_CTX_new(); if (!ctx) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); return -1; } BN_CTX_start(ctx); order = BN_CTX_get(ctx); u1 = BN_CTX_get(ctx); u2 = BN_CTX_get(ctx); m = BN_CTX_get(ctx); X = BN_CTX_get(ctx); if (!X) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } if (!EC_GROUP_get_order(group, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); goto err; } if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE); ret = 0; /* signature is invalid */ goto err; } /* calculate tmp1 = inv(S) mod order */ if (!BN_mod_inverse(u2, sig->s, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } /* digest -> m */ i = BN_num_bits(order); /* Need to truncate digest if it is too long: first truncate whole * bytes. */ if (8 * dgst_len > i) dgst_len = (i + 7)/8; if (!BN_bin2bn(dgst, dgst_len, m)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } /* If still too long truncate remaining bits with a shift */ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } /* u1 = m * tmp mod order */ if (!BN_mod_mul(u1, m, u2, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } /* u2 = r * w mod q */ if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } if ((point = EC_POINT_new(group)) == NULL) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); goto err; } if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); goto err; } } #ifndef OPENSSL_NO_EC2M else /* NID_X9_62_characteristic_two_field */ { if (!EC_POINT_get_affine_coordinates_GF2m(group, point, X, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); goto err; } } #endif if (!BN_nnmod(u1, X, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } /* if the signature is correct u1 is equal to sig->r */ ret = (BN_ucmp(u1, sig->r) == 0); err: BN_CTX_end(ctx); BN_CTX_free(ctx); EC_POINT_free(point); return ret; }
// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields // recid selects which key is recovered // if check is nonzero, additional checks are performed int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check) { if (!eckey) return 0; int ret = 0; BN_CTX *ctx = NULL; BIGNUM *x = NULL; BIGNUM *e = NULL; BIGNUM *order = NULL; BIGNUM *sor = NULL; BIGNUM *eor = NULL; BIGNUM *field = NULL; EC_POINT *R = NULL; EC_POINT *O = NULL; EC_POINT *Q = NULL; BIGNUM *rr = NULL; BIGNUM *zero = NULL; int n = 0; int i = recid / 2; const EC_GROUP *group = EC_KEY_get0_group(eckey); if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; } BN_CTX_start(ctx); order = BN_CTX_get(ctx); if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; } x = BN_CTX_get(ctx); if (!BN_copy(x, order)) { ret=-1; goto err; } if (!BN_mul_word(x, i)) { ret=-1; goto err; } if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; } field = BN_CTX_get(ctx); if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; } if (BN_cmp(x, field) >= 0) { ret=0; goto err; } if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; } if (check) { if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; } if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; } } if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } n = EC_GROUP_get_degree(group); e = BN_CTX_get(ctx); if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; } if (8*msglen > n) BN_rshift(e, e, 8-(n & 7)); zero = BN_CTX_get(ctx); if (!BN_zero(zero)) { ret=-1; goto err; } if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; } rr = BN_CTX_get(ctx); if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; } sor = BN_CTX_get(ctx); if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; } eor = BN_CTX_get(ctx); if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; } if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; } if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; } ret = 1; err: if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (R != NULL) EC_POINT_free(R); if (O != NULL) EC_POINT_free(O); if (Q != NULL) EC_POINT_free(Q); return ret; }
int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) { BIGNUM *t; int found=0; int i,j,c1=0; BN_CTX *ctx; int checks = BN_prime_checks_for_size(bits); ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); t = BN_CTX_get(ctx); if(!t) goto err; loop: /* make a random number and set the top and bottom bits */ if (add == NULL) { if (!probable_prime(ret,bits)) goto err; } else { if (safe) { if (!probable_prime_dh_safe(ret,bits,add,rem,ctx)) goto err; } else { if (!probable_prime_dh(ret,bits,add,rem,ctx)) goto err; } } /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */ if(!BN_GENCB_call(cb, 0, c1++)) /* aborted */ goto err; if (!safe) { i=BN_is_prime_fasttest_ex(ret,checks,ctx,0,cb); if (i == -1) goto err; if (i == 0) goto loop; } else { /* for "safe prime" generation, * check that (p-1)/2 is prime. * Since a prime is odd, We just * need to divide by 2 */ if (!BN_rshift1(t,ret)) goto err; for (i=0; i<checks; i++) { j=BN_is_prime_fasttest_ex(ret,1,ctx,0,cb); if (j == -1) goto err; if (j == 0) goto loop; j=BN_is_prime_fasttest_ex(t,1,ctx,0,cb); if (j == -1) goto err; if (j == 0) goto loop; if(!BN_GENCB_call(cb, 2, c1-1)) goto err; /* We have a safe prime test pass */ } } /* we have a prime :-) */ found = 1; err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } bn_check_top(ret); return found; }
/* Computes a + b and stores the result in r. r could be a or b, a could be b. * Uses algorithm A.10.2 of IEEE P1363. */ int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { BN_CTX *new_ctx = NULL; BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t; int ret = 0; if (EC_POINT_is_at_infinity(group, a)) { if (!EC_POINT_copy(r, b)) return 0; return 1; } if (EC_POINT_is_at_infinity(group, b)) { if (!EC_POINT_copy(r, a)) return 0; return 1; } if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return 0; } BN_CTX_start(ctx); x0 = BN_CTX_get(ctx); y0 = BN_CTX_get(ctx); x1 = BN_CTX_get(ctx); y1 = BN_CTX_get(ctx); x2 = BN_CTX_get(ctx); y2 = BN_CTX_get(ctx); s = BN_CTX_get(ctx); t = BN_CTX_get(ctx); if (t == NULL) goto err; if (a->Z_is_one) { if (!BN_copy(x0, &a->X)) goto err; if (!BN_copy(y0, &a->Y)) goto err; } else { if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) goto err; } if (b->Z_is_one) { if (!BN_copy(x1, &b->X)) goto err; if (!BN_copy(y1, &b->Y)) goto err; } else { if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) goto err; } if (BN_GF2m_cmp(x0, x1)) { if (!BN_GF2m_add(t, x0, x1)) goto err; if (!BN_GF2m_add(s, y0, y1)) goto err; if (!group->meth->field_div(group, s, s, t, ctx)) goto err; if (!group->meth->field_sqr(group, x2, s, ctx)) goto err; if (!BN_GF2m_add(x2, x2, &group->a)) goto err; if (!BN_GF2m_add(x2, x2, s)) goto err; if (!BN_GF2m_add(x2, x2, t)) goto err; } else { if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1)) { if (!EC_POINT_set_to_infinity(group, r)) goto err; ret = 1; goto err; } if (!group->meth->field_div(group, s, y1, x1, ctx)) goto err; if (!BN_GF2m_add(s, s, x1)) goto err; if (!group->meth->field_sqr(group, x2, s, ctx)) goto err; if (!BN_GF2m_add(x2, x2, s)) goto err; if (!BN_GF2m_add(x2, x2, &group->a)) goto err; } if (!BN_GF2m_add(y2, x1, x2)) goto err; if (!group->meth->field_mul(group, y2, y2, s, ctx)) goto err; if (!BN_GF2m_add(y2, y2, x2)) goto err; if (!BN_GF2m_add(y2, y2, y1)) goto err; if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) goto err; ret = 1; err: BN_CTX_end(ctx); if (new_ctx != NULL) BN_CTX_free(new_ctx); return ret; }
int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) { unsigned char *buffer = NULL; size_t buf_len = 0, i; int ret = 0, reason = ERR_R_BIO_LIB; BN_CTX *ctx = NULL; const EC_POINT *point = NULL; BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL, *order = NULL, *cofactor = NULL; const unsigned char *seed; size_t seed_len = 0; static const char *gen_compressed = "Generator (compressed):"; static const char *gen_uncompressed = "Generator (uncompressed):"; static const char *gen_hybrid = "Generator (hybrid):"; if (!x) { reason = ERR_R_PASSED_NULL_PARAMETER; goto err; } ctx = BN_CTX_new(); if (ctx == NULL) { reason = ERR_R_MALLOC_FAILURE; goto err; } if (EC_GROUP_get_asn1_flag(x)) { /* the curve parameter are given by an asn1 OID */ int nid; if (!BIO_indent(bp, off, 128)) goto err; nid = EC_GROUP_get_curve_name(x); if (nid == 0) goto err; if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0) goto err; if (BIO_printf(bp, "\n") <= 0) goto err; } else { /* explicit parameters */ int is_char_two = 0; point_conversion_form_t form; int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); if (tmp_nid == NID_X9_62_characteristic_two_field) is_char_two = 1; if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || (b = BN_new()) == NULL || (order = BN_new()) == NULL || (cofactor = BN_new()) == NULL) { reason = ERR_R_MALLOC_FAILURE; goto err; } #ifndef OPENSSL_NO_EC2M if (is_char_two) { if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) { reason = ERR_R_EC_LIB; goto err; } } else /* prime field */ #endif { if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) { reason = ERR_R_EC_LIB; goto err; } } if ((point = EC_GROUP_get0_generator(x)) == NULL) { reason = ERR_R_EC_LIB; goto err; } if (!EC_GROUP_get_order(x, order, NULL) || !EC_GROUP_get_cofactor(x, cofactor, NULL)) { reason = ERR_R_EC_LIB; goto err; } form = EC_GROUP_get_point_conversion_form(x); if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) { reason = ERR_R_EC_LIB; goto err; } buf_len = (size_t)BN_num_bytes(p); if (buf_len < (i = (size_t)BN_num_bytes(a))) buf_len = i; if (buf_len < (i = (size_t)BN_num_bytes(b))) buf_len = i; if (buf_len < (i = (size_t)BN_num_bytes(gen))) buf_len = i; if (buf_len < (i = (size_t)BN_num_bytes(order))) buf_len = i; if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) buf_len = i; if ((seed = EC_GROUP_get0_seed(x)) != NULL) seed_len = EC_GROUP_get_seed_len(x); buf_len += 10; if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { reason = ERR_R_MALLOC_FAILURE; goto err; } if (!BIO_indent(bp, off, 128)) goto err; /* print the 'short name' of the field type */ if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) <= 0) goto err; if (is_char_two) { /* print the 'short name' of the base type OID */ int basis_type = EC_GROUP_get_basis_type(x); if (basis_type == 0) goto err; if (!BIO_indent(bp, off, 128)) goto err; if (BIO_printf(bp, "Basis Type: %s\n", OBJ_nid2sn(basis_type)) <= 0) goto err; /* print the polynomial */ if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer, off)) goto err; } else { if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off)) goto err; } if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off)) goto err; if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off)) goto err; if (form == POINT_CONVERSION_COMPRESSED) { if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen, buffer, off)) goto err; } else if (form == POINT_CONVERSION_UNCOMPRESSED) { if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen, buffer, off)) goto err; } else { /* form == POINT_CONVERSION_HYBRID */ if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen, buffer, off)) goto err; } if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, buffer, off)) goto err; if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor, buffer, off)) goto err; if (seed && !print_bin(bp, "Seed:", seed, seed_len, off)) goto err; } ret = 1; err: if (!ret) ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); if (p) BN_free(p); if (a) BN_free(a); if (b) BN_free(b); if (gen) BN_free(gen); if (order) BN_free(order); if (cofactor) BN_free(cofactor); if (ctx) BN_CTX_free(ctx); if (buffer != NULL) OPENSSL_free(buffer); return (ret); }
int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) { BIGNUM *i, *j, *k, *l, *m; BN_CTX *ctx; int ret = 1, ex_primes = 0, idx; RSA_PRIME_INFO *pinfo; if (key->p == NULL || key->q == NULL || key->n == NULL || key->e == NULL || key->d == NULL) { RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_VALUE_MISSING); return 0; } /* multi-prime? */ if (key->version == RSA_ASN1_VERSION_MULTI) { ex_primes = sk_RSA_PRIME_INFO_num(key->prime_infos); if (ex_primes <= 0 || (ex_primes + 2) > rsa_multip_cap(BN_num_bits(key->n))) { RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_INVALID_MULTI_PRIME_KEY); return 0; } } i = BN_new(); j = BN_new(); k = BN_new(); l = BN_new(); m = BN_new(); ctx = BN_CTX_new(); if (i == NULL || j == NULL || k == NULL || l == NULL || m == NULL || ctx == NULL) { ret = -1; RSAerr(RSA_F_RSA_CHECK_KEY_EX, ERR_R_MALLOC_FAILURE); goto err; } if (BN_is_one(key->e)) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE); } if (!BN_is_odd(key->e)) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE); } /* p prime? */ if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, cb) != 1) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_P_NOT_PRIME); } /* q prime? */ if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, cb) != 1) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_Q_NOT_PRIME); } /* r_i prime? */ for (idx = 0; idx < ex_primes; idx++) { pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); if (BN_is_prime_ex(pinfo->r, BN_prime_checks, NULL, cb) != 1) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_R_NOT_PRIME); } } /* n = p*q * r_3...r_i? */ if (!BN_mul(i, key->p, key->q, ctx)) { ret = -1; goto err; } for (idx = 0; idx < ex_primes; idx++) { pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); if (!BN_mul(i, i, pinfo->r, ctx)) { ret = -1; goto err; } } if (BN_cmp(i, key->n) != 0) { ret = 0; if (ex_primes) RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES); else RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_N_DOES_NOT_EQUAL_P_Q); } /* d*e = 1 mod \lambda(n)? */ if (!BN_sub(i, key->p, BN_value_one())) { ret = -1; goto err; } if (!BN_sub(j, key->q, BN_value_one())) { ret = -1; goto err; } /* now compute k = \lambda(n) = LCM(i, j, r_3 - 1...) */ if (!BN_mul(l, i, j, ctx)) { ret = -1; goto err; } if (!BN_gcd(m, i, j, ctx)) { ret = -1; goto err; } for (idx = 0; idx < ex_primes; idx++) { pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); if (!BN_sub(k, pinfo->r, BN_value_one())) { ret = -1; goto err; } if (!BN_mul(l, l, k, ctx)) { ret = -1; goto err; } if (!BN_gcd(m, m, k, ctx)) { ret = -1; goto err; } } if (!BN_div(k, NULL, l, m, ctx)) { /* remainder is 0 */ ret = -1; goto err; } if (!BN_mod_mul(i, key->d, key->e, k, ctx)) { ret = -1; goto err; } if (!BN_is_one(i)) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_D_E_NOT_CONGRUENT_TO_1); } if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { /* dmp1 = d mod (p-1)? */ if (!BN_sub(i, key->p, BN_value_one())) { ret = -1; goto err; } if (!BN_mod(j, key->d, i, ctx)) { ret = -1; goto err; } if (BN_cmp(j, key->dmp1) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMP1_NOT_CONGRUENT_TO_D); } /* dmq1 = d mod (q-1)? */ if (!BN_sub(i, key->q, BN_value_one())) { ret = -1; goto err; } if (!BN_mod(j, key->d, i, ctx)) { ret = -1; goto err; } if (BN_cmp(j, key->dmq1) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMQ1_NOT_CONGRUENT_TO_D); } /* iqmp = q^-1 mod p? */ if (!BN_mod_inverse(i, key->q, key->p, ctx)) { ret = -1; goto err; } if (BN_cmp(i, key->iqmp) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_IQMP_NOT_INVERSE_OF_Q); } } for (idx = 0; idx < ex_primes; idx++) { pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); /* d_i = d mod (r_i - 1)? */ if (!BN_sub(i, pinfo->r, BN_value_one())) { ret = -1; goto err; } if (!BN_mod(j, key->d, i, ctx)) { ret = -1; goto err; } if (BN_cmp(j, pinfo->d) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D); } /* t_i = R_i ^ -1 mod r_i ? */ if (!BN_mod_inverse(i, pinfo->pp, pinfo->r, ctx)) { ret = -1; goto err; } if (BN_cmp(i, pinfo->t) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R); } } err: BN_free(i); BN_free(j); BN_free(k); BN_free(l); BN_free(m); BN_CTX_free(ctx); return ret; }
int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); const BIGNUM *p; BN_CTX *new_ctx = NULL; BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6; int ret = 0; if (a == b) { return EC_POINT_dbl(group, r, a, ctx); } if (EC_POINT_is_at_infinity(group, a)) { return EC_POINT_copy(r, b); } if (EC_POINT_is_at_infinity(group, b)) { return EC_POINT_copy(r, a); } field_mul = group->meth->field_mul; field_sqr = group->meth->field_sqr; p = &group->field; if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) { return 0; } } BN_CTX_start(ctx); n0 = BN_CTX_get(ctx); n1 = BN_CTX_get(ctx); n2 = BN_CTX_get(ctx); n3 = BN_CTX_get(ctx); n4 = BN_CTX_get(ctx); n5 = BN_CTX_get(ctx); n6 = BN_CTX_get(ctx); if (n6 == NULL) { goto end; } /* Note that in this function we must not read components of 'a' or 'b' * once we have written the corresponding components of 'r'. * ('r' might be one of 'a' or 'b'.) */ /* n1, n2 */ int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0; if (b_Z_is_one) { if (!BN_copy(n1, &a->X) || !BN_copy(n2, &a->Y)) { goto end; } /* n1 = X_a */ /* n2 = Y_a */ } else { if (!field_sqr(group, n0, &b->Z, ctx) || !field_mul(group, n1, &a->X, n0, ctx)) { goto end; } /* n1 = X_a * Z_b^2 */ if (!field_mul(group, n0, n0, &b->Z, ctx) || !field_mul(group, n2, &a->Y, n0, ctx)) { goto end; } /* n2 = Y_a * Z_b^3 */ } /* n3, n4 */ int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0; if (a_Z_is_one) { if (!BN_copy(n3, &b->X) || !BN_copy(n4, &b->Y)) { goto end; } /* n3 = X_b */ /* n4 = Y_b */ } else { if (!field_sqr(group, n0, &a->Z, ctx) || !field_mul(group, n3, &b->X, n0, ctx)) { goto end; } /* n3 = X_b * Z_a^2 */ if (!field_mul(group, n0, n0, &a->Z, ctx) || !field_mul(group, n4, &b->Y, n0, ctx)) { goto end; } /* n4 = Y_b * Z_a^3 */ } /* n5, n6 */ if (!BN_mod_sub_quick(n5, n1, n3, p) || !BN_mod_sub_quick(n6, n2, n4, p)) { goto end; } /* n5 = n1 - n3 */ /* n6 = n2 - n4 */ if (BN_is_zero(n5)) { if (BN_is_zero(n6)) { /* a is the same point as b */ BN_CTX_end(ctx); ret = EC_POINT_dbl(group, r, a, ctx); ctx = NULL; goto end; } else { /* a is the inverse of b */ BN_zero(&r->Z); ret = 1; goto end; } } /* 'n7', 'n8' */ if (!BN_mod_add_quick(n1, n1, n3, p) || !BN_mod_add_quick(n2, n2, n4, p)) { goto end; } /* 'n7' = n1 + n3 */ /* 'n8' = n2 + n4 */ /* Z_r */ if (a_Z_is_one && b_Z_is_one) { if (!BN_copy(&r->Z, n5)) { goto end; } } else { if (a_Z_is_one) { if (!BN_copy(n0, &b->Z)) { goto end; } } else if (b_Z_is_one) { if (!BN_copy(n0, &a->Z)) { goto end; } } else if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) { goto end; } if (!field_mul(group, &r->Z, n0, n5, ctx)) { goto end; } } /* Z_r = Z_a * Z_b * n5 */ /* X_r */ if (!field_sqr(group, n0, n6, ctx) || !field_sqr(group, n4, n5, ctx) || !field_mul(group, n3, n1, n4, ctx) || !BN_mod_sub_quick(&r->X, n0, n3, p)) { goto end; } /* X_r = n6^2 - n5^2 * 'n7' */ /* 'n9' */ if (!BN_mod_lshift1_quick(n0, &r->X, p) || !BN_mod_sub_quick(n0, n3, n0, p)) { goto end; } /* n9 = n5^2 * 'n7' - 2 * X_r */ /* Y_r */ if (!field_mul(group, n0, n0, n6, ctx) || !field_mul(group, n5, n4, n5, ctx)) { goto end; /* now n5 is n5^3 */ } if (!field_mul(group, n1, n2, n5, ctx) || !BN_mod_sub_quick(n0, n0, n1, p)) { goto end; } if (BN_is_odd(n0) && !BN_add(n0, n0, p)) { goto end; } /* now 0 <= n0 < 2*p, and n0 is even */ if (!BN_rshift1(&r->Y, n0)) { goto end; } /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */ ret = 1; end: if (ctx) { /* otherwise we already called BN_CTX_end */ BN_CTX_end(ctx); } BN_CTX_free(new_ctx); return ret; }
int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) { int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); const BIGNUM *p; BN_CTX *new_ctx = NULL; BIGNUM *n0, *n1, *n2, *n3; int ret = 0; if (EC_POINT_is_at_infinity(group, a)) { BN_zero(&r->Z); return 1; } field_mul = group->meth->field_mul; field_sqr = group->meth->field_sqr; p = &group->field; if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) { return 0; } } BN_CTX_start(ctx); n0 = BN_CTX_get(ctx); n1 = BN_CTX_get(ctx); n2 = BN_CTX_get(ctx); n3 = BN_CTX_get(ctx); if (n3 == NULL) { goto err; } /* Note that in this function we must not read components of 'a' * once we have written the corresponding components of 'r'. * ('r' might the same as 'a'.) */ /* n1 */ if (BN_cmp(&a->Z, &group->one) == 0) { if (!field_sqr(group, n0, &a->X, ctx) || !BN_mod_lshift1_quick(n1, n0, p) || !BN_mod_add_quick(n0, n0, n1, p) || !BN_mod_add_quick(n1, n0, &group->a, p)) { goto err; } /* n1 = 3 * X_a^2 + a_curve */ } else if (group->a_is_minus3) { if (!field_sqr(group, n1, &a->Z, ctx) || !BN_mod_add_quick(n0, &a->X, n1, p) || !BN_mod_sub_quick(n2, &a->X, n1, p) || !field_mul(group, n1, n0, n2, ctx) || !BN_mod_lshift1_quick(n0, n1, p) || !BN_mod_add_quick(n1, n0, n1, p)) { goto err; } /* n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) * = 3 * X_a^2 - 3 * Z_a^4 */ } else { if (!field_sqr(group, n0, &a->X, ctx) || !BN_mod_lshift1_quick(n1, n0, p) || !BN_mod_add_quick(n0, n0, n1, p) || !field_sqr(group, n1, &a->Z, ctx) || !field_sqr(group, n1, n1, ctx) || !field_mul(group, n1, n1, &group->a, ctx) || !BN_mod_add_quick(n1, n1, n0, p)) { goto err; } /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */ } /* Z_r */ if (BN_cmp(&a->Z, &group->one) == 0) { if (!BN_copy(n0, &a->Y)) { goto err; } } else if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) { goto err; } if (!BN_mod_lshift1_quick(&r->Z, n0, p)) { goto err; } /* Z_r = 2 * Y_a * Z_a */ /* n2 */ if (!field_sqr(group, n3, &a->Y, ctx) || !field_mul(group, n2, &a->X, n3, ctx) || !BN_mod_lshift_quick(n2, n2, 2, p)) { goto err; } /* n2 = 4 * X_a * Y_a^2 */ /* X_r */ if (!BN_mod_lshift1_quick(n0, n2, p) || !field_sqr(group, &r->X, n1, ctx) || !BN_mod_sub_quick(&r->X, &r->X, n0, p)) { goto err; } /* X_r = n1^2 - 2 * n2 */ /* n3 */ if (!field_sqr(group, n0, n3, ctx) || !BN_mod_lshift_quick(n3, n0, 3, p)) { goto err; } /* n3 = 8 * Y_a^4 */ /* Y_r */ if (!BN_mod_sub_quick(n0, n2, &r->X, p) || !field_mul(group, n0, n1, n0, ctx) || !BN_mod_sub_quick(&r->Y, n0, n3, p)) { goto err; } /* Y_r = n1 * (n2 - X_r) - n3 */ ret = 1; err: BN_CTX_end(ctx); BN_CTX_free(new_ctx); return ret; }
int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { int ret = 0; BN_CTX *new_ctx = NULL; BIGNUM *tmp_a; /* p must be a prime > 3 */ if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) { OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD); return 0; } if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) { return 0; } } BN_CTX_start(ctx); tmp_a = BN_CTX_get(ctx); if (tmp_a == NULL) { goto err; } /* group->field */ if (!BN_copy(&group->field, p)) { goto err; } BN_set_negative(&group->field, 0); /* group->a */ if (!BN_nnmod(tmp_a, a, p, ctx)) { goto err; } if (group->meth->field_encode) { if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) { goto err; } } else if (!BN_copy(&group->a, tmp_a)) { goto err; } /* group->b */ if (!BN_nnmod(&group->b, b, p, ctx)) { goto err; } if (group->meth->field_encode && !group->meth->field_encode(group, &group->b, &group->b, ctx)) { goto err; } /* group->a_is_minus3 */ if (!BN_add_word(tmp_a, 3)) { goto err; } group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field)); if (group->meth->field_encode != NULL) { if (!group->meth->field_encode(group, &group->one, BN_value_one(), ctx)) { goto err; } } else if (!BN_copy(&group->one, BN_value_one())) { goto err; } ret = 1; err: BN_CTX_end(ctx); BN_CTX_free(new_ctx); return ret; }
int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx) { BN_CTX *new_ctx = NULL; BIGNUM *Z, *Z_1, *Z_2, *Z_3; const BIGNUM *Z_; int ret = 0; if (EC_POINT_is_at_infinity(group, point)) { OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); return 0; } if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) { return 0; } } BN_CTX_start(ctx); Z = BN_CTX_get(ctx); Z_1 = BN_CTX_get(ctx); Z_2 = BN_CTX_get(ctx); Z_3 = BN_CTX_get(ctx); if (Z == NULL || Z_1 == NULL || Z_2 == NULL || Z_3 == NULL) { goto err; } /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */ if (group->meth->field_decode) { if (!group->meth->field_decode(group, Z, &point->Z, ctx)) { goto err; } Z_ = Z; } else { Z_ = &point->Z; } if (BN_is_one(Z_)) { if (group->meth->field_decode) { if (x != NULL && !group->meth->field_decode(group, x, &point->X, ctx)) { goto err; } if (y != NULL && !group->meth->field_decode(group, y, &point->Y, ctx)) { goto err; } } else { if (x != NULL && !BN_copy(x, &point->X)) { goto err; } if (y != NULL && !BN_copy(y, &point->Y)) { goto err; } } } else { if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) { OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); goto err; } if (group->meth->field_encode == 0) { /* field_sqr works on standard representation */ if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) { goto err; } } else if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) { goto err; } /* in the Montgomery case, field_mul will cancel out Montgomery factor in * X: */ if (x != NULL && !group->meth->field_mul(group, x, &point->X, Z_2, ctx)) { goto err; } if (y != NULL) { if (group->meth->field_encode == 0) { /* field_mul works on standard representation */ if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) { goto err; } } else if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) { goto err; } /* in the Montgomery case, field_mul will cancel out Montgomery factor in * Y: */ if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) { goto err; } } } ret = 1; err: BN_CTX_end(ctx); BN_CTX_free(new_ctx); return ret; }
int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx) { BN_CTX *new_ctx = NULL; BIGNUM *tmp, *tmp_Z; BIGNUM **prod_Z = NULL; size_t i; int ret = 0; if (num == 0) { return 1; } if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) { return 0; } } BN_CTX_start(ctx); tmp = BN_CTX_get(ctx); tmp_Z = BN_CTX_get(ctx); if (tmp == NULL || tmp_Z == NULL) { goto err; } prod_Z = OPENSSL_malloc(num * sizeof(prod_Z[0])); if (prod_Z == NULL) { goto err; } memset(prod_Z, 0, num * sizeof(prod_Z[0])); for (i = 0; i < num; i++) { prod_Z[i] = BN_new(); if (prod_Z[i] == NULL) { goto err; } } /* Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z, * skipping any zero-valued inputs (pretend that they're 1). */ if (!BN_is_zero(&points[0]->Z)) { if (!BN_copy(prod_Z[0], &points[0]->Z)) { goto err; } } else { if (BN_copy(prod_Z[0], &group->one) == NULL) { goto err; } } for (i = 1; i < num; i++) { if (!BN_is_zero(&points[i]->Z)) { if (!group->meth->field_mul(group, prod_Z[i], prod_Z[i - 1], &points[i]->Z, ctx)) { goto err; } } else { if (!BN_copy(prod_Z[i], prod_Z[i - 1])) { goto err; } } } /* Now use a single explicit inversion to replace every * non-zero points[i]->Z by its inverse. */ if (!BN_mod_inverse(tmp, prod_Z[num - 1], &group->field, ctx)) { OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); goto err; } if (group->meth->field_encode != NULL) { /* In the Montgomery case, we just turned R*H (representing H) * into 1/(R*H), but we need R*(1/H) (representing 1/H); * i.e. we need to multiply by the Montgomery factor twice. */ if (!group->meth->field_encode(group, tmp, tmp, ctx) || !group->meth->field_encode(group, tmp, tmp, ctx)) { goto err; } } for (i = num - 1; i > 0; --i) { /* Loop invariant: tmp is the product of the inverses of * points[0]->Z .. points[i]->Z (zero-valued inputs skipped). */ if (BN_is_zero(&points[i]->Z)) { continue; } /* Set tmp_Z to the inverse of points[i]->Z (as product * of Z inverses 0 .. i, Z values 0 .. i - 1). */ if (!group->meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx) || /* Update tmp to satisfy the loop invariant for i - 1. */ !group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx) || /* Replace points[i]->Z by its inverse. */ !BN_copy(&points[i]->Z, tmp_Z)) { goto err; } } /* Replace points[0]->Z by its inverse. */ if (!BN_is_zero(&points[0]->Z) && !BN_copy(&points[0]->Z, tmp)) { goto err; } /* Finally, fix up the X and Y coordinates for all points. */ for (i = 0; i < num; i++) { EC_POINT *p = points[i]; if (!BN_is_zero(&p->Z)) { /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1). */ if (!group->meth->field_sqr(group, tmp, &p->Z, ctx) || !group->meth->field_mul(group, &p->X, &p->X, tmp, ctx) || !group->meth->field_mul(group, tmp, tmp, &p->Z, ctx) || !group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx)) { goto err; } if (BN_copy(&p->Z, &group->one) == NULL) { goto err; } } } ret = 1; err: BN_CTX_end(ctx); BN_CTX_free(new_ctx); if (prod_Z != NULL) { for (i = 0; i < num; i++) { if (prod_Z[i] == NULL) { break; } BN_clear_free(prod_Z[i]); } OPENSSL_free(prod_Z); } return ret; }
static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { const unsigned char *p, *pm; int pklen, pmlen; int ptype; void *pval; ASN1_STRING *pstr; X509_ALGOR *palg; ASN1_INTEGER *privkey = NULL; BN_CTX *ctx = NULL; STACK_OF(ASN1_TYPE) *ndsa = NULL; DSA *dsa = NULL; if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); /* Check for broken DSA PKCS#8, UGH! */ if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) { ASN1_TYPE *t1, *t2; if(!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen))) goto decerr; if (sk_ASN1_TYPE_num(ndsa) != 2) goto decerr; /* Handle Two broken types: * SEQUENCE {parameters, priv_key} * SEQUENCE {pub_key, priv_key} */ t1 = sk_ASN1_TYPE_value(ndsa, 0); t2 = sk_ASN1_TYPE_value(ndsa, 1); if (t1->type == V_ASN1_SEQUENCE) { p8->broken = PKCS8_EMBEDDED_PARAM; pval = t1->value.ptr; } else if (ptype == V_ASN1_SEQUENCE) p8->broken = PKCS8_NS_DB; else goto decerr; if (t2->type != V_ASN1_INTEGER) goto decerr; privkey = t2->value.integer; } else { const unsigned char *q = p; if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen))) goto decerr; if (privkey->type == V_ASN1_NEG_INTEGER) { p8->broken = PKCS8_NEG_PRIVKEY; ASN1_INTEGER_free(privkey); if (!(privkey=d2i_ASN1_UINTEGER(NULL, &q, pklen))) goto decerr; } if (ptype != V_ASN1_SEQUENCE) goto decerr; } pstr = pval; pm = pstr->data; pmlen = pstr->length; if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) goto decerr; /* We have parameters now set private key */ if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR); goto dsaerr; } /* Calculate public key */ if (!(dsa->pub_key = BN_new())) { DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!(ctx = BN_CTX_new())) { DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR); goto dsaerr; } EVP_PKEY_assign_DSA(pkey, dsa); BN_CTX_free (ctx); if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); else ASN1_INTEGER_free(privkey); return 1; decerr: DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR); dsaerr: BN_CTX_free (ctx); if (privkey) ASN1_INTEGER_free(privkey); sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); DSA_free(dsa); return 0; }
static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DSA_SIG *sig, DSA *dsa) { BN_CTX *ctx; BIGNUM u1,u2,t1; BN_MONT_CTX *mont=NULL; int ret = -1; if (!dsa->p || !dsa->q || !dsa->g) { DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS); return -1; } if(FIPS_selftest_failed()) { FIPSerr(FIPS_F_DSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED); return -1; } if (BN_num_bits(dsa->q) != 160) { DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE); return -1; } if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE); return -1; } if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) { DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL); return -1; } BN_init(&u1); BN_init(&u2); BN_init(&t1); if ((ctx=BN_CTX_new()) == NULL) goto err; if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0) { ret = 0; goto err; } if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0) { ret = 0; goto err; } /* Calculate W = inv(S) mod Q * save W in u2 */ if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err; /* save M in u1 */ if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err; /* u1 = M * w mod q */ if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err; /* u2 = r * w mod q */ if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err; if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { mont = BN_MONT_CTX_set_locked( (BN_MONT_CTX **)&dsa->method_mont_p, CRYPTO_LOCK_DSA, dsa->p, ctx); if (!mont) goto err; } #if 0 { BIGNUM t2; BN_init(&t2); /* v = ( g^u1 * y^u2 mod p ) mod q */ /* let t1 = g ^ u1 mod p */ if (!BN_mod_exp_mont(&t1,dsa->g,&u1,dsa->p,ctx,mont)) goto err; /* let t2 = y ^ u2 mod p */ if (!BN_mod_exp_mont(&t2,dsa->pub_key,&u2,dsa->p,ctx,mont)) goto err; /* let u1 = t1 * t2 mod p */ if (!BN_mod_mul(&u1,&t1,&t2,dsa->p,ctx)) goto err_bn; BN_free(&t2); } /* let u1 = u1 mod q */ if (!BN_mod(&u1,&u1,dsa->q,ctx)) goto err; #else { if (!dsa->meth->dsa_mod_exp(dsa, &t1,dsa->g,&u1,dsa->pub_key,&u2, dsa->p,ctx,mont)) goto err; /* BN_copy(&u1,&t1); */ /* let u1 = u1 mod q */ if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err; } #endif /* V is now in u1. If the signature is correct, it will be * equal to R. */ ret=(BN_ucmp(&u1, sig->r) == 0); err: if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB); if (ctx != NULL) BN_CTX_free(ctx); BN_free(&u1); BN_free(&u2); BN_free(&t1); return(ret); }
int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) { unsigned char *buffer=NULL; size_t buf_len=0, i; int ret=0, reason=ERR_R_BIO_LIB; BIGNUM *pub_key=NULL, *order=NULL; BN_CTX *ctx=NULL; const EC_GROUP *group; const EC_POINT *public_key; const BIGNUM *priv_key; if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { reason = ERR_R_PASSED_NULL_PARAMETER; goto err; } public_key = EC_KEY_get0_public_key(x); if ((pub_key = EC_POINT_point2bn(group, public_key, EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) { reason = ERR_R_EC_LIB; goto err; } buf_len = (size_t)BN_num_bytes(pub_key); priv_key = EC_KEY_get0_private_key(x); if (priv_key != NULL) { if ((i = (size_t)BN_num_bytes(priv_key)) > buf_len) buf_len = i; } buf_len += 10; if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { reason = ERR_R_MALLOC_FAILURE; goto err; } if (priv_key != NULL) { if (!BIO_indent(bp, off, 128)) goto err; if ((order = BN_new()) == NULL) goto err; if (!EC_GROUP_get_order(group, order, NULL)) goto err; if (BIO_printf(bp, "Private-Key: (%d bit)\n", BN_num_bits(order)) <= 0) goto err; } if ((priv_key != NULL) && !print(bp, "priv:", priv_key, buffer, off)) goto err; if ((pub_key != NULL) && !print(bp, "pub: ", pub_key, buffer, off)) goto err; if (!ECPKParameters_print(bp, group, off)) goto err; ret=1; err: if (!ret) ECerr(EC_F_EC_KEY_PRINT, reason); if (pub_key) BN_free(pub_key); if (order) BN_free(order); if (ctx) BN_CTX_free(ctx); if (buffer != NULL) OPENSSL_free(buffer); return(ret); }
int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) { int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); const BIGNUM *p; BN_CTX *new_ctx = NULL; BIGNUM *rh, *tmp, *Z4, *Z6; int ret = 0; if (EC_POINT_is_at_infinity(group, point)) { return 1; } field_mul = group->meth->field_mul; field_sqr = group->meth->field_sqr; p = &group->field; if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) { return 0; } } BN_CTX_start(ctx); rh = BN_CTX_get(ctx); tmp = BN_CTX_get(ctx); Z4 = BN_CTX_get(ctx); Z6 = BN_CTX_get(ctx); if (Z6 == NULL) { goto err; } /* We have a curve defined by a Weierstrass equation * y^2 = x^3 + a*x + b. * The point to consider is given in Jacobian projective coordinates * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). * Substituting this and multiplying by Z^6 transforms the above equation * into * Y^2 = X^3 + a*X*Z^4 + b*Z^6. * To test this, we add up the right-hand side in 'rh'. */ /* rh := X^2 */ if (!field_sqr(group, rh, &point->X, ctx)) { goto err; } if (BN_cmp(&point->Z, &group->one) != 0) { if (!field_sqr(group, tmp, &point->Z, ctx) || !field_sqr(group, Z4, tmp, ctx) || !field_mul(group, Z6, Z4, tmp, ctx)) { goto err; } /* rh := (rh + a*Z^4)*X */ if (group->a_is_minus3) { if (!BN_mod_lshift1_quick(tmp, Z4, p) || !BN_mod_add_quick(tmp, tmp, Z4, p) || !BN_mod_sub_quick(rh, rh, tmp, p) || !field_mul(group, rh, rh, &point->X, ctx)) { goto err; } } else { if (!field_mul(group, tmp, Z4, &group->a, ctx) || !BN_mod_add_quick(rh, rh, tmp, p) || !field_mul(group, rh, rh, &point->X, ctx)) { goto err; } } /* rh := rh + b*Z^6 */ if (!field_mul(group, tmp, &group->b, Z6, ctx) || !BN_mod_add_quick(rh, rh, tmp, p)) { goto err; } } else { /* rh := (rh + a)*X */ if (!BN_mod_add_quick(rh, rh, &group->a, p) || !field_mul(group, rh, rh, &point->X, ctx)) { goto err; } /* rh := rh + b */ if (!BN_mod_add_quick(rh, rh, &group->b, p)) { goto err; } } /* 'lh' := Y^2 */ if (!field_sqr(group, tmp, &point->Y, ctx)) { goto err; } ret = (0 == BN_ucmp(tmp, rh)); err: BN_CTX_end(ctx); BN_CTX_free(new_ctx); return ret; }
/*- * Computes the sum * scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1] * gracefully ignoring NULL scalar values. */ int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) { BN_CTX *new_ctx = NULL; int ret = 0; size_t i; EC_POINT *p = NULL; EC_POINT *acc = NULL; if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return 0; } /* * This implementation is more efficient than the wNAF implementation for * 2 or fewer points. Use the ec_wNAF_mul implementation for 3 or more * points, or if we can perform a fast multiplication based on * precomputation. */ if ((scalar && (num > 1)) || (num > 2) || (num == 0 && EC_GROUP_have_precompute_mult(group))) { ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); goto err; } if ((p = EC_POINT_new(group)) == NULL) goto err; if ((acc = EC_POINT_new(group)) == NULL) goto err; if (!EC_POINT_set_to_infinity(group, acc)) goto err; if (scalar) { if (!ec_GF2m_montgomery_point_multiply (group, p, scalar, group->generator, ctx)) goto err; if (BN_is_negative(scalar)) if (!group->meth->invert(group, p, ctx)) goto err; if (!group->meth->add(group, acc, acc, p, ctx)) goto err; } for (i = 0; i < num; i++) { if (!ec_GF2m_montgomery_point_multiply (group, p, scalars[i], points[i], ctx)) goto err; if (BN_is_negative(scalars[i])) if (!group->meth->invert(group, p, ctx)) goto err; if (!group->meth->add(group, acc, acc, p, ctx)) goto err; } if (!EC_POINT_copy(r, acc)) goto err; ret = 1; err: if (p) EC_POINT_free(p); if (acc) EC_POINT_free(acc); if (new_ctx != NULL) BN_CTX_free(new_ctx); return ret; }
int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { /* return values: * -1 error * 0 equal (in affine coordinates) * 1 not equal */ int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); BN_CTX *new_ctx = NULL; BIGNUM *tmp1, *tmp2, *Za23, *Zb23; const BIGNUM *tmp1_, *tmp2_; int ret = -1; if (EC_POINT_is_at_infinity(group, a)) { return EC_POINT_is_at_infinity(group, b) ? 0 : 1; } if (EC_POINT_is_at_infinity(group, b)) { return 1; } int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0; int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0; if (a_Z_is_one && b_Z_is_one) { return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; } field_mul = group->meth->field_mul; field_sqr = group->meth->field_sqr; if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) { return -1; } } BN_CTX_start(ctx); tmp1 = BN_CTX_get(ctx); tmp2 = BN_CTX_get(ctx); Za23 = BN_CTX_get(ctx); Zb23 = BN_CTX_get(ctx); if (Zb23 == NULL) { goto end; } /* We have to decide whether * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3), * or equivalently, whether * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3). */ if (!b_Z_is_one) { if (!field_sqr(group, Zb23, &b->Z, ctx) || !field_mul(group, tmp1, &a->X, Zb23, ctx)) { goto end; } tmp1_ = tmp1; } else { tmp1_ = &a->X; } if (!a_Z_is_one) { if (!field_sqr(group, Za23, &a->Z, ctx) || !field_mul(group, tmp2, &b->X, Za23, ctx)) { goto end; } tmp2_ = tmp2; } else { tmp2_ = &b->X; } /* compare X_a*Z_b^2 with X_b*Z_a^2 */ if (BN_cmp(tmp1_, tmp2_) != 0) { ret = 1; /* points differ */ goto end; } if (!b_Z_is_one) { if (!field_mul(group, Zb23, Zb23, &b->Z, ctx) || !field_mul(group, tmp1, &a->Y, Zb23, ctx)) { goto end; } /* tmp1_ = tmp1 */ } else { tmp1_ = &a->Y; } if (!a_Z_is_one) { if (!field_mul(group, Za23, Za23, &a->Z, ctx) || !field_mul(group, tmp2, &b->Y, Za23, ctx)) { goto end; } /* tmp2_ = tmp2 */ } else { tmp2_ = &b->Y; } /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */ if (BN_cmp(tmp1_, tmp2_) != 0) { ret = 1; /* points differ */ goto end; } /* points are equal */ ret = 0; end: BN_CTX_end(ctx); BN_CTX_free(new_ctx); return ret; }
static int dsa_builtin_paramgen(DSA *ret, int bits, unsigned char *seed_in, int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { int ok=0; unsigned char seed[SHA_DIGEST_LENGTH]; unsigned char md[SHA_DIGEST_LENGTH]; unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH]; BIGNUM *r0,*W,*X,*c,*test; BIGNUM *g=NULL,*q=NULL,*p=NULL; BN_MONT_CTX *mont=NULL; int k,n=0,i,b,m=0; int counter=0; int r=0; BN_CTX *ctx=NULL; unsigned int h=2; 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 < 20)) seed_in = NULL; /* seed buffer too small -- ignore */ if (seed_len > 20) seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED, * but our internal buffers are restricted to 160 bits*/ if ((seed_in != NULL) && (seed_len == 20)) { memcpy(seed,seed_in,seed_len); /* set seed_in to NULL to avoid it being copied back */ seed_in = NULL; } 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,SHA_DIGEST_LENGTH); seed_is_random = 1; } else { seed_is_random = 0; seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/ } memcpy(buf,seed,SHA_DIGEST_LENGTH); memcpy(buf2,seed,SHA_DIGEST_LENGTH); /* precompute "SEED + 1" for step 7: */ for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) { buf[i]++; if (buf[i] != 0) break; } /* step 2 */ EVP_Digest(seed,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL); EVP_Digest(buf,SHA_DIGEST_LENGTH,buf2,NULL,HASH, NULL); for (i=0; i<SHA_DIGEST_LENGTH; i++) md[i]^=buf2[i]; /* step 3 */ md[0]|=0x80; md[SHA_DIGEST_LENGTH-1]|=0x01; if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,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; b=(bits-1)-n*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=SHA_DIGEST_LENGTH-1; i >= 0; i--) { buf[i]++; if (buf[i] != 0) break; } EVP_Digest(buf,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL); /* step 8 */ if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0)) goto err; if (!BN_lshift(r0,r0,160*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 (seed_in != NULL) memcpy(seed_in,seed,20); if (counter_ret != NULL) *counter_ret=counter; if (h_ret != NULL) *h_ret=h; } if(ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (mont != NULL) BN_MONT_CTX_free(mont); return ok; }
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) { EVP_PKEY *pkey = NULL; #ifndef OPENSSL_NO_RSA RSA *rsa = NULL; #endif #ifndef OPENSSL_NO_DSA DSA *dsa = NULL; ASN1_TYPE *t1, *t2; ASN1_INTEGER *privkey; STACK_OF(ASN1_TYPE) *ndsa = NULL; #endif #ifndef OPENSSL_NO_EC EC_KEY *eckey = NULL; const unsigned char *p_tmp; #endif #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) ASN1_TYPE *param = NULL; BN_CTX *ctx = NULL; int plen; #endif X509_ALGOR *a; const unsigned char *p; const unsigned char *cp; int pkeylen; int nid; char obj_tmp[80]; if(p8->pkey->type == V_ASN1_OCTET_STRING) { p8->broken = PKCS8_OK; p = p8->pkey->value.octet_string->data; pkeylen = p8->pkey->value.octet_string->length; } else { p8->broken = PKCS8_NO_OCTET; p = p8->pkey->value.sequence->data; pkeylen = p8->pkey->value.sequence->length; } if (!(pkey = EVP_PKEY_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); return NULL; } a = p8->pkeyalg; nid = OBJ_obj2nid(a->algorithm); switch(nid) { #ifndef OPENSSL_NO_RSA case NID_rsaEncryption: cp = p; if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); return NULL; } EVP_PKEY_assign_RSA (pkey, rsa); break; #endif #ifndef OPENSSL_NO_DSA case NID_dsa: /* PKCS#8 DSA is weird: you just get a private key integer * and parameters in the AlgorithmIdentifier the pubkey must * be recalculated. */ /* Check for broken DSA PKCS#8, UGH! */ if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) { if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen, d2i_ASN1_TYPE, ASN1_TYPE_free))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } if(sk_ASN1_TYPE_num(ndsa) != 2 ) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } /* Handle Two broken types: * SEQUENCE {parameters, priv_key} * SEQUENCE {pub_key, priv_key} */ t1 = sk_ASN1_TYPE_value(ndsa, 0); t2 = sk_ASN1_TYPE_value(ndsa, 1); if(t1->type == V_ASN1_SEQUENCE) { p8->broken = PKCS8_EMBEDDED_PARAM; param = t1; } else if(a->parameter->type == V_ASN1_SEQUENCE) { p8->broken = PKCS8_NS_DB; param = a->parameter; } else { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } if(t2->type != V_ASN1_INTEGER) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } privkey = t2->value.integer; } else { if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } param = p8->pkeyalg->parameter; } if (!param || (param->type != V_ASN1_SEQUENCE)) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } cp = p = param->value.sequence->data; plen = param->value.sequence->length; if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } /* We have parameters now set private key */ if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR); goto dsaerr; } /* Calculate public key (ouch!) */ if (!(dsa->pub_key = BN_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!(ctx = BN_CTX_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR); goto dsaerr; } EVP_PKEY_assign_DSA(pkey, dsa); BN_CTX_free (ctx); if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); else ASN1_INTEGER_free(privkey); break; dsaerr: BN_CTX_free (ctx); sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); DSA_free(dsa); EVP_PKEY_free(pkey); return NULL; break; #endif #ifndef OPENSSL_NO_EC case NID_X9_62_id_ecPublicKey: p_tmp = p; /* extract the ec parameters */ param = p8->pkeyalg->parameter; if (!param || ((param->type != V_ASN1_SEQUENCE) && (param->type != V_ASN1_OBJECT))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto ecerr; } if (param->type == V_ASN1_SEQUENCE) { cp = p = param->value.sequence->data; plen = param->value.sequence->length; if (!(eckey = d2i_ECParameters(NULL, &cp, plen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto ecerr; } } else { EC_GROUP *group; cp = p = param->value.object->data; plen = param->value.object->length; /* type == V_ASN1_OBJECT => the parameters are given * by an asn1 OID */ if ((eckey = EC_KEY_new()) == NULL) { EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE); goto ecerr; } group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object)); if (group == NULL) goto ecerr; EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); if (EC_KEY_set_group(eckey, group) == 0) goto ecerr; EC_GROUP_free(group); } /* We have parameters now set private key */ if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen)) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto ecerr; } /* calculate public key (if necessary) */ if (EC_KEY_get0_public_key(eckey) == NULL) { const BIGNUM *priv_key; const EC_GROUP *group; EC_POINT *pub_key; /* the public key was not included in the SEC1 private * key => calculate the public key */ group = EC_KEY_get0_group(eckey); pub_key = EC_POINT_new(group); if (pub_key == NULL) { EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { EC_POINT_free(pub_key); EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } priv_key = EC_KEY_get0_private_key(eckey); if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) { EC_POINT_free(pub_key); EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } if (EC_KEY_set_public_key(eckey, pub_key) == 0) { EC_POINT_free(pub_key); EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } EC_POINT_free(pub_key); } EVP_PKEY_assign_EC_KEY(pkey, eckey); if (ctx) BN_CTX_free(ctx); break; ecerr: if (ctx) BN_CTX_free(ctx); if (eckey) EC_KEY_free(eckey); if (pkey) EVP_PKEY_free(pkey); return NULL; #endif default: EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp); else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm); ERR_add_error_data(2, "TYPE=", obj_tmp); EVP_PKEY_free (pkey); return NULL; } return pkey; }
BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) { BIGNUM local_n; BIGNUM *e,*n; BN_CTX *ctx; BN_BLINDING *ret = NULL; if (in_ctx == NULL) { if ((ctx = BN_CTX_new()) == NULL) return 0; } else ctx = in_ctx; BN_CTX_start(ctx); e = BN_CTX_get(ctx); if (e == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); goto err; } if (rsa->e == NULL) { e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); if (e == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); goto err; } } else e = rsa->e; if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL) { /* if PRNG is not properly seeded, resort to secret * exponent as unpredictable seed */ RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0); } if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { /* Set BN_FLG_CONSTTIME flag */ n = &local_n; BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); } else n = rsa->n; ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp, rsa->_method_mod_n); if (ret == NULL) { RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); goto err; } CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret)); err: BN_CTX_end(ctx); if (in_ctx == NULL) BN_CTX_free(ctx); if(rsa->e == NULL) BN_free(e); return ret; }
/* * Verifies gost 2001 signature * */ int gost2001_do_verify(const unsigned char *dgst,int dgst_len, DSA_SIG *sig, EC_KEY *ec) { BN_CTX *ctx=BN_CTX_new(); const EC_GROUP *group = EC_KEY_get0_group(ec); BIGNUM *order; BIGNUM *md = NULL,*e=NULL,*R=NULL,*v=NULL,*z1=NULL,*z2=NULL; BIGNUM *X=NULL,*tmp=NULL; EC_POINT *C = NULL; const EC_POINT *pub_key=NULL; int ok=0; BN_CTX_start(ctx); order = BN_CTX_get(ctx); e = BN_CTX_get(ctx); z1 = BN_CTX_get(ctx); z2 = BN_CTX_get(ctx); tmp = BN_CTX_get(ctx); X= BN_CTX_get(ctx); R=BN_CTX_get(ctx); v=BN_CTX_get(ctx); EC_GROUP_get_order(group,order,ctx); pub_key = EC_KEY_get0_public_key(ec); if (BN_is_zero(sig->s) || BN_is_zero(sig->r) || (BN_cmp(sig->s,order)>=1) || (BN_cmp(sig->r,order)>=1)) { GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); goto err; } md = hashsum2bn(dgst); BN_mod(e,md,order,ctx); #ifdef DEBUG_SIGN fprintf(stderr,"digest as bignum: "); BN_print_fp(stderr,md); fprintf(stderr,"\ndigest mod q: "); BN_print_fp(stderr,e); #endif if (BN_is_zero(e)) BN_one(e); v=BN_mod_inverse(v,e,order,ctx); BN_mod_mul(z1,sig->s,v,order,ctx); BN_sub(tmp,order,sig->r); BN_mod_mul(z2,tmp,v,order,ctx); #ifdef DEBUG_SIGN fprintf(stderr,"\nInverted digest value: "); BN_print_fp(stderr,v); fprintf(stderr,"\nz1: "); BN_print_fp(stderr,z1); fprintf(stderr,"\nz2: "); BN_print_fp(stderr,z2); #endif C = EC_POINT_new(group); if (!EC_POINT_mul(group,C,z1,pub_key,z2,ctx)) { GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB); goto err; } if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) { GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB); goto err; } BN_mod(R,X,order,ctx); #ifdef DEBUG_SIGN fprintf(stderr,"\nX="); BN_print_fp(stderr,X); fprintf(stderr,"\nX mod q="); BN_print_fp(stderr,R); fprintf(stderr,"\n"); #endif if (BN_cmp(R,sig->r)!=0) { GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH); } else { ok = 1; } err: EC_POINT_free(C); BN_CTX_end(ctx); BN_CTX_free(ctx); BN_free(md); return ok; }
int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, int do_trial_division, BN_GENCB *cb) { int i, j, ret = -1; int k; BN_CTX *ctx = NULL; BIGNUM *A1, *A1_odd, *check; /* taken from ctx */ BN_MONT_CTX *mont = NULL; const BIGNUM *A = NULL; if (BN_cmp(a, BN_value_one()) <= 0) return 0; if (checks == BN_prime_checks) checks = BN_prime_checks_for_size(BN_num_bits(a)); /* first look for small factors */ if (!BN_is_odd(a)) /* a is even => a is prime if and only if a == 2 */ return BN_is_word(a, 2); if (do_trial_division) { for (i = 1; i < NUMPRIMES; i++) if (BN_mod_word(a, primes[i]) == 0) return 0; if(!BN_GENCB_call(cb, 1, -1)) goto err; } if (ctx_passed != NULL) ctx = ctx_passed; else if ((ctx=BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); /* A := abs(a) */ if (a->neg) { BIGNUM *t; if ((t = BN_CTX_get(ctx)) == NULL) goto err; BN_copy(t, a); t->neg = 0; A = t; } else A = a; A1 = BN_CTX_get(ctx); A1_odd = BN_CTX_get(ctx); check = BN_CTX_get(ctx); if (check == NULL) goto err; /* compute A1 := A - 1 */ if (!BN_copy(A1, A)) goto err; if (!BN_sub_word(A1, 1)) goto err; if (BN_is_zero(A1)) { ret = 0; goto err; } /* write A1 as A1_odd * 2^k */ k = 1; while (!BN_is_bit_set(A1, k)) k++; if (!BN_rshift(A1_odd, A1, k)) goto err; /* Montgomery setup for computations mod A */ mont = BN_MONT_CTX_new(); if (mont == NULL) goto err; if (!BN_MONT_CTX_set(mont, A, ctx)) goto err; for (i = 0; i < checks; i++) { if (!BN_pseudo_rand_range(check, A1)) goto err; if (!BN_add_word(check, 1)) goto err; /* now 1 <= check < A */ j = witness(check, A, A1, A1_odd, k, ctx, mont); if (j == -1) goto err; if (j) { ret=0; goto err; } if(!BN_GENCB_call(cb, 1, i)) goto err; } ret=1; err: if (ctx != NULL) { BN_CTX_end(ctx); if (ctx_passed == NULL) BN_CTX_free(ctx); } if (mont != NULL) BN_MONT_CTX_free(mont); return(ret); }
/* * Computes gost2001 signature as DSA_SIG structure * * */ DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey) { DSA_SIG *newsig = NULL; BIGNUM *md = hashsum2bn(dgst); BIGNUM *order = NULL; const EC_GROUP *group; const BIGNUM *priv_key; BIGNUM *r=NULL,*s=NULL,*X=NULL,*tmp=NULL,*tmp2=NULL, *k=NULL,*e=NULL; EC_POINT *C=NULL; BN_CTX *ctx = BN_CTX_new(); BN_CTX_start(ctx); OPENSSL_assert(dlen==32); newsig=DSA_SIG_new(); if (!newsig) { GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_NO_MEMORY); goto err; } group = EC_KEY_get0_group(eckey); order=BN_CTX_get(ctx); EC_GROUP_get_order(group,order,ctx); priv_key = EC_KEY_get0_private_key(eckey); e = BN_CTX_get(ctx); BN_mod(e,md,order,ctx); #ifdef DEBUG_SIGN fprintf(stderr,"digest as bignum="); BN_print_fp(stderr,md); fprintf(stderr,"\ndigest mod q="); BN_print_fp(stderr,e); fprintf(stderr,"\n"); #endif if (BN_is_zero(e)) { BN_one(e); } k =BN_CTX_get(ctx); C=EC_POINT_new(group); do { do { if (!BN_rand_range(k,order)) { GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); DSA_SIG_free(newsig); newsig = NULL; goto err; } if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx)) { GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB); DSA_SIG_free(newsig); newsig = NULL; goto err; } if (!X) X=BN_CTX_get(ctx); if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) { GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB); DSA_SIG_free(newsig); newsig = NULL; goto err; } if (!r) r=BN_CTX_get(ctx); BN_nnmod(r,X,order,ctx); } while (BN_is_zero(r)); /* s = (r*priv_key+k*e) mod order */ if (!tmp) tmp = BN_CTX_get(ctx); BN_mod_mul(tmp,priv_key,r,order,ctx); if (!tmp2) tmp2 = BN_CTX_get(ctx); BN_mod_mul(tmp2,k,e,order,ctx); if (!s) s=BN_CTX_get(ctx); BN_mod_add(s,tmp,tmp2,order,ctx); } while (BN_is_zero(s)); newsig->s=BN_dup(s); newsig->r=BN_dup(r); err: BN_CTX_end(ctx); BN_CTX_free(ctx); EC_POINT_free(C); BN_free(md); return newsig; }
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) { int ok = 0, i; BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL; const BIGNUM *ckinv; BN_CTX *ctx = NULL; const EC_GROUP *group; ECDSA_SIG *ret; ECDSA_DATA *ecdsa; const BIGNUM *priv_key; ecdsa = ecdsa_check(eckey); group = EC_KEY_get0_group(eckey); priv_key = EC_KEY_get0_private_key(eckey); if (group == NULL || priv_key == NULL || ecdsa == NULL) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); return NULL; } ret = ECDSA_SIG_new(); if (!ret) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); return NULL; } s = ret->s; if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); goto err; } if (!EC_GROUP_get_order(group, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); goto err; } i = BN_num_bits(order); /* Need to truncate digest if it is too long: first truncate whole * bytes. */ if (8 * dgst_len > i) dgst_len = (i + 7)/8; if (!BN_bin2bn(dgst, dgst_len, m)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } /* If still too long truncate remaining bits with a shift */ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } do { if (in_kinv == NULL || in_r == NULL) { if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB); goto err; } ckinv = kinv; } else { ckinv = in_kinv; if (BN_copy(ret->r, in_r) == NULL) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); goto err; } } if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } if (!BN_mod_add_quick(s, tmp, m, order)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } if (!BN_mod_mul(s, s, ckinv, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } if (BN_is_zero(s)) { /* if kinv and r have been supplied by the caller * don't to generate new kinv and r values */ if (in_kinv != NULL && in_r != NULL) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES); goto err; } } else /* s != 0 => we have a valid signature */ break; } while (1); ok = 1; err: if (!ok) { ECDSA_SIG_free(ret); ret = NULL; } BN_CTX_free(ctx); BN_clear_free(m); BN_clear_free(tmp); BN_free(order); BN_clear_free(kinv); return ret; }
int main(int argc, char *argv[]) { BN_CTX *ctx; BIO *out; char *outfile=NULL; results = 0; RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */ argc--; argv++; while (argc >= 1) { if (strcmp(*argv,"-results") == 0) results=1; else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) break; outfile= *(++argv); } argc--; argv++; } ctx=BN_CTX_new(); if (ctx == NULL) EXIT(1); out=BIO_new(BIO_s_file()); if (out == NULL) EXIT(1); if (outfile == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); } else { if (!BIO_write_filename(out,outfile)) { perror(outfile); EXIT(1); } } if (!results) BIO_puts(out,"obase=16\nibase=16\n"); message(out,"BN_add"); if (!test_add(out)) goto err; (void)BIO_flush(out); message(out,"BN_sub"); if (!test_sub(out)) goto err; (void)BIO_flush(out); message(out,"BN_lshift1"); if (!test_lshift1(out)) goto err; (void)BIO_flush(out); message(out,"BN_lshift (fixed)"); if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL))) goto err; (void)BIO_flush(out); message(out,"BN_lshift"); if (!test_lshift(out,ctx,NULL)) goto err; (void)BIO_flush(out); message(out,"BN_rshift1"); if (!test_rshift1(out)) goto err; (void)BIO_flush(out); message(out,"BN_rshift"); if (!test_rshift(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_sqr"); if (!test_sqr(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_mul"); if (!test_mul(out)) goto err; (void)BIO_flush(out); message(out,"BN_div"); if (!test_div(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_div_word"); if (!test_div_word(out)) goto err; (void)BIO_flush(out); message(out,"BN_div_recp"); if (!test_div_recp(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_mod"); if (!test_mod(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_mod_mul"); if (!test_mod_mul(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_mont"); if (!test_mont(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_mod_exp"); if (!test_mod_exp(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_mod_exp_mont_consttime"); if (!test_mod_exp_mont_consttime(out,ctx)) goto err; if (!test_mod_exp_mont5(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_exp"); if (!test_exp(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_kronecker"); if (!test_kron(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_mod_sqrt"); if (!test_sqrt(out,ctx)) goto err; (void)BIO_flush(out); message(out,"Small prime generation"); if (!test_small_prime(out,ctx)) goto err; (void)BIO_flush(out); #ifndef OPENSSL_NO_EC2M message(out,"BN_GF2m_add"); if (!test_gf2m_add(out)) goto err; (void)BIO_flush(out); message(out,"BN_GF2m_mod"); if (!test_gf2m_mod(out)) goto err; (void)BIO_flush(out); message(out,"BN_GF2m_mod_mul"); if (!test_gf2m_mod_mul(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_GF2m_mod_sqr"); if (!test_gf2m_mod_sqr(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_GF2m_mod_inv"); if (!test_gf2m_mod_inv(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_GF2m_mod_div"); if (!test_gf2m_mod_div(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_GF2m_mod_exp"); if (!test_gf2m_mod_exp(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_GF2m_mod_sqrt"); if (!test_gf2m_mod_sqrt(out,ctx)) goto err; (void)BIO_flush(out); message(out,"BN_GF2m_mod_solve_quad"); if (!test_gf2m_mod_solve_quad(out,ctx)) goto err; (void)BIO_flush(out); #endif BN_CTX_free(ctx); BIO_free(out); /**/ EXIT(0); err: BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices * the failure, see test_bn in test/Makefile.ssl*/ (void)BIO_flush(out); ERR_load_crypto_strings(); ERR_print_errors_fp(stderr); EXIT(1); return(1); }
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { BN_CTX *ctx = NULL; BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; EC_POINT *tmp_point=NULL; const EC_GROUP *group; int ret = 0; if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (ctx_in == NULL) { if ((ctx = BN_CTX_new()) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE); return 0; } } else ctx = ctx_in; k = BN_new(); /* this value is later returned in *kinvp */ r = BN_new(); /* this value is later returned in *rp */ order = BN_new(); X = BN_new(); if (!k || !r || !order || !X) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); goto err; } if ((tmp_point = EC_POINT_new(group)) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } if (!EC_GROUP_get_order(group, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } do { /* get random k */ do if (!BN_rand_range(k, order)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); goto err; } while (BN_is_zero(k)); /* We do not want timing information to leak the length of k, * so we compute G*k using an equivalent scalar of fixed * bit-length. */ if (!BN_add(k, k, order)) goto err; if (BN_num_bits(k) <= BN_num_bits(order)) if (!BN_add(k, k, order)) goto err; /* compute r the x-coordinate of generator * k */ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp(group, tmp_point, X, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); goto err; } } #ifndef OPENSSL_NO_EC2M else /* NID_X9_62_characteristic_two_field */ { if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp_point, X, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); goto err; } } #endif if (!BN_nnmod(r, X, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } } while (BN_is_zero(r)); /* compute the inverse of k */ if (!BN_mod_inverse(k, k, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } /* clear old values if necessary */ BN_clear_free(*rp); BN_clear_free(*kinvp); /* save the pre-computed values */ *rp = r; *kinvp = k; ret = 1; err: if (!ret) { BN_clear_free(k); BN_clear_free(r); } if (ctx_in == NULL) BN_CTX_free(ctx); BN_free(order); EC_POINT_free(tmp_point); BN_clear_free(X); return(ret); }
/* 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; } 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 EC_KEY_check_key(const EC_KEY *eckey) { int ok = 0; BN_CTX *ctx = NULL; const BIGNUM *order = NULL; EC_POINT *point = NULL; if (!eckey || !eckey->group || !eckey->pub_key) { ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY); goto err; } if ((ctx = BN_CTX_new()) == NULL) goto err; if ((point = EC_POINT_new(eckey->group)) == NULL) goto err; /* testing whether the pub_key is on the elliptic curve */ if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) { ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); goto err; } /* testing whether pub_key * order is the point at infinity */ order = eckey->group->order; if (BN_is_zero(order)) { ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); goto err; } if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); goto err; } if (!EC_POINT_is_at_infinity(eckey->group, point)) { ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); goto err; } /* * in case the priv_key is present : check if generator * priv_key == * pub_key */ if (eckey->priv_key) { if (BN_cmp(eckey->priv_key, order) >= 0) { ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); goto err; } if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) { ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); goto err; } if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY); goto err; } } ok = 1; err: if (ctx != NULL) BN_CTX_free(ctx); EC_POINT_free(point); return (ok); }
static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA *dsa) { BIGNUM *kinv=NULL,*r=NULL,*s=NULL; BIGNUM m; BIGNUM xr; BN_CTX *ctx=NULL; int i,reason=ERR_R_BN_LIB; DSA_SIG *ret=NULL; if(FIPS_selftest_failed()) { FIPSerr(FIPS_F_DSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED); return NULL; } if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) { DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL); return NULL; } BN_init(&m); BN_init(&xr); if (!dsa->p || !dsa->q || !dsa->g) { reason=DSA_R_MISSING_PARAMETERS; goto err; } s=BN_new(); if (s == NULL) goto err; i=BN_num_bytes(dsa->q); /* should be 20 */ if ((dlen > i) || (dlen > 50)) { reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE; goto err; } ctx=BN_CTX_new(); if (ctx == NULL) goto err; if (!dsa->meth->dsa_sign_setup(dsa,ctx,&kinv,&r)) goto err; if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err; /* Compute s = inv(k) (m + xr) mod q */ if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */ if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */ if (BN_cmp(s,dsa->q) > 0) BN_sub(s,s,dsa->q); if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err; ret= DSA_SIG_new(); if (ret == NULL) goto err; ret->r = r; ret->s = s; err: if (!ret) { DSAerr(DSA_F_DSA_DO_SIGN,reason); BN_free(r); BN_free(s); } if (ctx != NULL) BN_CTX_free(ctx); BN_clear_free(&m); BN_clear_free(&xr); if (kinv != NULL) /* dsa->kinv is NULL now if we used it */ BN_clear_free(kinv); return(ret); }