From: Mahantesh Salimath Date: Mon, 30 Nov 2020 22:03:03 +0000 (+0000) Subject: openssl: Use ECDH_compute_key() for 'x-coordinate only' setting X-Git-Tag: 5.9.2dr2~22^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7733ff7d4e2ccc272aef9ca12e0817fef3721f3b;p=thirdparty%2Fstrongswan.git openssl: Use ECDH_compute_key() for 'x-coordinate only' setting 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 --- diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c index 19de540b65..e3b4ca7116 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c +++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c @@ -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;