From 5b777f29fd612f9972d416ed77b90156e2373e9f Mon Sep 17 00:00:00 2001
From: Petr Gotthard <petr.gotthard@centrum.cz>
Date: Wed, 25 Aug 2021 14:02:38 +0200
Subject: [PATCH 05/23] Use default OpenSSL context for internal crypto
operations
The TPM2 provider may be loaded in the global library context.
As we don't want the TPM to be called for some operations, we have
to initialize own library context with the default provider.
This is similar to the RAND_set_rand_method dance with older OpenSSL.
Signed-off-by: Petr Gotthard <petr.gotthard@centrum.cz>
---
src/tss2-esys/esys_crypto_ossl.c | 175 ++++++++++++++++++++++---------
src/tss2-fapi/fapi_crypto.c | 152 ++++++++++++++++++---------
2 files changed, 225 insertions(+), 102 deletions(-)
diff --git a/src/tss2-esys/esys_crypto_ossl.c b/src/tss2-esys/esys_crypto_ossl.c
index ab08b3b8..35af2028 100644
--- a/src/tss2-esys/esys_crypto_ossl.c
+++ b/src/tss2-esys/esys_crypto_ossl.c
@@ -66,38 +66,101 @@ typedef struct _IESYS_CRYPTO_CONTEXT {
} type; /**< The type of context to hold; hash or hmac */
union {
struct {
- EVP_MD_CTX *ossl_context;
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
const EVP_MD *ossl_hash_alg;
+#else
+ OSSL_LIB_CTX *ossl_libctx;
+ EVP_MD *ossl_hash_alg;
+#endif
+ EVP_MD_CTX *ossl_context;
size_t hash_len;
- } hash; /**< the state variables for a hash context */
- struct {
- EVP_MD_CTX *ossl_context;
- const EVP_MD *ossl_hash_alg;
- size_t hmac_len;
- } hmac; /**< the state variables for an hmac context */
+ } hash; /**< the state variables for a HASH or HMAC context */
};
} IESYS_CRYPTOSSL_CONTEXT;
-const EVP_MD *
+static IESYS_CRYPTOSSL_CONTEXT *
+iesys_cryptossl_context_new() {
+ IESYS_CRYPTOSSL_CONTEXT *ctx;
+
+ if (!(ctx = calloc(1, sizeof(IESYS_CRYPTOSSL_CONTEXT))))
+ return NULL;
+
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ /* The TPM2 provider may be loaded in the global library context.
+ * As we don't want the TPM to be called for these operations, we have
+ * to initialize own library context with the default provider. */
+ if (!(ctx->hash.ossl_libctx = OSSL_LIB_CTX_new())) {
+ SAFE_FREE(ctx);
+ return NULL;
+ }
+#endif
+ return ctx;
+}
+
+static void
+iesys_cryptossl_context_free(IESYS_CRYPTOSSL_CONTEXT *ctx) {
+ if (!ctx)
+ return;
+
+ EVP_MD_CTX_free(ctx->hash.ossl_context);
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_MD_free(ctx->hash.ossl_hash_alg);
+ OSSL_LIB_CTX_free(ctx->hash.ossl_libctx);
+#endif
+ SAFE_FREE(ctx);
+}
+
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+static const EVP_MD *
get_ossl_hash_md(TPM2_ALG_ID hashAlg)
{
switch (hashAlg) {
case TPM2_ALG_SHA1:
return EVP_sha1();
- break;
case TPM2_ALG_SHA256:
return EVP_sha256();
- break;
case TPM2_ALG_SHA384:
return EVP_sha384();
- break;
case TPM2_ALG_SHA512:
return EVP_sha512();
- break;
default:
return NULL;
}
}
+#else
+static const char *
+get_ossl_hash_md(TPM2_ALG_ID hashAlg)
+{
+ switch (hashAlg) {
+ case TPM2_ALG_SHA1:
+ return "SHA1";
+ case TPM2_ALG_SHA256:
+ return "SHA256";
+ case TPM2_ALG_SHA384:
+ return "SHA384";
+ case TPM2_ALG_SHA512:
+ return "SHA512";
+ default:
+ return NULL;
+ }
+}
+#endif
+
+static int
+iesys_cryptossl_context_set_hash_md(IESYS_CRYPTOSSL_CONTEXT *ctx, TPM2_ALG_ID hashAlg) {
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ ctx->hash.ossl_hash_alg = get_ossl_hash_md(hashAlg);
+#else
+ const char *alg_name = get_ossl_hash_md(hashAlg);
+ if (!alg_name)
+ return 0;
+ ctx->hash.ossl_hash_alg = EVP_MD_fetch(ctx->hash.ossl_libctx, alg_name, NULL);
+#endif
+ if (!ctx->hash.ossl_hash_alg)
+ return 0;
+
+ return 1;
+}
/** Provide the context for the computation of a hash digest.
*
@@ -117,12 +180,12 @@ iesys_cryptossl_hash_start(IESYS_CRYPTO_CONTEXT_BLOB ** context,
LOG_TRACE("call: context=%p hashAlg=%"PRIu16, context, hashAlg);
return_if_null(context, "Context is NULL", TSS2_ESYS_RC_BAD_REFERENCE);
return_if_null(context, "Null-Pointer passed for context", TSS2_ESYS_RC_BAD_REFERENCE);
- IESYS_CRYPTOSSL_CONTEXT *mycontext;
- mycontext = calloc(1, sizeof(IESYS_CRYPTOSSL_CONTEXT));
+
+ IESYS_CRYPTOSSL_CONTEXT *mycontext = iesys_cryptossl_context_new();
return_if_null(mycontext, "Out of Memory", TSS2_ESYS_RC_MEMORY);
mycontext->type = IESYS_CRYPTOSSL_TYPE_HASH;
- if (!(mycontext->hash.ossl_hash_alg = get_ossl_hash_md(hashAlg))) {
+ if (!iesys_cryptossl_context_set_hash_md(mycontext, hashAlg)) {
goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED,
"Unsupported hash algorithm (%"PRIu16")", cleanup, hashAlg);
}
@@ -132,12 +195,12 @@ iesys_cryptossl_hash_start(IESYS_CRYPTO_CONTEXT_BLOB ** context,
"Unsupported hash algorithm (%"PRIu16")", cleanup, hashAlg);
}
- if (!(mycontext->hash.ossl_context = EVP_MD_CTX_create())) {
+ if (!(mycontext->hash.ossl_context = EVP_MD_CTX_create())) {
goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Error EVP_MD_CTX_create", cleanup);
}
if (1 != EVP_DigestInit(mycontext->hash.ossl_context,
- mycontext->hash.ossl_hash_alg)) {
+ mycontext->hash.ossl_hash_alg)) {
goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Errror EVP_DigestInit", cleanup);
}
@@ -146,9 +209,7 @@ iesys_cryptossl_hash_start(IESYS_CRYPTO_CONTEXT_BLOB ** context,
return TSS2_RC_SUCCESS;
cleanup:
- if (mycontext->hash.ossl_context)
- EVP_MD_CTX_destroy(mycontext->hash.ossl_context);
- SAFE_FREE(mycontext);
+ iesys_cryptossl_context_free(mycontext);
return r;
}
@@ -252,8 +313,8 @@ iesys_cryptossl_hash_finish(IESYS_CRYPTO_CONTEXT_BLOB ** context,
LOGBLOB_TRACE(buffer, mycontext->hash.hash_len, "read hash result");
*size = mycontext->hash.hash_len;
- EVP_MD_CTX_destroy(mycontext->hash.ossl_context);
- free(mycontext);
+
+ iesys_cryptossl_context_free(mycontext);
*context = NULL;
return TSS2_RC_SUCCESS;
@@ -279,8 +340,7 @@ iesys_cryptossl_hash_abort(IESYS_CRYPTO_CONTEXT_BLOB ** context)
return;
}
- EVP_MD_CTX_destroy(mycontext->hash.ossl_context);
- free(mycontext);
+ iesys_cryptossl_context_free(mycontext);
*context = NULL;
}
@@ -313,20 +373,20 @@ iesys_cryptossl_hmac_start(IESYS_CRYPTO_CONTEXT_BLOB ** context,
return_error(TSS2_ESYS_RC_BAD_REFERENCE,
"Null-Pointer passed in for context");
}
- IESYS_CRYPTOSSL_CONTEXT *mycontext = calloc(1, sizeof(IESYS_CRYPTOSSL_CONTEXT));
+ IESYS_CRYPTOSSL_CONTEXT *mycontext = iesys_cryptossl_context_new();
return_if_null(mycontext, "Out of Memory", TSS2_ESYS_RC_MEMORY);
- if (!(mycontext->hmac.ossl_hash_alg = get_ossl_hash_md(hashAlg))) {
+ if (!iesys_cryptossl_context_set_hash_md(mycontext, hashAlg)) {
goto_error(r, TSS2_ESYS_RC_NOT_IMPLEMENTED,
"Unsupported hash algorithm (%"PRIu16")", cleanup, hashAlg);
}
- if (iesys_crypto_hash_get_digest_size(hashAlg, &mycontext->hmac.hmac_len)) {
+ if (iesys_crypto_hash_get_digest_size(hashAlg, &mycontext->hash.hash_len)) {
goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
"Unsupported hash algorithm (%"PRIu16")", cleanup, hashAlg);
}
- if (!(mycontext->hmac.ossl_context = EVP_MD_CTX_create())) {
+ if (!(mycontext->hash.ossl_context = EVP_MD_CTX_create())) {
goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
"Error EVP_MD_CTX_create", cleanup);
}
@@ -341,8 +401,8 @@ iesys_cryptossl_hmac_start(IESYS_CRYPTO_CONTEXT_BLOB ** context,
"Failed to create HMAC key", cleanup);
}
- if(1 != EVP_DigestSignInit(mycontext->hmac.ossl_context, NULL,
- mycontext->hmac.ossl_hash_alg, NULL, hkey)) {
+ if(1 != EVP_DigestSignInit(mycontext->hash.ossl_context, NULL,
+ mycontext->hash.ossl_hash_alg, NULL, hkey)) {
goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE,
"DigestSignInit", cleanup);
}
@@ -356,11 +416,9 @@ iesys_cryptossl_hmac_start(IESYS_CRYPTO_CONTEXT_BLOB ** context,
return TSS2_RC_SUCCESS;
cleanup:
- if (mycontext->hmac.ossl_context)
- EVP_MD_CTX_destroy(mycontext->hmac.ossl_context);
if(hkey)
EVP_PKEY_free(hkey);
- SAFE_FREE(mycontext);
+ iesys_cryptossl_context_free(mycontext);
return r;
}
@@ -391,7 +449,7 @@ iesys_cryptossl_hmac_update(IESYS_CRYPTO_CONTEXT_BLOB * context,
LOGBLOB_TRACE(buffer, size, "Updating hmac with");
/* Call update with the message */
- if(1 != EVP_DigestSignUpdate(mycontext->hmac.ossl_context, buffer, size)) {
+ if(1 != EVP_DigestSignUpdate(mycontext->hash.ossl_context, buffer, size)) {
return_error(TSS2_ESYS_RC_GENERAL_FAILURE, "OSSL HMAC update");
}
@@ -448,19 +506,18 @@ iesys_cryptossl_hmac_finish(IESYS_CRYPTO_CONTEXT_BLOB ** context,
return_error(TSS2_ESYS_RC_BAD_REFERENCE, "bad context");
}
- if (*size < mycontext->hmac.hmac_len) {
+ if (*size < mycontext->hash.hash_len) {
return_error(TSS2_ESYS_RC_BAD_SIZE, "Buffer too small");
}
- if (1 != EVP_DigestSignFinal(mycontext->hmac.ossl_context, buffer, size)) {
+ if (1 != EVP_DigestSignFinal(mycontext->hash.ossl_context, buffer, size)) {
goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "DigestSignFinal", cleanup);
}
LOGBLOB_TRACE(buffer, *size, "read hmac result");
cleanup:
- EVP_MD_CTX_destroy(mycontext->hmac.ossl_context);
- SAFE_FREE(mycontext);
+ iesys_cryptossl_context_free(mycontext);
*context = NULL;
return r;
}
@@ -510,9 +567,7 @@ iesys_cryptossl_hmac_abort(IESYS_CRYPTO_CONTEXT_BLOB ** context)
return;
}
- EVP_MD_CTX_destroy(mycontext->hmac.ossl_context);
-
- free(mycontext);
+ iesys_cryptossl_context_free(mycontext);
*context = NULL;
}
}
@@ -529,9 +584,14 @@ iesys_cryptossl_hmac_abort(IESYS_CRYPTO_CONTEXT_BLOB ** context)
TSS2_RC
iesys_cryptossl_random2b(TPM2B_NONCE * nonce, size_t num_bytes)
{
+ int rc;
#if OPENSSL_VERSION_NUMBER < 0x30000000L
const RAND_METHOD *rand_save = RAND_get_rand_method();
RAND_set_rand_method(RAND_OpenSSL());
+#else
+ OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new();
+ if (!libctx)
+ return TSS2_ESYS_RC_MEMORY;
#endif
if (num_bytes == 0) {
@@ -540,16 +600,16 @@ iesys_cryptossl_random2b(TPM2B_NONCE * nonce, size_t num_bytes)
nonce->size = num_bytes;
}
- if (1 != RAND_bytes(&nonce->buffer[0], nonce->size)) {
#if OPENSSL_VERSION_NUMBER < 0x30000000L
- RAND_set_rand_method(rand_save);
+ rc = RAND_bytes(&nonce->buffer[0], nonce->size);
+ RAND_set_rand_method(rand_save);
+#else
+ rc = RAND_bytes_ex(libctx, &nonce->buffer[0], nonce->size, 0);
+ OSSL_LIB_CTX_free(libctx);
#endif
+ if (rc != 1)
return_error(TSS2_ESYS_RC_GENERAL_FAILURE,
"Failure in random number generator.");
- }
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
- RAND_set_rand_method(rand_save);
-#endif
return TSS2_RC_SUCCESS;
}
@@ -578,28 +638,37 @@ iesys_cryptossl_pk_encrypt(TPM2B_PUBLIC * pub_tpm_key,
{
#if OPENSSL_VERSION_NUMBER < 0x30000000L
RSA *rsa_key = NULL;
+ const EVP_MD * hashAlg = NULL;
const RAND_METHOD *rand_save = RAND_get_rand_method();
RAND_set_rand_method(RAND_OpenSSL());
#else
+ OSSL_LIB_CTX *libctx = NULL;
+ EVP_MD * hashAlg = NULL;
OSSL_PARAM *params = NULL;
OSSL_PARAM_BLD *build = NULL;
#endif
TSS2_RC r = TSS2_RC_SUCCESS;
- const EVP_MD * hashAlg = NULL;
EVP_PKEY *evp_rsa_key = NULL;
EVP_PKEY_CTX *genctx = NULL, *ctx = NULL;
BIGNUM *bne = NULL, *n = NULL;
int padding;
char *label_copy = NULL;
- if (!(hashAlg = get_ossl_hash_md(pub_tpm_key->publicArea.nameAlg))) {
- LOG_ERROR("Unsupported hash algorithm (%"PRIu16")",
- pub_tpm_key->publicArea.nameAlg);
#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ if (!(hashAlg = get_ossl_hash_md(pub_tpm_key->publicArea.nameAlg))) {
RAND_set_rand_method(rand_save);
+#else
+ if (!(libctx = OSSL_LIB_CTX_new()))
+ return TSS2_ESYS_RC_MEMORY;
+
+ if (!(hashAlg = EVP_MD_fetch(libctx,
+ get_ossl_hash_md(pub_tpm_key->publicArea.nameAlg), NULL))) {
+ OSSL_LIB_CTX_free(libctx);
#endif
+ LOG_ERROR("Unsupported hash algorithm (%"PRIu16")",
+ pub_tpm_key->publicArea.nameAlg);
return TSS2_ESYS_RC_NOT_IMPLEMENTED;
}
@@ -673,7 +742,7 @@ iesys_cryptossl_pk_encrypt(TPM2B_PUBLIC * pub_tpm_key,
cleanup);
}
- if ((genctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL
+ if ((genctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", NULL)) == NULL
|| EVP_PKEY_fromdata_init(genctx) <= 0
|| EVP_PKEY_fromdata(genctx, &evp_rsa_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Could not create rsa key.",
@@ -744,6 +813,8 @@ iesys_cryptossl_pk_encrypt(TPM2B_PUBLIC * pub_tpm_key,
#else
OSSL_FREE(params, OSSL_PARAM);
OSSL_FREE(build, OSSL_PARAM_BLD);
+ OSSL_FREE(hashAlg, EVP_MD);
+ OSSL_FREE(libctx, OSSL_LIB_CTX);
#endif
return r;
}
diff --git a/src/tss2-fapi/fapi_crypto.c b/src/tss2-fapi/fapi_crypto.c
index 9c7e566c..d061cf48 100644
--- a/src/tss2-fapi/fapi_crypto.c
+++ b/src/tss2-fapi/fapi_crypto.c
@@ -48,14 +48,34 @@
/** Context to hold temporary values for ifapi_crypto */
typedef struct _IFAPI_CRYPTO_CONTEXT {
- /** The hash engine's context */
- EVP_MD_CTX *osslContext;
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
/** The currently used hash algorithm */
const EVP_MD *osslHashAlgorithm;
+#else
+ OSSL_LIB_CTX *libctx;
+ /** The currently used hash algorithm */
+ EVP_MD *osslHashAlgorithm;
+#endif
+ /** The hash engine's context */
+ EVP_MD_CTX *osslContext;
/** The size of the hash's digest */
size_t hashSize;
} IFAPI_CRYPTO_CONTEXT;
+static void
+ifapi_crypto_context_free(IFAPI_CRYPTO_CONTEXT *ctx)
+{
+ if (!ctx)
+ return;
+
+ EVP_MD_CTX_destroy(ctx->osslContext);
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_MD_free(ctx->osslHashAlgorithm);
+ OSSL_LIB_CTX_free(ctx->libctx);
+#endif
+ SAFE_FREE(ctx);
+}
+
/**
* Returns the signature scheme that is currently used in the FAPI context.
*
@@ -225,6 +245,33 @@ ifapi_bn2binpad(const BIGNUM *bn, unsigned char *bin, int binSize)
return 1;
}
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+/**
+ * Converts a TSS hash algorithm identifier into an OpenSSL hash algorithm
+ * identifier object.
+ *
+ * @param[in] hashAlgorithm The TSS hash algorithm identifier to convert
+ *
+ * @retval A suitable OpenSSL identifier object if one could be found
+ * @retval NULL if no suitable identifier object could be found
+ */
+static const EVP_MD *
+get_ossl_hash_md(TPM2_ALG_ID hashAlgorithm)
+{
+ switch (hashAlgorithm) {
+ case TPM2_ALG_SHA1:
+ return EVP_sha1();
+ case TPM2_ALG_SHA256:
+ return EVP_sha256();
+ case TPM2_ALG_SHA384:
+ return EVP_sha384();
+ case TPM2_ALG_SHA512:
+ return EVP_sha512();
+ default:
+ return NULL;
+ }
+}
+#else
/**
* Returns a suitable openSSL hash algorithm identifier for a given TSS hash
* algorithm identifier.
@@ -235,22 +282,23 @@ ifapi_bn2binpad(const BIGNUM *bn, unsigned char *bin, int binSize)
* hashAlgorithm could be found
* @retval NULL if no suitable hash algorithm identifier could be found
*/
-static const EVP_MD *
+static const char *
get_hash_md(TPM2_ALG_ID hashAlgorithm)
{
switch (hashAlgorithm) {
case TPM2_ALG_SHA1:
- return EVP_sha1();
+ return "SHA1";
case TPM2_ALG_SHA256:
- return EVP_sha256();
+ return "SHA256";
case TPM2_ALG_SHA384:
- return EVP_sha384();
+ return "SHA384";
case TPM2_ALG_SHA512:
- return EVP_sha512();
+ return "SHA512";
default:
return NULL;
}
}
+#endif
/**
* Returns a suitable openSSL RSA signature scheme identifiver for a given TSS
@@ -1274,6 +1322,9 @@ ifapi_verify_signature_quote(
BIO *bufio = NULL;
EVP_PKEY_CTX *pctx = NULL;
EVP_MD_CTX *mdctx = NULL;
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ OSSL_LIB_CTX *libctx = NULL;
+#endif
/* Check whether or not the key is valid */
if (keyObject->objectType == IFAPI_KEY_OBJ) {
@@ -1304,8 +1355,8 @@ ifapi_verify_signature_quote(
goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "EVP_MD_CTX_create",
error_cleanup);
}
-
- const EVP_MD *hashAlgorithm = get_hash_md(signatureScheme->details.any.hashAlg);
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ const EVP_MD *hashAlgorithm = get_ossl_hash_md(signatureScheme->details.any.hashAlg);
if (!hashAlgorithm) {
goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Invalid hash alg.",
error_cleanup);
@@ -1316,6 +1367,26 @@ ifapi_verify_signature_quote(
goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "EVP_DigestVerifyInit",
error_cleanup);
}
+#else
+ const char *hashAlgorithm = get_hash_md(signatureScheme->details.any.hashAlg);
+ if (!hashAlgorithm) {
+ goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "Invalid hash alg.",
+ error_cleanup);
+ }
+
+ /* The TPM2 provider may be loaded in the global library context.
+ * As we don't want the TPM to be called for these operations, we have
+ * to initialize own library context with the default provider. */
+ libctx = OSSL_LIB_CTX_new();
+ goto_if_null(libctx, "Out of memory", TSS2_FAPI_RC_MEMORY, error_cleanup);
+
+ /* Verify the digest of the signature */
+ if (1 != EVP_DigestVerifyInit_ex(mdctx, &pctx, hashAlgorithm, libctx,
+ NULL, publicKey, NULL)) {
+ goto_error(r, TSS2_FAPI_RC_GENERAL_FAILURE, "EVP_DigestVerifyInit_ex",
+ error_cleanup);
+ }
+#endif
goto_if_null(pctx, "Out of memory", TSS2_FAPI_RC_MEMORY, error_cleanup);
if (EVP_PKEY_type(EVP_PKEY_id(publicKey)) == EVP_PKEY_RSA) {
int padding = get_sig_scheme(signatureScheme->scheme);
@@ -1339,12 +1410,13 @@ ifapi_verify_signature_quote(
}
error_cleanup:
- if (mdctx != NULL) {
- EVP_MD_CTX_destroy(mdctx);
- }
+ EVP_MD_CTX_destroy(mdctx);
SAFE_FREE(public_pem_key);
EVP_PKEY_free(publicKey);
BIO_free(bufio);
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ OSSL_LIB_CTX_free(libctx);
+#endif
return r;
}
@@ -1464,36 +1536,6 @@ ifapi_hash_get_digest_size(TPM2_ALG_ID hashAlgorithm)
}
}
-/**
- * Converts a TSS hash algorithm identifier into an OpenSSL hash algorithm
- * identifier object.
- *
- * @param[in] hashAlgorithm The TSS hash algorithm identifier to convert
- *
- * @retval A suitable OpenSSL identifier object if one could be found
- * @retval NULL if no suitable identifier object could be found
- */
-static const EVP_MD *
-get_ossl_hash_md(TPM2_ALG_ID hashAlgorithm)
-{
- switch (hashAlgorithm) {
- case TPM2_ALG_SHA1:
- return EVP_sha1();
- break;
- case TPM2_ALG_SHA256:
- return EVP_sha256();
- break;
- case TPM2_ALG_SHA384:
- return EVP_sha384();
- break;
- case TPM2_ALG_SHA512:
- return EVP_sha512();
- break;
- default:
- return NULL;
- }
-}
-
/**
* Starts the computation of a hash digest.
*
@@ -1520,11 +1562,26 @@ ifapi_crypto_hash_start(IFAPI_CRYPTO_CONTEXT_BLOB **context,
mycontext = calloc(1, sizeof(IFAPI_CRYPTO_CONTEXT));
return_if_null(mycontext, "Out of memory", TSS2_FAPI_RC_MEMORY);
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
if (!(mycontext->osslHashAlgorithm = get_ossl_hash_md(hashAlgorithm))) {
goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
"Unsupported hash algorithm (%" PRIu16 ")", cleanup,
hashAlgorithm);
}
+#else
+ /* The TPM2 provider may be loaded in the global library context.
+ * As we don't want the TPM to be called for these operations, we have
+ * to initialize own library context with the default provider. */
+ mycontext->libctx = OSSL_LIB_CTX_new();
+ return_if_null(mycontext->libctx, "Out of memory", TSS2_FAPI_RC_MEMORY);
+
+ if (!(mycontext->osslHashAlgorithm =
+ EVP_MD_fetch(mycontext->libctx, get_hash_md(hashAlgorithm), NULL))) {
+ goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
+ "Unsupported hash algorithm (%" PRIu16 ")", cleanup,
+ hashAlgorithm);
+ }
+#endif
if (!(mycontext->hashSize = ifapi_hash_get_digest_size(hashAlgorithm))) {
goto_error(r, TSS2_FAPI_RC_BAD_VALUE,
@@ -1548,10 +1605,7 @@ ifapi_crypto_hash_start(IFAPI_CRYPTO_CONTEXT_BLOB **context,
return TSS2_RC_SUCCESS;
cleanup:
- if (mycontext->osslContext)
- EVP_MD_CTX_destroy(mycontext->osslContext);
- SAFE_FREE(mycontext);
-
+ ifapi_crypto_context_free(mycontext);
return r;
}
@@ -1630,8 +1684,7 @@ ifapi_crypto_hash_finish(IFAPI_CRYPTO_CONTEXT_BLOB **context,
}
/* Finalize the hash context */
- EVP_MD_CTX_destroy(mycontext->osslContext);
- free(mycontext);
+ ifapi_crypto_context_free(mycontext);
*context = NULL;
return TSS2_RC_SUCCESS;
@@ -1653,8 +1706,7 @@ ifapi_crypto_hash_abort(IFAPI_CRYPTO_CONTEXT_BLOB **context)
}
IFAPI_CRYPTO_CONTEXT *mycontext = (IFAPI_CRYPTO_CONTEXT *) * context;
- EVP_MD_CTX_destroy(mycontext->osslContext);
- free(mycontext);
+ ifapi_crypto_context_free(mycontext);
*context = NULL;
}
--
2.34.3