]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
openssl: Use ECDH_compute_key() for 'x-coordinate only' setting
authorMahantesh Salimath <mahantesh@nvidia.com>
Mon, 30 Nov 2020 22:03:03 +0000 (22:03 +0000)
committerTobias Brunner <tobias@strongswan.org>
Wed, 20 Jan 2021 16:53:35 +0000 (17:53 +0100)
ECDH_compute_key() was not used because it only gives x-coordinate of
the result. However, the default setting, as per the errata mentioned,
is to use x-coordinate only.
Use ECDH_compute_key() for this setting as it additionally allows HW
offload of the computation using dynamic engine feature in OpenSSL.
EC_POINT_mul() doesn't allow HW offload.

Signed-off-by: Mahantesh Salimath <mahantesh@nvidia.com>
src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c

index 19de540b65a972760bdb9eff1eddee5fd1b0702c..e3b4ca7116a332dc329b52ae0e25970baafe0826 100644 (file)
@@ -163,14 +163,6 @@ error:
 
 /**
  * Compute the shared secret.
- *
- * We cannot use the function ECDH_compute_key() because that returns only the
- * x coordinate of the shared secret point (which is defined, for instance, in
- * 'NIST SP 800-56A').
- * However, we need both coordinates as RFC 4753 says: "The Diffie-Hellman
- *   public value is obtained by concatenating the x and y values. The format
- *   of the Diffie-Hellman shared secret value is the same as that of the
- *   Diffie-Hellman public value."
  */
 static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this,
                                                           chunk_t *shared_secret)
@@ -178,34 +170,54 @@ static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this,
        const BIGNUM *priv_key;
        EC_POINT *secret = NULL;
        bool x_coordinate_only, ret = FALSE;
-
-       priv_key = EC_KEY_get0_private_key(this->key);
-       if (!priv_key)
-       {
-               goto error;
-       }
-
-       secret = EC_POINT_new(this->ec_group);
-       if (!secret)
-       {
-               goto error;
-       }
-
-       if (!EC_POINT_mul(this->ec_group, secret, NULL, this->pub_key, priv_key, NULL))
-       {
-               goto error;
-       }
+       int len;
 
        /*
         * The default setting ecp_x_coordinate_only = TRUE
         * applies the following errata for RFC 4753:
         * http://www.rfc-editor.org/errata_search.php?eid=9
+        * ECDH_compute_key() is used under this setting as
+        * it also facilitates hardware offload through the use of
+        * dynamic engines in OpenSSL.
         */
        x_coordinate_only = lib->settings->get_bool(lib->settings,
                                                                        "%s.ecp_x_coordinate_only", TRUE, lib->ns);
-       if (!ecp2chunk(this->ec_group, secret, shared_secret, x_coordinate_only))
+       if (x_coordinate_only)
        {
-               goto error;
+               *shared_secret = chunk_alloc(EC_FIELD_ELEMENT_LEN(this->ec_group));
+               len = ECDH_compute_key(shared_secret->ptr, shared_secret->len,
+                                                          this->pub_key, this->key, NULL);
+               if (len <= 0)
+               {
+                       chunk_free(shared_secret);
+                       goto error;
+               }
+               shared_secret->len = len;
+       }
+       else
+       {
+               priv_key = EC_KEY_get0_private_key(this->key);
+               if (!priv_key)
+               {
+                       goto error;
+               }
+
+               secret = EC_POINT_new(this->ec_group);
+               if (!secret)
+               {
+                       goto error;
+               }
+
+               if (!EC_POINT_mul(this->ec_group, secret, NULL, this->pub_key, priv_key,
+                                                 NULL))
+               {
+                       goto error;
+               }
+
+               if (!ecp2chunk(this->ec_group, secret, shared_secret, x_coordinate_only))
+               {
+                       goto error;
+               }
        }
 
        ret = TRUE;