From 0caac28c1fa2d62dbf7c5a6c65346f6d3399d22c Mon Sep 17 00:00:00 2001 From: Petr Gotthard Date: Sun, 15 Aug 2021 16:26:06 +0200 Subject: [PATCH 15/17] openssl: Convert deprecated ECDH_compute_key to EVP_PKEY_derive The EC_KEY functions are replaced by corresponding EVP_PKEY functions. The tpm2_get_EC_public_key function is replaced by convert_pubkey_ECC from lib/tpm2_convert.c. Signed-off-by: Petr Gotthard --- lib/tpm2_kdfe.c | 186 +++++++++++++++++++++++------------------------- 1 file changed, 89 insertions(+), 97 deletions(-) diff --git a/lib/tpm2_kdfe.c b/lib/tpm2_kdfe.c index 84718b9f..91027e32 100644 --- a/lib/tpm2_kdfe.c +++ b/lib/tpm2_kdfe.c @@ -5,12 +5,16 @@ #include #include +#if OPENSSL_VERSION_NUMBER < 0x30000000L #include - +#else +#include +#endif #include #include #include "log.h" +#include "tpm2_convert.h" #include "tpm2_openssl.h" #include "tpm2_alg_util.h" #include "tpm2_util.h" @@ -65,72 +69,18 @@ TSS2_RC tpm2_kdfe( return rval; } -static EC_POINT * tpm2_get_EC_public_key(TPM2B_PUBLIC *public) { - EC_POINT *q = NULL; - BIGNUM *bn_qx, *bn_qy; - EC_KEY *key; - const EC_GROUP *group; - bool rval; - TPMS_ECC_PARMS *tpm_ecc = &public->publicArea.parameters.eccDetail; - TPMS_ECC_POINT *tpm_point = &public->publicArea.unique.ecc; - - int nid = tpm2_ossl_curve_to_nid(tpm_ecc->curveID); - if (nid < 0) { - return NULL; - } - - key = EC_KEY_new_by_curve_name(nid); - if (!key) { - LOG_ERR("Failed to create EC key from nid"); - return NULL; - } - - bn_qx = BN_bin2bn(tpm_point->x.buffer, tpm_point->x.size, NULL); - bn_qy = BN_bin2bn(tpm_point->y.buffer, tpm_point->y.size, NULL); - if ((bn_qx == NULL) || (bn_qy == NULL)) { - LOG_ERR("Could not convert EC public key to BN"); - goto out; - } - group = EC_KEY_get0_group(key); - if (!group) { - LOG_ERR("EC key missing group"); - goto out; - } - q = EC_POINT_new(group); - if (q == NULL) { - LOG_ERR("Could not allocate EC_POINT"); - goto out; - } - - rval = EC_POINT_set_affine_coordinates_tss(group, q, bn_qx, bn_qy, NULL); - if (rval == false) { - LOG_ERR("Could not set affine_coordinates"); - EC_POINT_free(q); - q = NULL; - } - -out: - if (bn_qx) { - BN_free(bn_qx); - } - if (bn_qy) { - BN_free(bn_qy); - } - if (key) { - EC_KEY_free(key); - } - - return q; -} - - -static bool get_public_key_from_ec_key(EC_KEY *key, TPMS_ECC_POINT *point) { - BIGNUM *x = BN_new(); - BIGNUM *y = BN_new(); - const EC_POINT *pubkey = EC_KEY_get0_public_key(key); +static bool get_public_key_from_ec_key(EVP_PKEY *pkey, TPMS_ECC_POINT *point) { + BIGNUM *x = NULL; + BIGNUM *y = NULL; unsigned int nbx, nby; bool result = false; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EC_KEY *key = EVP_PKEY_get0_EC_KEY(pkey); + const EC_POINT *pubkey = EC_KEY_get0_public_key(key); + + x = BN_new(); + y = BN_new(); if ((x == NULL) || (y == NULL) || (pubkey == NULL)) { LOG_ERR("Failed to allocate memory to store EC public key."); goto out; @@ -138,6 +88,18 @@ static bool get_public_key_from_ec_key(EC_KEY *key, TPMS_ECC_POINT *point) { EC_POINT_get_affine_coordinates_tss(EC_KEY_get0_group(key), pubkey, x, y, NULL); +#else + int rc = EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_X, &x); + if (!rc) { + LOG_ERR("Failed to get EC public key X."); + goto out; + } + rc = EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &y); + if (!rc) { + LOG_ERR("Failed to get EC public key Y."); + goto out; + } +#endif nbx = BN_num_bytes(x); nby = BN_num_bytes(y); if ((nbx > sizeof(point->x.buffer))|| @@ -153,29 +115,41 @@ static bool get_public_key_from_ec_key(EC_KEY *key, TPMS_ECC_POINT *point) { result = true; out: - if (x) { - BN_free(x); - } - if (y) { - BN_free(y); - } + BN_free(x); + BN_free(y); return result; } -static int get_ECDH_shared_secret(EC_KEY *key, - const EC_POINT *p_pub, TPM2B_ECC_PARAMETER *secret) { +static int get_ECDH_shared_secret(EVP_PKEY *pkey, + EVP_PKEY *p_pub, TPM2B_ECC_PARAMETER *secret) { - int shared_secret_length; + EVP_PKEY_CTX *ctx; + int result = -1; - shared_secret_length = EC_GROUP_get_degree(EC_KEY_get0_group(key)); - shared_secret_length = (shared_secret_length + 7) / 8; - if ((size_t) shared_secret_length > sizeof(secret->buffer)) { + ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!ctx) return -1; - } - secret->size = ECDH_compute_key(secret->buffer, - shared_secret_length, p_pub, key, NULL); - return secret->size; + + int rc = EVP_PKEY_derive_init(ctx); + if (rc <= 0) + goto out; + + rc = EVP_PKEY_derive_set_peer(ctx, p_pub); + if (rc <= 0) + goto out; + + size_t shared_secret_length = sizeof(secret->buffer); + rc = EVP_PKEY_derive(ctx, secret->buffer, &shared_secret_length); + if (rc <= 0) + goto out; + + secret->size = shared_secret_length; + result = secret->size; + +out: + EVP_PKEY_CTX_free(ctx); + return result; } @@ -190,25 +164,42 @@ bool ecdh_derive_seed_and_encrypted_seed( TPMI_ALG_HASH parent_name_alg = parent_pub->publicArea.nameAlg; UINT16 parent_hash_size = tpm2_alg_util_get_hash_size(parent_name_alg); bool result = false; - EC_KEY *key = NULL; - EC_POINT *qsv = NULL; + EVP_PKEY_CTX *ctx; + EVP_PKEY *pkey = NULL; + EVP_PKEY *qsv = NULL; TPMS_ECC_POINT qeu; bool qeu_is_valid; TPM2B_ECC_PARAMETER ecc_secret; // generate an ephemeral key int nid = tpm2_ossl_curve_to_nid(tpm_ecc->curveID); - if (nid >= 0) { - key = EC_KEY_new_by_curve_name(nid); - } - if (key == NULL) { - LOG_ERR("Failed to create EC key from curveID"); + + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + if (!ctx) { + LOG_ERR("Failed to create key creation context"); return false; } - EC_KEY_generate_key(key); + + int rc = EVP_PKEY_keygen_init(ctx); + if (rc <= 0) { + LOG_ERR("Failed to initialize key creation"); + goto out; + } + + rc = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); + if (rc <= 0) { + LOG_ERR("Failed to set EC curve NID %i", nid); + goto out; + } + + rc = EVP_PKEY_keygen(ctx, &pkey); + if (rc <= 0) { + LOG_ERR("Failed to generate the ephemeral EC key"); + goto out; + } // get public key for the ephemeral key - qeu_is_valid = get_public_key_from_ec_key(key, &qeu); + qeu_is_valid = get_public_key_from_ec_key(pkey, &qeu); if (qeu_is_valid == false) { LOG_ERR("Could not get the ECC public key"); goto out; @@ -226,13 +217,17 @@ bool ecdh_derive_seed_and_encrypted_seed( out_sym_seed->size = offset; /* get parents public key */ - qsv = tpm2_get_EC_public_key(parent_pub); + qsv = convert_pubkey_ECC(&parent_pub->publicArea); if (qsv == NULL) { LOG_ERR("Could not get parent's public key"); goto out; } - get_ECDH_shared_secret(key, qsv, &ecc_secret); + rc = get_ECDH_shared_secret(pkey, qsv, &ecc_secret); + if (rc <= 0) { + LOG_ERR("Could not derive shared secret"); + goto out; + } /* derive seed using KDFe */ TPM2B_ECC_PARAMETER *party_u_info = &qeu.x; @@ -244,11 +239,8 @@ bool ecdh_derive_seed_and_encrypted_seed( result = true; out: - if (qsv) { - EC_POINT_free(qsv); - } - if (key) { - EC_KEY_free(key); - } + EVP_PKEY_free(qsv); + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); return result; } -- 2.31.1