X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fec%2Fec_lib.c;h=1f487b48a071696812b98e83cf3367a24c5da81a;hp=890a274b9738141d44dba6e363085ca6373bf284;hb=77470e989cf3c502ee00eb060b197d0241f33a22;hpb=e69aa8000e410bd3fe2ad093d432c735397af3b8 diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index 890a274b97..1f487b48a0 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -1,4 +1,3 @@ -/* crypto/ec/ec_lib.c */ /* * Originally written by Bodo Moeller for the OpenSSL project. */ @@ -90,12 +89,14 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) } ret->meth = meth; - ret->order = BN_new(); - if (ret->order == NULL) - goto err; - ret->cofactor = BN_new(); - if (ret->cofactor == NULL) - goto err; + if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) { + ret->order = BN_new(); + if (ret->order == NULL) + goto err; + ret->cofactor = BN_new(); + if (ret->cofactor == NULL) + goto err; + } ret->asn1_flag = OPENSSL_EC_NAMED_CURVE; ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED; if (!meth->group_init(ret)) @@ -109,7 +110,7 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) return NULL; } -static void ec_group_free_precomp(EC_GROUP *group) +void EC_pre_comp_free(EC_GROUP *group) { switch (group->pre_comp_type) { default: @@ -145,7 +146,7 @@ void EC_GROUP_free(EC_GROUP *group) if (group->meth->group_finish != 0) group->meth->group_finish(group); - ec_group_free_precomp(group); + EC_pre_comp_free(group); BN_MONT_CTX_free(group->mont_data); EC_POINT_free(group->generator); BN_free(group->order); @@ -164,7 +165,7 @@ void EC_GROUP_clear_free(EC_GROUP *group) else if (group->meth->group_finish != 0) group->meth->group_finish(group); - ec_group_free_precomp(group); + EC_pre_comp_free(group); BN_MONT_CTX_free(group->mont_data); EC_POINT_clear_free(group->generator); BN_clear_free(group->order); @@ -241,10 +242,12 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) dest->generator = NULL; } - if (!BN_copy(dest->order, src->order)) - return 0; - if (!BN_copy(dest->cofactor, src->cofactor)) - return 0; + if ((src->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) { + if (!BN_copy(dest->order, src->order)) + return 0; + if (!BN_copy(dest->cofactor, src->cofactor)) + return 0; + } dest->curve_name = src->curve_name; dest->asn1_flag = src->asn1_flag; @@ -328,13 +331,18 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, } else BN_zero(group->cofactor); + /* - * We ignore the return value because some groups have an order with + * Some groups have an order with * factors of two, which makes the Montgomery setup fail. * |group->mont_data| will be NULL in this case. */ - ec_precompute_mont_data(group); + if (BN_is_odd(group->order)) { + return ec_precompute_mont_data(group); + } + BN_MONT_CTX_free(group->mont_data); + group->mont_data = NULL; return 1; } @@ -350,21 +358,45 @@ BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group) int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) { + if (group->order == NULL) + return 0; if (!BN_copy(order, group->order)) return 0; return !BN_is_zero(order); } +const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) +{ + return group->order; +} + +int EC_GROUP_order_bits(const EC_GROUP *group) +{ + if (group->meth->group_order_bits == NULL) { + ECerr(EC_F_EC_GROUP_ORDER_BITS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_order_bits(group); +} + int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) { + + if (group->cofactor == NULL) + return 0; if (!BN_copy(cofactor, group->cofactor)) return 0; return !BN_is_zero(group->cofactor); } +const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group) +{ + return group->cofactor; +} + void EC_GROUP_set_curve_name(EC_GROUP *group, int nid) { group->curve_name = nid; @@ -501,6 +533,8 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) 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 1; + if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE) + return 0; if (ctx == NULL) ctx_new = ctx = BN_CTX_new(); @@ -537,16 +571,18 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) r = 1; if (!r) { + const BIGNUM *ao, *bo, *ac, *bc; /* compare the order and cofactor */ - if (!EC_GROUP_get_order(a, a1, ctx) || - !EC_GROUP_get_order(b, b1, ctx) || - !EC_GROUP_get_cofactor(a, a2, ctx) || - !EC_GROUP_get_cofactor(b, b2, ctx)) { + ao = EC_GROUP_get0_order(a); + bo = EC_GROUP_get0_order(b); + ac = EC_GROUP_get0_cofactor(a); + bc = EC_GROUP_get0_cofactor(b); + if (ao == NULL || bo == NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx_new); return -1; } - if (BN_cmp(a1, b1) || BN_cmp(a2, b2)) + if (BN_cmp(ao, bo) || BN_cmp(ac, bc)) r = 1; } @@ -571,7 +607,7 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) return NULL; } - ret = OPENSSL_malloc(sizeof(*ret)); + ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE); return NULL; @@ -994,3 +1030,10 @@ void *EC_KEY_get_ex_data(const EC_KEY *key, int idx) { return CRYPTO_get_ex_data(&key->ex_data, idx); } + +int ec_group_simple_order_bits(const EC_GROUP *group) +{ + if (group->order == NULL) + return 0; + return BN_num_bits(group->order); +}