From 27918b7c25d0c916315cb2f9ee026bed41f83ee9 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Mon, 22 Sep 2014 00:05:46 +0200 Subject: [PATCH] crypto/ec: harmonize new code with FIPS module. RT: 3149 Reviewed-by: Dr. Stephen Henson --- crypto/ec/ec_curve.c | 8 ++++++++ crypto/ec/ec_cvt.c | 14 +++++++++++++- crypto/ec/ec_lcl.h | 13 +++++++++++++ crypto/ec/ec_lib.c | 20 ++++++++++++-------- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c index 2cdf651f2a..217b4fec42 100644 --- a/crypto/ec/ec_curve.c +++ b/crypto/ec/ec_curve.c @@ -69,6 +69,10 @@ * */ +#ifdef OPENSSL_FIPS +#include +#endif + #include #include "ec_lcl.h" #include @@ -2508,6 +2512,10 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid) size_t i; EC_GROUP *ret = NULL; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_ec_group_new_by_curve_name(nid); +#endif if (nid <= 0) return NULL; diff --git a/crypto/ec/ec_cvt.c b/crypto/ec/ec_cvt.c index bfcbab35fe..d357c33031 100644 --- a/crypto/ec/ec_cvt.c +++ b/crypto/ec/ec_cvt.c @@ -69,6 +69,10 @@ * */ +#ifdef OPENSSL_FIPS +#include +#endif + #include #include "ec_lcl.h" @@ -78,6 +82,10 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM const EC_METHOD *meth; EC_GROUP *ret; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_ec_group_new_curve_gfp(p,a,b,ctx); +#endif #if defined(OPENSSL_BN_ASM_MONT) /* * This might appear controversial, but the fact is that generic @@ -152,7 +160,11 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM { const EC_METHOD *meth; EC_GROUP *ret; - + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_ec_group_new_curve_gf2m(p,a,b,ctx); +#endif meth = EC_GF2m_simple_method(); ret = EC_GROUP_new(meth); diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h index 22b53d28a9..dca3e732d0 100644 --- a/crypto/ec/ec_lcl.h +++ b/crypto/ec/ec_lcl.h @@ -194,6 +194,13 @@ struct ec_group_st { int curve_name;/* optional NID for named curve */ int asn1_flag; /* flag to control the asn1 encoding */ + /* + * Kludge: upper bit of ans1_flag is used to denote structure + * version. Is set, then last field is present. This is done + * for interoperation with FIPS code. + */ +#define EC_GROUP_ASN1_FLAG_MASK 0x7fffffff +#define EC_GROUP_VERSION(p) (p->asn1_flag&~EC_GROUP_ASN1_FLAG_MASK) point_conversion_form_t asn1_form; unsigned char *seed; /* optional seed for parameters (appears in ASN1) */ @@ -455,3 +462,9 @@ int ec_precompute_mont_data(EC_GROUP *); */ const EC_METHOD *EC_GFp_nistz256_method(void); #endif + +#ifdef OPENSSL_FIPS +EC_GROUP *FIPS_ec_group_new_curve_gfp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +EC_GROUP *FIPS_ec_group_new_curve_gf2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +EC_GROUP *FIPS_ec_group_new_by_curve_name(int nid); +#endif diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index 7fe31157ca..37990303fd 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -105,7 +105,7 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) BN_init(&ret->cofactor); ret->curve_name = 0; - ret->asn1_flag = 0; + ret->asn1_flag = ~EC_GROUP_ASN1_FLAG_MASK; ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED; ret->seed = NULL; @@ -130,7 +130,7 @@ void EC_GROUP_free(EC_GROUP *group) EC_EX_DATA_free_all_data(&group->extra_data); - if (group->mont_data) + if (EC_GROUP_VERSION(group) && group->mont_data) BN_MONT_CTX_free(group->mont_data); if (group->generator != NULL) @@ -156,7 +156,7 @@ void EC_GROUP_clear_free(EC_GROUP *group) EC_EX_DATA_clear_free_all_data(&group->extra_data); - if (group->mont_data) + if (EC_GROUP_VERSION(group) && group->mont_data) BN_MONT_CTX_free(group->mont_data); if (group->generator != NULL) @@ -204,7 +204,7 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) return 0; } - if (src->mont_data != NULL) + if (EC_GROUP_VERSION(src) && src->mont_data != NULL) { if (dest->mont_data == NULL) { @@ -216,7 +216,7 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) else { /* src->generator == NULL */ - if (dest->mont_data != NULL) + if (EC_GROUP_VERSION(dest) && dest->mont_data != NULL) { BN_MONT_CTX_free(dest->mont_data); dest->mont_data = NULL; @@ -348,7 +348,7 @@ const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group) { - return group->mont_data; + return EC_GROUP_VERSION(group) ? group->mont_data : NULL; } int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) @@ -383,13 +383,14 @@ int EC_GROUP_get_curve_name(const EC_GROUP *group) void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) { - group->asn1_flag = flag; + group->asn1_flag &= ~EC_GROUP_ASN1_FLAG_MASK; + group->asn1_flag |= flag&EC_GROUP_ASN1_FLAG_MASK; } int EC_GROUP_get_asn1_flag(const EC_GROUP *group) { - return group->asn1_flag; + return group->asn1_flag&EC_GROUP_ASN1_FLAG_MASK; } @@ -1137,6 +1138,9 @@ int ec_precompute_mont_data(EC_GROUP *group) BN_CTX *ctx = BN_CTX_new(); int ret = 0; + if (!EC_GROUP_VERSION(group)) + goto err; + if (group->mont_data) { BN_MONT_CTX_free(group->mont_data); -- 2.25.1