d8b5733ac7
The segfault was caused by calling tpm2 command on ppc64le without any additional arguments. Resolves: rhbz#1989617 Signed-off-by: Štěpán Horáček <shoracek@redhat.com>
287 lines
7.8 KiB
Diff
287 lines
7.8 KiB
Diff
From 0caac28c1fa2d62dbf7c5a6c65346f6d3399d22c Mon Sep 17 00:00:00 2001
|
|
From: Petr Gotthard <petr.gotthard@centrum.cz>
|
|
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 <petr.gotthard@centrum.cz>
|
|
---
|
|
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 <string.h>
|
|
|
|
#include <openssl/bn.h>
|
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
|
#include <openssl/ecdh.h>
|
|
-
|
|
+#else
|
|
+#include <openssl/core_names.h>
|
|
+#endif
|
|
#include <tss2/tss2_tpm2_types.h>
|
|
#include <tss2/tss2_mu.h>
|
|
|
|
#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
|
|
|