Add flag to support cofactor ECDH
authorDr. Stephen Henson <steve@openssl.org>
Sat, 19 Nov 2011 17:03:44 +0000 (17:03 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sat, 19 Nov 2011 17:03:44 +0000 (17:03 +0000)
CHANGES
crypto/ecdh/ecdh.h
crypto/ecdh/ech_ossl.c
fips/ecdh/fips_ecdh_selftest.c
fips/ecdh/fips_ecdhvs.c

diff --git a/CHANGES b/CHANGES
index 795ada567e70951ec61682908e5ff26e89ff4212..0e9afd12ed643675191cad4fd1588eadf1479800 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,9 @@
 
  Changes between 1.0.1 and 1.1.0  [xx XXX xxxx]
 
+  *) Add flag to EC_KEY to use cofactor ECDH if set.
+     [Steve Henson]
+
   *) Update fips_test_suite to support multiple command line options. New
      test to induce all self test errors in sequence and check expected
      failures.
index b4b58ee65ba2caee7a968e7a8d7070ea9d94ea01..8ac82b8cbdb6d86b8d8b18bfbfcd9b36fe250a69 100644 (file)
@@ -85,6 +85,8 @@
 extern "C" {
 #endif
 
+#define EC_FLAG_COFACTOR_ECDH  0x1000
+
 const ECDH_METHOD *ECDH_OpenSSL(void);
 
 void     ECDH_set_default_method(const ECDH_METHOD *);
index 94a8f4b696a5fcb97c3cd08ab4c471d8dc696210..2656797449e7075cd910bd69deaf4c6c8012b3f5 100644 (file)
@@ -146,6 +146,18 @@ static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
                }
 
        group = EC_KEY_get0_group(ecdh);
+
+       if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH)
+               {
+               if (!EC_GROUP_get_cofactor(group, x, ctx) ||
+                       !BN_mul(x, x, priv_key, ctx))
+                       {
+                       ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+                       goto err;
+                       }
+               priv_key = x;
+               }
+
        if ((tmp=EC_POINT_new(group)) == NULL)
                {
                ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
index 2b21ceaf4815e973f7f830b917f4f4dd6f0c38fb..0b16c57aae3ab6e6007f688deeb85c26b4bbe325 100644 (file)
@@ -166,6 +166,7 @@ int FIPS_selftest_ecdh(void)
                        rv = -1;
                        goto err;
                        }
+               EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH);
 
                if (!EC_KEY_set_public_key_affine_coordinates(ec1, x, y))
                        {
@@ -194,6 +195,7 @@ int FIPS_selftest_ecdh(void)
                        rv = -1;
                        goto err;
                        }
+               EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH);
 
                if (!EC_KEY_set_public_key_affine_coordinates(ec2, x, y))
                        {
index 099285aac3d9961385a284b8a94dd48d1093a7cf..61d216d1b7318eebe927b1537a7b710ce88abc75 100644 (file)
@@ -261,6 +261,7 @@ static void ec_output_Zhash(FILE *out, int exout, EC_GROUP *group,
        unsigned char chash[EVP_MAX_MD_SIZE];
        int Zlen;
        ec = EC_KEY_new();
+       EC_KEY_set_flags(ec, EC_FLAG_COFACTOR_ECDH);
        EC_KEY_set_group(ec, group);
        peerkey = make_peer(group, cx, cy);
        if (rhash == NULL)