From be2e334fce734e726a4085701bc3cbbaabf9d893 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sun, 31 Jan 2016 16:34:07 +0000 Subject: [PATCH] Add EC_GROUP_order_bits, EC_GROUP_get0_order and EC_GROUP_get0_cofactor New functions to return internal pointer for order and cofactor. This avoids the need to allocate a new BIGNUM which to copy the value to. Simplify code to use new functions. Reviewed-by: Rich Salz --- crypto/ec/ec_ameth.c | 28 ++++------------------------ crypto/ec/ec_asn1.c | 24 +++++++----------------- crypto/ec/ec_check.c | 5 +++-- crypto/ec/ec_key.c | 9 ++++----- crypto/ec/ec_lib.c | 34 +++++++++++++++++++++++++++++----- crypto/ec/ec_mult.c | 8 +++----- crypto/ec/ecdsa_ossl.c | 27 ++++++++++++++------------- crypto/ec/eck_prn.c | 14 ++++++-------- crypto/ec/ecp_nistz256.c | 7 ++----- doc/crypto/EC_GROUP_copy.pod | 7 +++++++ include/openssl/ec.h | 21 +++++++++++++++++++++ util/libeay.num | 3 +++ 12 files changed, 103 insertions(+), 84 deletions(-) diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index bc77391ef4..1ba26853ab 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -356,23 +356,7 @@ static int int_ec_size(const EVP_PKEY *pkey) static int ec_bits(const EVP_PKEY *pkey) { - BIGNUM *order = BN_new(); - const EC_GROUP *group; - int ret; - - if (order == NULL) { - ERR_clear_error(); - return 0; - } - group = EC_KEY_get0_group(pkey->pkey.ec); - if (!EC_GROUP_get_order(group, order, NULL)) { - ERR_clear_error(); - return 0; - } - - ret = BN_num_bits(order); - BN_free(order); - return ret; + return EC_GROUP_order_bits(EC_KEY_get0_group(pkey->pkey.ec)); } static int ec_security_bits(const EVP_PKEY *pkey) @@ -435,7 +419,7 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) const char *ecstr; size_t buf_len = 0, i; int ret = 0, reason = ERR_R_BIO_LIB; - BIGNUM *pub_key = NULL, *order = NULL; + BIGNUM *pub_key = NULL; BN_CTX *ctx = NULL; const EC_GROUP *group; const EC_POINT *public_key; @@ -488,11 +472,8 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) 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, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) + if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, + EC_GROUP_order_bits(group)) <= 0) goto err; if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, @@ -508,7 +489,6 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) if (!ret) ECerr(EC_F_DO_EC_KEY_PRINT, reason); BN_free(pub_key); - BN_free(order); BN_CTX_free(ctx); OPENSSL_free(buffer); return (ret); diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index ab68e1ea5a..842f9c31df 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -536,16 +536,11 @@ static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group, { size_t len = 0; ECPARAMETERS *ret = NULL; - BIGNUM *tmp = NULL; + const BIGNUM *tmp; unsigned char *buffer = NULL; const EC_POINT *point = NULL; point_conversion_form_t form; - if ((tmp = BN_new()) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); - goto err; - } - if (param == NULL) { if ((ret = ECPARAMETERS_new()) == NULL) { ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); @@ -592,7 +587,8 @@ static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group, } /* set the order */ - if (!EC_GROUP_get_order(group, tmp, NULL)) { + tmp = EC_GROUP_get0_order(group); + if (tmp == NULL) { ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); goto err; } @@ -603,7 +599,8 @@ static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group, } /* set the cofactor (optional) */ - if (EC_GROUP_get_cofactor(group, tmp, NULL)) { + tmp = EC_GROUP_get0_cofactor(group); + if (tmp != NULL) { ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor); if (ret->cofactor == NULL) { ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); @@ -616,7 +613,6 @@ static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group, err: if (!param) ECPARAMETERS_free(ret); - BN_free(tmp); OPENSSL_free(buffer); return NULL; } @@ -1315,7 +1311,6 @@ int ECDSA_size(const EC_KEY *r) { int ret, i; ASN1_INTEGER bs; - BIGNUM *order = NULL; unsigned char buf[4]; const EC_GROUP *group; @@ -1325,13 +1320,9 @@ int ECDSA_size(const EC_KEY *r) if (group == NULL) return 0; - if ((order = BN_new()) == NULL) + i = EC_GROUP_order_bits(group); + if (i == 0) return 0; - if (!EC_GROUP_get_order(group, order, NULL)) { - BN_clear_free(order); - return 0; - } - i = BN_num_bits(order); bs.length = (i + 7) / 8; bs.data = buf; bs.type = V_ASN1_INTEGER; @@ -1341,6 +1332,5 @@ int ECDSA_size(const EC_KEY *r) i = i2d_ASN1_INTEGER(&bs, NULL); i += i; /* r and s */ ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); - BN_clear_free(order); return (ret); } diff --git a/crypto/ec/ec_check.c b/crypto/ec/ec_check.c index c168ab4e06..aa35322355 100644 --- a/crypto/ec/ec_check.c +++ b/crypto/ec/ec_check.c @@ -58,7 +58,7 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) { int ret = 0; - BIGNUM *order; + const BIGNUM *order; BN_CTX *new_ctx = NULL; EC_POINT *point = NULL; @@ -92,7 +92,8 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) /* check the order of the generator */ if ((point = EC_POINT_new(group)) == NULL) goto err; - if (!EC_GROUP_get_order(group, order, ctx)) + order = EC_GROUP_get0_order(group); + if (order == NULL) goto err; if (BN_is_zero(order)) { ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER); diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index 970aeca63b..a5c60f680f 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -241,11 +241,10 @@ int ossl_ec_key_gen(EC_KEY *eckey) { int ok = 0; BN_CTX *ctx = NULL; - BIGNUM *priv_key = NULL, *order = NULL; + BIGNUM *priv_key = NULL; + const BIGNUM *order = NULL; EC_POINT *pub_key = NULL; - if ((order = BN_new()) == NULL) - goto err; if ((ctx = BN_CTX_new()) == NULL) goto err; @@ -256,7 +255,8 @@ int ossl_ec_key_gen(EC_KEY *eckey) } else priv_key = eckey->priv_key; - if (!EC_GROUP_get_order(eckey->group, order, ctx)) + order = EC_GROUP_get0_order(eckey->group); + if (order == NULL) goto err; do @@ -280,7 +280,6 @@ int ossl_ec_key_gen(EC_KEY *eckey) ok = 1; err: - BN_free(order); if (eckey->pub_key == NULL) EC_POINT_free(pub_key); if (eckey->priv_key != priv_key) diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index f81489d20d..ac3903cbce 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -349,21 +349,43 @@ 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->order) + return BN_num_bits(group->order); + return 0; +} + 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; @@ -536,16 +558,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; } diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c index 1bbb7da729..596b5f8062 100644 --- a/crypto/ec/ec_mult.c +++ b/crypto/ec/ec_mult.c @@ -554,7 +554,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) const EC_POINT *generator; EC_POINT *tmp_point = NULL, *base = NULL, **var; BN_CTX *new_ctx = NULL; - BIGNUM *order; + const BIGNUM *order; size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num; EC_POINT **points = NULL; EC_PRE_COMP *pre_comp; @@ -578,11 +578,9 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) } BN_CTX_start(ctx); - order = BN_CTX_get(ctx); - if (order == NULL) - goto err; - if (!EC_GROUP_get_order(group, order, ctx)) + order = EC_GROUP_get0_order(group); + if (order == NULL) goto err; if (BN_is_zero(order)) { ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER); diff --git a/crypto/ec/ecdsa_ossl.c b/crypto/ec/ecdsa_ossl.c index b4e37adcce..3e755fbafa 100644 --- a/crypto/ec/ecdsa_ossl.c +++ b/crypto/ec/ecdsa_ossl.c @@ -84,7 +84,8 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, const unsigned char *dgst, int dlen) { BN_CTX *ctx = NULL; - BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; + BIGNUM *k = NULL, *r = NULL, *X = NULL; + const BIGNUM *order; EC_POINT *tmp_point = NULL; const EC_GROUP *group; int ret = 0; @@ -104,9 +105,8 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_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 == NULL || r == NULL || order == NULL || X == NULL) { + if (k == NULL || r == NULL || X == NULL) { ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); goto err; } @@ -114,7 +114,8 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } - if (!EC_GROUP_get_order(group, order, ctx)) { + order = EC_GROUP_get0_order(group); + if (order == NULL) { ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } @@ -222,7 +223,6 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, } if (ctx != ctx_in) BN_CTX_free(ctx); - BN_free(order); EC_POINT_free(tmp_point); BN_clear_free(X); return (ret); @@ -239,8 +239,8 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, EC_KEY *eckey) { int ok = 0, i; - BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL; - const BIGNUM *ckinv; + BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL; + const BIGNUM *order, *ckinv; BN_CTX *ctx = NULL; const EC_GROUP *group; ECDSA_SIG *ret; @@ -261,13 +261,14 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, } s = ret->s; - if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || + if ((ctx = BN_CTX_new()) == NULL || (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) { ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE); goto err; } - if (!EC_GROUP_get_order(group, order, ctx)) { + order = EC_GROUP_get0_order(group); + if (order == NULL) { ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_EC_LIB); goto err; } @@ -337,7 +338,6 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, BN_CTX_free(ctx); BN_clear_free(m); BN_clear_free(tmp); - BN_free(order); BN_clear_free(kinv); return ret; } @@ -378,7 +378,8 @@ int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, { int ret = -1, i; BN_CTX *ctx; - BIGNUM *order, *u1, *u2, *m, *X; + const BIGNUM *order; + BIGNUM *u1, *u2, *m, *X; EC_POINT *point = NULL; const EC_GROUP *group; const EC_POINT *pub_key; @@ -396,7 +397,6 @@ int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, 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); @@ -406,7 +406,8 @@ int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, goto err; } - if (!EC_GROUP_get_order(group, order, ctx)) { + order = EC_GROUP_get0_order(group); + if (order == NULL) { ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB); goto err; } diff --git a/crypto/ec/eck_prn.c b/crypto/ec/eck_prn.c index 6449bc441c..fa4cf6aefc 100644 --- a/crypto/ec/eck_prn.c +++ b/crypto/ec/eck_prn.c @@ -147,8 +147,8 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) 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; + BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL; + const BIGNUM *order = NULL, *cofactor = NULL; const unsigned char *seed; size_t seed_len = 0; @@ -199,8 +199,7 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) 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) { + (b = BN_new()) == NULL) { reason = ERR_R_MALLOC_FAILURE; goto err; } @@ -223,8 +222,9 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) reason = ERR_R_EC_LIB; goto err; } - if (!EC_GROUP_get_order(x, order, NULL) || - !EC_GROUP_get_cofactor(x, cofactor, NULL)) { + order = EC_GROUP_get0_order(x); + cofactor = EC_GROUP_get0_cofactor(x); + if (order == NULL) { reason = ERR_R_EC_LIB; goto err; } @@ -321,8 +321,6 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) BN_free(a); BN_free(b); BN_free(gen); - BN_free(order); - BN_free(cofactor); BN_CTX_free(ctx); OPENSSL_free(buffer); return (ret); diff --git a/crypto/ec/ecp_nistz256.c b/crypto/ec/ecp_nistz256.c index 7d953a306d..388e87e0fb 100644 --- a/crypto/ec/ecp_nistz256.c +++ b/crypto/ec/ecp_nistz256.c @@ -756,7 +756,7 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) * implicit value of infinity at index zero. We use window of size 7, and * therefore require ceil(256/7) = 37 tables. */ - BIGNUM *order; + const BIGNUM *order; EC_POINT *P = NULL, *T = NULL; const EC_POINT *generator; NISTZ256_PRE_COMP *pre_comp; @@ -793,14 +793,11 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) } BN_CTX_start(ctx); - order = BN_CTX_get(ctx); + order = EC_GROUP_get0_order(group); if (order == NULL) goto err; - if (!EC_GROUP_get_order(group, order, ctx)) - goto err; - if (BN_is_zero(order)) { ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, EC_R_UNKNOWN_ORDER); goto err; diff --git a/doc/crypto/EC_GROUP_copy.pod b/doc/crypto/EC_GROUP_copy.pod index 837995b31c..938092eed5 100644 --- a/doc/crypto/EC_GROUP_copy.pod +++ b/doc/crypto/EC_GROUP_copy.pod @@ -18,7 +18,10 @@ EC_GROUP_copy, EC_GROUP_dup, EC_GROUP_method_of, EC_GROUP_set_generator, EC_GROU const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); + const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); + const BIGNUM *EC_GROUP_order_bits(const EC_GROUP *group); int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); + const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group); void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); int EC_GROUP_get_curve_name(const EC_GROUP *group); @@ -162,6 +165,10 @@ EC_GROUP_get_order, EC_GROUP_get_cofactor, EC_GROUP_get_curve_name, EC_GROUP_get and EC_GROUP_get_degree return the order, cofactor, curve name (NID), ASN1 flag, point_conversion_form and degree for the specified curve respectively. If there is no curve name associated with a curve then EC_GROUP_get_curve_name will return 0. +EC_GROUP_get0_order() returns an internal pointer to the group order. +EC_GROUP_get_order_bits() returns the number of bits in the group order. +EC_GROUP_get0_cofactor() returns an internal pointer to the group cofactor. + EC_GROUP_get0_seed returns a pointer to the seed that was used to generate the parameter b, or NULL if the seed is not specified. EC_GROUP_get_seed_len returns the length of the seed or 0 if the seed is not specified. diff --git a/include/openssl/ec.h b/include/openssl/ec.h index 3188cae953..75be82a320 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -257,6 +257,20 @@ 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); +/** Gets the order of an EC_GROUP + * \param group EC_GROUP object + * \return the group order + */ + +const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); + +/** Gets the number of bits of ther order of an EC_GROUP + * \param group EC_GROUP object + * \return number of bits of group order. + */ + +int EC_GROUP_order_bits(const EC_GROUP *group); + /** Gets the cofactor of a EC_GROUP * \param group EC_GROUP object * \param cofactor BIGNUM to which the cofactor is copied @@ -266,6 +280,13 @@ int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); +/** Gets the cofactor of an EC_GROUP + * \param group EC_GROUP object + * \return the group cofactor + */ + +const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group); + /** Sets the name of a EC_GROUP object * \param group EC_GROUP object * \param nid NID of the curve name OID diff --git a/util/libeay.num b/util/libeay.num index 951add79ee..0bbe1a838d 100755 --- a/util/libeay.num +++ b/util/libeay.num @@ -4766,3 +4766,6 @@ TS_STATUS_INFO_get0_failure_info 5160 1_1_0 EXIST::FUNCTION: TS_STATUS_INFO_get0_text 5161 1_1_0 EXIST::FUNCTION: CRYPTO_secure_zalloc 5162 1_1_0 EXIST::FUNCTION: X509_NAME_get0_der 5163 1_1_0 EXIST::FUNCTION: +EC_GROUP_order_bits 5164 1_1_0 EXIST::FUNCTION:EC +EC_GROUP_get0_order 5165 1_1_0 EXIST::FUNCTION:EC +EC_GROUP_get0_cofactor 5166 1_1_0 EXIST::FUNCTION:EC -- 2.40.0