X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fec%2Fec_key.c;h=7a15e5f159f82457e5655ea20db445028be5ce28;hp=59bc08494eb78cfa9a465197ad69a86d42726250;hb=8a99cb29d1f0013243a532bccc1dc70ed678eebe;hpb=a6311f856b9ed7d71460872148a735335338918e diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index 59bc08494e..7a15e5f159 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -80,10 +80,12 @@ EC_KEY *EC_KEY_new(void) } ret->version = 1; + ret->flags = 0; ret->group = NULL; ret->pub_key = NULL; ret->priv_key= NULL; ret->enc_flag= 0; + ret->nonce_from_hash_flag = 0; ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; ret->references= 1; ret->method_data = NULL; @@ -197,8 +199,10 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) /* copy the rest */ dest->enc_flag = src->enc_flag; + dest->nonce_from_hash_flag = src->nonce_from_hash_flag; dest->conv_form = src->conv_form; dest->version = src->version; + dest->flags = src->flags; return dest; } @@ -235,6 +239,8 @@ int EC_KEY_up_ref(EC_KEY *r) #ifdef OPENSSL_FIPS #include +#include +#include static int fips_check_ec(EC_KEY *key) { @@ -244,7 +250,7 @@ static int fips_check_ec(EC_KEY *key) pk.pkey.ec = key; if (!fips_pkey_signature_test(FIPS_TEST_PAIRWISE, - &pk, tbs, -1, NULL, 0, NULL, 0, NULL)) + &pk, tbs, 0, NULL, 0, NULL, 0, NULL)) { FIPSerr(FIPS_F_FIPS_CHECK_EC,FIPS_R_PAIRWISE_TEST_FAILED); fips_set_selftest_fail(); @@ -253,6 +259,46 @@ static int fips_check_ec(EC_KEY *key) return 1; } +int fips_check_ec_prng(EC_KEY *ec) + { + int bits, strength; + if (!FIPS_module_mode()) + return 1; + + if (ec->flags & (EC_FLAG_NON_FIPS_ALLOW|EC_FLAG_FIPS_CHECKED)) + return 1; + + if (!ec->group) + return 1; + + bits = BN_num_bits(&ec->group->order); + + if (bits < 160) + { + FIPSerr(FIPS_F_FIPS_CHECK_EC_PRNG,FIPS_R_KEY_TOO_SHORT); + return 0; + } + /* Comparable algorithm strengths: from SP800-57 table 2 */ + if (bits >= 512) + strength = 256; + else if (bits >= 384) + strength = 192; + else if (bits >= 256) + strength = 128; + else if (bits >= 224) + strength = 112; + else + strength = 80; + + + if (FIPS_rand_strength() >= strength) + return 1; + + FIPSerr(FIPS_F_FIPS_CHECK_EC_PRNG,FIPS_R_PRNG_STRENGTH_TOO_LOW); + return 0; + + } + #endif int EC_KEY_generate_key(EC_KEY *eckey) @@ -262,6 +308,14 @@ int EC_KEY_generate_key(EC_KEY *eckey) BIGNUM *priv_key = NULL, *order = NULL; EC_POINT *pub_key = NULL; +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_EC_KEY_GENERATE_KEY,FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } +#endif + if (!eckey || !eckey->group) { ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); @@ -283,6 +337,11 @@ int EC_KEY_generate_key(EC_KEY *eckey) if (!EC_GROUP_get_order(eckey->group, order, ctx)) goto err; +#ifdef OPENSSL_FIPS + if (!fips_check_ec_prng(eckey)) + goto err; +#endif + do if (!BN_rand_range(priv_key, order)) goto err; @@ -454,10 +513,12 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y) tx, ty, ctx)) goto err; } - /* Check if retrieved coordinates match originals: if not values - * are out of range. + /* Check if retrieved coordinates match originals and are less than + * field order: if not values are out of range. */ - if (BN_cmp(x, tx) || BN_cmp(y, ty)) + if (BN_cmp(x, tx) || BN_cmp(y, ty) + || (BN_cmp(x, &key->group->field) >= 0) + || (BN_cmp(y, &key->group->field) >= 0)) { ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, EC_R_COORDINATES_OUT_OF_RANGE); @@ -530,6 +591,16 @@ void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) key->enc_flag = flags; } +int EC_KEY_get_nonce_from_hash(const EC_KEY *key) + { + return key->nonce_from_hash_flag; + } + +void EC_KEY_set_nonce_from_hash(EC_KEY *key, int on) + { + key->nonce_from_hash_flag = on != 0; + } + point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) { return key->conv_form; @@ -545,18 +616,27 @@ void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) void *EC_KEY_get_key_method_data(EC_KEY *key, void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)) { - return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); + void *ret; + + CRYPTO_r_lock(CRYPTO_LOCK_EC); + ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); + CRYPTO_r_unlock(CRYPTO_LOCK_EC); + + return ret; } -void EC_KEY_insert_key_method_data(EC_KEY *key, void *data, +void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)) { EC_EXTRA_DATA *ex_data; + CRYPTO_w_lock(CRYPTO_LOCK_EC); ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); if (ex_data == NULL) EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func); CRYPTO_w_unlock(CRYPTO_LOCK_EC); + + return ex_data; } void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) @@ -571,3 +651,18 @@ int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) return 0; return EC_GROUP_precompute_mult(key->group, ctx); } + +int EC_KEY_get_flags(const EC_KEY *key) + { + return key->flags; + } + +void EC_KEY_set_flags(EC_KEY *key, int flags) + { + key->flags |= flags; + } + +void EC_KEY_clear_flags(EC_KEY *key, int flags) + { + key->flags &= ~flags; + }