From 52628ee3f51f011b463aaedb1a28aa0524b43cb3 Mon Sep 17 00:00:00 2001 From: miod <> Date: Sun, 13 Apr 2014 15:16:40 +0000 Subject: Import OpenSSL 1.0.1g --- src/lib/libcrypto/ec/ec.h | 28 ++++++++++++++++++---------- src/lib/libcrypto/ec/ec2_mult.c | 27 ++++++++++++++++----------- src/lib/libcrypto/ec/ec_ameth.c | 2 +- src/lib/libcrypto/ec/ec_asn1.c | 6 ++++-- src/lib/libcrypto/ec/ec_key.c | 13 +++++++++++-- src/lib/libcrypto/ec/ec_lib.c | 10 +++++----- src/lib/libcrypto/ec/ec_pmeth.c | 2 +- src/lib/libcrypto/ec/ecp_mont.c | 1 - 8 files changed, 56 insertions(+), 33 deletions(-) (limited to 'src/lib/libcrypto/ec') diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h index 9d01325af3..dfe8710d33 100644 --- a/src/lib/libcrypto/ec/ec.h +++ b/src/lib/libcrypto/ec/ec.h @@ -274,10 +274,10 @@ int EC_GROUP_get_curve_name(const EC_GROUP *group); void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); int EC_GROUP_get_asn1_flag(const EC_GROUP *group); -void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t); +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, point_conversion_form_t form); point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); -unsigned char *EC_GROUP_get0_seed(const EC_GROUP *); +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x); size_t EC_GROUP_get_seed_len(const EC_GROUP *); size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); @@ -626,8 +626,8 @@ int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *c */ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); -int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); -int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx); /** Computes r = generator * n sum_{i=0}^num p[i] * m[i] * \param group underlying EC_GROUP object @@ -800,16 +800,24 @@ const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); unsigned EC_KEY_get_enc_flags(const EC_KEY *key); -void EC_KEY_set_enc_flags(EC_KEY *, unsigned int); -point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *); -void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t); +void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags); +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); +void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform); /* functions to set/get method specific data */ -void *EC_KEY_get_key_method_data(EC_KEY *, +void *EC_KEY_get_key_method_data(EC_KEY *key, void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)); -void EC_KEY_insert_key_method_data(EC_KEY *, void *data, +/** Sets the key method data of an EC_KEY object, if none has yet been set. + * \param key EC_KEY object + * \param data opaque data to install. + * \param dup_func a function that duplicates |data|. + * \param free_func a function that frees |data|. + * \param clear_free_func a function that wipes and frees |data|. + * \return the previously set data pointer, or NULL if |data| was inserted. + */ +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 *)); /* wrapper functions for the underlying EC_GROUP object */ -void EC_KEY_set_asn1_flag(EC_KEY *, int); +void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); /** Creates a table of pre-computed multiples of the generator to * accelerate further EC_KEY operations. diff --git a/src/lib/libcrypto/ec/ec2_mult.c b/src/lib/libcrypto/ec/ec2_mult.c index 26f4a783fc..1c575dc47a 100644 --- a/src/lib/libcrypto/ec/ec2_mult.c +++ b/src/lib/libcrypto/ec/ec2_mult.c @@ -208,11 +208,15 @@ static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIG return ret; } + /* Computes scalar*point and stores the result in r. * point can not equal r. - * Uses algorithm 2P of + * Uses a modified algorithm 2P of * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over * GF(2^m) without precomputation" (CHES '99, LNCS 1717). + * + * To protect against side-channel attack the function uses constant time swap, + * avoiding conditional branches. */ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx) @@ -246,6 +250,11 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, x2 = &r->X; z2 = &r->Y; + bn_wexpand(x1, group->field.top); + bn_wexpand(z1, group->field.top); + bn_wexpand(x2, group->field.top); + bn_wexpand(z2, group->field.top); + if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */ if (!BN_one(z1)) goto err; /* z1 = 1 */ if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */ @@ -270,16 +279,12 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, word = scalar->d[i]; while (mask) { - if (word & mask) - { - if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err; - if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err; - } - else - { - if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; - if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; - } + BN_consttime_swap(word & mask, x1, x2, group->field.top); + BN_consttime_swap(word & mask, z1, z2, group->field.top); + if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; + if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; + BN_consttime_swap(word & mask, x1, x2, group->field.top); + BN_consttime_swap(word & mask, z1, z2, group->field.top); mask >>= 1; } mask = BN_TBIT; diff --git a/src/lib/libcrypto/ec/ec_ameth.c b/src/lib/libcrypto/ec/ec_ameth.c index 83909c1853..0ce4524076 100644 --- a/src/lib/libcrypto/ec/ec_ameth.c +++ b/src/lib/libcrypto/ec/ec_ameth.c @@ -88,7 +88,7 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) if (!pstr) return 0; pstr->length = i2d_ECParameters(ec_key, &pstr->data); - if (pstr->length < 0) + if (pstr->length <= 0) { ASN1_STRING_free(pstr); ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB); diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c index 175eec5342..145807b611 100644 --- a/src/lib/libcrypto/ec/ec_asn1.c +++ b/src/lib/libcrypto/ec/ec_asn1.c @@ -89,7 +89,8 @@ int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) if (group == NULL) return 0; - if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != + NID_X9_62_characteristic_two_field || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0))) { ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); @@ -107,7 +108,8 @@ int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, if (group == NULL) return 0; - if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != + NID_X9_62_characteristic_two_field || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0))) { ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); diff --git a/src/lib/libcrypto/ec/ec_key.c b/src/lib/libcrypto/ec/ec_key.c index bf9fd2dc2c..7fa247593d 100644 --- a/src/lib/libcrypto/ec/ec_key.c +++ b/src/lib/libcrypto/ec/ec_key.c @@ -520,18 +520,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) diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c index 25247b5803..de9a0cc2b3 100644 --- a/src/lib/libcrypto/ec/ec_lib.c +++ b/src/lib/libcrypto/ec/ec_lib.c @@ -480,10 +480,10 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) != EC_METHOD_get_field_type(EC_GROUP_method_of(b))) return 1; - /* compare the curve name (if present) */ + /* compare the curve name (if present in both) */ if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) && - EC_GROUP_get_curve_name(a) == EC_GROUP_get_curve_name(b)) - return 0; + EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b)) + return 1; if (!ctx) ctx_new = ctx = BN_CTX_new(); @@ -993,12 +993,12 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN if (group->meth->point_cmp == 0) { ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + return -1; } if ((group->meth != a->meth) || (a->meth != b->meth)) { ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS); - return 0; + return -1; } return group->meth->point_cmp(group, a, b, ctx); } diff --git a/src/lib/libcrypto/ec/ec_pmeth.c b/src/lib/libcrypto/ec/ec_pmeth.c index d1ed66c37e..66ee397d86 100644 --- a/src/lib/libcrypto/ec/ec_pmeth.c +++ b/src/lib/libcrypto/ec/ec_pmeth.c @@ -188,7 +188,7 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); - /* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is + /* NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is * not an error, the result is truncated. */ diff --git a/src/lib/libcrypto/ec/ecp_mont.c b/src/lib/libcrypto/ec/ecp_mont.c index 079e47431b..f04f132c7a 100644 --- a/src/lib/libcrypto/ec/ecp_mont.c +++ b/src/lib/libcrypto/ec/ecp_mont.c @@ -114,7 +114,6 @@ const EC_METHOD *EC_GFp_mont_method(void) ec_GFp_mont_field_decode, ec_GFp_mont_field_set_to_one }; - return &ret; #endif } -- cgit v1.2.3-55-g6feb