diff options
Diffstat (limited to 'thirdparty/openssl/crypto/ec')
-rw-r--r-- | thirdparty/openssl/crypto/ec/ec2_mult.c | 20 | ||||
-rw-r--r-- | thirdparty/openssl/crypto/ec/ec_ameth.c | 36 | ||||
-rw-r--r-- | thirdparty/openssl/crypto/ec/ec_asn1.c | 11 | ||||
-rw-r--r-- | thirdparty/openssl/crypto/ec/ec_key.c | 13 | ||||
-rw-r--r-- | thirdparty/openssl/crypto/ec/ec_mult.c | 12 | ||||
-rw-r--r-- | thirdparty/openssl/crypto/ec/eck_prn.c | 2 | ||||
-rw-r--r-- | thirdparty/openssl/crypto/ec/ecp_nistz256.c | 125 |
7 files changed, 139 insertions, 80 deletions
diff --git a/thirdparty/openssl/crypto/ec/ec2_mult.c b/thirdparty/openssl/crypto/ec/ec2_mult.c index 68cc8771d5..1f9cc00aea 100644 --- a/thirdparty/openssl/crypto/ec/ec2_mult.c +++ b/thirdparty/openssl/crypto/ec/ec2_mult.c @@ -267,7 +267,7 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, BN_CTX *ctx) { BIGNUM *x1, *x2, *z1, *z2; - int ret = 0, i; + int ret = 0, i, group_top; BN_ULONG mask, word; if (r == point) { @@ -297,10 +297,12 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, 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); + group_top = group->field.top; + if (bn_wexpand(x1, group_top) == NULL + || bn_wexpand(z1, group_top) == NULL + || bn_wexpand(x2, group_top) == NULL + || bn_wexpand(z2, group_top) == NULL) + goto err; if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */ @@ -329,14 +331,14 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, for (; i >= 0; i--) { word = scalar->d[i]; while (mask) { - BN_consttime_swap(word & mask, x1, x2, group->field.top); - BN_consttime_swap(word & mask, z1, z2, group->field.top); + BN_consttime_swap(word & mask, x1, x2, group_top); + BN_consttime_swap(word & mask, z1, z2, group_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); + BN_consttime_swap(word & mask, x1, x2, group_top); + BN_consttime_swap(word & mask, z1, z2, group_top); mask >>= 1; } mask = BN_TBIT; diff --git a/thirdparty/openssl/crypto/ec/ec_ameth.c b/thirdparty/openssl/crypto/ec/ec_ameth.c index 83e208cfe4..2c41c6e7a9 100644 --- a/thirdparty/openssl/crypto/ec/ec_ameth.c +++ b/thirdparty/openssl/crypto/ec/ec_ameth.c @@ -66,9 +66,12 @@ #endif #include <openssl/asn1t.h> #include "asn1_locl.h" +#include "ec_lcl.h" +#ifndef OPENSSL_NO_CMS static int ecdh_cms_decrypt(CMS_RecipientInfo *ri); static int ecdh_cms_encrypt(CMS_RecipientInfo *ri); +#endif static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) { @@ -221,6 +224,8 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), *pb = EC_KEY_get0_public_key(b->pkey.ec); + if (group == NULL || pa == NULL || pb == NULL) + return -2; r = EC_POINT_cmp(group, pa, pb, NULL); if (r == 0) return 1; @@ -299,15 +304,13 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { - EC_KEY *ec_key; + EC_KEY ec_key = *(pkey->pkey.ec); unsigned char *ep, *p; int eplen, ptype; void *pval; - unsigned int tmp_flags, old_flags; + unsigned int old_flags; - ec_key = pkey->pkey.ec; - - if (!eckey_param2type(&ptype, &pval, ec_key)) { + if (!eckey_param2type(&ptype, &pval, &ec_key)) { ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); return 0; } @@ -318,34 +321,31 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) * do not include the parameters in the SEC1 private key see PKCS#11 * 12.11 */ - old_flags = EC_KEY_get_enc_flags(ec_key); - tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; - EC_KEY_set_enc_flags(ec_key, tmp_flags); - eplen = i2d_ECPrivateKey(ec_key, NULL); + old_flags = EC_KEY_get_enc_flags(&ec_key); + EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS); + + eplen = i2d_ECPrivateKey(&ec_key, NULL); if (!eplen) { - EC_KEY_set_enc_flags(ec_key, old_flags); ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); return 0; } ep = (unsigned char *)OPENSSL_malloc(eplen); if (!ep) { - EC_KEY_set_enc_flags(ec_key, old_flags); ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); return 0; } p = ep; - if (!i2d_ECPrivateKey(ec_key, &p)) { - EC_KEY_set_enc_flags(ec_key, old_flags); + if (!i2d_ECPrivateKey(&ec_key, &p)) { OPENSSL_free(ep); ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); return 0; } - /* restore old encoding flags */ - EC_KEY_set_enc_flags(ec_key, old_flags); if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, - ptype, pval, ep, eplen)) + ptype, pval, ep, eplen)) { + OPENSSL_free(ep); return 0; + } return 1; } @@ -378,7 +378,7 @@ static int ec_bits(const EVP_PKEY *pkey) static int ec_missing_parameters(const EVP_PKEY *pkey) { - if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) + if (pkey->pkey.ec == NULL || EC_KEY_get0_group(pkey->pkey.ec) == NULL) return 1; return 0; } @@ -398,6 +398,8 @@ static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), *group_b = EC_KEY_get0_group(b->pkey.ec); + if (group_a == NULL || group_b == NULL) + return -2; if (EC_GROUP_cmp(group_a, group_b, NULL)) return 0; else diff --git a/thirdparty/openssl/crypto/ec/ec_asn1.c b/thirdparty/openssl/crypto/ec/ec_asn1.c index 33abf61f44..b0cd3e1788 100644 --- a/thirdparty/openssl/crypto/ec/ec_asn1.c +++ b/thirdparty/openssl/crypto/ec/ec_asn1.c @@ -62,17 +62,22 @@ #include <openssl/asn1t.h> #include <openssl/objects.h> +#define OSSL_NELEM(x) (sizeof(x)/sizeof(x[0])) + int EC_GROUP_get_basis_type(const EC_GROUP *group) { - int i = 0; + int i; if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != NID_X9_62_characteristic_two_field) /* everything else is currently not supported */ return 0; - while (group->poly[i] != 0) - i++; + /* Find the last non-zero element of group->poly[] */ + for (i = 0; + i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0; + i++) + continue; if (i == 4) return NID_X9_62_ppBasis; diff --git a/thirdparty/openssl/crypto/ec/ec_key.c b/thirdparty/openssl/crypto/ec/ec_key.c index bc94ab5661..456080ecfe 100644 --- a/thirdparty/openssl/crypto/ec/ec_key.c +++ b/thirdparty/openssl/crypto/ec/ec_key.c @@ -377,9 +377,9 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, return 0; } ctx = BN_CTX_new(); - if (!ctx) - goto err; - + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); point = EC_POINT_new(key->group); if (!point) @@ -432,10 +432,9 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, ok = 1; err: - if (ctx) - BN_CTX_free(ctx); - if (point) - EC_POINT_free(point); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_POINT_free(point); return ok; } diff --git a/thirdparty/openssl/crypto/ec/ec_mult.c b/thirdparty/openssl/crypto/ec/ec_mult.c index 23b8c3089b..24ca67a6ef 100644 --- a/thirdparty/openssl/crypto/ec/ec_mult.c +++ b/thirdparty/openssl/crypto/ec/ec_mult.c @@ -68,10 +68,14 @@ #include "ec_lcl.h" /* - * This file implements the wNAF-based interleaving multi-exponentation method - * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>); - * for multiplication with precomputation, we use wNAF splitting - * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>). + * This file implements the wNAF-based interleaving multi-exponentiation method + * Formerly at: + * http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp + * You might now find it here: + * http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13 + * http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf + * For multiplication with precomputation, we use wNAF splitting, formerly at: + * http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp */ /* structure for precomputed multiples of the generator */ diff --git a/thirdparty/openssl/crypto/ec/eck_prn.c b/thirdparty/openssl/crypto/ec/eck_prn.c index df9b37a750..176ec1f173 100644 --- a/thirdparty/openssl/crypto/ec/eck_prn.c +++ b/thirdparty/openssl/crypto/ec/eck_prn.c @@ -342,7 +342,7 @@ static int print_bin(BIO *fp, const char *name, const unsigned char *buf, size_t len, int off) { size_t i; - char str[128]; + char str[128 + 1 + 4]; if (buf == NULL) return 1; diff --git a/thirdparty/openssl/crypto/ec/ecp_nistz256.c b/thirdparty/openssl/crypto/ec/ecp_nistz256.c index ca44d0aaee..99b8d613c8 100644 --- a/thirdparty/openssl/crypto/ec/ecp_nistz256.c +++ b/thirdparty/openssl/crypto/ec/ecp_nistz256.c @@ -82,19 +82,36 @@ typedef struct ec_pre_comp_st { } EC_PRE_COMP; /* Functions implemented in assembly */ +/* + * Most of below mentioned functions *preserve* the property of inputs + * being fully reduced, i.e. being in [0, modulus) range. Simply put if + * inputs are fully reduced, then output is too. Note that reverse is + * not true, in sense that given partially reduced inputs output can be + * either, not unlikely reduced. And "most" in first sentence refers to + * the fact that given the calculations flow one can tolerate that + * addition, 1st function below, produces partially reduced result *if* + * multiplications by 2 and 3, which customarily use addition, fully + * reduce it. This effectively gives two options: a) addition produces + * fully reduced result [as long as inputs are, just like remaining + * functions]; b) addition is allowed to produce partially reduced + * result, but multiplications by 2 and 3 perform additional reduction + * step. Choice between the two can be platform-specific, but it was a) + * in all cases so far... + */ +/* Modular add: res = a+b mod P */ +void ecp_nistz256_add(BN_ULONG res[P256_LIMBS], + const BN_ULONG a[P256_LIMBS], + const BN_ULONG b[P256_LIMBS]); /* Modular mul by 2: res = 2*a mod P */ void ecp_nistz256_mul_by_2(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]); -/* Modular div by 2: res = a/2 mod P */ -void ecp_nistz256_div_by_2(BN_ULONG res[P256_LIMBS], - const BN_ULONG a[P256_LIMBS]); /* Modular mul by 3: res = 3*a mod P */ void ecp_nistz256_mul_by_3(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]); -/* Modular add: res = a+b mod P */ -void ecp_nistz256_add(BN_ULONG res[P256_LIMBS], - const BN_ULONG a[P256_LIMBS], - const BN_ULONG b[P256_LIMBS]); + +/* Modular div by 2: res = a/2 mod P */ +void ecp_nistz256_div_by_2(BN_ULONG res[P256_LIMBS], + const BN_ULONG a[P256_LIMBS]); /* Modular sub: res = a-b mod P */ void ecp_nistz256_sub(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS], @@ -205,21 +222,29 @@ static BN_ULONG is_equal(const BN_ULONG a[P256_LIMBS], return is_zero(res); } -static BN_ULONG is_one(const BN_ULONG a[P256_LIMBS]) +static BN_ULONG is_one(const BIGNUM *z) { - BN_ULONG res; - - res = a[0] ^ ONE[0]; - res |= a[1] ^ ONE[1]; - res |= a[2] ^ ONE[2]; - res |= a[3] ^ ONE[3]; - if (P256_LIMBS == 8) { - res |= a[4] ^ ONE[4]; - res |= a[5] ^ ONE[5]; - res |= a[6] ^ ONE[6]; + BN_ULONG res = 0; + BN_ULONG *a = z->d; + + if (z->top == (P256_LIMBS - P256_LIMBS / 8)) { + res = a[0] ^ ONE[0]; + res |= a[1] ^ ONE[1]; + res |= a[2] ^ ONE[2]; + res |= a[3] ^ ONE[3]; + if (P256_LIMBS == 8) { + res |= a[4] ^ ONE[4]; + res |= a[5] ^ ONE[5]; + res |= a[6] ^ ONE[6]; + /* + * no check for a[7] (being zero) on 32-bit platforms, + * because value of "one" takes only 7 limbs. + */ + } + res = is_zero(res); } - return is_zero(res); + return res; } static int ecp_nistz256_set_words(BIGNUM *a, BN_ULONG words[P256_LIMBS]) @@ -315,19 +340,16 @@ static void ecp_nistz256_point_add(P256_POINT *r, const BN_ULONG *in2_y = b->Y; const BN_ULONG *in2_z = b->Z; - /* We encode infinity as (0,0), which is not on the curve, - * so it is OK. */ - in1infty = (in1_x[0] | in1_x[1] | in1_x[2] | in1_x[3] | - in1_y[0] | in1_y[1] | in1_y[2] | in1_y[3]); + /* + * Infinity in encoded as (,,0) + */ + in1infty = (in1_z[0] | in1_z[1] | in1_z[2] | in1_z[3]); if (P256_LIMBS == 8) - in1infty |= (in1_x[4] | in1_x[5] | in1_x[6] | in1_x[7] | - in1_y[4] | in1_y[5] | in1_y[6] | in1_y[7]); + in1infty |= (in1_z[4] | in1_z[5] | in1_z[6] | in1_z[7]); - in2infty = (in2_x[0] | in2_x[1] | in2_x[2] | in2_x[3] | - in2_y[0] | in2_y[1] | in2_y[2] | in2_y[3]); + in2infty = (in2_z[0] | in2_z[1] | in2_z[2] | in2_z[3]); if (P256_LIMBS == 8) - in2infty |= (in2_x[4] | in2_x[5] | in2_x[6] | in2_x[7] | - in2_y[4] | in2_y[5] | in2_y[6] | in2_y[7]); + in2infty |= (in2_z[4] | in2_z[5] | in2_z[6] | in2_z[7]); in1infty = is_zero(in1infty); in2infty = is_zero(in2infty); @@ -416,15 +438,16 @@ static void ecp_nistz256_point_add_affine(P256_POINT *r, const BN_ULONG *in2_y = b->Y; /* - * In affine representation we encode infty as (0,0), which is not on the - * curve, so it is OK + * Infinity in encoded as (,,0) */ - in1infty = (in1_x[0] | in1_x[1] | in1_x[2] | in1_x[3] | - in1_y[0] | in1_y[1] | in1_y[2] | in1_y[3]); + in1infty = (in1_z[0] | in1_z[1] | in1_z[2] | in1_z[3]); if (P256_LIMBS == 8) - in1infty |= (in1_x[4] | in1_x[5] | in1_x[6] | in1_x[7] | - in1_y[4] | in1_y[5] | in1_y[6] | in1_y[7]); + in1infty |= (in1_z[4] | in1_z[5] | in1_z[6] | in1_z[7]); + /* + * In affine representation we encode infinity as (0,0), which is + * not on the curve, so it is OK + */ in2infty = (in2_x[0] | in2_x[1] | in2_x[2] | in2_x[3] | in2_y[0] | in2_y[1] | in2_y[2] | in2_y[3]); if (P256_LIMBS == 8) @@ -741,9 +764,8 @@ static int ecp_nistz256_is_affine_G(const EC_POINT *generator) { return (generator->X.top == P256_LIMBS) && (generator->Y.top == P256_LIMBS) && - (generator->Z.top == (P256_LIMBS - P256_LIMBS / 8)) && is_equal(generator->X.d, def_xG) && - is_equal(generator->Y.d, def_yG) && is_one(generator->Z.d); + is_equal(generator->Y.d, def_yG) && is_one(&generator->Z); } static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) @@ -1249,6 +1271,8 @@ static int ecp_nistz256_points_mul(const EC_GROUP *group, } else #endif { + BN_ULONG infty; + /* First window */ wvalue = (p_str[0] << 1) & mask; index += window_size; @@ -1260,7 +1284,30 @@ static int ecp_nistz256_points_mul(const EC_GROUP *group, ecp_nistz256_neg(p.p.Z, p.p.Y); copy_conditional(p.p.Y, p.p.Z, wvalue & 1); - memcpy(p.p.Z, ONE, sizeof(ONE)); + /* + * Since affine infinity is encoded as (0,0) and + * Jacobian ias (,,0), we need to harmonize them + * by assigning "one" or zero to Z. + */ + infty = (p.p.X[0] | p.p.X[1] | p.p.X[2] | p.p.X[3] | + p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]); + if (P256_LIMBS == 8) + infty |= (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] | + p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]); + + infty = 0 - is_zero(infty); + infty = ~infty; + + p.p.Z[0] = ONE[0] & infty; + p.p.Z[1] = ONE[1] & infty; + p.p.Z[2] = ONE[2] & infty; + p.p.Z[3] = ONE[3] & infty; + if (P256_LIMBS == 8) { + p.p.Z[4] = ONE[4] & infty; + p.p.Z[5] = ONE[5] & infty; + p.p.Z[6] = ONE[6] & infty; + p.p.Z[7] = ONE[7] & infty; + } for (i = 1; i < 37; i++) { unsigned int off = (index - 1) / 8; @@ -1331,7 +1378,7 @@ static int ecp_nistz256_points_mul(const EC_GROUP *group, !ecp_nistz256_set_words(&r->Z, p.p.Z)) { goto err; } - r->Z_is_one = is_one(p.p.Z) & 1; + r->Z_is_one = is_one(&r->Z) & 1; ret = 1; |