Loading crypto/ec/ec.h +6 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,12 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIG */ const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); /** Returns the montgomery data for order(Generator) * \param group EC_GROUP object * \return the currently used generator (possibly NULL). */ BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group); /** Gets the order of a EC_GROUP * \param group EC_GROUP object * \param order BIGNUM to which the order is copied Loading crypto/ec/ec_lcl.h +11 −0 Original line number Diff line number Diff line Loading @@ -235,6 +235,8 @@ struct ec_group_st { void *field_data1; /* method-specific (e.g., Montgomery structure) */ void *field_data2; /* method-specific */ int (*field_mod_func)(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); /* method-specific */ BN_MONT_CTX *mont_data; /* data for ECDSA inverse */ } /* EC_GROUP */; struct ec_key_st { Loading Loading @@ -444,3 +446,12 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, void (*felem_contract)(void *out, const void *in)); void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in); #endif int ec_precompute_mont_data(EC_GROUP *); #ifdef ECP_NISTZ256_ASM /** Returns GFp methods using montgomery multiplication, with x86-64 optimized * P256. See http://eprint.iacr.org/2013/816. * \return EC_METHOD object */ const EC_METHOD *EC_GFp_nistz256_method(void); #endif crypto/ec/ec_lib.c +71 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) ret->meth = meth; ret->extra_data = NULL; ret->mont_data = NULL; ret->generator = NULL; BN_init(&ret->order); Loading Loading @@ -132,6 +133,9 @@ void EC_GROUP_free(EC_GROUP *group) EC_EX_DATA_free_all_data(&group->extra_data); if (group->mont_data) BN_MONT_CTX_free(group->mont_data); if (group->generator != NULL) EC_POINT_free(group->generator); BN_free(&group->order); Loading @@ -155,6 +159,9 @@ void EC_GROUP_clear_free(EC_GROUP *group) EC_EX_DATA_clear_free_all_data(&group->extra_data); if (group->mont_data) BN_MONT_CTX_free(group->mont_data); if (group->generator != NULL) EC_POINT_clear_free(group->generator); BN_clear_free(&group->order); Loading Loading @@ -200,6 +207,25 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) return 0; } if (src->mont_data != NULL) { if (dest->mont_data == NULL) { dest->mont_data = BN_MONT_CTX_new(); if (dest->mont_data == NULL) return 0; } if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data)) return 0; } else { /* src->generator == NULL */ if (dest->mont_data != NULL) { BN_MONT_CTX_free(dest->mont_data); dest->mont_data = NULL; } } if (src->generator != NULL) { if (dest->generator == NULL) Loading Loading @@ -309,6 +335,11 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIG else BN_zero(&group->cofactor); /* We ignore the return value because 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); return 1; } Loading @@ -318,6 +349,10 @@ const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) return group->generator; } BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group) { return group->mont_data; } int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) { Loading Loading @@ -1097,3 +1132,39 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group) else return 0; /* cannot tell whether precomputation has been performed */ } /* ec_precompute_mont_data sets |group->mont_data| from |group->order| and * returns one on success. On error it returns zero. */ int ec_precompute_mont_data(EC_GROUP *group) { BN_CTX *ctx = BN_CTX_new(); int ret = 0; if (group->mont_data) { BN_MONT_CTX_free(group->mont_data); group->mont_data = NULL; } if (ctx == NULL) goto err; group->mont_data = BN_MONT_CTX_new(); if (!group->mont_data) goto err; if (!BN_MONT_CTX_set(group->mont_data, &group->order, ctx)) { BN_MONT_CTX_free(group->mont_data); group->mont_data = NULL; goto err; } ret = 1; err: if (ctx) BN_CTX_free(ctx); return ret; } crypto/ecdsa/ecs_ossl.c +31 −5 Original line number Diff line number Diff line Loading @@ -219,11 +219,37 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, while (BN_is_zero(r)); /* compute the inverse of k */ if (EC_GROUP_get_mont_data(group) != NULL) { /* We want inverse in constant time, therefore we utilize the * fact order must be prime and use Fermats Little Theorem * instead. */ if (!BN_set_word(X, 2) ) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } if (!BN_mod_sub(X, order, X, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } BN_set_flags(X, BN_FLG_CONSTTIME); if (!BN_mod_exp_mont_consttime(k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } } else { if (!BN_mod_inverse(k, k, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } } /* clear old values if necessary */ if (*rp != NULL) BN_clear_free(*rp); Loading Loading
crypto/ec/ec.h +6 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,12 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIG */ const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); /** Returns the montgomery data for order(Generator) * \param group EC_GROUP object * \return the currently used generator (possibly NULL). */ BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group); /** Gets the order of a EC_GROUP * \param group EC_GROUP object * \param order BIGNUM to which the order is copied Loading
crypto/ec/ec_lcl.h +11 −0 Original line number Diff line number Diff line Loading @@ -235,6 +235,8 @@ struct ec_group_st { void *field_data1; /* method-specific (e.g., Montgomery structure) */ void *field_data2; /* method-specific */ int (*field_mod_func)(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); /* method-specific */ BN_MONT_CTX *mont_data; /* data for ECDSA inverse */ } /* EC_GROUP */; struct ec_key_st { Loading Loading @@ -444,3 +446,12 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, void (*felem_contract)(void *out, const void *in)); void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in); #endif int ec_precompute_mont_data(EC_GROUP *); #ifdef ECP_NISTZ256_ASM /** Returns GFp methods using montgomery multiplication, with x86-64 optimized * P256. See http://eprint.iacr.org/2013/816. * \return EC_METHOD object */ const EC_METHOD *EC_GFp_nistz256_method(void); #endif
crypto/ec/ec_lib.c +71 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) ret->meth = meth; ret->extra_data = NULL; ret->mont_data = NULL; ret->generator = NULL; BN_init(&ret->order); Loading Loading @@ -132,6 +133,9 @@ void EC_GROUP_free(EC_GROUP *group) EC_EX_DATA_free_all_data(&group->extra_data); if (group->mont_data) BN_MONT_CTX_free(group->mont_data); if (group->generator != NULL) EC_POINT_free(group->generator); BN_free(&group->order); Loading @@ -155,6 +159,9 @@ void EC_GROUP_clear_free(EC_GROUP *group) EC_EX_DATA_clear_free_all_data(&group->extra_data); if (group->mont_data) BN_MONT_CTX_free(group->mont_data); if (group->generator != NULL) EC_POINT_clear_free(group->generator); BN_clear_free(&group->order); Loading Loading @@ -200,6 +207,25 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) return 0; } if (src->mont_data != NULL) { if (dest->mont_data == NULL) { dest->mont_data = BN_MONT_CTX_new(); if (dest->mont_data == NULL) return 0; } if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data)) return 0; } else { /* src->generator == NULL */ if (dest->mont_data != NULL) { BN_MONT_CTX_free(dest->mont_data); dest->mont_data = NULL; } } if (src->generator != NULL) { if (dest->generator == NULL) Loading Loading @@ -309,6 +335,11 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIG else BN_zero(&group->cofactor); /* We ignore the return value because 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); return 1; } Loading @@ -318,6 +349,10 @@ const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) return group->generator; } BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group) { return group->mont_data; } int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) { Loading Loading @@ -1097,3 +1132,39 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group) else return 0; /* cannot tell whether precomputation has been performed */ } /* ec_precompute_mont_data sets |group->mont_data| from |group->order| and * returns one on success. On error it returns zero. */ int ec_precompute_mont_data(EC_GROUP *group) { BN_CTX *ctx = BN_CTX_new(); int ret = 0; if (group->mont_data) { BN_MONT_CTX_free(group->mont_data); group->mont_data = NULL; } if (ctx == NULL) goto err; group->mont_data = BN_MONT_CTX_new(); if (!group->mont_data) goto err; if (!BN_MONT_CTX_set(group->mont_data, &group->order, ctx)) { BN_MONT_CTX_free(group->mont_data); group->mont_data = NULL; goto err; } ret = 1; err: if (ctx) BN_CTX_free(ctx); return ret; }
crypto/ecdsa/ecs_ossl.c +31 −5 Original line number Diff line number Diff line Loading @@ -219,11 +219,37 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, while (BN_is_zero(r)); /* compute the inverse of k */ if (EC_GROUP_get_mont_data(group) != NULL) { /* We want inverse in constant time, therefore we utilize the * fact order must be prime and use Fermats Little Theorem * instead. */ if (!BN_set_word(X, 2) ) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } if (!BN_mod_sub(X, order, X, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } BN_set_flags(X, BN_FLG_CONSTTIME); if (!BN_mod_exp_mont_consttime(k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } } else { if (!BN_mod_inverse(k, k, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } } /* clear old values if necessary */ if (*rp != NULL) BN_clear_free(*rp); Loading