You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1376 lines
43 KiB

From de47f3c95f973fa8fc873287ca8927038d225aa8 Mon Sep 17 00:00:00 2001
From: Ken Goldman <kgold@linux.ibm.com>
Date: Fri, 17 Sep 2021 19:04:39 -0400
Subject: [PATCH 7/7] utils: Port to openssl 3.0.0 replaces RSA with EVP_PKEY
The RSA structure is deprecated. This flows through all the
utilities, including the X509 public key handling, the PEM and DER
public and private key converters, the functions to convert to and
from the RSA bignums, the sign and encrypt functions.
TODO are the equivalent updates for ECC and AES.
- Compared to the next branch commit 65c77e87, changes related to HMAC are
ommited and a conflict is resolved.
Signed-off-by: Ken Goldman <kgold@linux.ibm.com>
---
utils/cryptoutils.c | 349 ++++++++++++++++++++++++++++++++++-----
utils/cryptoutils.h | 22 ++-
utils/efilib.c | 27 ++-
utils/ekutils.c | 50 ++++--
utils/ekutils.h | 4 +-
utils/ibmtss/tsscrypto.h | 3 +-
utils/sign.c | 4 +-
utils/tsscrypto.c | 202 +++++++++++++++++++---
8 files changed, 572 insertions(+), 89 deletions(-)
diff --git a/utils/cryptoutils.c b/utils/cryptoutils.c
index eb5f0d2..57eade7 100644
--- a/utils/cryptoutils.c
+++ b/utils/cryptoutils.c
@@ -61,6 +61,9 @@
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000
+#include <openssl/core_names.h>
+#endif
#ifndef TPM_TSS_NOECC
#include <openssl/ec.h>
@@ -75,6 +78,9 @@
#include <ibmtss/tsscryptoh.h>
#include <ibmtss/Implementation.h>
+TPM_RC TSS_Hash_GetMd(const EVP_MD **md,
+ TPMI_ALG_HASH hashAlg);
+
#include "objecttemplates.h"
#include "cryptoutils.h"
@@ -283,7 +289,8 @@ TPM_RC convertPemToEvpPubKey(EVP_PKEY **evpPkey, /* freed by caller */
The return is void because the structure is opaque to the caller. This accomodates other crypto
libraries.
- rsaKey is an RSA structure
+ For Openssl < 3, rsaKey is an RSA structure.
+ For Openssl 3, rsaKey is an EVP_PKEY,
*/
TPM_RC convertPemToRsaPrivKey(void **rsaKey, /* freed by caller */
@@ -297,7 +304,11 @@ TPM_RC convertPemToRsaPrivKey(void **rsaKey, /* freed by caller */
rc = TSS_File_Open(&pemKeyFile, pemKeyFilename, "rb"); /* closed @1 */
}
if (rc == 0) {
+#if OPENSSL_VERSION_NUMBER < 0x30000000
*rsaKey = (void *)PEM_read_RSAPrivateKey(pemKeyFile, NULL, NULL, (void *)password);
+#else
+ *rsaKey = (void *)PEM_read_PrivateKey(pemKeyFile, NULL, NULL, (void *)password);
+#endif
if (*rsaKey == NULL) {
printf("convertPemToRsaPrivKey: Error in OpenSSL PEM_read_RSAPrivateKey()\n");
rc = TSS_RC_PEM_ERROR;
@@ -334,6 +345,8 @@ TPM_RC convertEvpPkeyToEckey(EC_KEY **ecKey, /* freed by caller */
#endif /* TPM_TSS_NOECC */
#endif /* TPM_TPM20 */
+#if OPENSSL_VERSION_NUMBER < 0x30000000
+
/* convertEvpPkeyToRsakey() retrieves the RSA key token from the EVP_PKEY */
TPM_RC convertEvpPkeyToRsakey(RSA **rsaKey, /* freed by caller */
@@ -350,6 +363,7 @@ TPM_RC convertEvpPkeyToRsakey(RSA **rsaKey, /* freed by caller */
}
return rc;
}
+#endif
#ifdef TPM_TPM20
#ifndef TPM_TSS_NOECC
@@ -426,19 +440,26 @@ TPM_RC convertEcKeyToPrivateKeyBin(int *privateKeyBytes,
#endif /* TPM_TPM20 */
/* convertRsaKeyToPrivateKeyBin() converts an OpenSSL RSA key token private prime p to a binary
- array */
+ array
+
+ For Openssl < 3, rsaKey is an RSA structure.
+ For Openssl 3, rsaKey is an EVP_PKEY,
+*/
TPM_RC convertRsaKeyToPrivateKeyBin(int *privateKeyBytes,
uint8_t **privateKeyBin, /* freed by caller */
+#if OPENSSL_VERSION_NUMBER < 0x30000000
const RSA *rsaKey)
+#else
+ const EVP_PKEY *rsaKey)
+#endif
{
TPM_RC rc = 0;
const BIGNUM *p = NULL;
- const BIGNUM *q;
/* get the private primes */
if (rc == 0) {
- rc = getRsaKeyParts(NULL, NULL, NULL, &p, &q, rsaKey);
+ rc = getRsaKeyParts(NULL, NULL, NULL, &p, NULL, rsaKey); /* freed @2 */
}
/* allocate a buffer for the private key array */
if (rc == 0) {
@@ -448,7 +469,10 @@ TPM_RC convertRsaKeyToPrivateKeyBin(int *privateKeyBytes,
/* convert the private key bignum to binary */
if (rc == 0) {
BN_bn2bin(p, *privateKeyBin);
- }
+ }
+#if OPENSSL_VERSION_NUMBER >= 0x30000000
+ BN_free((BIGNUM *)p); /* @2 */
+#endif
return rc;
}
@@ -500,7 +524,11 @@ TPM_RC convertEcKeyToPublicKeyBin(int *modulusBytes,
#endif /* TPM_TSS_NOECC */
#endif /* TPM_TPM20 */
-/* convertRsaKeyToPublicKeyBin() converts from an openssl RSA key token to a public modulus */
+/* convertRsaKeyToPublicKeyBin() converts from an openssl RSA key token to a public modulus
+
+ For Openssl < 3, rsaKey is an RSA structure.
+ For Openssl 3, rsaKey is an EVP_PKEY,
+*/
TPM_RC convertRsaKeyToPublicKeyBin(int *modulusBytes,
uint8_t **modulusBin, /* freed by caller */
@@ -508,12 +536,10 @@ TPM_RC convertRsaKeyToPublicKeyBin(int *modulusBytes,
{
TPM_RC rc = 0;
const BIGNUM *n = NULL;
- const BIGNUM *e;
- const BIGNUM *d;
/* get the public modulus from the RSA key token */
if (rc == 0) {
- rc = getRsaKeyParts(&n, &e, &d, NULL, NULL, rsaKey);
+ rc = getRsaKeyParts(&n, NULL, NULL, NULL, NULL, rsaKey);
}
if (rc == 0) {
*modulusBytes = BN_num_bytes(n);
@@ -524,7 +550,10 @@ TPM_RC convertRsaKeyToPublicKeyBin(int *modulusBytes,
if (rc == 0) {
BN_bn2bin(n, *modulusBin);
}
- return rc;
+#if OPENSSL_VERSION_NUMBER >= 0x30000000
+ BN_free((BIGNUM *)n); /* @2 */
+#endif
+ return rc;
}
#ifdef TPM_TPM20
@@ -882,11 +911,18 @@ TPM_RC convertEcKeyToPrivate(TPM2B_PRIVATE *objectPrivate,
/* convertRsaKeyToPrivate() converts an openssl RSA key token to either a TPM2B_PRIVATE or
TPM2B_SENSITIVE
+
+ For Openssl < 3, rsaKey is an RSA structure.
+ For Openssl 3, rsaKey is an EVP_PKEY,
*/
TPM_RC convertRsaKeyToPrivate(TPM2B_PRIVATE *objectPrivate,
TPM2B_SENSITIVE *objectSensitive,
- RSA *rsaKey,
+#if OPENSSL_VERSION_NUMBER < 0x30000000
+ RSA *rsaKey,
+#else
+ EVP_PKEY *rsaKey,
+#endif
const char *password)
{
TPM_RC rc = 0;
@@ -957,7 +993,11 @@ TPM_RC convertEcKeyToPublic(TPM2B_PUBLIC *objectPublic,
#ifdef TPM_TPM20
-/* convertRsaKeyToPublic() converts from an openssl RSA key token to a TPM2B_PUBLIC */
+/* convertRsaKeyToPublic() converts from an openssl RSA key token to a TPM2B_PUBLIC
+
+ For Openssl < 3, rsaKey is an RSA structure.
+ For Openssl 3, rsaKey is an EVP_PKEY,
+*/
TPM_RC convertRsaKeyToPublic(TPM2B_PUBLIC *objectPublic,
int keyType,
@@ -1110,16 +1150,25 @@ TPM_RC convertRsaPemToKeyPair(TPM2B_PUBLIC *objectPublic,
{
TPM_RC rc = 0;
EVP_PKEY *evpPkey = NULL;
+#if OPENSSL_VERSION_NUMBER < 0x30000000
RSA *rsaKey = NULL;
-
+#else
+ EVP_PKEY *rsaKey = NULL;
+#endif
+
if (rc == 0) {
rc = convertPemToEvpPrivKey(&evpPkey, /* freed @1 */
pemKeyFilename,
password);
}
if (rc == 0) {
+#if OPENSSL_VERSION_NUMBER < 0x30000000
rc = convertEvpPkeyToRsakey(&rsaKey, /* freed @2 */
evpPkey);
+#else
+ /* openssl 3.0.0 and up use the EVP_PKEY directly */
+ rsaKey = evpPkey;
+#endif
}
if (rc == 0) {
rc = convertRsaKeyToPrivate(objectPrivate, /* TPM2B_PRIVATE */
@@ -1135,10 +1184,12 @@ TPM_RC convertRsaPemToKeyPair(TPM2B_PUBLIC *objectPublic,
halg,
rsaKey);
}
- TSS_RsaFree(rsaKey); /* @2 */
if (evpPkey != NULL) {
EVP_PKEY_free(evpPkey); /* @1 */
}
+#if OPENSSL_VERSION_NUMBER < 0x30000000
+ TSS_RsaFree(rsaKey); /* @2 */
+#endif
return rc;
}
@@ -1281,7 +1332,11 @@ TPM_RC convertRsaDerToKeyPair(TPM2B_PUBLIC *objectPublic,
const char *password)
{
TPM_RC rc = 0;
+#if OPENSSL_VERSION_NUMBER < 0x30000000
RSA *rsaKey = NULL;
+#else
+ EVP_PKEY *rsaKey = NULL;
+#endif
unsigned char *derBuffer = NULL;
size_t derSize;
@@ -1293,7 +1348,12 @@ TPM_RC convertRsaDerToKeyPair(TPM2B_PUBLIC *objectPublic,
}
if (rc == 0) {
const unsigned char *tmpPtr = derBuffer; /* because pointer moves */
+#if OPENSSL_VERSION_NUMBER < 0x30000000
rsaKey = d2i_RSAPrivateKey(NULL, &tmpPtr, (long)derSize); /* freed @2 */
+#else
+ rsaKey = d2i_PrivateKey(EVP_PKEY_RSA, NULL,
+ &tmpPtr, (long)derSize);
+#endif
if (rsaKey == NULL) {
printf("convertRsaDerToKeyPair: could not convert key to RSA\n");
rc = TPM_RC_VALUE;
@@ -1331,7 +1391,11 @@ TPM_RC convertRsaDerToPublic(TPM2B_PUBLIC *objectPublic,
const char *derKeyFilename)
{
TPM_RC rc = 0;
+#if OPENSSL_VERSION_NUMBER < 0x30000000
RSA *rsaKey = NULL;
+#else
+ EVP_PKEY *rsaKey = NULL;
+#endif
unsigned char *derBuffer = NULL;
size_t derSize;
@@ -1343,7 +1407,11 @@ TPM_RC convertRsaDerToPublic(TPM2B_PUBLIC *objectPublic,
}
if (rc == 0) {
const unsigned char *tmpPtr = derBuffer; /* because pointer moves */
+#if OPENSSL_VERSION_NUMBER < 0x30000000
rsaKey = d2i_RSA_PUBKEY(NULL, &tmpPtr, (long)derSize); /* freed @2 */
+#else
+ rsaKey = d2i_PUBKEY(NULL, &tmpPtr, (long)derSize);
+#endif
if (rsaKey == NULL) {
printf("convertRsaDerToPublic: could not convert key to RSA\n");
rc = TPM_RC_VALUE;
@@ -1362,13 +1430,6 @@ TPM_RC convertRsaDerToPublic(TPM2B_PUBLIC *objectPublic,
return rc;
}
-#endif /* TPM_TSS_NORSA */
-#endif /* TPM_TPM20 */
-#endif /* TPM_TSS_NOFILE */
-
-#ifndef TPM_TSS_NOFILE
-#ifdef TPM_TPM20
-
/* convertRsaPemToPublic() converts an RSA public key in PEM format to a TPM2B_PUBLIC */
TPM_RC convertRsaPemToPublic(TPM2B_PUBLIC *objectPublic,
@@ -1380,15 +1441,24 @@ TPM_RC convertRsaPemToPublic(TPM2B_PUBLIC *objectPublic,
{
TPM_RC rc = 0;
EVP_PKEY *evpPkey = NULL;
+#if OPENSSL_VERSION_NUMBER < 0x30000000
RSA *rsaKey = NULL;
+#else
+ EVP_PKEY *rsaKey = NULL;
+#endif
if (rc == 0) {
rc = convertPemToEvpPubKey(&evpPkey, /* freed @1 */
pemKeyFilename);
}
if (rc == 0) {
+#if OPENSSL_VERSION_NUMBER < 0x30000000
rc = convertEvpPkeyToRsakey(&rsaKey, /* freed @2 */
evpPkey);
+#else
+ /* openssl 3.0.0 and up use the EVP_PKEY directly */
+ rsaKey = evpPkey;
+#endif
}
if (rc == 0) {
rc = convertRsaKeyToPublic(objectPublic,
@@ -1398,35 +1468,97 @@ TPM_RC convertRsaPemToPublic(TPM2B_PUBLIC *objectPublic,
halg,
rsaKey);
}
- RSA_free(rsaKey); /* @2 */
if (evpPkey != NULL) {
EVP_PKEY_free(evpPkey); /* @1 */
}
+#if OPENSSL_VERSION_NUMBER < 0x30000000
+ TSS_RsaFree(rsaKey); /* @2 */
+#endif
return rc;
}
+#endif /* TPM_TSS_NORSA */
#endif /* TPM_TPM20 */
#endif /* TPM_TSS_NOFILE */
/* getRsaKeyParts() gets the RSA key parts from an OpenSSL RSA key token.
If n is not NULL, returns n, e, and d. If p is not NULL, returns p and q.
+
+ For openssl < 3.0.0, the bignums are references to the RSA key and should not be freed separately.
+
+ For openssl >= 3.0.0, the bignums are allocated and must be freed.
+
+ FIXME - is there a better way?
*/
TPM_RC getRsaKeyParts(const BIGNUM **n,
- const BIGNUM **e,
- const BIGNUM **d,
- const BIGNUM **p,
- const BIGNUM **q,
- const RSA *rsaKey)
+ const BIGNUM **e,
+ const BIGNUM **d,
+ const BIGNUM **p,
+ const BIGNUM **q,
+#if OPENSSL_VERSION_NUMBER < 0x30000000
+ const RSA *rsaKey)
+#else
+ const EVP_PKEY *rsaKey)
+#endif
{
TPM_RC rc = 0;
+#if OPENSSL_VERSION_NUMBER < 0x30000000
if (n != NULL) {
RSA_get0_key(rsaKey, n, e, d);
}
if (p != NULL) {
RSA_get0_factors(rsaKey, p, q);
}
+#else
+ int irc;
+ if (rc == 0) {
+ if (n != NULL) {
+ irc = EVP_PKEY_get_bn_param(rsaKey, OSSL_PKEY_PARAM_RSA_N, (BIGNUM **)n);
+ if (irc != 1) {
+ printf("getRsaKeyParts: Error getting n\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ }
+ if (rc == 0) {
+ if (e != NULL) {
+ irc = EVP_PKEY_get_bn_param(rsaKey, OSSL_PKEY_PARAM_RSA_E, (BIGNUM **)e);
+ if (irc != 1) {
+ printf("getRsaKeyParts: Error getting e\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ }
+ if (rc == 0) {
+ if (d != NULL) {
+ irc = EVP_PKEY_get_bn_param(rsaKey, OSSL_PKEY_PARAM_RSA_D, (BIGNUM **)d);
+ if (irc != 1) {
+ printf("getRsaKeyParts: Error getting d\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ }
+ if (rc == 0) {
+ if (p != NULL) {
+ irc = EVP_PKEY_get_bn_param(rsaKey, OSSL_PKEY_PARAM_RSA_FACTOR1, (BIGNUM **)p);
+ if (irc != 1) {
+ printf("getRsaKeyParts: Error getting p\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ }
+ if (rc == 0) {
+ if (q != NULL) {
+ irc = EVP_PKEY_get_bn_param(rsaKey, OSSL_PKEY_PARAM_RSA_FACTOR2, (BIGNUM **)q);
+ if (irc != 1) {
+ printf("getRsaKeyParts: Error getting q\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ }
+#endif
return rc;
}
@@ -1501,11 +1633,16 @@ TPM_RC convertRsaPublicToEvpPubKey(EVP_PKEY **evpPubkey, /* freed by caller */
const TPM2B_PUBLIC_KEY_RSA *tpm2bRsa)
{
TPM_RC rc = 0;
+ /* public exponent */
+ unsigned char earr[3] = {0x01, 0x00, 0x01};
+#if OPENSSL_VERSION_NUMBER < 0x30000000
int irc;
RSA *rsaPubKey = NULL;
-
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x30000000
if (rc == 0) {
- *evpPubkey = EVP_PKEY_new();
+ *evpPubkey = EVP_PKEY_new(); /* freed by caller */
if (*evpPubkey == NULL) {
printf("convertRsaPublicToEvpPubKey: EVP_PKEY failed\n");
rc = TSS_RC_OUT_OF_MEMORY;
@@ -1513,10 +1650,10 @@ TPM_RC convertRsaPublicToEvpPubKey(EVP_PKEY **evpPubkey, /* freed by caller */
}
/* TPM to RSA token */
if (rc == 0) {
- /* public exponent */
- unsigned char earr[3] = {0x01, 0x00, 0x01};
+ /* For Openssl < 3, rsaKey is an RSA structure. */
+ /* For Openssl 3, rsaKey is an EVP_PKEY. */
rc = TSS_RSAGeneratePublicTokenI
- ((void **)&rsaPubKey, /* freed as part of EVP_PKEY */
+ ((void **)&rsaPubKey, /* freed by caller */
tpm2bRsa->t.buffer, /* public modulus */
tpm2bRsa->t.size,
earr, /* public exponent */
@@ -1526,11 +1663,24 @@ TPM_RC convertRsaPublicToEvpPubKey(EVP_PKEY **evpPubkey, /* freed by caller */
if (rc == 0) {
irc = EVP_PKEY_assign_RSA(*evpPubkey, rsaPubKey);
if (irc == 0) {
- TSS_RsaFree(rsaPubKey); /* because not assigned tp EVP_PKEY */
+ TSS_RsaFree(rsaPubKey); /* because not assigned to EVP_PKEY */
printf("convertRsaPublicToEvpPubKey: EVP_PKEY_assign_RSA failed\n");
rc = TSS_RC_RSA_KEY_CONVERT;
}
}
+#else /* FIXME this should always work? */
+ /* TPM to RSA token */
+ if (rc == 0) {
+ /* For Openssl < 3, rsaKey is an RSA structure. */
+ /* For Openssl 3, rsaKey is an EVP_PKEY. */
+ rc = TSS_RSAGeneratePublicTokenI
+ ((void **)evpPubkey, /* freed by caller */
+ tpm2bRsa->t.buffer, /* public modulus */
+ tpm2bRsa->t.size,
+ earr, /* public exponent */
+ sizeof(earr));
+ }
+#endif
return rc;
}
@@ -1828,8 +1978,9 @@ TPM_RC verifyRSASignatureFromEvpPubKey(unsigned char *message,
EVP_PKEY *evpPkey)
{
TPM_RC rc = 0;
+#if OPENSSL_VERSION_NUMBER < 0x30000000
RSA *rsaPubKey = NULL; /* OpenSSL public key, RSA format */
-
+
/* construct the RSA key token */
if (rc == 0) {
rsaPubKey = EVP_PKEY_get1_RSA(evpPkey); /* freed @1 */
@@ -1838,6 +1989,9 @@ TPM_RC verifyRSASignatureFromEvpPubKey(unsigned char *message,
rc = TSS_RC_RSA_KEY_CONVERT;
}
}
+#else
+ EVP_PKEY *rsaPubKey = evpPkey;
+#endif
if (rc == 0) {
rc = verifyRSASignatureFromRSA(message,
messageSize,
@@ -1845,11 +1999,17 @@ TPM_RC verifyRSASignatureFromEvpPubKey(unsigned char *message,
halg,
rsaPubKey);
}
+#if OPENSSL_VERSION_NUMBER < 0x30000000
TSS_RsaFree(rsaPubKey); /* @1 */
+#endif
return rc;
}
-/* signRSAFromRSA() signs digest to signature, using th4 RSA key rsaKey. */
+/* signRSAFromRSA() signs digest to signature, using rsaKey.
+
+ For Openssl < 3, rsaKey is an RSA structure.
+ For Openssl 3, rsaKey is an EVP_PKEY,
+*/
TPM_RC signRSAFromRSA(uint8_t *signature, size_t *signatureLength,
size_t signatureSize,
@@ -1859,8 +2019,9 @@ TPM_RC signRSAFromRSA(uint8_t *signature, size_t *signatureLength,
{
TPM_RC rc = 0;
int irc;
+#if OPENSSL_VERSION_NUMBER < 0x30000000
int nid; /* openssl hash algorithm */
-
+
/* map the hash algorithm to the openssl NID */
if (rc == 0) {
switch (hashAlg) {
@@ -1903,6 +2064,54 @@ TPM_RC signRSAFromRSA(uint8_t *signature, size_t *signatureLength,
rc = TSS_RC_RSA_SIGNATURE;
}
}
+#else
+ EVP_PKEY_CTX *ctx = NULL;
+ const EVP_MD *md;
+
+ if (rc == 0) {
+ ctx = EVP_PKEY_CTX_new(rsaKey, NULL); /* freed @1 */
+ if (ctx == NULL) {
+ printf("signRSAFromRSA: Error in EVP_PKEY_CTX_new()\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ if (rc == 0) {
+ irc = EVP_PKEY_sign_init(ctx);
+ if (irc != 1) {
+ printf("signRSAFromRSA: Error in EVP_PKEY_sign_init()\n");
+ rc = TSS_RC_RSA_SIGNATURE;
+ }
+ }
+ if (rc == 0) {
+ rc = TSS_Hash_GetMd(&md, hashAlg);
+ }
+ if (rc == 0) {
+ irc = EVP_PKEY_CTX_set_signature_md(ctx, md);
+ if (irc <= 0) {
+ printf("signRSAFromRSA: Error in EVP_PKEY_CTX_set_signature_md()\n");
+ rc = TSS_RC_RSA_SIGNATURE;
+ }
+ }
+ if (rc == 0) {
+ irc = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING);
+ if (irc <= 0) {
+ printf("signRSAFromRSA: Error in EVP_PKEY_CTX_set_rsa_padding()\n");
+ rc = TSS_RC_RSA_SIGNATURE;
+ }
+ }
+ if (rc == 0) {
+ size_t siglen = signatureSize;
+ irc = EVP_PKEY_sign(ctx,
+ signature, &siglen,
+ digest, (unsigned int)digestLength);
+ *signatureLength = siglen;
+ if (irc != 1) {
+ printf("signRSAFromRSA: Error in EVP_PKEY_sign()\n");
+ rc = TSS_RC_RSA_SIGNATURE;
+ }
+ }
+ EVP_PKEY_CTX_free(ctx); /* @1 */
+#endif
return rc;
}
@@ -1910,6 +2119,9 @@ TPM_RC signRSAFromRSA(uint8_t *signature, size_t *signatureLength,
using the RSA public key in the OpenSSL RSA format.
Supports RSASSA and RSAPSS schemes.
+
+ For Openssl < 3, rsaKey is an RSA structure.
+ For Openssl 3, rsaKey is an EVP_PKEY,
*/
TPM_RC verifyRSASignatureFromRSA(unsigned char *message,
@@ -1920,9 +2132,10 @@ TPM_RC verifyRSASignatureFromRSA(unsigned char *message,
{
TPM_RC rc = 0;
int irc;
+ const EVP_MD *md = NULL;
+#if OPENSSL_VERSION_NUMBER < 0x30000000
int nid = 0; /* initialized these two to suppress false gcc -O3
warnings */
- const EVP_MD *md = NULL;
/* map from hash algorithm to openssl nid */
if (rc == 0) {
switch (halg) {
@@ -1989,8 +2202,68 @@ TPM_RC verifyRSASignatureFromRSA(unsigned char *message,
else {
printf("verifyRSASignatureFromRSA: Bad signature scheme %04x\n",
tSignature->sigAlg);
+ rc = TSS_RC_RSA_SIGNATURE;
}
- return rc;
+#else
+ EVP_PKEY_CTX *ctx = NULL;
+
+ if (rc == 0) {
+ ctx = EVP_PKEY_CTX_new(rsaPubKey, NULL); /* freed @1 */
+ if (ctx == NULL) {
+ printf("verifyRSAFSignatureromRSA: Error in EVP_PKEY_CTX_new()\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ if (rc == 0) {
+ irc = EVP_PKEY_verify_init(ctx);
+ if (irc != 1) {
+ printf("verifyRSASignatureFromRSA: Error in EVP_PKEY_verify_init()\n");
+ rc = TSS_RC_RSA_SIGNATURE;
+ }
+ }
+ if (rc == 0) {
+ rc = TSS_Hash_GetMd(&md, halg);
+ }
+ if (rc == 0) {
+ irc = EVP_PKEY_CTX_set_signature_md(ctx, md);
+ if (irc <= 0) {
+ printf("verifyRSASignatureFromRSA: Error in EVP_PKEY_CTX_set_signature_md()\n");
+ rc = TSS_RC_RSA_SIGNATURE;
+ }
+ }
+ /* verify the signature */
+ if (rc == 0) {
+ if (tSignature->sigAlg == TPM_ALG_RSASSA) {
+ irc = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING);
+ }
+ else if (tSignature->sigAlg == TPM_ALG_RSAPSS) {
+ irc = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING);
+ }
+ else {
+ rc = TSS_RC_RSA_SIGNATURE;
+ printf("verifyRSASignatureFromRSA: Bad signature scheme %04x\n",
+ tSignature->sigAlg);
+ }
+ }
+ if (rc == 0) {
+ if (irc <= 0) {
+ printf("verifyRSASignatureFromRSA: Error in EVP_PKEY_CTX_set_rsa_padding()\n");
+ rc = TSS_RC_RSA_SIGNATURE;
+ }
+ }
+ if (rc == 0) {
+ irc = EVP_PKEY_verify(ctx,
+ tSignature->signature.rsapss.sig.t.buffer,
+ tSignature->signature.rsapss.sig.t.size,
+ message, messageSize);
+ if (irc != 1) {
+ printf("verifyRSASignatureFromRSA: Error in EVP_PKEY_verify()\n");
+ rc = TSS_RC_RSA_SIGNATURE;
+ }
+ }
+ EVP_PKEY_CTX_free(ctx); /* @1 */
+#endif
+ return rc;
}
#endif /* TPM_TSS_NORSA */
diff --git a/utils/cryptoutils.h b/utils/cryptoutils.h
index 03452de..6809dea 100644
--- a/utils/cryptoutils.h
+++ b/utils/cryptoutils.h
@@ -248,9 +248,10 @@ extern "C" {
TPM_RC convertEvpPkeyToRsakey(RSA **rsaKey,
EVP_PKEY *evpPkey);
- TPM_RC convertRsaKeyToPrivateKeyBin(int *privateKeyBytes,
+#if OPENSSL_VERSION_NUMBER < 0x30000000
+ TPM_RC convertRsaKeyToPrivateKeyBin(int *privateKeyBytes,
uint8_t **privateKeyBin,
- const RSA *rsaKey);
+ const RSA *rsaKey);
TPM_RC convertRsaKeyToPrivate(TPM2B_PRIVATE *objectPrivate,
TPM2B_SENSITIVE *objectSensitive,
RSA *rsaKey,
@@ -260,7 +261,22 @@ extern "C" {
const BIGNUM **d,
const BIGNUM **p,
const BIGNUM **q,
- const RSA *rsaKey);
+ const RSA *rsaKey);
+#else
+ TPM_RC convertRsaKeyToPrivateKeyBin(int *privateKeyBytes,
+ uint8_t **privateKeyBin,
+ const EVP_PKEY *rsaKey);
+ TPM_RC convertRsaKeyToPrivate(TPM2B_PRIVATE *objectPrivate,
+ TPM2B_SENSITIVE *objectSensitive,
+ EVP_PKEY *rsaKey,
+ const char *password);
+ TPM_RC getRsaKeyParts(const BIGNUM **n,
+ const BIGNUM **e,
+ const BIGNUM **d,
+ const BIGNUM **p,
+ const BIGNUM **q,
+ const EVP_PKEY *rsaKey);
+#endif
int getRsaPubkeyAlgorithm(EVP_PKEY *pkey);
TPM_RC convertRsaPublicToEvpPubKey(EVP_PKEY **evpPubkey,
const TPM2B_PUBLIC_KEY_RSA *tpm2bRsa);
diff --git a/utils/efilib.c b/utils/efilib.c
index ab8177b..afed9dd 100644
--- a/utils/efilib.c
+++ b/utils/efilib.c
@@ -64,6 +64,7 @@
#include <ibmtss/tsserror.h>
#include <ibmtss/tssprint.h>
#include <ibmtss/Unmarshal_fp.h>
+#include <ibmtss/tsscrypto.h>
#include "eventlib.h"
#include "efilib.h"
@@ -4805,7 +4806,13 @@ static void TSS_EfiEventTag_Trace(TSST_EFIData *efiData)
uint32_t count;
TSS_UEFI_TAGGED_EVENT *taggedEventList = &efiData->efiData.taggedEventList;
#ifndef TPM_TSS_MBEDTLS
- RSA *rsaKey = NULL;
+#ifndef TPM_TSS_NORSA
+#if OPENSSL_VERSION_NUMBER < 0x30000000
+ RSA *rsaKey = NULL;
+#else
+ EVP_PKEY *rsaKey = NULL;
+#endif
+#endif /* TPM_TSS_NORSA */
#endif /* TPM_TSS_MBEDTLS */
printf(" tagged events %u\n", taggedEventList->count);
@@ -4815,17 +4822,25 @@ static void TSS_EfiEventTag_Trace(TSST_EFIData *efiData)
printf(" taggedEventID %08x\n", taggedEvent->taggedEventID);
/* https://github.com/mattifestation/TCGLogTools/blob/master/TCGLogTools.psm1 */
/* by observation 0x00060002 appears to be a DER encoded public key */
-#ifndef TPM_TSS_MBEDTLS
+#if ! defined TPM_TSS_MBEDTLS && ! defined TPM_TSS_NORSA
if (taggedEvent->taggedEventID == 0x00060002) {
const unsigned char *tmpData = NULL;
/* tmp pointer because d2i moves the pointer */
tmpData = taggedEvent->taggedEventData;
- rsaKey = d2i_RSA_PUBKEY(NULL, &tmpData , taggedEvent->taggedEventDataSize); /* freed @2 */
+#if OPENSSL_VERSION_NUMBER < 0x30000000
+ rsaKey = d2i_RSA_PUBKEY(NULL, &tmpData ,taggedEvent->taggedEventDataSize); /* freed @2 */
+#else
+ rsaKey = d2i_PUBKEY(NULL, &tmpData, (long)taggedEvent->taggedEventDataSize);
+#endif /* OPENSSL_VERSION_NUMBER */
if (rsaKey != NULL) { /* success */
+#if OPENSSL_VERSION_NUMBER < 0x30000000
RSA_print_fp(stdout, rsaKey, 4);
+#else
+ EVP_PKEY_print_public_fp(stdout, rsaKey, 4, NULL);
+#endif /* OPENSSL_VERSION_NUMBER */
}
if (rsaKey != NULL) {
- RSA_free(rsaKey);
+ TSS_RsaFree(rsaKey); /* @2 */
}
}
/* if it's not 0x00060002 or if the d2i fails */
@@ -4834,10 +4849,10 @@ static void TSS_EfiEventTag_Trace(TSST_EFIData *efiData)
TSS_PrintAll(" taggedEvent",
taggedEvent->taggedEventData, taggedEvent->taggedEventDataSize);
}
-#else
+#else /* TPM_TSS_MBEDTLS or TPM_TSS_NORSA */
TSS_PrintAll(" taggedEvent",
taggedEvent->taggedEventData, taggedEvent->taggedEventDataSize);
-#endif /* TPM_TSS_MBEDTLS */
+#endif /* TPM_TSS_MBEDTLS TPM_TSS_NORSA */
}
return;
}
diff --git a/utils/ekutils.c b/utils/ekutils.c
index a0a2734..cb7f938 100644
--- a/utils/ekutils.c
+++ b/utils/ekutils.c
@@ -567,9 +567,12 @@ TPM_RC getIndexX509Certificate(TSS_CONTEXT *tssContext,
certificate stored in a file.
Returns both the OpenSSL X509 certificate token and RSA public key token.
+
+ For Openssl < 3, rsaKey is an RSA structure.
+ For Openssl 3, rsaKey is an EVP_PKEY,
*/
-uint32_t getPubkeyFromDerCertFile(RSA **rsaPkey,
+uint32_t getPubkeyFromDerCertFile(void **rsaPkey, /* freed by caller */
X509 **x509,
const char *derCertificateFileName)
{
@@ -594,7 +597,7 @@ uint32_t getPubkeyFromDerCertFile(RSA **rsaPkey,
}
/* extract the OpenSSL format public key from the X509 token */
if (rc == 0) {
- rc = getPubKeyFromX509Cert(rsaPkey, *x509);
+ rc = getPubKeyFromX509Cert(rsaPkey, *x509); /* freed by caller */
}
/* for debug, print the X509 certificate */
if (rc == 0) {
@@ -612,9 +615,13 @@ uint32_t getPubkeyFromDerCertFile(RSA **rsaPkey,
#ifndef TPM_TSS_NORSA
/* getPubKeyFromX509Cert() gets an OpenSSL RSA public key token from an OpenSSL X509 certificate
- token. */
+ token.
+
+ For Openssl < 3, rsaKey is an RSA structure.
+ For Openssl 3, rsaKey is an EVP_PKEY,
+*/
-uint32_t getPubKeyFromX509Cert(RSA **rsaPkey,
+uint32_t getPubKeyFromX509Cert(void **rsaPkey,
X509 *x509)
{
uint32_t rc = 0;
@@ -623,20 +630,24 @@ uint32_t getPubKeyFromX509Cert(RSA **rsaPkey,
if (rc == 0) {
evpPkey = X509_get_pubkey(x509); /* freed @1 */
if (evpPkey == NULL) {
- printf("getPubKeyFromX509Cert: X509_get_pubkey failed\n");
+ printf("getPubKeyFromX509Cert: X509_get_pubkey failed\n");
rc = TSS_RC_X509_ERROR;
}
}
+#if OPENSSL_VERSION_NUMBER < 0x30000000
if (rc == 0) {
*rsaPkey = EVP_PKEY_get1_RSA(evpPkey);
if (*rsaPkey == NULL) {
- printf("getPubKeyFromX509Cert: EVP_PKEY_get1_RSA failed\n");
+ printf("getPubKeyFromX509Cert: EVP_PKEY_get1_RSA failed\n");
rc = TSS_RC_X509_ERROR;
}
}
if (evpPkey != NULL) {
EVP_PKEY_free(evpPkey); /* @1 */
}
+#else
+ *rsaPkey = evpPkey;
+#endif
return rc;
}
#endif /* TPM_TSS_NORSA */
@@ -1105,8 +1116,8 @@ TPM_RC convertX509ToEc(EC_KEY **ecKey, /* freed by caller */
If print is true, prints the EK certificate
- The return is void because the structure is opaque to the caller. This accomodates other crypto
- libraries.
+ The ekCertificate return is void because the structure is opaque to the caller. This
+ accommodates other crypto libraries.
ekCertificate is an X509 structure.
*/
@@ -1158,7 +1169,11 @@ TPM_RC convertCertificatePubKey(uint8_t **modulusBin, /* freed by caller */
case EK_CERT_RSA_3072_INDEX_H6:
case EK_CERT_RSA_4096_INDEX_H7:
{
+#if OPENSSL_VERSION_NUMBER < 0x30000000
RSA *rsaKey = NULL;
+#else
+ EVP_PKEY *rsaKey = NULL;
+#endif
/* check that the public key algorithm matches the ekCertIndex algorithm */
if (rc == 0) {
if (pkeyType != EVP_PKEY_RSA) {
@@ -1169,12 +1184,16 @@ TPM_RC convertCertificatePubKey(uint8_t **modulusBin, /* freed by caller */
}
/* convert the public key to OpenSSL structure */
if (rc == 0) {
+#if OPENSSL_VERSION_NUMBER < 0x30000000
rsaKey = EVP_PKEY_get1_RSA(pkey); /* freed @3 */
if (rsaKey == NULL) {
printf("convertCertificatePubKey: Could not extract RSA public key "
"from X509 certificate\n");
rc = TPM_RC_INTEGRITY;
}
+#else /* use the EVP_PKEY directly */
+ rsaKey = pkey;
+#endif
}
if (rc == 0) {
rc = convertRsaKeyToPublicKeyBin(modulusBytes,
@@ -1185,7 +1204,9 @@ TPM_RC convertCertificatePubKey(uint8_t **modulusBin, /* freed by caller */
if (print) TSS_PrintAll("Certificate public key:",
*modulusBin, *modulusBytes);
}
+#if OPENSSL_VERSION_NUMBER < 0x30000000
RSA_free(rsaKey); /* @3 */
+#endif
}
break;
#endif /* TPM_TSS_NORSA */
@@ -1254,7 +1275,11 @@ TPM_RC convertCertificatePubKey12(uint8_t **modulusBin, /* freed by caller */
const unsigned char *pk = NULL; /* do not free */
int ppklen;
X509_ALGOR *palg = NULL; /* algorithm identifier for public key */
+#if OPENSSL_VERSION_NUMBER < 0x30000000
RSA *rsaKey = NULL;
+#else
+ EVP_PKEY *rsaKey = NULL;
+#endif
/* get internal pointer to the public key in the certificate */
if (rc == 0) {
@@ -1278,7 +1303,12 @@ TPM_RC convertCertificatePubKey12(uint8_t **modulusBin, /* freed by caller */
}
if (rc == 0) {
const unsigned char *tmppk = pk; /* because d2i moves the pointer */
+#if OPENSSL_VERSION_NUMBER < 0x30000000
rsaKey = d2i_RSAPublicKey(NULL, &tmppk, ppklen); /* freed @1 */
+#else
+ rsaKey = d2i_PublicKey(EVP_PKEY_RSA, NULL,
+ &tmppk, (long)ppklen);
+#endif
if (rsaKey == NULL) {
printf("convertCertificatePubKey12: Could not convert to RSA structure\n");
rc = TPM_RC_INTEGRITY;
@@ -1290,9 +1320,7 @@ TPM_RC convertCertificatePubKey12(uint8_t **modulusBin, /* freed by caller */
rsaKey);
TSS_PrintAll("convertCertificatePubKey12", *modulusBin, *modulusBytes);
}
- if (rsaKey != NULL) {
- RSA_free(rsaKey); /* @1 */
- }
+ TSS_RsaFree(rsaKey); /* @1 */
return rc;
}
diff --git a/utils/ekutils.h b/utils/ekutils.h
index f37b7d2..18b0e48 100644
--- a/utils/ekutils.h
+++ b/utils/ekutils.h
@@ -218,10 +218,10 @@ extern "C" {
#ifndef TPM_TSS_NO_OPENSSL
- uint32_t getPubkeyFromDerCertFile(RSA **rsaPkey,
+ uint32_t getPubkeyFromDerCertFile(void **rsaPkey,
X509 **x509,
const char *derCertificateFileName);
- uint32_t getPubKeyFromX509Cert(RSA **rsaPkey,
+ uint32_t getPubKeyFromX509Cert(void **rsaPkey,
X509 *x509);
TPM_RC getCaStore(X509_STORE **caStore,
X509 *caCert[],
diff --git a/utils/ibmtss/tsscrypto.h b/utils/ibmtss/tsscrypto.h
index 5bf5591..30d2ef1 100644
--- a/utils/ibmtss/tsscrypto.h
+++ b/utils/ibmtss/tsscrypto.h
@@ -4,7 +4,7 @@
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* */
-/* (c) Copyright IBM Corporation 2015 - 2019. */
+/* (c) Copyright IBM Corporation 2015 - 2021. */
/* */
/* All rights reserved. */
/* */
@@ -107,6 +107,7 @@ extern "C" {
LIB_EXPORT
TPM_RC TSS_RsaNew(void **rsaKey);
+ /* deprecated */
LIB_EXPORT
TPM_RC TSS_RSAGeneratePublicToken(RSA **rsa_pub_key, /* freed by caller */
const unsigned char *narr, /* public modulus */
diff --git a/utils/sign.c b/utils/sign.c
index 0635366..ba2be27 100644
--- a/utils/sign.c
+++ b/utils/sign.c
@@ -4,7 +4,7 @@
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* */
-/* (c) Copyright IBM Corporation 2015 - 2019. */
+/* (c) Copyright IBM Corporation 2015 - 2021. */
/* */
/* All rights reserved. */
/* */
@@ -426,6 +426,8 @@ int main(int argc, char *argv[])
/* construct the OpenSSL RSA public key token */
if (rc == 0) {
unsigned char earr[3] = {0x01, 0x00, 0x01};
+ /* For Openssl < 3, rsaKey is an RSA structure. */
+ /* For Openssl 3, rsaKey is an EVP_PKEY. */
rc = TSS_RSAGeneratePublicTokenI
(&rsaPubKey, /* freed @2 */
public.publicArea.unique.rsa.t.buffer, /* public modulus */
diff --git a/utils/tsscrypto.c b/utils/tsscrypto.c
index 1974563..2efddfc 100644
--- a/utils/tsscrypto.c
+++ b/utils/tsscrypto.c
@@ -5,7 +5,7 @@
/* IBM Thomas J. Watson Research Center */
/* ECC Salt functions written by Bill Martin */
/* */
-/* (c) Copyright IBM Corporation 2015 - 2019. */
+/* (c) Copyright IBM Corporation 2015 - 2021. */
/* */
/* All rights reserved. */
/* */
@@ -37,7 +37,7 @@
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/********************************************************************************/
-/* Interface to OpenSSL version 1.0 or 1.1 crypto library */
+/* Interface to OpenSSL version 1.0.2, 1.1.1, 3.0.0 crypto library */
#include <string.h>
#include <stdio.h>
@@ -59,6 +59,10 @@
#include <openssl/rand.h>
#include <openssl/engine.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000
+#include <openssl/param_build.h>
+#endif
+
#include <ibmtss/tssresponsecode.h>
#include <ibmtss/tssutils.h>
#include <ibmtss/tssprint.h>
@@ -67,6 +71,9 @@
#include <ibmtss/tsscryptoh.h>
#include <ibmtss/tsscrypto.h>
+TPM_RC TSS_Hash_GetMd(const EVP_MD **md,
+ TPMI_ALG_HASH hashAlg);
+
extern int tssVverbose;
extern int tssVerbose;
@@ -80,8 +87,6 @@ extern int tssVerbose;
/* local prototypes */
static TPM_RC TSS_Hash_GetOsslString(const char **str, TPMI_ALG_HASH hashAlg);
-static TPM_RC TSS_Hash_GetMd(const EVP_MD **md,
- TPMI_ALG_HASH hashAlg);
#ifndef TPM_TSS_NOECC
@@ -164,8 +169,8 @@ static TPM_RC TSS_Hash_GetOsslString(const char **str, TPMI_ALG_HASH hashAlg)
return rc;
}
-static TPM_RC TSS_Hash_GetMd(const EVP_MD **md,
- TPMI_ALG_HASH hashAlg)
+TPM_RC TSS_Hash_GetMd(const EVP_MD **md,
+ TPMI_ALG_HASH hashAlg)
{
TPM_RC rc = 0;
const char *str = NULL;
@@ -352,7 +357,8 @@ TPM_RC TSS_RandBytes(unsigned char *buffer, uint32_t size)
This abstracts the crypto library specific allocation.
- For Openssl, rsaKey is an RSA structure.
+ For Openssl < 3, rsaKey is an RSA structure.
+ For Openssl 3, rsaKey is an EVP_PKEY,
*/
TPM_RC TSS_RsaNew(void **rsaKey)
@@ -369,6 +375,7 @@ TPM_RC TSS_RsaNew(void **rsaKey)
}
}
/* construct the OpenSSL private key object */
+#if OPENSSL_VERSION_NUMBER < 0x30000000
if (rc == 0) {
*rsaKey = RSA_new(); /* freed by caller */
if (*rsaKey == NULL) {
@@ -376,20 +383,36 @@ TPM_RC TSS_RsaNew(void **rsaKey)
rc = TSS_RC_RSA_KEY_CONVERT;
}
}
+#else
+ if (rc == 0) {
+ *rsaKey = EVP_PKEY_new();
+ if (*rsaKey == NULL) {
+ if (tssVerbose) printf("TSS_RsaNew: Error in EVP_PKEY_new()\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ if (rc == 0) {
+ }
+#endif
return rc;
}
/* TSS_RsaFree() frees an openssl RSA key token.
This abstracts the crypto library specific free.
-
- For Openssl, rsaKey is an RSA structure.
+
+ For Openssl < 3, rsaKey is an RSA structure.
+ For Openssl 3, rsaKey is an EVP_PKEY,
*/
void TSS_RsaFree(void *rsaKey)
{
if (rsaKey != NULL) {
+#if OPENSSL_VERSION_NUMBER < 0x30000000
RSA_free(rsaKey);
+#else
+ EVP_PKEY_free(rsaKey);
+#endif
}
return;
}
@@ -418,42 +441,122 @@ TPM_RC TSS_RSAGeneratePublicToken(RSA **rsa_pub_key, /* freed by caller */
/* TSS_RSAGeneratePublicTokenI() generates an RSA key token from n and e
Free rsa_pub_key using TSS_RsaFree();
+
+ For Openssl < 3, rsaKey is an RSA structure.
+ For Openssl 3, rsaKey is an EVP_PKEY.
*/
TPM_RC TSS_RSAGeneratePublicTokenI(void **rsa_pub_key, /* freed by caller */
- const unsigned char *narr, /* public modulus */
+ const unsigned char *narr, /* public modulus */
uint32_t nbytes,
- const unsigned char *earr, /* public exponent */
+ const unsigned char *earr, /* public exponent */
uint32_t ebytes)
{
TPM_RC rc = 0;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000
+ int irc;
+#endif
BIGNUM * n = NULL;
BIGNUM * e = NULL;
+#if OPENSSL_VERSION_NUMBER < 0x30000000
RSA ** rsaPubKey = (RSA **)rsa_pub_key; /* openssl specific structure */
+#else
+ EVP_PKEY_CTX *ctx = NULL;
+ OSSL_PARAM_BLD *param_bld = NULL;
+ OSSL_PARAM *params = NULL;
+#endif
/* construct the OpenSSL private key object */
+#if OPENSSL_VERSION_NUMBER < 0x30000000
if (rc == 0) {
- rc = TSS_RsaNew(rsa_pub_key);
- }
- if (rc == 0) {
- rc = TSS_bin2bn(&n, narr, nbytes); /* freed by caller */
+ rc = TSS_RsaNew(rsa_pub_key); /* freed by caller */
}
+#endif
if (rc == 0) {
- rc = TSS_bin2bn(&e, earr, ebytes); /* freed by caller */
- }
+ rc = TSS_bin2bn(&n, narr, nbytes); /* freed by caller, < 3.0.0 */
+ } /* freed @4, 3.0.0 */
if (rc == 0) {
+ rc = TSS_bin2bn(&e, earr, ebytes); /* freed by caller, < 3.0.0 */
+ } /* freed @5, 3.0.0 */
#if OPENSSL_VERSION_NUMBER < 0x10100000
+ if (rc == 0) {
(*rsaPubKey)->n = n;
(*rsaPubKey)->e = e;
(*rsaPubKey)->d = NULL;
-#else
- int irc = RSA_set0_key(*rsaPubKey, n, e, NULL);
+ }
+#elif OPENSSL_VERSION_NUMBER < 0x30000000
+ if (rc == 0) {
+ irc = RSA_set0_key(*rsaPubKey, n, e, NULL);
if (irc != 1) {
if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: Error in RSA_set0_key()\n");
rc = TSS_RC_RSA_KEY_CONVERT;
}
-#endif
}
+#else
+ if (rc == 0) {
+ param_bld = OSSL_PARAM_BLD_new(); /* freed @2 */
+ if (param_bld == NULL) {
+ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: Error in OSSL_PARAM_BLD_new()\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ if (rc == 0) {
+ irc = OSSL_PARAM_BLD_push_BN(param_bld, "n", n);
+ if (irc != 1) {
+ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: "
+ "Error in OSSL_PARAM_BLD_push_BN()\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ if (rc == 0) {
+ irc = OSSL_PARAM_BLD_push_BN(param_bld, "e", e);
+ if (irc != 1) {
+ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: "
+ "Error in OSSL_PARAM_BLD_push_BN()\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ if (rc == 0) {
+ params = OSSL_PARAM_BLD_to_param(param_bld); /* freed @3 */
+ if (params == NULL) {
+ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: "
+ "Error in OSSL_PARAM_BLD_to_param()\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ if (rc == 0) {
+ ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); /* freed @1 */
+ if (ctx == NULL) {
+ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: "
+ "Error in EVP_PKEY_CTX_new_from_name()\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ if (rc == 0) {
+ irc = EVP_PKEY_fromdata_init(ctx);
+ if (irc != 1) {
+ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: "
+ "Error in EVP_PKEY_fromdata_init()\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ if (rc == 0) {
+ irc = EVP_PKEY_fromdata(ctx, (EVP_PKEY **)rsa_pub_key, /* freed by caller */
+ EVP_PKEY_PUBLIC_KEY, params);
+ if (irc != 1) {
+ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: "
+ "Error in OSSL_PARAM_BLD_push_BN()\n");
+ rc = TSS_RC_RSA_KEY_CONVERT;
+ }
+ }
+ OSSL_PARAM_free(params); /* @3 */
+ OSSL_PARAM_BLD_free(param_bld); /* @2 */
+ EVP_PKEY_CTX_free(ctx); /* @1 */
+ /* for openssl < 3.0.0, n and e are part of the RSA structure, freed with it. For 3.0.0 and up,
+ they're copied to the EVP_PKEY, so the parts are freed here. */
+ BN_free(n); /* @4 */
+ BN_free(e); /* @5 */
+#endif
return rc;
}
@@ -475,7 +578,12 @@ TPM_RC TSS_RSAPublicEncrypt(unsigned char *encrypt_data, /* encrypted data */
{
TPM_RC rc = 0;
int irc;
+#if OPENSSL_VERSION_NUMBER < 0x30000000
RSA *rsa_pub_key = NULL;
+#else
+ EVP_PKEY *rsa_pub_key = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+#endif
unsigned char *padded_data = NULL;
if (tssVverbose) printf(" TSS_RSAPublicEncrypt: Input data size %lu\n",
@@ -486,12 +594,16 @@ TPM_RC TSS_RSAPublicEncrypt(unsigned char *encrypt_data, /* encrypted data */
}
/* construct the OpenSSL public key object */
if (rc == 0) {
- rc = TSS_RSAGeneratePublicTokenI((void **)&rsa_pub_key, /* freed @1 */
+ /* For Openssl < 3, rsaKey is an RSA structure. */
+ /* For Openssl 3, rsaKey is an EVP_PKEY, */
+ rc = TSS_RSAGeneratePublicTokenI((void **)&rsa_pub_key, /* freed @3 */
narr, /* public modulus */
nbytes,
earr, /* public exponent */
ebytes);
}
+ /* Must pad first and then encrypt because the encrypt call cannot specify an encoding
+ parameter */
if (rc == 0) {
padded_data[0] = 0x00;
rc = TSS_RSA_padding_add_PKCS1_OAEP(padded_data, /* to */
@@ -508,25 +620,61 @@ TPM_RC TSS_RSAPublicEncrypt(unsigned char *encrypt_data, /* encrypted data */
(unsigned long)encrypt_data_size);
if (tssVverbose) TSS_PrintAll(" TPM_RSAPublicEncrypt: Padded data", padded_data,
(uint32_t)encrypt_data_size);
- /* encrypt with public key. Must pad first and then encrypt because the encrypt
- call cannot specify an encoding parameter */
+ }
+#if OPENSSL_VERSION_NUMBER < 0x30000000
+ if (rc == 0) {
+ /* encrypt with public key. */
/* returns the size of the encrypted data. On error, -1 is returned */
irc = RSA_public_encrypt((int)encrypt_data_size, /* from length */
padded_data, /* from - the clear text data */
encrypt_data, /* the padded and encrypted data */
- rsa_pub_key, /* key */
+ rsa_pub_key, /* RSA key structure */
RSA_NO_PADDING); /* padding */
if (irc < 0) {
if (tssVerbose) printf("TSS_RSAPublicEncrypt: Error in RSA_public_encrypt()\n");
rc = TSS_RC_RSA_ENCRYPT;
}
}
+#else
+ /* create EVP_PKEY_CTX for the encrypt */
+ if (rc == 0) {
+ ctx = EVP_PKEY_CTX_new(rsa_pub_key, NULL); /* freed @1 */
+ if (ctx == NULL) {
+ printf("TSS_RSAPublicEncrypt: Error in EVP_PKEY_CTX_new()\n");
+ rc = TSS_RC_RSA_ENCRYPT;
+ }
+ }
+ if (rc == 0) {
+ irc = EVP_PKEY_encrypt_init(ctx);
+ if (irc != 1) {
+ printf("TSS_RSAPublicEncrypt: Error in EVP_PKEY_encrypt_init()\n");
+ rc = TSS_RC_RSA_ENCRYPT;
+ }
+ }
+ if (rc == 0) {
+ irc = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING);
+ if (irc <= 0) {
+ if (tssVerbose) printf("TSS_RSAPublicEncrypt: Error in EVP_PKEY_CTX_set_rsa_padding\n");
+ rc = TSS_RC_RSA_ENCRYPT;
+ }
+ }
+ if (rc == 0) {
+ size_t outlen = encrypt_data_size;
+ irc = EVP_PKEY_encrypt(ctx,
+ encrypt_data, &outlen,
+ padded_data, encrypt_data_size);
+ }
+#endif
if (rc == 0) {
if (tssVverbose) printf(" TSS_RSAPublicEncrypt: RSA_public_encrypt() success\n");
}
- TSS_RsaFree(rsa_pub_key); /* @1 */
- free(padded_data); /* @2 */
- return rc;
+#if OPENSSL_VERSION_NUMBER < 0x30000000
+#else
+ EVP_PKEY_CTX_free(ctx); /* @1 */
+#endif
+ TSS_RsaFree(rsa_pub_key); /* @3 */
+ free(padded_data); /* @2 */
+ return rc;
}
#endif /* TPM_TSS_NORSA */
--
2.34.1