1377 lines
43 KiB
Diff
1377 lines
43 KiB
Diff
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
|
|
|