tpm2-tools: Fix segfault and add support for OpenSSL 3

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>
This commit is contained in:
Štěpán Horáček 2021-09-29 15:40:46 +02:00
parent 4eba1ab649
commit d8b5733ac7
18 changed files with 3233 additions and 1 deletions

View File

@ -0,0 +1,46 @@
From 3520df21494727e5dcde19e079d06d8d9899c7f1 Mon Sep 17 00:00:00 2001
From: Erik Larsson <who+github@cnackers.org>
Date: Sat, 21 Nov 2020 10:59:13 +0100
Subject: [PATCH 01/17] Don't assume end of argv is NULL
On a musl based system argv[optind] && strcmp(...) where optind > argc might read random memory and segfault.
Signed-off-by: Erik Larsson <who+github@cnackers.org>
---
lib/tpm2_options.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/tpm2_options.c b/lib/tpm2_options.c
index e9aaa036..9fa583c6 100644
--- a/lib/tpm2_options.c
+++ b/lib/tpm2_options.c
@@ -300,7 +300,7 @@ tpm2_option_code tpm2_handle_options(int argc, char **argv,
if (argv[optind - 1]) {
if (!strcmp(argv[optind - 1], "--help=no-man") ||
!strcmp(argv[optind - 1], "-h=no-man") ||
- (argv[optind] && !strcmp(argv[optind], "no-man"))) {
+ (argc < optind && !strcmp(argv[optind], "no-man"))) {
manpager = false;
optind++;
/*
@@ -309,7 +309,7 @@ tpm2_option_code tpm2_handle_options(int argc, char **argv,
*/
} else if (!strcmp(argv[optind - 1], "--help=man") ||
!strcmp(argv[optind - 1], "-h=man") ||
- (argv[optind] && !strcmp(argv[optind], "man"))) {
+ (argc < optind && !strcmp(argv[optind], "man"))) {
manpager = true;
explicit_manpager = true;
optind++;
@@ -318,7 +318,7 @@ tpm2_option_code tpm2_handle_options(int argc, char **argv,
* argv[0] = "tool name"
* argv[1] = "--help" argv[2] = 0
*/
- if (!argv[optind] && argc == 2) {
+ if (optind >= argc && argc == 2) {
manpager = false;
} else {
/*
--
2.31.1

View File

@ -0,0 +1,31 @@
From 2a064f4c91a90ab95fe354a42e1166a4c64452fb Mon Sep 17 00:00:00 2001
From: William Roberts <william.c.roberts@intel.com>
Date: Wed, 25 Nov 2020 07:48:44 -0600
Subject: [PATCH 02/17] tpm2_options: fix possible null ptr passed to strdup
Fixes:
../lib/tpm2_options.c:201:20: warning: Null pointer passed as an argument to a 'nonnull' parameter
command_copy = strdup(command);
Signed-off-by: William Roberts <william.c.roberts@intel.com>
---
lib/tpm2_options.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/tpm2_options.c b/lib/tpm2_options.c
index 9fa583c6..c2e18bad 100644
--- a/lib/tpm2_options.c
+++ b/lib/tpm2_options.c
@@ -193,8 +193,7 @@ void tpm2_print_usage(const char *command, struct tpm2_options *tool_opts) {
unsigned int i;
bool indent = true;
char *command_copy;
-
- if (!tool_opts) {
+ if (!tool_opts || !command) {
return;
}
--
2.31.1

View File

@ -0,0 +1,143 @@
From 6a3100ad060934228a1bec06ae43b41f5ea8a51b Mon Sep 17 00:00:00 2001
From: Trammell hudson <hudson@trmm.net>
Date: Fri, 26 Mar 2021 17:23:07 +0000
Subject: [PATCH 03/17] tpm2_identity_util: move create_name() into utility
library
Signed-off-by: Trammell Hudson <hudson@trmm.net>
---
lib/tpm2_identity_util.c | 40 ++++++++++++++++++++++++++++++++++++++
lib/tpm2_identity_util.h | 10 ++++++++++
tools/tpm2_import.c | 42 +---------------------------------------
3 files changed, 51 insertions(+), 41 deletions(-)
diff --git a/lib/tpm2_identity_util.c b/lib/tpm2_identity_util.c
index a3b0e387..e11137ab 100644
--- a/lib/tpm2_identity_util.c
+++ b/lib/tpm2_identity_util.c
@@ -423,3 +423,43 @@ void tpm2_identity_util_calculate_outer_integrity(TPMI_ALG_HASH parent_name_alg,
encrypted_duplicate_sensitive->size, pubname->name, pubname->size,
protection_hmac_key->buffer, outer_hmac);
}
+
+bool tpm2_identity_create_name(TPM2B_PUBLIC *public, TPM2B_NAME *pubname) {
+
+ /*
+ * A TPM2B_NAME is the name of the algorithm, followed by the hash.
+ * Calculate the name by:
+ * 1. Marshaling the name algorithm
+ * 2. Marshaling the TPMT_PUBLIC past the name algorithm from step 1.
+ * 3. Hash the TPMT_PUBLIC portion in marshaled data.
+ */
+
+ TPMI_ALG_HASH name_alg = public->publicArea.nameAlg;
+
+ // Step 1 - set beginning of name to hash alg
+ size_t hash_offset = 0;
+ Tss2_MU_UINT16_Marshal(name_alg, pubname->name, pubname->size,
+ &hash_offset);
+
+ // Step 2 - marshal TPMTP
+ TPMT_PUBLIC marshaled_tpmt;
+ size_t tpmt_marshalled_size = 0;
+ Tss2_MU_TPMT_PUBLIC_Marshal(&public->publicArea,
+ (uint8_t *) &marshaled_tpmt, sizeof(public->publicArea),
+ &tpmt_marshalled_size);
+
+ // Step 3 - Hash the data into name just past the alg type.
+ digester d = tpm2_openssl_halg_to_digester(name_alg);
+ if (!d) {
+ return false;
+ }
+
+ d((const unsigned char *) &marshaled_tpmt, tpmt_marshalled_size,
+ pubname->name + hash_offset);
+
+ //Set the name size, UINT16 followed by HASH
+ UINT16 hash_size = tpm2_alg_util_get_hash_size(name_alg);
+ pubname->size = hash_size + hash_offset;
+
+ return true;
+}
diff --git a/lib/tpm2_identity_util.h b/lib/tpm2_identity_util.h
index 0ac55793..61e10376 100644
--- a/lib/tpm2_identity_util.h
+++ b/lib/tpm2_identity_util.h
@@ -102,4 +102,14 @@ void tpm2_identity_util_calculate_outer_integrity(TPMI_ALG_HASH parent_name_alg,
TPM2B_MAX_BUFFER *encrypted_duplicate_sensitive,
TPM2B_DIGEST *outer_hmac);
+/**
+ * Computes the name of a TPM key.
+ *
+ * @param public
+ * Public key structure
+ * @param pubname
+ * The name structure to populate.
+ */
+bool tpm2_identity_create_name(TPM2B_PUBLIC *public, TPM2B_NAME *pubname);
+
#endif /* LIB_TPM2_IDENTITY_UTIL_H_ */
diff --git a/tools/tpm2_import.c b/tools/tpm2_import.c
index eb8dd9a7..a5d1b4e6 100644
--- a/tools/tpm2_import.c
+++ b/tools/tpm2_import.c
@@ -74,46 +74,6 @@ static tool_rc readpublic(ESYS_CONTEXT *ectx, ESYS_TR handle,
return tpm2_readpublic(ectx, handle, public, NULL, NULL);
}
-static bool create_name(TPM2B_PUBLIC *public, TPM2B_NAME *pubname) {
-
- /*
- * A TPM2B_NAME is the name of the algorithm, followed by the hash.
- * Calculate the name by:
- * 1. Marshaling the name algorithm
- * 2. Marshaling the TPMT_PUBLIC past the name algorithm from step 1.
- * 3. Hash the TPMT_PUBLIC portion in marshaled data.
- */
-
- TPMI_ALG_HASH name_alg = public->publicArea.nameAlg;
-
- // Step 1 - set beginning of name to hash alg
- size_t hash_offset = 0;
- Tss2_MU_UINT16_Marshal(name_alg, pubname->name, pubname->size,
- &hash_offset);
-
- // Step 2 - marshal TPMTP
- TPMT_PUBLIC marshaled_tpmt;
- size_t tpmt_marshalled_size = 0;
- Tss2_MU_TPMT_PUBLIC_Marshal(&public->publicArea,
- (uint8_t *) &marshaled_tpmt, sizeof(public->publicArea),
- &tpmt_marshalled_size);
-
- // Step 3 - Hash the data into name just past the alg type.
- digester d = tpm2_openssl_halg_to_digester(name_alg);
- if (!d) {
- return false;
- }
-
- d((const unsigned char *) &marshaled_tpmt, tpmt_marshalled_size,
- pubname->name + 2);
-
- //Set the name size, UINT16 followed by HASH
- UINT16 hash_size = tpm2_alg_util_get_hash_size(name_alg);
- pubname->size = hash_size + 2;
-
- return true;
-}
-
static void create_import_key_private_data(TPM2B_PRIVATE *private,
TPMI_ALG_HASH parent_name_alg,
TPM2B_MAX_BUFFER *encrypted_duplicate_sensitive,
@@ -155,7 +115,7 @@ static tool_rc key_import(ESYS_CONTEXT *ectx, TPM2B_PUBLIC *parent_pub,
* Calculate the object name.
*/
TPM2B_NAME pubname = TPM2B_TYPE_INIT(TPM2B_NAME, name);
- bool res = create_name(pubkey, &pubname);
+ bool res = tpm2_identity_create_name(pubkey, &pubname);
if (!res) {
return false;
}
--
2.31.1

View File

@ -0,0 +1,254 @@
From 61989b4c0a2da337a5c8df56e68c83e73259ed75 Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Sat, 7 Aug 2021 11:39:52 +0200
Subject: [PATCH 04/17] openssl: Remove support for OpenSSL < 1.1.0
The OpenSSL 1.0.2 is no longer maintained. Supporting an EOL crypto
library is not a good idea.
- Compared to the upstream commit 1e439d85 changes related to functions
and features not previously backported were ommited.
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
configure.ac | 2 +-
doc/CHANGELOG.md | 5 +++
doc/INSTALL.md | 2 +-
doc/RELEASE.md | 7 ----
lib/tpm2_openssl.c | 87 ----------------------------------------------
lib/tpm2_openssl.h | 10 ------
6 files changed, 7 insertions(+), 106 deletions(-)
diff --git a/configure.ac b/configure.ac
index a3988e15..9561fa86 100644
--- a/configure.ac
+++ b/configure.ac
@@ -58,7 +58,7 @@ PKG_CHECK_MODULES([TSS2_TCTILDR], [tss2-tctildr])
PKG_CHECK_MODULES([TSS2_MU], [tss2-mu])
PKG_CHECK_MODULES([TSS2_RC], [tss2-rc])
PKG_CHECK_MODULES([TSS2_SYS], [tss2-sys])
-PKG_CHECK_MODULES([CRYPTO], [libcrypto >= 1.0.2g])
+PKG_CHECK_MODULES([CRYPTO], [libcrypto >= 1.1.0])
PKG_CHECK_MODULES([CURL], [libcurl])
PKG_CHECK_MODULES([UUID], [uuid])
diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md
index 87573fd7..b244dfee 100644
--- a/doc/CHANGELOG.md
+++ b/doc/CHANGELOG.md
@@ -1,5 +1,10 @@
## Changelog
+### next
+
+ * openssl:
+ - Dropped support for OpenSSL < 1.1.0
+
### 5.0 - 2020-11-16
#### Non Backwards Compatible Changes
diff --git a/doc/INSTALL.md b/doc/INSTALL.md
index b23b8d61..ab160581 100644
--- a/doc/INSTALL.md
+++ b/doc/INSTALL.md
@@ -19,7 +19,7 @@ To build and install the tpm2-tools software the following software is required:
* C compiler
* C Library Development Libraries and Header Files (for pthreads headers)
* ESAPI - TPM2.0 TSS ESAPI library (tss2-esys) and header files
- * OpenSSL libcrypto library and header files
+ * OpenSSL libcrypto library and header files (version >= 1.1.0)
* Curl library and header files
* Universally Unique ID library (UUID)
diff --git a/doc/RELEASE.md b/doc/RELEASE.md
index e2c72a67..8769b57d 100644
--- a/doc/RELEASE.md
+++ b/doc/RELEASE.md
@@ -23,13 +23,6 @@ the next release.
- [3.0.X](https://github.com/tpm2-software/tpm2-tools/tree/3.0.X): EOL after
3.2.1 release.
-## OpenSSL
-
-tpm2-tools relies heavily on OpenSSL. OpenSSL will be EOL'ing 1.0.2 at the end
-of 2019, see: https://www.openssl.org/blog/blog/2018/05/18/new-lts/. When this
-occurs, we will remove OSSL 1.0.2 support from the tpm2-tools repository as
-supporting an EOL crypto library is not a good idea.
-
# Release Information
Releases shall be tagged following semantic version guidelines found at:
diff --git a/lib/tpm2_openssl.c b/lib/tpm2_openssl.c
index e769d6df..877d2764 100644
--- a/lib/tpm2_openssl.c
+++ b/lib/tpm2_openssl.c
@@ -72,58 +72,6 @@ const EVP_MD *tpm2_openssl_halg_from_tpmhalg(TPMI_ALG_HASH algorithm) {
/* no return, not possible */
}
-#if defined(LIB_TPM2_OPENSSL_OPENSSL_PRE11)
-int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) {
-
- if ((r->n == NULL && n == NULL) || (r->e == NULL && e == NULL)) {
- return 0;
- }
-
- if (n != NULL) {
- BN_free(r->n);
- r->n = n;
- }
-
- if (e != NULL) {
- BN_free(r->e);
- r->e = e;
- }
-
- if (d != NULL) {
- BN_free(r->d);
- r->d = d;
- }
-
- return 1;
-}
-
-void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) {
- if(p) {
- *p = r->p;
- }
-
- if (q) {
- *q = r->q;
- }
-}
-
-int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) {
-
- if (!r || !s) {
- return 0;
- }
-
- BN_clear_free(sig->r);
- BN_clear_free(sig->s);
-
- sig->r = r;
- sig->s = s;
-
- return 1;
-}
-
-#endif
-
bool tpm2_openssl_hash_compute_data(TPMI_ALG_HASH halg, BYTE *buffer,
UINT16 length, TPM2B_DIGEST *digest) {
@@ -422,54 +370,28 @@ out:
HMAC_CTX *tpm2_openssl_hmac_new() {
HMAC_CTX *ctx;
-#if defined(LIB_TPM2_OPENSSL_OPENSSL_PRE11)
- ctx = malloc(sizeof(*ctx));
-#else
ctx = HMAC_CTX_new();
-#endif
if (!ctx)
return NULL;
-#if defined(LIB_TPM2_OPENSSL_OPENSSL_PRE11)
- HMAC_CTX_init(ctx);
-#endif
-
return ctx;
}
void tpm2_openssl_hmac_free(HMAC_CTX *ctx) {
-#if defined(LIB_TPM2_OPENSSL_OPENSSL_PRE11)
- HMAC_CTX_cleanup(ctx);
- free(ctx);
-#else
HMAC_CTX_free(ctx);
-#endif
}
EVP_CIPHER_CTX *tpm2_openssl_cipher_new(void) {
EVP_CIPHER_CTX *ctx;
-#if defined(LIB_TPM2_OPENSSL_OPENSSL_PRE11)
- ctx = malloc(sizeof(*ctx));
-#else
ctx = EVP_CIPHER_CTX_new();
-#endif
if (!ctx)
return NULL;
-#if defined(LIB_TPM2_OPENSSL_OPENSSL_PRE11)
- EVP_CIPHER_CTX_init(ctx);
-#endif
-
return ctx;
}
void tpm2_openssl_cipher_free(EVP_CIPHER_CTX *ctx) {
-#if defined(LIB_TPM2_OPENSSL_OPENSSL_PRE11)
- EVP_CIPHER_CTX_cleanup(ctx);
- free(ctx);
-#else
EVP_CIPHER_CTX_free(ctx);
-#endif
}
digester tpm2_openssl_halg_to_digester(TPMI_ALG_HASH halg) {
@@ -680,12 +602,7 @@ static bool load_public_RSA_from_key(RSA *k, TPM2B_PUBLIC *pub) {
const BIGNUM *n; /* modulus */
const BIGNUM *e; /* public key exponent */
-#if defined(LIB_TPM2_OPENSSL_OPENSSL_PRE11)
- n = k->n;
- e = k->e;
-#else
RSA_get0_key(k, &n, &e, NULL);
-#endif
/*
* The size of the modulus is the key size in RSA, store this as the
@@ -1006,11 +923,7 @@ static bool load_private_RSA_from_key(RSA *k, TPM2B_SENSITIVE *priv) {
const BIGNUM *p; /* the private key exponent */
-#if defined(LIB_TPM2_OPENSSL_OPENSSL_PRE11)
- p = k->p;
-#else
RSA_get0_factors(k, &p, NULL);
-#endif
TPMT_SENSITIVE *sa = &priv->sensitiveArea;
diff --git a/lib/tpm2_openssl.h b/lib/tpm2_openssl.h
index 46c8f9c0..8e3e0c17 100644
--- a/lib/tpm2_openssl.h
+++ b/lib/tpm2_openssl.h
@@ -13,10 +13,6 @@
#include "pcr.h"
-#if (OPENSSL_VERSION_NUMBER < 0x1010000fL && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) /* OpenSSL 1.1.0 */
-#define LIB_TPM2_OPENSSL_OPENSSL_PRE11
-#endif
-
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
#define EC_POINT_set_affine_coordinates_tss(group, tpm_pub_key, bn_x, bn_y, dmy) \
EC_POINT_set_affine_coordinates(group, tpm_pub_key, bn_x, bn_y, dmy)
@@ -32,12 +28,6 @@
EC_POINT_get_affine_coordinates_GFp(group, tpm_pub_key, bn_x, bn_y, dmy)
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
-#if defined(LIB_TPM2_OPENSSL_OPENSSL_PRE11)
-int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
-void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q);
-int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
-#endif
-
/**
* Function prototype for a hashing routine.
*
--
2.31.1

View File

@ -0,0 +1,48 @@
From 8c1968a1e52c3d45a96509e9eba753357ad377c9 Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Sat, 7 Aug 2021 11:45:14 +0200
Subject: [PATCH 05/17] openssl: Remove functions that have no effect in
OpenSSL >= 1.1.0
This will work with OpenSSL 1.1.0 through 3.0.0.
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
lib/tpm2_convert.c | 1 -
tools/tpm2_tool.c | 8 --------
2 files changed, 9 deletions(-)
diff --git a/lib/tpm2_convert.c b/lib/tpm2_convert.c
index 27a0effe..cc1c18ab 100644
--- a/lib/tpm2_convert.c
+++ b/lib/tpm2_convert.c
@@ -262,7 +262,6 @@ static bool tpm2_convert_pubkey_bio(TPMT_PUBLIC *public,
"Unsupported key type for requested output format. Only RSA is supported.");
}
- ERR_free_strings();
return result;
}
diff --git a/tools/tpm2_tool.c b/tools/tpm2_tool.c
index f4865266..edd04c83 100644
--- a/tools/tpm2_tool.c
+++ b/tools/tpm2_tool.c
@@ -230,14 +230,6 @@ int main(int argc, char **argv) {
tpm2_errata_init(ctx.ectx);
}
- /*
- * Load the openssl error strings and algorithms
- * so library routines work as expected.
- */
- OpenSSL_add_all_algorithms();
- OpenSSL_add_all_ciphers();
- ERR_load_crypto_strings();
-
/*
* Call the specific tool, all tools implement this function instead of
* 'main'.
--
2.31.1

View File

@ -0,0 +1,150 @@
From 43ad483907069798920a949a3cc9615cb3156975 Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Sat, 7 Aug 2021 11:56:22 +0200
Subject: [PATCH 06/17] openssl: Remove unnecesary EVP_CIPHER_CTX and HMAC_CTX
wrappers
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
lib/tpm2_identity_util.c | 7 +++++--
lib/tpm2_kdfa.c | 4 ++--
lib/tpm2_openssl.c | 26 --------------------------
lib/tpm2_openssl.h | 31 -------------------------------
4 files changed, 7 insertions(+), 61 deletions(-)
diff --git a/lib/tpm2_identity_util.c b/lib/tpm2_identity_util.c
index e11137ab..a268295f 100644
--- a/lib/tpm2_identity_util.c
+++ b/lib/tpm2_identity_util.c
@@ -289,7 +289,10 @@ static bool aes_encrypt_buffers(TPMT_SYM_DEF_OBJECT *sym,
return false;
}
- EVP_CIPHER_CTX *ctx = tpm2_openssl_cipher_new();
+ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+ if (!ctx) {
+ return false;
+ }
int rc = EVP_EncryptInit_ex(ctx, cipher, NULL, encryption_key, iv);
if (!rc) {
@@ -336,7 +339,7 @@ static bool aes_encrypt_buffers(TPMT_SYM_DEF_OBJECT *sym,
result = true;
out:
- tpm2_openssl_cipher_free(ctx);
+ EVP_CIPHER_CTX_free(ctx);
return result;
}
diff --git a/lib/tpm2_kdfa.c b/lib/tpm2_kdfa.c
index 354516e8..5747b3ca 100644
--- a/lib/tpm2_kdfa.c
+++ b/lib/tpm2_kdfa.c
@@ -40,7 +40,7 @@ TSS2_RC tpm2_kdfa(TPMI_ALG_HASH hash_alg, TPM2B *key, char *label,
return TPM2_RC_HASH;
}
- HMAC_CTX *ctx = tpm2_openssl_hmac_new();
+ HMAC_CTX *ctx = HMAC_CTX_new();
if (!ctx) {
LOG_ERR("HMAC context allocation failed");
return TPM2_RC_MEMORY;
@@ -100,7 +100,7 @@ TSS2_RC tpm2_kdfa(TPMI_ALG_HASH hash_alg, TPM2B *key, char *label,
result_key->size = bytes;
err:
- tpm2_openssl_hmac_free(ctx);
+ HMAC_CTX_free(ctx);
return rval;
}
diff --git a/lib/tpm2_openssl.c b/lib/tpm2_openssl.c
index 877d2764..1752525e 100644
--- a/lib/tpm2_openssl.c
+++ b/lib/tpm2_openssl.c
@@ -368,32 +368,6 @@ out:
return result;
}
-HMAC_CTX *tpm2_openssl_hmac_new() {
- HMAC_CTX *ctx;
- ctx = HMAC_CTX_new();
- if (!ctx)
- return NULL;
-
- return ctx;
-}
-
-void tpm2_openssl_hmac_free(HMAC_CTX *ctx) {
- HMAC_CTX_free(ctx);
-}
-
-EVP_CIPHER_CTX *tpm2_openssl_cipher_new(void) {
- EVP_CIPHER_CTX *ctx;
- ctx = EVP_CIPHER_CTX_new();
- if (!ctx)
- return NULL;
-
- return ctx;
-}
-
-void tpm2_openssl_cipher_free(EVP_CIPHER_CTX *ctx) {
- EVP_CIPHER_CTX_free(ctx);
-}
-
digester tpm2_openssl_halg_to_digester(TPMI_ALG_HASH halg) {
switch (halg) {
diff --git a/lib/tpm2_openssl.h b/lib/tpm2_openssl.h
index 8e3e0c17..642e4635 100644
--- a/lib/tpm2_openssl.h
+++ b/lib/tpm2_openssl.h
@@ -67,20 +67,6 @@ int tpm2_openssl_halgid_from_tpmhalg(TPMI_ALG_HASH algorithm);
*/
const EVP_MD *tpm2_openssl_halg_from_tpmhalg(TPMI_ALG_HASH algorithm);
-/**
- * Start an openssl hmac session.
- * @return
- * A valid session pointer or NULL on error.
- */
-HMAC_CTX *tpm2_openssl_hmac_new();
-
-/**
- * Free an hmac context created via tpm2_openssl_hmac_new().
- * @param ctx
- * The context to release resources of.
- */
-void tpm2_openssl_hmac_free(HMAC_CTX *ctx);
-
/**
* Hash a byte buffer.
* @param halg
@@ -161,23 +147,6 @@ bool tpm2_openssl_hash_pcr_banks_le(TPMI_ALG_HASH hashAlg,
bool tpm2_openssl_pcr_extend(TPMI_ALG_HASH halg, BYTE *pcr,
const BYTE *data, UINT16 length);
-/**
- * Obtains an OpenSSL EVP_CIPHER_CTX dealing with version
- * API changes in OSSL.
- *
- * @return
- * An Initialized OpenSSL EVP_CIPHER_CTX.
- */
-EVP_CIPHER_CTX *tpm2_openssl_cipher_new(void);
-
-/**
- * Free's an EVP_CIPHER_CTX obtained via tpm2_openssl_cipher_new()
- * dealing with OSSL API version changes.
- * @param ctx
- * The EVP_CIPHER_CTX to free.
- */
-void tpm2_openssl_cipher_free(EVP_CIPHER_CTX *ctx);
-
/**
* Returns a function pointer capable of performing the
* given digest from a TPMI_HASH_ALG.
--
2.31.1

View File

@ -0,0 +1,104 @@
From 59f35567cf810d9eafdeedced5dc5571d9b33dfd Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Sat, 7 Aug 2021 12:26:15 +0200
Subject: [PATCH 07/17] openssl: Replace SHA256_CTX by EVP_MD_CTX
The EVP_MD_CTX_new() was introduced in OpenSSL 1.1.0 and
the SHA256_CTX was deprecated in OpenSSL 3.0.0.
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
tools/tpm2_getekcertificate.c | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/tools/tpm2_getekcertificate.c b/tools/tpm2_getekcertificate.c
index b480dbc3..81600b61 100644
--- a/tools/tpm2_getekcertificate.c
+++ b/tools/tpm2_getekcertificate.c
@@ -63,20 +63,20 @@ static unsigned char *hash_ek_public(void) {
return NULL;
}
- SHA256_CTX sha256;
- int is_success = SHA256_Init(&sha256);
+ EVP_MD_CTX *sha256 = EVP_MD_CTX_new();
+ int is_success = EVP_DigestInit(sha256, EVP_sha256());
if (!is_success) {
- LOG_ERR("SHA256_Init failed");
+ LOG_ERR("EVP_DigestInit failed");
goto err;
}
switch (ctx.out_public->publicArea.type) {
case TPM2_ALG_RSA:
- is_success = SHA256_Update(&sha256,
+ is_success = EVP_DigestUpdate(sha256,
ctx.out_public->publicArea.unique.rsa.buffer,
ctx.out_public->publicArea.unique.rsa.size);
if (!is_success) {
- LOG_ERR("SHA256_Update failed");
+ LOG_ERR("EVP_DigestUpdate failed");
goto err;
}
@@ -85,27 +85,27 @@ static unsigned char *hash_ek_public(void) {
goto err;
}
BYTE buf[3] = { 0x1, 0x00, 0x01 }; // Exponent
- is_success = SHA256_Update(&sha256, buf, sizeof(buf));
+ is_success = EVP_DigestUpdate(sha256, buf, sizeof(buf));
if (!is_success) {
- LOG_ERR("SHA256_Update failed");
+ LOG_ERR("EVP_DigestUpdate failed");
goto err;
}
break;
case TPM2_ALG_ECC:
- is_success = SHA256_Update(&sha256,
+ is_success = EVP_DigestUpdate(sha256,
ctx.out_public->publicArea.unique.ecc.x.buffer,
ctx.out_public->publicArea.unique.ecc.x.size);
if (!is_success) {
- LOG_ERR("SHA256_Update failed");
+ LOG_ERR("EVP_DigestUpdate failed");
goto err;
}
- is_success = SHA256_Update(&sha256,
+ is_success = EVP_DigestUpdate(sha256,
ctx.out_public->publicArea.unique.ecc.y.buffer,
ctx.out_public->publicArea.unique.ecc.y.size);
if (!is_success) {
- LOG_ERR("SHA256_Update failed");
+ LOG_ERR("EVP_DigestUpdate failed");
goto err;
}
break;
@@ -115,12 +115,13 @@ static unsigned char *hash_ek_public(void) {
goto err;
}
- is_success = SHA256_Final(hash, &sha256);
+ is_success = EVP_DigestFinal_ex(sha256, hash, NULL);
if (!is_success) {
- LOG_ERR("SHA256_Final failed");
+ LOG_ERR("EVP_DigestFinal failed");
goto err;
}
+ EVP_MD_CTX_free(sha256);
if (ctx.verbose) {
tpm2_tool_output("public-key-hash:\n");
tpm2_tool_output(" sha256: ");
@@ -134,6 +135,7 @@ static unsigned char *hash_ek_public(void) {
return hash;
err:
free(hash);
+ EVP_MD_CTX_free(sha256);
return NULL;
}
--
2.31.1

View File

@ -0,0 +1,31 @@
From 0dfb7b70f77ddcb8a82ca45f04e028c5fcfc350e Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Sat, 7 Aug 2021 12:29:28 +0200
Subject: [PATCH 08/17] openssl: Replace deprecated X509_get_ by X509_getm_
The X509_get_notBefore() and X509_get_notAfter() were deprecated already
in OpenSSL 1.1.0.
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
tools/misc/tpm2_certifyX509certutil.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/misc/tpm2_certifyX509certutil.c b/tools/misc/tpm2_certifyX509certutil.c
index e56da2d3..62ed644a 100644
--- a/tools/misc/tpm2_certifyX509certutil.c
+++ b/tools/misc/tpm2_certifyX509certutil.c
@@ -260,8 +260,8 @@ static tool_rc generate_partial_X509() {
goto out_err;
}
- X509_gmtime_adj(X509_get_notBefore(cert), 0); // add valid not before
- X509_gmtime_adj(X509_get_notAfter(cert), valid_days * 86400); // add valid not after
+ X509_gmtime_adj(X509_getm_notBefore(cert), 0); // add valid not before
+ X509_gmtime_adj(X509_getm_notAfter(cert), valid_days * 86400); // add valid not after
X509_NAME *subject = X509_get_subject_name(cert);
if (!subject) {
--
2.31.1

View File

@ -0,0 +1,209 @@
From 220b7e0afa943693a4fdafd9a5b8d9e38ea4e785 Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Sat, 7 Aug 2021 15:54:51 +0200
Subject: [PATCH 09/17] openssl: Convert deprecated SHA256|384 digesters to
EVP_Digest
The EVP_Digest function is available since OpenSSL 1.1.0
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
lib/tpm2_identity_util.c | 34 ++++++++++++++++++++++++----------
lib/tpm2_kdfe.c | 13 +++++++++++--
lib/tpm2_openssl.c | 17 -----------------
lib/tpm2_openssl.h | 28 ----------------------------
lib/tpm2_util.c | 15 +++++++++++----
5 files changed, 46 insertions(+), 61 deletions(-)
diff --git a/lib/tpm2_identity_util.c b/lib/tpm2_identity_util.c
index a268295f..e0c3f404 100644
--- a/lib/tpm2_identity_util.c
+++ b/lib/tpm2_identity_util.c
@@ -391,11 +391,20 @@ bool tpm2_identity_util_calculate_inner_integrity(TPMI_ALG_HASH name_alg,
Tss2_MU_UINT16_Marshal(hash_size, marshalled_sensitive_and_name_digest,
sizeof(uint16_t), &digest_size_info);
- digester d = tpm2_openssl_halg_to_digester(name_alg);
- d(buffer_marshalled_sensitiveArea,
- marshalled_sensitive_size_info + marshalled_sensitive_size
- + pubname->size,
- marshalled_sensitive_and_name_digest + digest_size_info);
+ const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(name_alg);
+ if (!md) {
+ LOG_ERR("Algorithm not supported: %x", name_alg);
+ return false;
+ }
+ int rc = EVP_Digest(buffer_marshalled_sensitiveArea,
+ marshalled_sensitive_size_info + marshalled_sensitive_size
+ + pubname->size,
+ marshalled_sensitive_and_name_digest + digest_size_info,
+ NULL, md, NULL);
+ if (!rc) {
+ LOG_ERR("Hash calculation failed");
+ return false;
+ }
//Inner integrity
encrypted_inner_integrity->size = marshalled_sensitive_size_info
@@ -452,16 +461,21 @@ bool tpm2_identity_create_name(TPM2B_PUBLIC *public, TPM2B_NAME *pubname) {
&tpmt_marshalled_size);
// Step 3 - Hash the data into name just past the alg type.
- digester d = tpm2_openssl_halg_to_digester(name_alg);
- if (!d) {
+ const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(name_alg);
+ if (!md) {
+ LOG_ERR("Algorithm not supported: %x", name_alg);
return false;
}
- d((const unsigned char *) &marshaled_tpmt, tpmt_marshalled_size,
- pubname->name + hash_offset);
+ unsigned int hash_size;
+ int rc = EVP_Digest(&marshaled_tpmt, tpmt_marshalled_size,
+ pubname->name + hash_offset, &hash_size, md, NULL);
+ if (!rc) {
+ LOG_ERR("Hash calculation failed");
+ return false;
+ }
//Set the name size, UINT16 followed by HASH
- UINT16 hash_size = tpm2_alg_util_get_hash_size(name_alg);
pubname->size = hash_size + hash_offset;
return true;
diff --git a/lib/tpm2_kdfe.c b/lib/tpm2_kdfe.c
index e8aeb04c..aa4d3e0b 100644
--- a/lib/tpm2_kdfe.c
+++ b/lib/tpm2_kdfe.c
@@ -42,13 +42,22 @@ TSS2_RC tpm2_kdfe(
tpm2_util_concat_buffer(&hash_input, (TPM2B *) party_u);
tpm2_util_concat_buffer(&hash_input, (TPM2B *) party_v);
- digester d = tpm2_openssl_halg_to_digester(hash_alg);
+ const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(hash_alg);
+ if (!md) {
+ LOG_ERR("Algorithm not supported: %x", hash_alg);
+ return TPM2_RC_HASH;
+ }
for (done = 0, counter = 1; done < bytes; done += hash_size, counter++) {
counter_be = tpm2_util_hton_32(counter);
memcpy(hash_input.buffer, &counter_be, 4);
- d(hash_input.buffer, hash_input.size, result_key->buffer + done);
+ int rc = EVP_Digest(hash_input.buffer, hash_input.size,
+ result_key->buffer + done, NULL, md, NULL);
+ if (!rc) {
+ LOG_ERR("Hash calculation failed");
+ return TPM2_RC_MEMORY;
+ }
}
// truncate the result to the desired size
result_key->size = bytes;
diff --git a/lib/tpm2_openssl.c b/lib/tpm2_openssl.c
index 1752525e..cdce92f8 100644
--- a/lib/tpm2_openssl.c
+++ b/lib/tpm2_openssl.c
@@ -368,23 +368,6 @@ out:
return result;
}
-digester tpm2_openssl_halg_to_digester(TPMI_ALG_HASH halg) {
-
- switch (halg) {
- case TPM2_ALG_SHA1:
- return SHA1;
- case TPM2_ALG_SHA256:
- return SHA256;
- case TPM2_ALG_SHA384:
- return SHA384;
- case TPM2_ALG_SHA512:
- return SHA512;
- /* no default */
- }
-
- return NULL;
-}
-
/*
* Per man openssl(1), handle the following --passin formats:
* pass:password
diff --git a/lib/tpm2_openssl.h b/lib/tpm2_openssl.h
index 642e4635..78cb826a 100644
--- a/lib/tpm2_openssl.h
+++ b/lib/tpm2_openssl.h
@@ -28,23 +28,6 @@
EC_POINT_get_affine_coordinates_GFp(group, tpm_pub_key, bn_x, bn_y, dmy)
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
-/**
- * Function prototype for a hashing routine.
- *
- * This is a wrapper around OSSL SHA256|384 and etc digesters.
- *
- * @param d
- * The data to digest.
- * @param n
- * The length of the data to digest.
- * @param md
- * The output message digest.
- * @return
- * A pointer to the digest or NULL on error.
- */
-typedef unsigned char *(*digester)(const unsigned char *d, size_t n,
- unsigned char *md);
-
static inline const char *tpm2_openssl_get_err(void) {
return ERR_error_string(ERR_get_error(), NULL);
}
@@ -147,17 +130,6 @@ bool tpm2_openssl_hash_pcr_banks_le(TPMI_ALG_HASH hashAlg,
bool tpm2_openssl_pcr_extend(TPMI_ALG_HASH halg, BYTE *pcr,
const BYTE *data, UINT16 length);
-/**
- * Returns a function pointer capable of performing the
- * given digest from a TPMI_HASH_ALG.
- *
- * @param halg
- * The hashing algorithm to use.
- * @return
- * NULL on failure or a valid digester on success.
- */
-digester tpm2_openssl_halg_to_digester(TPMI_ALG_HASH halg);
-
typedef enum tpm2_openssl_load_rc tpm2_openssl_load_rc;
enum tpm2_openssl_load_rc {
lprc_error = 0, /* an error has occurred */
diff --git a/lib/tpm2_util.c b/lib/tpm2_util.c
index 4125a4b9..d2c654db 100644
--- a/lib/tpm2_util.c
+++ b/lib/tpm2_util.c
@@ -579,13 +579,20 @@ bool tpm2_util_calc_unique(TPMI_ALG_HASH name_alg,
memcpy(buf.buffer, seed->buffer, seed->size);
memcpy(&buf.buffer[seed->size], key->buffer, key->size);
- digester d = tpm2_openssl_halg_to_digester(name_alg);
- if (!d) {
+ const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(name_alg);
+ if (!md) {
+ LOG_ERR("Algorithm not supported: %x", name_alg);
return false;
}
- unique_data->size = tpm2_alg_util_get_hash_size(name_alg);
- d(buf.buffer, buf.size, unique_data->buffer);
+ unsigned int hash_size;
+ int rc = EVP_Digest(buf.buffer, buf.size, unique_data->buffer, &hash_size,
+ md, NULL);
+ if (!rc) {
+ LOG_ERR("Hash calculation failed");
+ return false;
+ }
+ unique_data->size = hash_size;
return true;
}
--
2.31.1

View File

@ -0,0 +1,194 @@
From b32168af24708f42a0ee28252912e3155505e983 Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Tue, 10 Aug 2021 11:49:00 +0200
Subject: [PATCH 10/17] openssl: Rename tpm2_openssl_halg_from_tpmhalg
Change its name to tpm2_openssl_md_from_tpmhalg for better naming
consistency with the openssl.
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
lib/tpm2_identity_util.c | 8 ++++----
lib/tpm2_kdfa.c | 2 +-
lib/tpm2_kdfe.c | 2 +-
lib/tpm2_openssl.c | 12 ++++++------
lib/tpm2_openssl.h | 2 +-
lib/tpm2_util.c | 4 ++--
tools/misc/tpm2_checkquote.c | 2 +-
7 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/lib/tpm2_identity_util.c b/lib/tpm2_identity_util.c
index e0c3f404..ba0c0e1c 100644
--- a/lib/tpm2_identity_util.c
+++ b/lib/tpm2_identity_util.c
@@ -134,7 +134,7 @@ static bool share_secret_with_tpm2_rsa_public_key(TPM2B_DIGEST *protection_seed,
unsigned char encoded[TPM2_MAX_DIGEST_BUFFER];
return_code = RSA_padding_add_PKCS1_OAEP_mgf1(encoded, mod_size,
protection_seed->buffer, protection_seed->size, label, label_len,
- tpm2_openssl_halg_from_tpmhalg(parent_name_alg), NULL);
+ tpm2_openssl_md_from_tpmhalg(parent_name_alg), NULL);
if (return_code != 1) {
LOG_ERR("Failed RSA_padding_add_PKCS1_OAEP_mgf1\n");
goto error;
@@ -356,7 +356,7 @@ static void hmac_outer_integrity(TPMI_ALG_HASH parent_name_alg,
UINT16 hash_size = tpm2_alg_util_get_hash_size(parent_name_alg);
- HMAC(tpm2_openssl_halg_from_tpmhalg(parent_name_alg), hmac_key, hash_size,
+ HMAC(tpm2_openssl_md_from_tpmhalg(parent_name_alg), hmac_key, hash_size,
to_hmac_buffer, buffer1_size + buffer2_size,
outer_integrity_hmac->buffer, &size);
outer_integrity_hmac->size = size;
@@ -391,7 +391,7 @@ bool tpm2_identity_util_calculate_inner_integrity(TPMI_ALG_HASH name_alg,
Tss2_MU_UINT16_Marshal(hash_size, marshalled_sensitive_and_name_digest,
sizeof(uint16_t), &digest_size_info);
- const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(name_alg);
+ const EVP_MD *md = tpm2_openssl_md_from_tpmhalg(name_alg);
if (!md) {
LOG_ERR("Algorithm not supported: %x", name_alg);
return false;
@@ -461,7 +461,7 @@ bool tpm2_identity_create_name(TPM2B_PUBLIC *public, TPM2B_NAME *pubname) {
&tpmt_marshalled_size);
// Step 3 - Hash the data into name just past the alg type.
- const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(name_alg);
+ const EVP_MD *md = tpm2_openssl_md_from_tpmhalg(name_alg);
if (!md) {
LOG_ERR("Algorithm not supported: %x", name_alg);
return false;
diff --git a/lib/tpm2_kdfa.c b/lib/tpm2_kdfa.c
index 5747b3ca..c8d0a2e1 100644
--- a/lib/tpm2_kdfa.c
+++ b/lib/tpm2_kdfa.c
@@ -34,7 +34,7 @@ TSS2_RC tpm2_kdfa(TPMI_ALG_HASH hash_alg, TPM2B *key, char *label,
i = 1;
- const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(hash_alg);
+ const EVP_MD *md = tpm2_openssl_md_from_tpmhalg(hash_alg);
if (!md) {
LOG_ERR("Algorithm not supported for hmac: %x", hash_alg);
return TPM2_RC_HASH;
diff --git a/lib/tpm2_kdfe.c b/lib/tpm2_kdfe.c
index aa4d3e0b..84718b9f 100644
--- a/lib/tpm2_kdfe.c
+++ b/lib/tpm2_kdfe.c
@@ -42,7 +42,7 @@ TSS2_RC tpm2_kdfe(
tpm2_util_concat_buffer(&hash_input, (TPM2B *) party_u);
tpm2_util_concat_buffer(&hash_input, (TPM2B *) party_v);
- const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(hash_alg);
+ const EVP_MD *md = tpm2_openssl_md_from_tpmhalg(hash_alg);
if (!md) {
LOG_ERR("Algorithm not supported: %x", hash_alg);
return TPM2_RC_HASH;
diff --git a/lib/tpm2_openssl.c b/lib/tpm2_openssl.c
index cdce92f8..9cc362af 100644
--- a/lib/tpm2_openssl.c
+++ b/lib/tpm2_openssl.c
@@ -55,7 +55,7 @@ int tpm2_openssl_halgid_from_tpmhalg(TPMI_ALG_HASH algorithm) {
/* no return, not possible */
}
-const EVP_MD *tpm2_openssl_halg_from_tpmhalg(TPMI_ALG_HASH algorithm) {
+const EVP_MD *tpm2_openssl_md_from_tpmhalg(TPMI_ALG_HASH algorithm) {
switch (algorithm) {
case TPM2_ALG_SHA1:
@@ -77,7 +77,7 @@ bool tpm2_openssl_hash_compute_data(TPMI_ALG_HASH halg, BYTE *buffer,
bool result = false;
- const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(halg);
+ const EVP_MD *md = tpm2_openssl_md_from_tpmhalg(halg);
if (!md) {
return false;
}
@@ -121,7 +121,7 @@ bool tpm2_openssl_pcr_extend(TPMI_ALG_HASH halg, BYTE *pcr,
bool result = false;
- const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(halg);
+ const EVP_MD *md = tpm2_openssl_md_from_tpmhalg(halg);
if (!md) {
return false;
}
@@ -170,7 +170,7 @@ bool tpm2_openssl_hash_pcr_values(TPMI_ALG_HASH halg, TPML_DIGEST *digests,
bool result = false;
- const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(halg);
+ const EVP_MD *md = tpm2_openssl_md_from_tpmhalg(halg);
if (!md) {
return false;
}
@@ -222,7 +222,7 @@ bool tpm2_openssl_hash_pcr_banks(TPMI_ALG_HASH hash_alg,
UINT32 vi = 0, di = 0, i;
bool result = false;
- const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(hash_alg);
+ const EVP_MD *md = tpm2_openssl_md_from_tpmhalg(hash_alg);
if (!md) {
return false;
}
@@ -299,7 +299,7 @@ bool tpm2_openssl_hash_pcr_banks_le(TPMI_ALG_HASH hash_alg,
UINT32 vi = 0, di = 0, i;
bool result = false;
- const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(hash_alg);
+ const EVP_MD *md = tpm2_openssl_md_from_tpmhalg(hash_alg);
if (!md) {
return false;
}
diff --git a/lib/tpm2_openssl.h b/lib/tpm2_openssl.h
index 78cb826a..b757baa5 100644
--- a/lib/tpm2_openssl.h
+++ b/lib/tpm2_openssl.h
@@ -48,7 +48,7 @@ int tpm2_openssl_halgid_from_tpmhalg(TPMI_ALG_HASH algorithm);
* @return
* A pointer to a message digester or NULL on failure.
*/
-const EVP_MD *tpm2_openssl_halg_from_tpmhalg(TPMI_ALG_HASH algorithm);
+const EVP_MD *tpm2_openssl_md_from_tpmhalg(TPMI_ALG_HASH algorithm);
/**
* Hash a byte buffer.
diff --git a/lib/tpm2_util.c b/lib/tpm2_util.c
index d2c654db..c4dc68e4 100644
--- a/lib/tpm2_util.c
+++ b/lib/tpm2_util.c
@@ -579,7 +579,7 @@ bool tpm2_util_calc_unique(TPMI_ALG_HASH name_alg,
memcpy(buf.buffer, seed->buffer, seed->size);
memcpy(&buf.buffer[seed->size], key->buffer, key->size);
- const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(name_alg);
+ const EVP_MD *md = tpm2_openssl_md_from_tpmhalg(name_alg);
if (!md) {
LOG_ERR("Algorithm not supported: %x", name_alg);
return false;
@@ -951,7 +951,7 @@ bool tpm2_calq_qname(TPM2B_NAME *pqname,
// QNB ≔ HB (QNA || NAMEB)
bool result = false;
- const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(halg);
+ const EVP_MD *md = tpm2_openssl_md_from_tpmhalg(halg);
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
if (!mdctx) {
diff --git a/tools/misc/tpm2_checkquote.c b/tools/misc/tpm2_checkquote.c
index ca78238e..5e0c42a5 100644
--- a/tools/misc/tpm2_checkquote.c
+++ b/tools/misc/tpm2_checkquote.c
@@ -74,7 +74,7 @@ static bool verify(void) {
/* get the digest alg */
/* TODO SPlit loading on plain vs tss format to detect the hash alg */
/* If its a plain sig we need -g */
- const EVP_MD *md = tpm2_openssl_halg_from_tpmhalg(ctx.halg);
+ const EVP_MD *md = tpm2_openssl_md_from_tpmhalg(ctx.halg);
// TODO error handling
int rc = EVP_PKEY_verify_init(pkey_ctx);
--
2.31.1

View File

@ -0,0 +1,103 @@
From d67cbd4e6dc7ac83fd0c06a382a89d12f921628a Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Sun, 15 Aug 2021 11:54:00 +0200
Subject: [PATCH 11/17] openssl: Use EVP_MAC_update instead HMAC_Update on
OpenSSL >= 3.0.0
The HMAC_Update is deprecated in OpenSSL 3.0, but the replacement
EVP_MAC_update was added in OpenSSL 3.0, so version specific code is
needed.
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
lib/tpm2_kdfa.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/lib/tpm2_kdfa.c b/lib/tpm2_kdfa.c
index c8d0a2e1..5eb8d558 100644
--- a/lib/tpm2_kdfa.c
+++ b/lib/tpm2_kdfa.c
@@ -2,6 +2,13 @@
#include <string.h>
+#include <openssl/evp.h>
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+#include <openssl/hmac.h>
+#else
+#include <openssl/core_names.h>
+#endif
+
#include "log.h"
#include "tpm2_kdfa.h"
#include "tpm2_openssl.h"
@@ -40,13 +47,27 @@ TSS2_RC tpm2_kdfa(TPMI_ALG_HASH hash_alg, TPM2B *key, char *label,
return TPM2_RC_HASH;
}
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
HMAC_CTX *ctx = HMAC_CTX_new();
+#else
+ EVP_MAC *hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+ EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(hmac);
+#endif
if (!ctx) {
LOG_ERR("HMAC context allocation failed");
return TPM2_RC_MEMORY;
}
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
int rc = HMAC_Init_ex(ctx, key->buffer, key->size, md, NULL);
+#else
+ OSSL_PARAM params[2];
+
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_DIGEST,
+ (char *)EVP_MD_get0_name(md), 0);
+ params[1] = OSSL_PARAM_construct_end();
+ int rc = EVP_MAC_init(ctx, key->buffer, key->size, params);
+#endif
if (!rc) {
LOG_ERR("HMAC Init failed: %s", ERR_error_string(rc, NULL));
rval = TPM2_RC_MEMORY;
@@ -71,7 +92,11 @@ TSS2_RC tpm2_kdfa(TPMI_ALG_HASH hash_alg, TPM2B *key, char *label,
int c;
for (c = 0; c < j; c++) {
TPM2B_DIGEST *digest = buffer_list[c];
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
int rc = HMAC_Update(ctx, digest->buffer, digest->size);
+#else
+ int rc = EVP_MAC_update(ctx, digest->buffer, digest->size);
+#endif
if (!rc) {
LOG_ERR("HMAC Update failed: %s", ERR_error_string(rc, NULL));
rval = TPM2_RC_MEMORY;
@@ -79,8 +104,13 @@ TSS2_RC tpm2_kdfa(TPMI_ALG_HASH hash_alg, TPM2B *key, char *label,
}
}
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
unsigned size = sizeof(tmpResult.buffer);
int rc = HMAC_Final(ctx, tmpResult.buffer, &size);
+#else
+ size_t size;
+ int rc = EVP_MAC_final(ctx, tmpResult.buffer, &size, sizeof(tmpResult.buffer));
+#endif
if (!rc) {
LOG_ERR("HMAC Final failed: %s", ERR_error_string(rc, NULL));
rval = TPM2_RC_MEMORY;
@@ -100,7 +130,12 @@ TSS2_RC tpm2_kdfa(TPMI_ALG_HASH hash_alg, TPM2B *key, char *label,
result_key->size = bytes;
err:
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
HMAC_CTX_free(ctx);
+#else
+ EVP_MAC_CTX_free(ctx);
+ EVP_MAC_free(hmac);
+#endif
return rval;
}
--
2.31.1

View File

@ -0,0 +1,50 @@
From d295e6214ec4562b3940ac4a88178a260e656929 Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Sun, 15 Aug 2021 13:50:36 +0200
Subject: [PATCH 12/17] openssl: Remove unnecessary compatibility function
This was required for OpenSSL < 1.1.0 only.
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
lib/tpm2_openssl.c | 24 ------------------------
1 file changed, 24 deletions(-)
diff --git a/lib/tpm2_openssl.c b/lib/tpm2_openssl.c
index 9cc362af..ea1d6c3b 100644
--- a/lib/tpm2_openssl.c
+++ b/lib/tpm2_openssl.c
@@ -14,30 +14,6 @@
#include "tpm2_openssl.h"
#include "tpm2_systemdeps.h"
-/* compatibility function for OpenSSL versions < 1.1.0 */
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-static int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) {
- int r;
- int topad;
- int islen;
-
- islen = BN_num_bytes(a);
-
- if (tolen < islen)
- return -1;
-
- topad = tolen - islen;
-
- memset(to, 0x00, topad);
- r = BN_bn2bin(a, to + topad);
- if (r == 0) {
- return -1;
- }
-
- return tolen;
-}
-#endif
-
int tpm2_openssl_halgid_from_tpmhalg(TPMI_ALG_HASH algorithm) {
switch (algorithm) {
--
2.31.1

View File

@ -0,0 +1,555 @@
From 7852dfbda959aa326de7dcd341f6e4808d918e15 Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Sun, 15 Aug 2021 14:01:06 +0200
Subject: [PATCH 13/17] openssl: Implement EVP_PKEY based key import
The `RSA_KEY` and `EC_KEY` are not publicly available in OpenSSL 3.0 and
the generic `EVP_PKEY` must be used instead.
Since import of raw keys still requires access to the internal structures
the OpenSSL 3.0 introduced a completely new approach to access key internals.
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
lib/tpm2_openssl.c | 297 ++++++++++++++++++++++++++++-----------------
lib/tpm2_openssl.h | 12 --
2 files changed, 184 insertions(+), 125 deletions(-)
diff --git a/lib/tpm2_openssl.c b/lib/tpm2_openssl.c
index ea1d6c3b..036127c3 100644
--- a/lib/tpm2_openssl.c
+++ b/lib/tpm2_openssl.c
@@ -6,7 +6,11 @@
#include <string.h>
#include <openssl/pem.h>
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
#include <openssl/rand.h>
+#else
+#include <openssl/core_names.h>
+#endif
#include "files.h"
#include "log.h"
@@ -516,8 +520,9 @@ static bool handle_ossl_pass(const char *passin, char **pass) {
return pfn(passin, pass);
}
-static bool load_public_RSA_from_key(RSA *k, TPM2B_PUBLIC *pub) {
+static bool load_public_RSA_from_key(EVP_PKEY *key, TPM2B_PUBLIC *pub) {
+ bool result = false;
TPMT_PUBLIC *pt = &pub->publicArea;
pt->type = TPM2_ALG_RSA;
@@ -532,11 +537,33 @@ static bool load_public_RSA_from_key(RSA *k, TPM2B_PUBLIC *pub) {
sym->keyBits.sym = 0;
sym->mode.sym = TPM2_ALG_NULL;
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
const BIGNUM *n; /* modulus */
const BIGNUM *e; /* public key exponent */
+ RSA *k = EVP_PKEY_get0_RSA(key);
+ if (!k) {
+ LOG_ERR("Could not retrieve RSA key");
+ goto out;
+ }
+
RSA_get0_key(k, &n, &e, NULL);
+#else
+ BIGNUM *n = NULL; /* modulus */
+ BIGNUM *e = NULL; /* public key exponent */
+
+ int rc = EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_RSA_N, &n);
+ if (!rc) {
+ LOG_ERR("Could not read public modulus N");
+ goto out;
+ }
+ rc = EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_RSA_E, &e);
+ if (!rc) {
+ LOG_ERR("Could not read public exponent E");
+ goto out;
+ }
+#endif
/*
* The size of the modulus is the key size in RSA, store this as the
* keyBits in the RSA details.
@@ -549,7 +576,7 @@ static bool load_public_RSA_from_key(RSA *k, TPM2B_PUBLIC *pub) {
break;
default:
LOG_ERR("RSA key-size %u is not supported", rdetail->keyBits);
- return false;
+ goto out;
}
/* copy the modulus to the unique RSA field */
@@ -557,47 +584,25 @@ static bool load_public_RSA_from_key(RSA *k, TPM2B_PUBLIC *pub) {
int success = BN_bn2bin(n, pt->unique.rsa.buffer);
if (!success) {
LOG_ERR("Could not copy public modulus N");
- return false;
- }
-
- /*Make sure that we can fit the exponent into a UINT32 */
- unsigned e_size = BN_num_bytes(e);
- if (e_size > sizeof(rdetail->exponent)) {
- LOG_ERR(
- "Exponent is too big. Got %d expected less than or equal to %zu",
- e_size, sizeof(rdetail->exponent));
- return false;
- }
-
- /*
- * Copy the exponent into the field.
- * Returns 1 on success false on error.
- */
- return BN_bn2bin(e, (unsigned char *) &rdetail->exponent);
-}
-
-static RSA *tpm2_openssl_get_public_RSA_from_pem(FILE *f, const char *path) {
-
- /*
- * Public PEM files appear in two formats:
- * 1. PEM format, read with PEM_read_RSA_PUBKEY
- * 2. PKCS#1 format, read with PEM_read_RSAPublicKey
- *
- * See:
- * - https://stackoverflow.com/questions/7818117/why-i-cant-read-openssl-generated-rsa-pub-key-with-pem-read-rsapublickey
- */
- RSA *pub = PEM_read_RSA_PUBKEY(f, NULL, NULL, NULL);
- if (!pub) {
- pub = PEM_read_RSAPublicKey(f, NULL, NULL, NULL);
+ goto out;
}
- if (!pub) {
- ERR_print_errors_fp(stderr);
- LOG_ERR("Reading public PEM file \"%s\" failed", path);
- return NULL;
+ unsigned long exp = BN_get_word(e);
+ if (exp == 0xffffffffL) {
+ LOG_ERR("Could not copy public exponent E");
+ goto out;
}
+ rdetail->exponent = exp;
- return pub;
+ result = true;
+out:
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ /* k,n,e point to internal structrues and must not be freed after use */
+#else
+ BN_free(n);
+ BN_free(e);
+#endif
+ return result;
}
static bool load_public_RSA_from_pem(FILE *f, const char *path,
@@ -611,15 +616,19 @@ static bool load_public_RSA_from_pem(FILE *f, const char *path,
* See:
* - https://stackoverflow.com/questions/7818117/why-i-cant-read-openssl-generated-rsa-pub-key-with-pem-read-rsapublickey
*/
- RSA *k = tpm2_openssl_get_public_RSA_from_pem(f, path);
+ EVP_PKEY *k = PEM_read_PUBKEY(f, NULL, NULL, NULL);
if (!k) {
- /* tpm2_openssl_get_public_RSA_from_pem() should already log errors */
+ ERR_print_errors_fp(stderr);
+ LOG_ERR("Reading public PEM file \"%s\" failed", path);
return false;
}
- bool result = load_public_RSA_from_key(k, pub);
+ bool result = false;
+ if (EVP_PKEY_base_id(k) == EVP_PKEY_RSA) {
+ result = load_public_RSA_from_key(k, pub);
+ }
- RSA_free(k);
+ EVP_PKEY_free(k);
return result;
}
@@ -682,39 +691,41 @@ int tpm2_ossl_curve_to_nid(TPMI_ECC_CURVE curve) {
return -1;
}
-static bool load_public_ECC_from_key(EC_KEY *k, TPM2B_PUBLIC *pub) {
+static bool load_public_ECC_from_key(EVP_PKEY *key, TPM2B_PUBLIC *pub) {
+ BIGNUM *y = NULL;
+ BIGNUM *x = NULL;
+ int nid;
+ unsigned keysize;
bool result = false;
- BIGNUM *y = BN_new();
- BIGNUM *x = BN_new();
- if (!x || !y) {
- LOG_ERR("oom");
- goto out;
- }
-
/*
* Set the algorithm type
*/
pub->publicArea.type = TPM2_ALG_ECC;
+ TPMS_ECC_PARMS *pp = &pub->publicArea.parameters.eccDetail;
/*
- * Get the curve type
+ * Get the curve type and the public key (X and Y)
*/
- const EC_GROUP *group = EC_KEY_get0_group(k);
- int nid = EC_GROUP_get_curve_name(group);
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ EC_KEY *k = EVP_PKEY_get0_EC_KEY(key);
+ if (!k) {
+ LOG_ERR("Could not retrieve ECC key");
+ goto out;
+ }
- TPMS_ECC_PARMS *pp = &pub->publicArea.parameters.eccDetail;
- TPM2_ECC_CURVE curve_id = ossl_nid_to_curve(nid); // Not sure what lines up with NIST 256...
- if (curve_id == TPM2_ALG_ERROR) {
+ y = BN_new();
+ x = BN_new();
+ if (!x || !y) {
+ LOG_ERR("oom");
goto out;
}
- pp->curveID = curve_id;
+ const EC_GROUP *group = EC_KEY_get0_group(k);
+ nid = EC_GROUP_get_curve_name(group);
+ keysize = (EC_GROUP_get_degree(group) + 7) / 8;
- /*
- * Set the unique data to the public key.
- */
const EC_POINT *point = EC_KEY_get0_public_key(k);
int ret = EC_POINT_get_affine_coordinates_tss(group, point, x, y, NULL);
@@ -722,6 +733,39 @@ static bool load_public_ECC_from_key(EC_KEY *k, TPM2B_PUBLIC *pub) {
LOG_ERR("Could not get X and Y affine coordinates");
goto out;
}
+#else
+ char curve_name[80];
+
+ int rc = EVP_PKEY_get_utf8_string_param(key, OSSL_PKEY_PARAM_GROUP_NAME,
+ curve_name, sizeof(curve_name), NULL);
+ if (!rc) {
+ LOG_ERR("Could not read ECC curve name");
+ goto out;
+ }
+ nid = OBJ_txt2nid(curve_name);
+ keysize = (EVP_PKEY_bits(key) + 7) / 8;
+
+ rc = EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_EC_PUB_X, &x);
+ if (!rc) {
+ LOG_ERR("Could not read public X coordinate");
+ goto out;
+ }
+
+ rc = EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_EC_PUB_Y, &y);
+ if (!rc) {
+ LOG_ERR("Could not read public Y coordinate");
+ goto out;
+ }
+#endif
+
+ /*
+ * Set the curve type
+ */
+ TPM2_ECC_CURVE curve_id = ossl_nid_to_curve(nid); // Not sure what lines up with NIST 256...
+ if (curve_id == TPM2_ALG_ERROR) {
+ goto out;
+ }
+ pp->curveID = curve_id;
/*
* Copy the X and Y coordinate data into the ECC unique field,
@@ -730,28 +774,26 @@ static bool load_public_ECC_from_key(EC_KEY *k, TPM2B_PUBLIC *pub) {
TPM2B_ECC_PARAMETER *X = &pub->publicArea.unique.ecc.x;
TPM2B_ECC_PARAMETER *Y = &pub->publicArea.unique.ecc.y;
- unsigned x_size = (EC_GROUP_get_degree(group) + 7) / 8;
- if (x_size > sizeof(X->buffer)) {
+ if (keysize > sizeof(X->buffer)) {
LOG_ERR("X coordinate is too big. Got %u expected less than or equal to"
- " %zu", x_size, sizeof(X->buffer));
+ " %zu", keysize, sizeof(X->buffer));
goto out;
}
- unsigned y_size = (EC_GROUP_get_degree(group) + 7) / 8;
- if (y_size > sizeof(Y->buffer)) {
+ if (keysize > sizeof(Y->buffer)) {
LOG_ERR("X coordinate is too big. Got %u expected less than or equal to"
- " %zu", y_size, sizeof(Y->buffer));
+ " %zu", keysize, sizeof(Y->buffer));
goto out;
}
- X->size = BN_bn2binpad(x, X->buffer, x_size);
- if (X->size != x_size) {
+ X->size = BN_bn2binpad(x, X->buffer, keysize);
+ if (X->size != keysize) {
LOG_ERR("Error converting X point BN to binary");
goto out;
}
- Y->size = BN_bn2binpad(y, Y->buffer, y_size);
- if (Y->size != y_size) {
+ Y->size = BN_bn2binpad(y, Y->buffer, keysize);
+ if (Y->size != keysize) {
LOG_ERR("Error converting Y point BN to binary");
goto out;
}
@@ -771,43 +813,28 @@ static bool load_public_ECC_from_key(EC_KEY *k, TPM2B_PUBLIC *pub) {
sym->mode.sym = TPM2_ALG_NULL;
result = true;
-
out:
- if (x) {
- BN_free(x);
- }
- if (y) {
- BN_free(y);
- }
-
+ BN_free(x);
+ BN_free(y);
return result;
}
-EC_KEY *tpm2_openssl_get_public_ECC_from_pem(FILE *f, const char *path) {
-
- EC_KEY *pub = PEM_read_EC_PUBKEY(f, NULL, NULL, NULL);
- if (!pub) {
- ERR_print_errors_fp(stderr);
- LOG_ERR("Reading public PEM file \"%s\" failed", path);
- return NULL;
- }
-
- return pub;
-}
-
static bool load_public_ECC_from_pem(FILE *f, const char *path,
TPM2B_PUBLIC *pub) {
- EC_KEY *k = tpm2_openssl_get_public_ECC_from_pem(f, path);
+ EVP_PKEY *k = PEM_read_PUBKEY(f, NULL, NULL, NULL);
if (!k) {
ERR_print_errors_fp(stderr);
LOG_ERR("Reading PEM file \"%s\" failed", path);
return false;
}
- bool result = load_public_ECC_from_key(k, pub);
+ bool result = false;
+ if (EVP_PKEY_base_id(k) == EVP_PKEY_EC) {
+ result = load_public_ECC_from_key(k, pub);
+ }
- EC_KEY_free(k);
+ EVP_PKEY_free(k);
return result;
}
@@ -852,11 +879,27 @@ static bool load_public_AES_from_file(FILE *f, const char *path,
return tpm2_util_calc_unique(name_alg, key, seed, unique);
}
-static bool load_private_RSA_from_key(RSA *k, TPM2B_SENSITIVE *priv) {
+static bool load_private_RSA_from_key(EVP_PKEY *key, TPM2B_SENSITIVE *priv) {
- const BIGNUM *p; /* the private key exponent */
+ bool result = false;
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ const BIGNUM *p = NULL; /* the private key exponent */
+ RSA *k = EVP_PKEY_get0_RSA(key);
+ if (!k) {
+ LOG_ERR("Could not retrieve RSA key");
+ goto out;
+ }
RSA_get0_factors(k, &p, NULL);
+#else
+ BIGNUM *p = NULL; /* the private key exponent */
+
+ int rc = EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_RSA_FACTOR1, &p);
+ if (!rc) {
+ LOG_ERR("Could not read private key");
+ goto out;
+ }
+#endif
TPMT_SENSITIVE *sa = &priv->sensitiveArea;
@@ -868,7 +911,7 @@ static bool load_private_RSA_from_key(RSA *k, TPM2B_SENSITIVE *priv) {
if (priv_bytes > sizeof(pkr->buffer)) {
LOG_ERR("Expected prime \"d\" to be less than or equal to %zu,"
" got: %u", sizeof(pkr->buffer), priv_bytes);
- return false;
+ goto out;
}
pkr->size = priv_bytes;
@@ -877,10 +920,16 @@ static bool load_private_RSA_from_key(RSA *k, TPM2B_SENSITIVE *priv) {
if (!success) {
ERR_print_errors_fp(stderr);
LOG_ERR("Could not copy private exponent \"d\"");
- return false;
+ goto out;
}
-
- return true;
+ result = true;
+out:
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ /* k,p point to internal structrues and must not be freed after use */
+#else
+ BN_free(p);
+#endif
+ return result;
}
bool tpm2_openssl_load_public(const char *path, TPMI_ALG_PUBLIC alg,
@@ -912,8 +961,9 @@ bool tpm2_openssl_load_public(const char *path, TPMI_ALG_PUBLIC alg,
return result;
}
-static bool load_private_ECC_from_key(EC_KEY *k, TPM2B_SENSITIVE *priv) {
+static bool load_private_ECC_from_key(EVP_PKEY *key, TPM2B_SENSITIVE *priv) {
+ bool result = false;
/*
* private data
*/
@@ -921,22 +971,45 @@ static bool load_private_ECC_from_key(EC_KEY *k, TPM2B_SENSITIVE *priv) {
TPM2B_ECC_PARAMETER *p = &priv->sensitiveArea.sensitive.ecc;
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ EC_KEY *k = EVP_PKEY_get0_EC_KEY(key);
+ if (!k) {
+ LOG_ERR("Could not retrieve ECC key");
+ goto out;
+ }
+
const EC_GROUP *group = EC_KEY_get0_group(k);
const BIGNUM *b = EC_KEY_get0_private_key(k);
-
unsigned priv_bytes = (EC_GROUP_get_degree(group) + 7) / 8;
+#else
+ BIGNUM *b = NULL; /* the private key exponent */
+
+ int rc = EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_PRIV_KEY, &b);
+ if (!rc) {
+ LOG_ERR("Could not read ECC private key");
+ goto out;
+ }
+ unsigned priv_bytes = (EVP_PKEY_bits(key) + 7) / 8;
+#endif
+
if (priv_bytes > sizeof(p->buffer)) {
LOG_ERR("Expected ECC private portion to be less than or equal to %zu,"
" got: %u", sizeof(p->buffer), priv_bytes);
- return false;
+ goto out;
}
p->size = BN_bn2binpad(b, p->buffer, priv_bytes);
if (p->size != priv_bytes) {
- return false;
+ goto out;
}
-
- return true;
+ result = true;
+out:
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ /* k,b point to internal structrues and must not be freed after use */
+#else
+ BN_free(b);
+#endif
+ return result;
}
static tpm2_openssl_load_rc load_private_ECC_from_pem(FILE *f, const char *path,
@@ -950,8 +1023,7 @@ static tpm2_openssl_load_rc load_private_ECC_from_pem(FILE *f, const char *path,
return lprc_error;
}
- EC_KEY *k = PEM_read_ECPrivateKey(f, NULL,
- NULL, (void *) pass);
+ EVP_PKEY *k = PEM_read_PrivateKey(f, NULL, NULL, (void *) pass);
free(pass);
if (!k) {
ERR_print_errors_fp(stderr);
@@ -976,14 +1048,14 @@ static tpm2_openssl_load_rc load_private_ECC_from_pem(FILE *f, const char *path,
rc |= lprc_public;
out:
- EC_KEY_free(k);
+ EVP_PKEY_free(k);
return rc;
}
static tpm2_openssl_load_rc load_private_RSA_from_pem(FILE *f, const char *path,
const char *passin, TPM2B_PUBLIC *pub, TPM2B_SENSITIVE *priv) {
- RSA *k = NULL;
+ EVP_PKEY *k = NULL;
tpm2_openssl_load_rc rc = lprc_error;
@@ -993,8 +1065,7 @@ static tpm2_openssl_load_rc load_private_RSA_from_pem(FILE *f, const char *path,
return lprc_error;
}
- k = PEM_read_RSAPrivateKey(f, NULL,
- NULL, (void *) pass);
+ k = PEM_read_PrivateKey(f, NULL, NULL, (void *) pass);
free(pass);
if (!k) {
ERR_print_errors_fp(stderr);
@@ -1016,7 +1087,7 @@ static tpm2_openssl_load_rc load_private_RSA_from_pem(FILE *f, const char *path,
rc |= lprc_public;
}
out:
- RSA_free(k);
+ EVP_PKEY_free(k);
return rc;
}
diff --git a/lib/tpm2_openssl.h b/lib/tpm2_openssl.h
index b757baa5..5579ae45 100644
--- a/lib/tpm2_openssl.h
+++ b/lib/tpm2_openssl.h
@@ -196,18 +196,6 @@ tpm2_openssl_load_rc tpm2_openssl_load_private(const char *path,
bool tpm2_openssl_load_public(const char *path, TPMI_ALG_PUBLIC alg,
TPM2B_PUBLIC *pub);
-/**
- * Retrieves a public portion of an ECC key from a PEM file.
- *
- * @param f
- * The FILE object that is open for reading the path.
- * @param path
- * The path to load from.
- * @return
- * The public structure.
- */
-EC_KEY* tpm2_openssl_get_public_ECC_from_pem(FILE *f, const char *path);
-
/**
* Maps an ECC curve to an openssl nid value.
* @param curve
--
2.31.1

View File

@ -0,0 +1,484 @@
From e34d393d7c73a58b3bf6fccbe88ea1eedfe1d7b7 Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Sun, 15 Aug 2021 15:58:28 +0200
Subject: [PATCH 14/17] openssl: Implement EVP_PKEY based key export
The `RSA_KEY` and `EC_KEY` are not publicly available in OpenSSL 3.0 and
the generic `EVP_PKEY` must be used instead.
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
lib/tpm2_convert.c | 319 ++++++++++++++++++++++++++++++++-------------
lib/tpm2_convert.h | 20 +++
2 files changed, 245 insertions(+), 94 deletions(-)
diff --git a/lib/tpm2_convert.c b/lib/tpm2_convert.c
index cc1c18ab..986fc1a7 100644
--- a/lib/tpm2_convert.c
+++ b/lib/tpm2_convert.c
@@ -9,6 +9,13 @@
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+#include <openssl/rsa.h>
+#else
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include <openssl/param_build.h>
+#endif
#include "files.h"
#include "log.h"
@@ -70,36 +77,49 @@ bool tpm2_convert_pubkey_save(TPM2B_PUBLIC *public,
return false;
}
-static bool convert_pubkey_RSA(TPMT_PUBLIC *public,
- tpm2_convert_pubkey_fmt format, BIO *bio) {
+EVP_PKEY *convert_pubkey_RSA(TPMT_PUBLIC *public) {
- bool ret = false;
- RSA *ssl_rsa_key = NULL;
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ RSA *rsa_key = NULL;
+#else
+ OSSL_PARAM_BLD *build = NULL;
+ OSSL_PARAM *params = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+#endif
BIGNUM *e = NULL, *n = NULL;
+ EVP_PKEY *pkey = NULL;
UINT32 exponent = (public->parameters).rsaDetail.exponent;
if (exponent == 0) {
exponent = 0x10001;
}
- // OpenSSL expects this in network byte order
- exponent = tpm2_util_hton_32(exponent);
- ssl_rsa_key = RSA_new();
- if (!ssl_rsa_key) {
- print_ssl_error("Failed to allocate OpenSSL RSA structure");
+ n = BN_bin2bn(public->unique.rsa.buffer, public->unique.rsa.size, NULL);
+ if (!n) {
+ print_ssl_error("Failed to convert data to SSL internal format");
goto error;
}
- e = BN_bin2bn((void*) &exponent, sizeof(exponent), NULL);
- n = BN_bin2bn(public->unique.rsa.buffer, public->unique.rsa.size,
- NULL);
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ rsa_key = RSA_new();
+ if (!rsa_key) {
+ print_ssl_error("Failed to allocate OpenSSL RSA structure");
+ goto error;
+ }
- if (!n || !e) {
+ e = BN_new();
+ if (!e) {
+ print_ssl_error("Failed to convert data to SSL internal format");
+ goto error;
+ }
+ int rc = BN_set_word(e, exponent);
+ if (!rc) {
print_ssl_error("Failed to convert data to SSL internal format");
goto error;
}
- if (!RSA_set0_key(ssl_rsa_key, n, e, NULL)) {
+ rc = RSA_set0_key(rsa_key, n, e, NULL);
+ if (!rc) {
print_ssl_error("Failed to set RSA modulus and exponent components");
goto error;
}
@@ -107,162 +127,273 @@ static bool convert_pubkey_RSA(TPMT_PUBLIC *public,
/* modulus and exponent components are now owned by the RSA struct */
n = e = NULL;
- int ssl_res = 0;
+ pkey = EVP_PKEY_new();
+ if (!pkey) {
+ print_ssl_error("Failed to allocate OpenSSL EVP structure");
+ goto error;
+ }
- switch (format) {
- case pubkey_format_pem:
- ssl_res = PEM_write_bio_RSA_PUBKEY(bio, ssl_rsa_key);
- break;
- case pubkey_format_der:
- ssl_res = i2d_RSA_PUBKEY_bio(bio, ssl_rsa_key);
- break;
- default:
- LOG_ERR("Invalid OpenSSL target format %d encountered", format);
+ rc = EVP_PKEY_assign_RSA(pkey, rsa_key);
+ if (!rc) {
+ print_ssl_error("Failed to set OpenSSL EVP structure");
+ EVP_PKEY_free(pkey);
+ pkey = NULL;
+ goto error;
+ }
+ /* rsa key is now owner by the EVP_PKEY struct */
+ rsa_key = NULL;
+#else
+ build = OSSL_PARAM_BLD_new();
+ if (!build) {
+ print_ssl_error("Failed to allocate OpenSSL parameters");
goto error;
}
- if (ssl_res <= 0) {
- print_ssl_error("OpenSSL public key conversion failed");
+ int rc = OSSL_PARAM_BLD_push_BN(build, OSSL_PKEY_PARAM_RSA_N, n);
+ if (!rc) {
+ print_ssl_error("Failed to set RSA modulus");
goto error;
}
- ret = true;
+ rc = OSSL_PARAM_BLD_push_uint32(build, OSSL_PKEY_PARAM_RSA_E, exponent);
+ if (!rc) {
+ print_ssl_error("Failed to set RSA exponent");
+ goto error;
+ }
- error: if (n) {
- BN_free(n);
+ params = OSSL_PARAM_BLD_to_param(build);
+ if (!params) {
+ print_ssl_error("Failed to build OpenSSL parameters");
+ goto error;
}
- if (e) {
- BN_free(e);
+
+ ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
+ if (!ctx) {
+ print_ssl_error("Failed to allocate RSA key context");
+ goto error;
}
- if (ssl_rsa_key) {
- RSA_free(ssl_rsa_key);
+
+ rc = EVP_PKEY_fromdata_init(ctx);
+ if (rc <= 0) {
+ print_ssl_error("Failed to initialize RSA key creation");
+ goto error;
}
- return ret;
+ rc = EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params);
+ if (rc <= 0) {
+ print_ssl_error("Failed to create a RSA public key");
+ goto error;
+ }
+#endif
+error:
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ RSA_free(rsa_key);
+#else
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_free(params);
+ OSSL_PARAM_BLD_free(build);
+#endif
+ BN_free(n);
+ BN_free(e);
+ return pkey;
}
-static bool convert_pubkey_ECC(TPMT_PUBLIC *public,
- tpm2_convert_pubkey_fmt format, BIO *bio) {
+EVP_PKEY *convert_pubkey_ECC(TPMT_PUBLIC *public) {
BIGNUM *x = NULL;
BIGNUM *y = NULL;
- EC_KEY *key = NULL;
EC_POINT *point = NULL;
- const EC_GROUP *group = NULL;
-
- bool result = false;
+ EC_GROUP *group = NULL;
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ EC_KEY *ec_key = NULL;
+#else
+ OSSL_PARAM_BLD *build = NULL;
+ OSSL_PARAM *params = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ unsigned char *puboct = NULL;
+ size_t bsize;
+#endif
+ EVP_PKEY *pkey = NULL;
TPMS_ECC_PARMS *tpm_ecc = &public->parameters.eccDetail;
TPMS_ECC_POINT *tpm_point = &public->unique.ecc;
+ /*
+ * Set the affine coordinates for the point
+ */
+ x = BN_bin2bn(tpm_point->x.buffer, tpm_point->x.size, NULL);
+ if (!x) {
+ print_ssl_error("Could not convert x coordinate to BN");
+ goto out;
+ }
+
+ y = BN_bin2bn(tpm_point->y.buffer, tpm_point->y.size, NULL);
+ if (!y) {
+ print_ssl_error("Could not convert y coordinate to BN");
+ goto out;
+ }
+
int nid = tpm2_ossl_curve_to_nid(tpm_ecc->curveID);
if (nid < 0) {
- return false;
+ goto out;
}
/*
- * Create an empty EC key by the NID
+ * Create a new point in the group, which is the public key.
*/
- key = EC_KEY_new_by_curve_name(nid);
- if (!key) {
- print_ssl_error("Failed to create EC key from nid");
- return false;
- }
-
- group = EC_KEY_get0_group(key);
+ group = EC_GROUP_new_by_curve_name(nid);
if (!group) {
print_ssl_error("EC key missing group");
goto out;
}
- /*
- * Create a new point in the group, which is the public key.
- */
point = EC_POINT_new(group);
+ int rc = EC_POINT_set_affine_coordinates_tss(group, point, x, y, NULL);
+ if (!rc) {
+ print_ssl_error("Could not set affine coordinates");
+ goto out;
+ }
+
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
/*
- * Set the affine coordinates for the point
+ * Create an empty EC key by the NID
*/
- x = BN_bin2bn(tpm_point->x.buffer, tpm_point->x.size, NULL);
- if (!x) {
- print_ssl_error("Could not convert x coordinate to BN");
+ ec_key = EC_KEY_new_by_curve_name(nid);
+ if (!ec_key) {
+ print_ssl_error("Failed to create EC key from nid");
+ return false;
+ }
+
+ rc = EC_KEY_set_public_key(ec_key, point);
+ if (!rc) {
+ print_ssl_error("Could not set point as public key portion");
goto out;
}
- y = BN_bin2bn(tpm_point->y.buffer, tpm_point->y.size, NULL);
- if (!y) {
- print_ssl_error("Could not convert y coordinate to BN");
+ if ((pkey = EVP_PKEY_new()) == NULL) {
+ print_ssl_error("Failed to allocate OpenSSL EVP structure");
goto out;
}
- int rc = EC_POINT_set_affine_coordinates_tss(group, point, x, y, NULL);
+ rc = EVP_PKEY_assign_EC_KEY(pkey, ec_key);
if (!rc) {
- print_ssl_error("Could not set affine coordinates");
+ print_ssl_error("Failed to set OpenSSL EVP structure");
+ EVP_PKEY_free(pkey);
+ pkey = NULL;
+ goto out;
+ }
+ /* rsa key is now owner by the EVP_PKEY struct */
+ ec_key = NULL;
+#else
+ build = OSSL_PARAM_BLD_new();
+ if (!build) {
+ print_ssl_error("Failed to allocate OpenSSL parameters");
goto out;
}
- rc = EC_KEY_set_public_key(key, point);
+ rc = OSSL_PARAM_BLD_push_utf8_string(build, OSSL_PKEY_PARAM_GROUP_NAME,
+ (char *)OBJ_nid2sn(nid), 0);
if (!rc) {
- print_ssl_error("Could not set point as public key portion");
+ print_ssl_error("Failed to set the EC group name");
goto out;
}
- int ssl_res = 0;
-
- switch (format) {
- case pubkey_format_pem:
- ssl_res = PEM_write_bio_EC_PUBKEY(bio, key);
- break;
- case pubkey_format_der:
- ssl_res = i2d_EC_PUBKEY_bio(bio, key);
- break;
- default:
- LOG_ERR("Invalid OpenSSL target format %d encountered", format);
+ bsize = EC_POINT_point2buf(group, point,
+ POINT_CONVERSION_COMPRESSED,
+ &puboct, NULL);
+ if (bsize == 0) {
+ print_ssl_error("Failed compress the EC public key");
goto out;
}
- if (ssl_res <= 0) {
- print_ssl_error("OpenSSL public key conversion failed");
+ rc = OSSL_PARAM_BLD_push_octet_string(build, OSSL_PKEY_PARAM_PUB_KEY,
+ puboct, bsize);
+ if (!rc) {
+ print_ssl_error("Failed set the EC public key");
goto out;
}
- result = true;
-
-out:
- if (x) {
- BN_free(x);
+ params = OSSL_PARAM_BLD_to_param(build);
+ if (!params) {
+ print_ssl_error("Failed to build OpenSSL parameters");
+ goto out;
}
- if (y) {
- BN_free(y);
+
+ ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
+ if (!ctx) {
+ print_ssl_error("Failed to allocate EC key context");
+ goto out;
}
- if (point) {
- EC_POINT_free(point);
+
+ rc = EVP_PKEY_fromdata_init(ctx);
+ if (rc <= 0) {
+ print_ssl_error("Failed to initialize EC key creation");
+ goto out;
}
- if (key) {
- EC_KEY_free(key);
+
+ rc = EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params);
+ if (rc <= 0) {
+ print_ssl_error("Failed to create a EC public key");
+ goto out;
}
+#endif
- return result;
+out:
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ EC_KEY_free(ec_key);
+#else
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_free(params);
+ OSSL_PARAM_BLD_free(build);
+ OPENSSL_free(puboct);
+#endif
+ EC_POINT_free(point);
+ EC_GROUP_free(group);
+ BN_free(x);
+ BN_free(y);
+ return pkey;
}
static bool tpm2_convert_pubkey_bio(TPMT_PUBLIC *public,
tpm2_convert_pubkey_fmt format, BIO *bio) {
- bool result = false;
+ EVP_PKEY *pubkey = NULL;
+ int ssl_res = 0;
switch (public->type) {
case TPM2_ALG_RSA:
- result = convert_pubkey_RSA(public, format, bio);
+ pubkey = convert_pubkey_RSA(public);
break;
case TPM2_ALG_ECC:
- result = convert_pubkey_ECC(public, format, bio);
+ pubkey = convert_pubkey_ECC(public);
break;
default:
- LOG_ERR(
- "Unsupported key type for requested output format. Only RSA is supported.");
+ LOG_ERR("Unsupported key type for requested output format.");
}
- return result;
+ if (pubkey == NULL)
+ return false;
+
+ switch (format) {
+ case pubkey_format_pem:
+ ssl_res = PEM_write_bio_PUBKEY(bio, pubkey);
+ break;
+ case pubkey_format_der:
+ ssl_res = i2d_PUBKEY_bio(bio, pubkey);
+ break;
+ default:
+ LOG_ERR("Invalid OpenSSL target format %d encountered", format);
+ }
+
+ EVP_PKEY_free(pubkey);
+
+ if (ssl_res <= 0) {
+ print_ssl_error("OpenSSL public key conversion failed");
+ return false;
+ }
+
+ return true;
}
static bool tpm2_convert_pubkey_ssl(TPMT_PUBLIC *public,
diff --git a/lib/tpm2_convert.h b/lib/tpm2_convert.h
index f8c82155..bddb455d 100644
--- a/lib/tpm2_convert.h
+++ b/lib/tpm2_convert.h
@@ -45,6 +45,26 @@ tpm2_convert_pubkey_fmt tpm2_convert_pubkey_fmt_from_optarg(const char *label);
bool tpm2_convert_pubkey_save(TPM2B_PUBLIC *public,
tpm2_convert_pubkey_fmt format, const char *path);
+/**
+ * Converts the given RSA public key structure into the EVP_PKEY.
+ *
+ * @param public
+ * TPM2 public key structure structure.
+ * @return
+ * OpenSSL key structure, or NULL on error.
+ */
+EVP_PKEY *convert_pubkey_RSA(TPMT_PUBLIC *public);
+
+/**
+ * Converts the given ECC public key structure into the EVP_PKEY.
+ *
+ * @param public
+ * TPM2 public key structure structure.
+ * @return
+ * OpenSSL key structure, or NULL on error.
+ */
+EVP_PKEY *convert_pubkey_ECC(TPMT_PUBLIC *public);
+
/**
* Parses the given command line signature format option string and returns
* the corresponding signature_format enum value.
--
2.31.1

View File

@ -0,0 +1,286 @@
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

View File

@ -0,0 +1,240 @@
From 317c1ea1d9893d6f4f837196648c53b7f7dd762f Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Sun, 15 Aug 2021 17:22:44 +0200
Subject: [PATCH 16/17] openssl: Reimplement RSA OAEP encryption using EVP
functions
The RSA_padding_add_PKCS1_OAEP_mgf1 is deprecated and the entire
semi-custom implementation of OAEP is unnecessary.
The Part 1, B.10.3 talks about a standard OAEP with a given label,
which can be easily implemented using the standard EVP functions.
Also, the public key retrieval can be replaced by invocation of
convert_pubkey_RSA from lib/tpm2_convert.c
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
lib/tpm2_identity_util.c | 162 +++++++++++----------------------------
1 file changed, 43 insertions(+), 119 deletions(-)
diff --git a/lib/tpm2_identity_util.c b/lib/tpm2_identity_util.c
index ba0c0e1c..b04a56d6 100644
--- a/lib/tpm2_identity_util.c
+++ b/lib/tpm2_identity_util.c
@@ -10,6 +10,7 @@
#include "log.h"
#include "tpm2_alg_util.h"
+#include "tpm2_convert.h"
#include "tpm2_identity_util.h"
#include "tpm2_kdfa.h"
#include "tpm2_kdfe.h"
@@ -17,73 +18,6 @@
// Identity-related functionality that the TPM normally does, but using OpenSSL
-#if defined(LIBRESSL_VERSION_NUMBER)
-static int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
- const unsigned char *from, int flen, const unsigned char *param, int plen,
- const EVP_MD *md, const EVP_MD *mgf1md) {
-
- int ret = 0;
- int i, emlen = tlen - 1;
- unsigned char *db, *seed;
- unsigned char *dbmask, seedmask[EVP_MAX_MD_SIZE];
- int mdlen;
-
- if (md == NULL)
- md = EVP_sha1();
- if (mgf1md == NULL)
- mgf1md = md;
-
- mdlen = EVP_MD_size(md);
-
- if (flen > emlen - 2 * mdlen - 1) {
- RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
- return 0;
- }
-
- if (emlen < 2 * mdlen + 1) {
- RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,
- RSA_R_KEY_SIZE_TOO_SMALL);
- return 0;
- }
-
- to[0] = 0;
- seed = to + 1;
- db = to + mdlen + 1;
-
- if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL))
- return 0;
- memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1);
- db[emlen - flen - mdlen - 1] = 0x01;
- memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen);
- if (RAND_bytes(seed, mdlen) <= 0)
- return 0;
-
- dbmask = OPENSSL_malloc(emlen - mdlen);
- if (dbmask == NULL) {
- RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
- return 0;
- }
-
- if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0)
- goto err;
- for (i = 0; i < emlen - mdlen; i++)
- db[i] ^= dbmask[i];
-
- if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0)
- goto err;
- for (i = 0; i < mdlen; i++)
- seed[i] ^= seedmask[i];
-
- ret = 1;
-
-err:
- OPENSSL_free(dbmask);
-
- return ret;
-}
-#endif
-
static TPM2_KEY_BITS get_pub_asym_key_bits(TPM2B_PUBLIC *public) {
TPMU_PUBLIC_PARMS *p = &public->publicArea.parameters;
@@ -102,19 +36,13 @@ static bool share_secret_with_tpm2_rsa_public_key(TPM2B_DIGEST *protection_seed,
TPM2B_PUBLIC *parent_pub, unsigned char *label, int label_len,
TPM2B_ENCRYPTED_SECRET *encrypted_protection_seed) {
bool rval = false;
- RSA *rsa = NULL;
-
- // Public modulus (RSA-only!)
- TPMI_RSA_KEY_BITS mod_size_bits =
- parent_pub->publicArea.parameters.rsaDetail.keyBits;
- UINT16 mod_size = mod_size_bits / 8;
- TPM2B *pub_key_val = (TPM2B *) &parent_pub->publicArea.unique.rsa;
- unsigned char *pub_modulus = malloc(mod_size);
- if (pub_modulus == NULL) {
- LOG_ERR("Failed to allocate memory to store public key's modulus.");
+ EVP_PKEY_CTX *ctx = NULL;
+
+ EVP_PKEY *pkey = convert_pubkey_RSA(&parent_pub->publicArea);
+ if (pkey == NULL) {
+ LOG_ERR("Failed to retrieve public key");
return false;
}
- memcpy(pub_modulus, pub_key_val->buffer, mod_size);
TPMI_ALG_HASH parent_name_alg = parent_pub->publicArea.nameAlg;
@@ -122,70 +50,66 @@ static bool share_secret_with_tpm2_rsa_public_key(TPM2B_DIGEST *protection_seed,
* RSA Secret Sharing uses a randomly generated seed (Part 1, B.10.3).
*/
protection_seed->size = tpm2_alg_util_get_hash_size(parent_name_alg);
- int return_code = RAND_bytes(protection_seed->buffer, protection_seed->size);
- if (return_code != 1) {
+ int rc = RAND_bytes(protection_seed->buffer, protection_seed->size);
+ if (rc != 1) {
LOG_ERR("Failed to get random bytes");
goto error;
}
/*
- * This is the biggest buffer value, so it should always be sufficient.
+ * The seed value will be OAEP encrypted with a given L parameter.
*/
- unsigned char encoded[TPM2_MAX_DIGEST_BUFFER];
- return_code = RSA_padding_add_PKCS1_OAEP_mgf1(encoded, mod_size,
- protection_seed->buffer, protection_seed->size, label, label_len,
- tpm2_openssl_md_from_tpmhalg(parent_name_alg), NULL);
- if (return_code != 1) {
- LOG_ERR("Failed RSA_padding_add_PKCS1_OAEP_mgf1\n");
- goto error;
- }
- BIGNUM* bne = BN_new();
- if (!bne) {
- LOG_ERR("BN_new for bne failed\n");
+ ctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (!ctx) {
+ LOG_ERR("Failed EVP_PKEY_CTX_new");
goto error;
}
- return_code = BN_set_word(bne, RSA_F4);
- if (return_code != 1) {
- LOG_ERR("BN_set_word failed\n");
- BN_free(bne);
+
+ rc = EVP_PKEY_encrypt_init(ctx);
+ if (rc <= 0) {
+ LOG_ERR("Failed EVP_PKEY_encrypt_init");
goto error;
}
- rsa = RSA_new();
- if (!rsa) {
- LOG_ERR("RSA_new failed\n");
- BN_free(bne);
+
+ rc = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING);
+ if (rc <= 0) {
+ LOG_ERR("Failed EVP_PKEY_CTX_set_rsa_padding");
goto error;
}
- return_code = RSA_generate_key_ex(rsa, mod_size_bits, bne, NULL);
- BN_free(bne);
- if (return_code != 1) {
- LOG_ERR("RSA_generate_key_ex failed\n");
+
+ rc = EVP_PKEY_CTX_set_rsa_oaep_md(ctx,
+ tpm2_openssl_md_from_tpmhalg(parent_name_alg));
+ if (rc <= 0) {
+ LOG_ERR("Failed EVP_PKEY_CTX_set_rsa_oaep_md");
goto error;
}
- BIGNUM *n = BN_bin2bn(pub_modulus, mod_size, NULL);
- if (n == NULL) {
- LOG_ERR("BN_bin2bn failed\n");
+
+ // the library will take ownership of the label
+ char *newlabel = strdup((const char *)label);
+ if (newlabel == NULL) {
+ LOG_ERR("Failed to allocate label");
goto error;
}
- if (!RSA_set0_key(rsa, n, NULL, NULL)) {
- LOG_ERR("RSA_set0_key failed\n");
- BN_free(n);
+
+ rc = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, newlabel, label_len);
+ if (rc <= 0) {
+ LOG_ERR("Failed EVP_PKEY_CTX_set0_rsa_oaep_label");
+ free(newlabel);
goto error;
}
- // Encrypting
- encrypted_protection_seed->size = mod_size;
- return_code = RSA_public_encrypt(mod_size, encoded,
- encrypted_protection_seed->secret, rsa, RSA_NO_PADDING);
- if (return_code < 0) {
- LOG_ERR("Failed RSA_public_encrypt\n");
+
+ size_t outlen = sizeof(TPMU_ENCRYPTED_SECRET);
+ if (EVP_PKEY_encrypt(ctx, encrypted_protection_seed->secret, &outlen,
+ protection_seed->buffer, protection_seed->size) <= 0) {
+ LOG_ERR("Failed EVP_PKEY_encrypt\n");
goto error;
}
-
+ encrypted_protection_seed->size = outlen;
rval = true;
error:
- free(pub_modulus);
- RSA_free(rsa);
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(pkey);
return rval;
}
--
2.31.1

View File

@ -0,0 +1,282 @@
From 22ecb8a2c00db7a53508d2106957e0c112a5a020 Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Tue, 31 Aug 2021 12:27:35 +0200
Subject: [PATCH 17/17] Generate partial X.509 certificate using own struct
The tpm2_certifyX509certutil.c:generate_partial_X509() creates a partial
(in fact, an incomplete) certificate, see Part 3, 18.8.1. The OpenSSL
team decided that starting from 3.0 the i2d should not create invalid
encodings, so we need to create an own ASN.1 structure for this.
The structure is adapted from
https://github.com/openssl/openssl/issues/16257#issuecomment-895448370.
Fixes: #2813
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
tools/misc/tpm2_certifyX509certutil.c | 179 +++++++++-----------------
1 file changed, 59 insertions(+), 120 deletions(-)
diff --git a/tools/misc/tpm2_certifyX509certutil.c b/tools/misc/tpm2_certifyX509certutil.c
index 62ed644a..5eea08e8 100644
--- a/tools/misc/tpm2_certifyX509certutil.c
+++ b/tools/misc/tpm2_certifyX509certutil.c
@@ -8,6 +8,8 @@
#include <sys/stat.h>
#include <unistd.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/bio.h>
@@ -15,6 +17,46 @@
#include "log.h"
#include "tpm2_tool.h"
+typedef struct {
+ ASN1_TIME *notBefore;
+ ASN1_TIME *notAfter;
+} TPM2_PARTIAL_CERT_VALIDITY;
+
+typedef struct {
+ X509_ALGOR *algorithm;
+ X509_NAME *issuer;
+ TPM2_PARTIAL_CERT_VALIDITY *validity;
+ X509_NAME *subject;
+ STACK_OF(X509_EXTENSION) *extensions;
+} TPM2_PARTIAL_CERT;
+
+ASN1_SEQUENCE(TPM2_PARTIAL_CERT_VALIDITY) = {
+ ASN1_SIMPLE(TPM2_PARTIAL_CERT_VALIDITY, notBefore, ASN1_TIME),
+ ASN1_SIMPLE(TPM2_PARTIAL_CERT_VALIDITY, notAfter, ASN1_TIME),
+} ASN1_SEQUENCE_END(TPM2_PARTIAL_CERT_VALIDITY)
+
+/* partialCertificate per Part 3, 18.8.1 */
+ASN1_SEQUENCE(TPM2_PARTIAL_CERT) = {
+ ASN1_OPT(TPM2_PARTIAL_CERT, algorithm, X509_ALGOR),
+ ASN1_SIMPLE(TPM2_PARTIAL_CERT, issuer, X509_NAME),
+ ASN1_SIMPLE(TPM2_PARTIAL_CERT, validity, TPM2_PARTIAL_CERT_VALIDITY),
+ ASN1_SIMPLE(TPM2_PARTIAL_CERT, subject, X509_NAME),
+ ASN1_EXP_SEQUENCE_OF(TPM2_PARTIAL_CERT, extensions, X509_EXTENSION, 3),
+} ASN1_SEQUENCE_END(TPM2_PARTIAL_CERT)
+
+IMPLEMENT_ASN1_FUNCTIONS(TPM2_PARTIAL_CERT)
+
+int i2d_TPM2_PARTIAL_CERT_bio(BIO *bp, const TPM2_PARTIAL_CERT *a)
+{
+ return ASN1_i2d_bio_of(TPM2_PARTIAL_CERT, i2d_TPM2_PARTIAL_CERT, bp, a);
+}
+
+int TPM2_add_ext(TPM2_PARTIAL_CERT *x, X509_EXTENSION *ex, int loc)
+{
+ return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL);
+}
+
+
struct tpm_gen_partial_cert {
const char *out_path;
const char *valid_str;
@@ -95,80 +137,6 @@ static struct name_fields names[] = {
.def = "CA Unit" },
};
-static tool_rc fixup_cert(const char *cert) {
-
- int fd = open(cert, O_RDONLY);
- if (fd < 0) {
- LOG_ERR("open failed");
- return tool_rc_general_error;
- }
-
- struct stat fs;
- int ret = fstat(fd, &fs);
- if (ret < 0) {
- close(fd);
- return tool_rc_general_error;
- }
-
- ssize_t size = fs.st_size;
- if (size < 100 || size > 255) {
- LOG_ERR("Wrong cert size %zd", size);
- close(fd);
- return tool_rc_general_error; /* there is something wrong with this cert */
- }
-
- char* buf = calloc(1, size);
- if (!buf) {
- LOG_ERR("Alloc failed");
- close(fd);
- return tool_rc_general_error;
- }
-
- tool_rc rc = tool_rc_success;
- ret = read(fd, buf, size);
- close(fd);
- if (ret != size) {
- LOG_ERR("read failed");
- rc = tool_rc_general_error;
- goto out;
- }
-
- fd = open(cert, O_WRONLY | O_TRUNC);
- if (fd < 0) {
- LOG_ERR("second open failed");
- rc = tool_rc_general_error;
- goto out;
- }
-
- /* We need to skip one wrapping sequence (8 bytes) and one
- * sequence with one empty byte field at the end (5 bytes).
- * Fix the size here */
- buf[2] = size - 16;
-
- /* Write the external sequence with the fixed size */
- ret = write(fd, buf, 3);
- if (ret != 3) {
- LOG_ERR("write failed");
- rc = tool_rc_general_error;
- close(fd);
- goto out;
- }
-
- /* skip the wrapping sequence the write the rest
- * without the 5 bytes at the end */
- ret = write(fd, buf + 11, size - 16);
- close(fd);
- if (ret != size - 16) {
- LOG_ERR("second write failed");
- rc = tool_rc_general_error;
- }
-
-out:
- free(buf);
-
- return rc;
-}
-
static int populate_fields(X509_NAME *name, const char *opt) {
char *name_opt = strdup(opt);
@@ -228,19 +196,14 @@ static tool_rc generate_partial_X509() {
}
X509_EXTENSION *extv3 = NULL;
- X509 *cert = X509_new();
+ TPM2_PARTIAL_CERT *cert = TPM2_PARTIAL_CERT_new();
if (!cert) {
- LOG_ERR("X509_new");
- goto out_err;
- }
-
- X509_NAME *issuer = X509_get_issuer_name(cert);
- if (!issuer) {
- LOG_ERR("X509_get_issuer_name");
+ LOG_ERR("TPM2_PARTIAL_CERT_new");
goto out_err;
}
- int fields_added = populate_fields(issuer, ctx.issuer);
+ /* populate issuer */
+ int fields_added = populate_fields(cert->issuer, ctx.issuer);
if (fields_added <= 0) {
LOG_ERR("Could not parse any issuer fields");
goto out_err;
@@ -248,28 +211,18 @@ static tool_rc generate_partial_X509() {
LOG_INFO("Added %d issuer fields", fields_added);
}
- int ret = X509_set_issuer_name(cert, issuer); // add issuer
- if (ret != 1) {
- LOG_ERR("X509_set_issuer_name");
- goto out_err;
- }
-
+ /* populate validity */
unsigned int valid_days;
if (!tpm2_util_string_to_uint32(ctx.valid_str, &valid_days)) {
LOG_ERR("string_to_uint32");
goto out_err;
}
- X509_gmtime_adj(X509_getm_notBefore(cert), 0); // add valid not before
- X509_gmtime_adj(X509_getm_notAfter(cert), valid_days * 86400); // add valid not after
-
- X509_NAME *subject = X509_get_subject_name(cert);
- if (!subject) {
- LOG_ERR("X509_get_subject_name");
- goto out_err;
- }
+ X509_gmtime_adj(cert->validity->notBefore, 0); // add valid not before
+ X509_gmtime_adj(cert->validity->notAfter, valid_days * 86400); // add valid not after
- fields_added = populate_fields(subject, ctx.subject);
+ /* populate subject */
+ fields_added = populate_fields(cert->subject, ctx.subject);
if (fields_added <= 0) {
LOG_ERR("Could not parse any subject fields");
goto out_err;
@@ -277,51 +230,37 @@ static tool_rc generate_partial_X509() {
LOG_INFO("Added %d subject fields", fields_added);
}
- ret = X509_set_subject_name(cert, subject); // add subject
- if (ret != 1) {
- LOG_ERR("X509_NAME_add_entry_by_txt");
- goto out_err;
- }
-
+ /* populate extensions */
extv3 = X509V3_EXT_conf_nid(NULL, NULL, NID_key_usage,
- "critical,digitalSignature,keyCertSign,cRLSign");
+ "critical,digitalSignature,keyCertSign,cRLSign");
if (!extv3) {
LOG_ERR("X509V3_EXT_conf_nid");
goto out_err;
}
- ret = X509_add_ext(cert, extv3, -1); // add required v3 extention: key usage
+ int ret = TPM2_add_ext(cert, extv3, -1); // add required v3 extention: key usage
if (ret != 1) {
LOG_ERR("X509_add_ext");
goto out_err;
}
- ret = i2d_X509_bio(cert_out, cert); // print cert in DER format
+ /* output */
+ ret = i2d_TPM2_PARTIAL_CERT_bio(cert_out, cert); // print cert in DER format
if (ret != 1) {
LOG_ERR("i2d_X509_bio");
goto out_err;
}
X509_EXTENSION_free(extv3);
- X509_free(cert);
+ TPM2_PARTIAL_CERT_free(cert);
BIO_free_all(cert_out);
- ret = fixup_cert(ctx.out_path);
- if (ret) {
- LOG_ERR("fixup_cert");
- return tool_rc_general_error;
- }
-
return tool_rc_success;
out_err:
BIO_free_all(cert_out);
- if (cert) {
- X509_free(cert);
- }
- if (extv3) {
- X509_EXTENSION_free(extv3);
- }
+ X509_EXTENSION_free(extv3);
+ TPM2_PARTIAL_CERT_free(cert);
return tool_rc_general_error;
}
--
2.31.1

View File

@ -2,13 +2,30 @@
Name: tpm2-tools
Version: 5.0
Release: 8%{?candidate:.%{candidate}}%{?dist}
Release: 9%{?candidate:.%{candidate}}%{?dist}
Summary: A bunch of TPM testing toolS build upon tpm2-tss
License: BSD
URL: https://github.com/tpm2-software/tpm2-tools
Source0: https://github.com/tpm2-software/tpm2-tools/releases/download/%{version}%{?candidate:-%{candidate}}/%{name}-%{version}%{?candidate:-%{candidate}}.tar.gz
Patch0: 0001-tpm2_import-fix-fixed-AES-key-CVE-2021-3565.patch
Patch1: 0002-Don-t-assume-end-of-argv-is-NULL.patch
Patch2: 0003-tpm2_options-fix-possible-null-ptr-passed-to-strdup.patch
Patch3: 0004-tpm2_identity_util-move-create_name-into-utility-lib.patch
Patch4: 0005-openssl-Remove-support-for-OpenSSL-1.1.0.patch
Patch5: 0006-openssl-Remove-functions-that-have-no-effect-in-Open.patch
Patch6: 0007-openssl-Remove-unnecesary-EVP_CIPHER_CTX-and-HMAC_CT.patch
Patch7: 0008-openssl-Replace-SHA256_CTX-by-EVP_MD_CTX.patch
Patch8: 0009-openssl-Replace-deprecated-X509_get_-by-X509_getm_.patch
Patch9: 0010-openssl-Convert-deprecated-SHA256-384-digesters-to-E.patch
Patch10: 0011-openssl-Rename-tpm2_openssl_halg_from_tpmhalg.patch
Patch11: 0012-openssl-Use-EVP_MAC_update-instead-HMAC_Update-on-Op.patch
Patch12: 0013-openssl-Remove-unnecessary-compatibility-function.patch
Patch13: 0014-openssl-Implement-EVP_PKEY-based-key-import.patch
Patch14: 0015-openssl-Implement-EVP_PKEY-based-key-export.patch
Patch15: 0016-openssl-Convert-deprecated-ECDH_compute_key-to-EVP_P.patch
Patch16: 0017-openssl-Reimplement-RSA-OAEP-encryption-using-EVP-fu.patch
Patch17: 0018-Generate-partial-X.509-certificate-using-own-struct.patch
BuildRequires: make
BuildRequires: gcc-c++
@ -33,6 +50,7 @@ tpm2-tools is a batch of tools for tpm2.0. It is based on tpm2-tss.
%autosetup -p1 -n %{name}-%{version}%{?candidate:-%{candidate}}
%build
autoreconf -i
# LTO exposes a latent uninitialized variable "value" in the function # "nt".
# This has been reported to the maintainer (Yunying), but they have not
# responded and I am not comfortable enough with the code to know if a trivial
@ -58,6 +76,10 @@ tpm2-tools is a batch of tools for tpm2.0. It is based on tpm2-tss.
%{_mandir}/man1/tss2_*.1.gz
%changelog
* Fri Oct 1 2021 Štěpán Horáček <shoracek@redhat.com> - 5.0-9
- Fix a segfault on ppc64le and add support for OpenSSL 3
Resolves: rhbz#1989617
* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - 5.0-8
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688