crypto/ec: harmonize new code with FIPS module.
authorAndy Polyakov <appro@openssl.org>
Sun, 21 Sep 2014 22:05:46 +0000 (00:05 +0200)
committerAndy Polyakov <appro@openssl.org>
Sun, 21 Sep 2014 22:07:44 +0000 (00:07 +0200)
RT: 3149
Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
crypto/ec/ec_curve.c
crypto/ec/ec_cvt.c
crypto/ec/ec_lcl.h
crypto/ec/ec_lib.c

index 2cdf651f2a991cf4ae56e2f8ad1ec6e249857af1..217b4fec42bfbea89e0e0c453132f21de773f92f 100644 (file)
  *
  */
 
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 #include <string.h>
 #include "ec_lcl.h"
 #include <openssl/err.h>
@@ -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;
 
index bfcbab35fe695d32beffbe8a704af40289f81d5c..d357c33031e2054cc6db73410ff6adc1e1f6059e 100644 (file)
  *
  */
 
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 #include <openssl/err.h>
 #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);
index 22b53d28a9f33a0b458ba26027501481d77f9b88..dca3e732d039a4aca99a8b8c41fbfb4410b4a4fa 100644 (file)
@@ -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
index 7fe31157cafe0742ab0e2410280c8c373a1a0613..37990303fd2a4302ed3b342ac39edb00c1aa3da4 100644 (file)
@@ -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);