Added PKCS7 ECC support to example. Added wrapper function to export TPM public key as DER/ASN.1 or PEM. Fix for crypto callback ECC sign to handle getting keySz for unknown cases (like PKCS7 without privateKey set).

pull/322/head
David Garske 2024-01-17 14:08:14 -08:00
parent e54734a3ab
commit 0aa01f4f5a
11 changed files with 375 additions and 225 deletions

View File

@ -110,10 +110,14 @@ The script creates the following X.509 files (also in .pem format):
Example signs and verifies data with PKCS #7 using a TPM based key. Example signs and verifies data with PKCS #7 using a TPM based key.
* Must first run: ```sh
1. `./examples/csr/csr` ./examples/keygen/keygen rsa_test_blob.raw -rsa -t
2. `./certs/certreq.sh` ./examples/keygen/keygen ecc_test_blob.raw -ecc -t
3. `./examples/pkcs7/pkcs7` ./examples/csr/csr
./certs/certreq.sh
./examples/pkcs7/pkcs7
./examples/pkcs7/pkcs7 -ecc
```
The result is displayed to stdout on the console. The result is displayed to stdout on the console.

View File

@ -186,17 +186,18 @@ int TPM2_CSR_ExampleArgs(void* userCtx, int argc, char *argv[])
rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx, rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx,
&tpmDevId); &tpmDevId);
if (rc == 0) {
/* See if primary storage key already exists */
rc = getPrimaryStoragekey(&dev, &storageKey, TPM_ALG_RSA);
}
#ifndef NO_RSA #ifndef NO_RSA
if (rc == 0) { if (rc == 0) {
tpmCtx.rsaKey = &key; /* Setup the wolf crypto device callback */ tpmCtx.rsaKey = &key; /* Setup the wolf crypto device callback */
/* open the RSA SRK */
rc = getPrimaryStoragekey(&dev, &storageKey, TPM_ALG_RSA);
if (rc == 0) {
rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate,
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA); TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA);
}
if (rc == 0) { if (rc == 0) {
rc = getRSAkey(&dev, &storageKey, &key, NULL, tpmDevId, rc = getRSAkey(&dev, &storageKey, &key, NULL, tpmDevId,
(byte*)gKeyAuth, sizeof(gKeyAuth)-1, &publicTemplate); (byte*)gKeyAuth, sizeof(gKeyAuth)-1, &publicTemplate);
@ -207,6 +208,7 @@ int TPM2_CSR_ExampleArgs(void* userCtx, int argc, char *argv[])
makeSelfSignedCert, tpmDevId, CTC_SHA256wRSA); makeSelfSignedCert, tpmDevId, CTC_SHA256wRSA);
} }
wolfTPM2_UnloadHandle(&dev, &key.handle); wolfTPM2_UnloadHandle(&dev, &key.handle);
wolfTPM2_UnloadHandle(&dev, &storageKey.handle);
} }
#endif /* !NO_RSA */ #endif /* !NO_RSA */
@ -214,18 +216,21 @@ int TPM2_CSR_ExampleArgs(void* userCtx, int argc, char *argv[])
if (rc == 0) { if (rc == 0) {
int sigType = CTC_SHA256wECDSA; int sigType = CTC_SHA256wECDSA;
TPM_ECC_CURVE curve = TPM_ECC_NIST_P256; TPM_ECC_CURVE curve = TPM_ECC_NIST_P256;
tpmCtx.eccKey = &key;
#if defined(NO_ECC256) && defined(HAVE_ECC384) && ECC_MIN_KEY_SZ <= 384 #if defined(NO_ECC256) && defined(HAVE_ECC384) && ECC_MIN_KEY_SZ <= 384
/* make sure we use a curve that is enabled */ /* make sure we use a curve that is enabled */
sigType = CTC_SHA384wECDSA; sigType = CTC_SHA384wECDSA;
curve = TPM_ECC_NIST_P384; curve = TPM_ECC_NIST_P384;
#endif #endif
tpmCtx.eccKey = &key;
/* open the ECC SRK */
rc = getPrimaryStoragekey(&dev, &storageKey, TPM_ALG_ECC);
if (rc == 0) {
rc = wolfTPM2_GetKeyTemplate_ECC(&publicTemplate, rc = wolfTPM2_GetKeyTemplate_ECC(&publicTemplate,
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
TPMA_OBJECT_sign | TPMA_OBJECT_noDA, TPMA_OBJECT_sign | TPMA_OBJECT_noDA,
curve, TPM_ALG_ECDSA); curve, TPM_ALG_ECDSA);
}
if (rc == 0) { if (rc == 0) {
rc = getECCkey(&dev, &storageKey, &key, NULL, tpmDevId, rc = getECCkey(&dev, &storageKey, &key, NULL, tpmDevId,
(byte*)gKeyAuth, sizeof(gKeyAuth)-1, &publicTemplate); (byte*)gKeyAuth, sizeof(gKeyAuth)-1, &publicTemplate);
@ -236,6 +241,7 @@ int TPM2_CSR_ExampleArgs(void* userCtx, int argc, char *argv[])
makeSelfSignedCert, tpmDevId, sigType); makeSelfSignedCert, tpmDevId, sigType);
} }
wolfTPM2_UnloadHandle(&dev, &key.handle); wolfTPM2_UnloadHandle(&dev, &key.handle);
wolfTPM2_UnloadHandle(&dev, &storageKey.handle);
} }
#endif /* HAVE_ECC */ #endif /* HAVE_ECC */
@ -243,7 +249,6 @@ int TPM2_CSR_ExampleArgs(void* userCtx, int argc, char *argv[])
printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc)); printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc));
} }
wolfTPM2_UnloadHandle(&dev, &storageKey.handle);
wolfTPM2_Cleanup(&dev); wolfTPM2_Cleanup(&dev);
return rc; return rc;

View File

@ -232,14 +232,18 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
} }
if (endorseKey) { if (endorseKey) {
/* endorsement is always RSA */
rc = wolfTPM2_CreateEK(&dev, &endorse, TPM_ALG_RSA); rc = wolfTPM2_CreateEK(&dev, &endorse, TPM_ALG_RSA);
endorse.handle.policyAuth = 1; /* EK requires Policy auth, not Password */ endorse.handle.policyAuth = 1; /* EK requires Policy auth, not Password */
pubFilename = ekPubFile; pubFilename = ekPubFile;
primary = &endorse; primary = &endorse;
} }
else { else {
/* get SRK */ /* SRK: Use RSA or ECC SRK only. Prefer ECC */
rc = getPrimaryStoragekey(&dev, &storage, TPM_ALG_RSA); TPMI_ALG_PUBLIC srkAlg = TPM_ALG_ECC;
if (alg == TPM_ALG_RSA)
srkAlg = TPM_ALG_RSA;
rc = getPrimaryStoragekey(&dev, &storage, srkAlg);
pubFilename = srkPubFile; pubFilename = srkPubFile;
primary = &storage; primary = &storage;
} }
@ -403,7 +407,8 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
pemFilename = (endorseKey) ? pemFileEk : pemFileSrk; pemFilename = (endorseKey) ? pemFileEk : pemFileSrk;
pemSz = (word32)sizeof(pem); pemSz = (word32)sizeof(pem);
rc = wolfTPM2_RsaKey_TpmToPemPub(&dev, primary, pem, &pemSz); rc = wolfTPM2_ExportPublicKeyBuffer(&dev, primary,
ENCODING_TYPE_PEM, pem, &pemSz);
if (rc == 0) { if (rc == 0) {
rc = writeBin(pemFilename, pem, pemSz); rc = writeBin(pemFilename, pem, pemSz);
} }
@ -411,8 +416,8 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
pemFilename = (bAIK) ? pemFileAk : pemFileKey; pemFilename = (bAIK) ? pemFileAk : pemFileKey;
pemSz = (word32)sizeof(pem); pemSz = (word32)sizeof(pem);
rc = wolfTPM2_RsaKey_TpmToPemPub(&dev, (WOLFTPM2_KEY*)&newKeyBlob, rc = wolfTPM2_ExportPublicKeyBuffer(&dev, (WOLFTPM2_KEY*)&newKeyBlob,
pem, &pemSz); ENCODING_TYPE_PEM, pem, &pemSz);
if (rc == 0) { if (rc == 0) {
rc = writeBin(pemFilename, pem, pemSz); rc = writeBin(pemFilename, pem, pemSz);
} }

View File

@ -116,14 +116,29 @@ int TPM2_Keyload_Example(void* userCtx, int argc, char *argv[])
goto exit; goto exit;
} }
/* Load encrypted key from the disk */
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
rc = readKeyBlob(inputFile, &newKey);
if (rc != 0) goto exit;
#else
/* TODO: Option to load hex blob */
printf("Loading blob from disk not supported. Enable wolfcrypt support.\n");
goto exit;
#endif
if (endorseKey) { if (endorseKey) {
/* endorsement is always RSA */
rc = wolfTPM2_CreateEK(&dev, &endorse, TPM_ALG_RSA); rc = wolfTPM2_CreateEK(&dev, &endorse, TPM_ALG_RSA);
if (rc != 0) goto exit; if (rc != 0) goto exit;
endorse.handle.policyAuth = 1; endorse.handle.policyAuth = 1;
primary = &endorse; primary = &endorse;
} }
else { /* SRK */ else {
rc = getPrimaryStoragekey(&dev, &storage, TPM_ALG_RSA); /* SRK: Use RSA or ECC SRK only. Prefer ECC */
TPMI_ALG_PUBLIC srkAlg = TPM_ALG_ECC;
if (newKey.pub.publicArea.type == TPM_ALG_RSA)
srkAlg = TPM_ALG_RSA;
rc = getPrimaryStoragekey(&dev, &storage, srkAlg);
if (rc != 0) goto exit; if (rc != 0) goto exit;
primary = &storage; primary = &storage;
} }
@ -153,15 +168,6 @@ int TPM2_Keyload_Example(void* userCtx, int argc, char *argv[])
if (rc != 0) goto exit; if (rc != 0) goto exit;
} }
/* Load encrypted key from the disk */
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
rc = readKeyBlob(inputFile, &newKey);
if (rc != 0) goto exit;
#else
/* TODO: Option to load hex blob */
printf("Loading blob from disk not supported. Enable wolfcrypt support.\n");
goto exit;
#endif
if (newKey.priv.size == 0) { if (newKey.priv.size == 0) {
rc = wolfTPM2_LoadPublicKey(&dev, (WOLFTPM2_KEY*)&newKey, &newKey.pub); rc = wolfTPM2_LoadPublicKey(&dev, (WOLFTPM2_KEY*)&newKey, &newKey.pub);

View File

@ -89,14 +89,14 @@ static int GetMyData(byte* buffer, word32 bufSz, word32 offset)
/* The wc_PKCS7_EncodeSignedData_ex and wc_PKCS7_VerifySignedData_ex functions /* The wc_PKCS7_EncodeSignedData_ex and wc_PKCS7_VerifySignedData_ex functions
were added in this PR https://github.com/wolfSSL/wolfssl/pull/1780. */ were added in this PR https://github.com/wolfSSL/wolfssl/pull/1780. */
static int PKCS7_SignVerifyEx(WOLFTPM2_DEV* dev, int tpmDevId, WOLFTPM2_BUFFER* der) static int PKCS7_SignVerifyEx(WOLFTPM2_DEV* dev, int tpmDevId, WOLFTPM2_BUFFER* derCert,
WOLFTPM2_BUFFER* derPubKey, int alg, enum wc_HashType hashType, const char* outFile)
{ {
int rc; int rc;
PKCS7 pkcs7; PKCS7 pkcs7;
wc_HashAlg hash; wc_HashAlg hash;
enum wc_HashType hashType = WC_HASH_TYPE_SHA256; byte hashBuf[TPM_MAX_DIGEST_SIZE];
byte hashBuf[TPM_SHA256_DIGEST_SIZE]; word32 hashSz;
word32 hashSz = wc_HashGetDigestSize(hashType);
byte outputHead[MAX_PKCS7_SIZE], outputFoot[MAX_PKCS7_SIZE]; byte outputHead[MAX_PKCS7_SIZE], outputFoot[MAX_PKCS7_SIZE];
int outputHeadSz, outputFootSz; int outputHeadSz, outputFootSz;
byte dataChunk[MY_DATA_CHUNKS]; byte dataChunk[MY_DATA_CHUNKS];
@ -107,6 +107,11 @@ static int PKCS7_SignVerifyEx(WOLFTPM2_DEV* dev, int tpmDevId, WOLFTPM2_BUFFER*
XMEMSET(&pkcs7, 0, sizeof(pkcs7)); XMEMSET(&pkcs7, 0, sizeof(pkcs7));
hashSz = wc_HashGetDigestSize(hashType);
if (hashSz <= 0) {
return hashSz;
}
/* calculate hash for content */ /* calculate hash for content */
rc = wc_HashInit(&hash, hashType); rc = wc_HashInit(&hash, hashType);
if (rc == 0) { if (rc == 0) {
@ -131,14 +136,18 @@ static int PKCS7_SignVerifyEx(WOLFTPM2_DEV* dev, int tpmDevId, WOLFTPM2_BUFFER*
/* Generate and verify PKCS#7 files containing data using TPM key */ /* Generate and verify PKCS#7 files containing data using TPM key */
rc = wc_PKCS7_Init(&pkcs7, NULL, tpmDevId); rc = wc_PKCS7_Init(&pkcs7, NULL, tpmDevId);
if (rc != 0) goto exit; if (rc != 0) goto exit;
rc = wc_PKCS7_InitWithCert(&pkcs7, der->buffer, der->size); rc = wc_PKCS7_InitWithCert(&pkcs7, derCert->buffer, derCert->size);
if (rc != 0) goto exit; if (rc != 0) goto exit;
pkcs7.content = NULL; /* not used */ pkcs7.content = NULL; /* not used */
pkcs7.contentSz = dataChunkSz; pkcs7.contentSz = dataChunkSz;
pkcs7.encryptOID = RSAk; pkcs7.encryptOID = (alg == TPM_ALG_RSA) ? RSAk : ECDSAk;
pkcs7.hashOID = SHA256h; pkcs7.hashOID = wc_HashGetOID(hashType);
pkcs7.rng = wolfTPM2_GetRng(dev); pkcs7.rng = wolfTPM2_GetRng(dev);
/* pass public key instead of private here. The PKCS7 will try a public
* key decode if using crypto callbacks */
pkcs7.privateKey = derPubKey->buffer;
pkcs7.privateKeySz = derPubKey->size;
outputHeadSz = (int)sizeof(outputHead); outputHeadSz = (int)sizeof(outputHead);
outputFootSz = (int)sizeof(outputFoot); outputFootSz = (int)sizeof(outputFoot);
@ -157,7 +166,7 @@ static int PKCS7_SignVerifyEx(WOLFTPM2_DEV* dev, int tpmDevId, WOLFTPM2_BUFFER*
TPM2_PrintBin(outputFoot, outputFootSz); TPM2_PrintBin(outputFoot, outputFootSz);
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) #if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
pemFile = XFOPEN("./examples/pkcs7/pkcs7tpmsignedex.p7s", "wb"); pemFile = XFOPEN(outFile, "wb");
if (pemFile != XBADFILE) { if (pemFile != XBADFILE) {
/* Header */ /* Header */
@ -227,7 +236,8 @@ exit:
} }
#endif /* ENABLE_PKCS7EX_EXAMPLE */ #endif /* ENABLE_PKCS7EX_EXAMPLE */
static int PKCS7_SignVerify(WOLFTPM2_DEV* dev, int tpmDevId, WOLFTPM2_BUFFER* der) static int PKCS7_SignVerify(WOLFTPM2_DEV* dev, int tpmDevId, WOLFTPM2_BUFFER* derCert,
WOLFTPM2_BUFFER* derPubKey, int alg, enum wc_HashType hashType, const char* outFile)
{ {
int rc; int rc;
PKCS7 pkcs7; PKCS7 pkcs7;
@ -243,14 +253,18 @@ static int PKCS7_SignVerify(WOLFTPM2_DEV* dev, int tpmDevId, WOLFTPM2_BUFFER* de
/* Generate and verify PKCS#7 files containing data using TPM key */ /* Generate and verify PKCS#7 files containing data using TPM key */
rc = wc_PKCS7_Init(&pkcs7, NULL, tpmDevId); rc = wc_PKCS7_Init(&pkcs7, NULL, tpmDevId);
if (rc != 0) goto exit; if (rc != 0) goto exit;
rc = wc_PKCS7_InitWithCert(&pkcs7, der->buffer, der->size); rc = wc_PKCS7_InitWithCert(&pkcs7, derCert->buffer, derCert->size);
if (rc != 0) goto exit; if (rc != 0) goto exit;
pkcs7.content = data; pkcs7.content = data;
pkcs7.contentSz = (word32)sizeof(data); pkcs7.contentSz = (word32)sizeof(data);
pkcs7.encryptOID = RSAk; pkcs7.encryptOID = (alg == TPM_ALG_RSA) ? RSAk : ECDSAk;
pkcs7.hashOID = SHA256h; pkcs7.hashOID = wc_HashGetOID(hashType);
pkcs7.rng = wolfTPM2_GetRng(dev); pkcs7.rng = wolfTPM2_GetRng(dev);
/* pass public key instead of private here. The PKCS7 will try a public
* key decode if using crypto callbacks */
pkcs7.privateKey = derPubKey->buffer;
pkcs7.privateKeySz = derPubKey->size;
rc = wc_PKCS7_EncodeSignedData(&pkcs7, output, sizeof(output)); rc = wc_PKCS7_EncodeSignedData(&pkcs7, output, sizeof(output));
if (rc <= 0) goto exit; if (rc <= 0) goto exit;
@ -261,7 +275,7 @@ static int PKCS7_SignVerify(WOLFTPM2_DEV* dev, int tpmDevId, WOLFTPM2_BUFFER* de
TPM2_PrintBin(output, outputSz); TPM2_PrintBin(output, outputSz);
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) #if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
pemFile = XFOPEN("./examples/pkcs7/pkcs7tpmsigned.p7s", "wb"); pemFile = XFOPEN(outFile, "wb");
if (pemFile != XBADFILE) { if (pemFile != XBADFILE) {
rc = (int)XFWRITE(output, 1, outputSz, pemFile); rc = (int)XFWRITE(output, 1, outputSz, pemFile);
XFCLOSE(pemFile); XFCLOSE(pemFile);
@ -297,6 +311,16 @@ exit:
return rc; return rc;
} }
static void usage(void)
{
printf("Expected usage:\n");
printf("./examples/pkcs7/pkcs7 [-ecc/-rsa] [-out=]\n");
printf("* -ecc/-rsa: Use RSA or ECC key (default is RSA)\n");
printf("* -incert=file: Certificate for key used\n");
printf("\tDefault: RSA=./certs/client-rsa-cert.der, ECC=./certs/client-ecc-cert.der\n");
printf("* -out=file: Generated PKCS7 file containing signed data and certificate\n");
}
int TPM2_PKCS7_Example(void* userCtx) int TPM2_PKCS7_Example(void* userCtx)
{ {
return TPM2_PKCS7_ExampleArgs(userCtx, 0, NULL); return TPM2_PKCS7_ExampleArgs(userCtx, 0, NULL);
@ -306,22 +330,60 @@ int TPM2_PKCS7_ExampleArgs(void* userCtx, int argc, char *argv[])
int rc; int rc;
WOLFTPM2_DEV dev; WOLFTPM2_DEV dev;
WOLFTPM2_KEY storageKey; WOLFTPM2_KEY storageKey;
WOLFTPM2_KEY rsaKey; WOLFTPM2_KEY tpmKey;
TPMT_PUBLIC publicTemplate; TPMT_PUBLIC publicTemplate;
TpmCryptoDevCtx tpmCtx; TpmCryptoDevCtx tpmCtx;
int tpmDevId; int tpmDevId;
WOLFTPM2_BUFFER der; WOLFTPM2_BUFFER derCert;
WOLFTPM2_BUFFER derPubKey;
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) #if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
XFILE derFile; XFILE derFile;
const char* inCert = NULL;
#endif #endif
TPM_ALG_ID alg = TPM_ALG_RSA;
const char* outFile = "./examples/pkcs7/pkcs7tpmsigned.p7s";
const char* outFileEx = "./examples/pkcs7/pkcs7tpmsignedex.p7s";
enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
(void)argc; if (argc >= 2) {
(void)argv; if (XSTRCMP(argv[1], "-?") == 0 ||
XSTRCMP(argv[1], "-h") == 0 ||
XSTRCMP(argv[1], "--help") == 0) {
usage();
return 0;
}
}
while (argc > 1) {
if (XSTRCMP(argv[argc-1], "-ecc") == 0) {
alg = TPM_ALG_ECC;
}
else if (XSTRCMP(argv[argc-1], "-rsa") == 0) {
alg = TPM_ALG_RSA;
}
else if (XSTRNCMP(argv[argc-1], "-incert=",
XSTRLEN("-incert=")) == 0) {
inCert = argv[argc-1] + XSTRLEN("-incert=");
}
else if (XSTRNCMP(argv[argc-1], "-out=",
XSTRLEN("-out=")) == 0) {
outFile = argv[argc-1] + XSTRLEN("-out=");
}
else if (XSTRNCMP(argv[argc-1], "-outex=",
XSTRLEN("-outex=")) == 0) {
outFileEx = argv[argc-1] + XSTRLEN("-outex=");
}
else {
printf("Warning: Unrecognized option: %s\n", argv[argc-1]);
}
argc--;
}
printf("TPM2 PKCS7 Example\n"); printf("TPM2 PKCS7 Example\n");
XMEMSET(&der, 0, sizeof(der));
XMEMSET(&rsaKey, 0, sizeof(rsaKey)); XMEMSET(&derCert, 0, sizeof(derCert));
XMEMSET(&derPubKey, 0, sizeof(derPubKey));
XMEMSET(&tpmKey, 0, sizeof(tpmKey));
XMEMSET(&storageKey, 0, sizeof(storageKey)); XMEMSET(&storageKey, 0, sizeof(storageKey));
/* Init the TPM2 device */ /* Init the TPM2 device */
@ -331,60 +393,110 @@ int TPM2_PKCS7_ExampleArgs(void* userCtx, int argc, char *argv[])
/* Setup the wolf crypto device callback */ /* Setup the wolf crypto device callback */
XMEMSET(&tpmCtx, 0, sizeof(tpmCtx)); XMEMSET(&tpmCtx, 0, sizeof(tpmCtx));
#ifndef NO_RSA #ifndef NO_RSA
tpmCtx.rsaKey = &rsaKey; if (alg == TPM_ALG_RSA)
tpmCtx.rsaKey = &tpmKey;
#endif
#ifdef HAVE_ECC
if (alg == TPM_ALG_ECC)
tpmCtx.eccKey = &tpmKey;
#endif #endif
rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx, &tpmDevId); rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx, &tpmDevId);
if (rc < 0) goto exit; if (rc < 0) goto exit;
/* get SRK */ /* get SRK */
rc = getPrimaryStoragekey(&dev, &storageKey, TPM_ALG_RSA); rc = getPrimaryStoragekey(&dev, &storageKey, alg);
if (rc != 0) goto exit; if (rc != 0) goto exit;
/* Create/Load RSA key for PKCS7 signing */ /* Create/Load key for PKCS7 signing */
if (alg == TPM_ALG_RSA) {
rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate, rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate,
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth | TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA); TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA);
if (rc != 0) goto exit; if (rc == 0) {
rc = getRSAkey(&dev, rc = getRSAkey(&dev,
&storageKey, &storageKey,
&rsaKey, &tpmKey,
NULL, NULL,
tpmDevId, tpmDevId,
(byte*)gKeyAuth, sizeof(gKeyAuth)-1, (byte*)gKeyAuth, sizeof(gKeyAuth)-1,
&publicTemplate); &publicTemplate);
if (rc != 0) goto exit; }
wolfTPM2_SetAuthHandle(&dev, 0, &rsaKey.handle); if (rc == 0) {
/* export public key as DER for PKCS7, so it has the key information */
}
}
else {
TPM_ECC_CURVE curve;
#if defined(NO_ECC256) && defined(HAVE_ECC384) && ECC_MIN_KEY_SZ <= 384
/* make sure we use a curve that is enabled */
curve = TPM_ECC_NIST_P384;
#else
curve = TPM_ECC_NIST_P256;
#endif
rc = wolfTPM2_GetKeyTemplate_ECC(&publicTemplate,
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
TPMA_OBJECT_sign | TPMA_OBJECT_noDA,
curve, TPM_ALG_ECDSA);
if (rc == 0) {
rc = getECCkey(&dev,
&storageKey,
&tpmKey,
NULL,
tpmDevId,
(byte*)gKeyAuth, sizeof(gKeyAuth)-1,
&publicTemplate);
}
if (rc == 0) {
/* export public key as DER for PKCS7, so it has the key information */
}
}
if (rc != 0) goto exit;
wolfTPM2_SetAuthHandle(&dev, 0, &tpmKey.handle);
/* load DER certificate for TPM key (obtained by running /* load DER certificate for TPM key (obtained by running
`./examples/csr/csr` and `./certs/certreq.sh`) */ * `./examples/csr/csr` and `./certs/certreq.sh`) */
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) #if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
derFile = XFOPEN("./certs/client-rsa-cert.der", "rb"); if (inCert == NULL) {
if (alg == TPM_ALG_RSA)
inCert = "./certs/client-rsa-cert.der";
else
inCert = "./certs/client-ecc-cert.der";
}
derFile = XFOPEN(inCert, "rb");
if (derFile != XBADFILE) { if (derFile != XBADFILE) {
XFSEEK(derFile, 0, XSEEK_END); XFSEEK(derFile, 0, XSEEK_END);
der.size = (int)XFTELL(derFile); derCert.size = (int)XFTELL(derFile);
XREWIND(derFile); XREWIND(derFile);
if (der.size > (int)sizeof(der.buffer)) { if (derCert.size > (int)sizeof(derCert.buffer)) {
rc = BUFFER_E; rc = BUFFER_E;
} }
else { else {
rc = (int)XFREAD(der.buffer, 1, der.size, derFile); rc = (int)XFREAD(derCert.buffer, 1, derCert.size, derFile);
rc = (rc == der.size) ? 0 : -1; rc = (rc == derCert.size) ? 0 : -1;
} }
XFCLOSE(derFile); XFCLOSE(derFile);
if (rc != 0) goto exit; if (rc != 0) goto exit;
} }
#endif #endif
/* Export TPM public key as DER/ASN.1 (should match certificate) */
derPubKey.size = (int)sizeof(derPubKey.buffer);
rc = wolfTPM2_ExportPublicKeyBuffer(&dev, &tpmKey,
ENCODING_TYPE_ASN1, derPubKey.buffer, (word32*)&derPubKey.size);
if (rc != 0) goto exit;
/* PKCS 7 sign/verify example */ /* PKCS 7 sign/verify example */
rc = PKCS7_SignVerify(&dev, tpmDevId, &der); rc = PKCS7_SignVerify(&dev, tpmDevId, &derCert, &derPubKey, alg, hashType,
outFile);
if (rc != 0) goto exit; if (rc != 0) goto exit;
#ifdef ENABLE_PKCS7EX_EXAMPLE #ifdef ENABLE_PKCS7EX_EXAMPLE
/* PKCS 7 large data sign/verify example */ /* PKCS 7 large data sign/verify example */
rc = PKCS7_SignVerifyEx(&dev, tpmDevId, &der); rc = PKCS7_SignVerifyEx(&dev, tpmDevId, &derCert, &derPubKey, alg, hashType,
outFileEx);
if (rc != 0) goto exit; if (rc != 0) goto exit;
#endif #endif
@ -394,7 +506,7 @@ exit:
printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc)); printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc));
} }
wolfTPM2_UnloadHandle(&dev, &rsaKey.handle); wolfTPM2_UnloadHandle(&dev, &tpmKey.handle);
wolfTPM2_Cleanup(&dev); wolfTPM2_Cleanup(&dev);

View File

@ -187,6 +187,10 @@ if [ $WOLFCRYPT_ENABLE -eq 1 ]; then
./examples/pkcs7/pkcs7 >> run.out ./examples/pkcs7/pkcs7 >> run.out
RESULT=$? RESULT=$?
[ $RESULT -ne 0 ] && echo -e "pkcs7 failed! $RESULT" && exit 1 [ $RESULT -ne 0 ] && echo -e "pkcs7 failed! $RESULT" && exit 1
./examples/pkcs7/pkcs7 -ecc >> run.out
RESULT=$?
[ $RESULT -ne 0 ] && echo -e "pkcs7 ecc failed! $RESULT" && exit 1
fi fi
# TLS Tests # TLS Tests

View File

@ -103,11 +103,9 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
WOLFTPM2_KEY storageKey; WOLFTPM2_KEY storageKey;
#ifndef NO_RSA #ifndef NO_RSA
WOLFTPM2_KEY rsaKey; WOLFTPM2_KEY rsaKey;
RsaKey wolfRsaKey;
#endif #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
WOLFTPM2_KEY eccKey; WOLFTPM2_KEY eccKey;
ecc_key wolfEccKey;
#ifndef WOLFTPM2_USE_SW_ECDHE #ifndef WOLFTPM2_USE_SW_ECDHE
WOLFTPM2_KEY ecdhKey; WOLFTPM2_KEY ecdhKey;
#endif #endif
@ -141,11 +139,9 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
XMEMSET(&tpmCtx, 0, sizeof(tpmCtx)); XMEMSET(&tpmCtx, 0, sizeof(tpmCtx));
#ifndef NO_RSA #ifndef NO_RSA
XMEMSET(&rsaKey, 0, sizeof(rsaKey)); XMEMSET(&rsaKey, 0, sizeof(rsaKey));
XMEMSET(&wolfRsaKey, 0, sizeof(wolfRsaKey));
#endif #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
XMEMSET(&eccKey, 0, sizeof(eccKey)); XMEMSET(&eccKey, 0, sizeof(eccKey));
XMEMSET(&wolfEccKey, 0, sizeof(wolfEccKey));
#ifndef WOLFTPM2_USE_SW_ECDHE #ifndef WOLFTPM2_USE_SW_ECDHE
/* Ephemeral Key */ /* Ephemeral Key */
XMEMSET(&ecdhKey, 0, sizeof(ecdhKey)); XMEMSET(&ecdhKey, 0, sizeof(ecdhKey));
@ -222,7 +218,8 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
} }
#endif #endif
/* See if primary storage key already exists */ /* See if primary storage key already exists */
rc = getPrimaryStoragekey(&dev, &storageKey, TPM_ALG_RSA); rc = getPrimaryStoragekey(&dev, &storageKey,
useECC ? TPM_ALG_ECC : TPM_ALG_RSA);
if (rc != 0) goto exit; if (rc != 0) goto exit;
/* Start an authenticated session (salted / unbound) with parameter encryption */ /* Start an authenticated session (salted / unbound) with parameter encryption */
@ -250,7 +247,7 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
rc = getRSAkey(&dev, rc = getRSAkey(&dev,
&storageKey, &storageKey,
&rsaKey, &rsaKey,
&wolfRsaKey, NULL,
tpmDevId, tpmDevId,
(byte*)gKeyAuth, sizeof(gKeyAuth)-1, (byte*)gKeyAuth, sizeof(gKeyAuth)-1,
&publicTemplate); &publicTemplate);
@ -269,7 +266,7 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
rc = getECCkey(&dev, rc = getECCkey(&dev,
&storageKey, &storageKey,
&eccKey, &eccKey,
&wolfEccKey, NULL,
tpmDevId, tpmDevId,
(byte*)gKeyAuth, sizeof(gKeyAuth)-1, (byte*)gKeyAuth, sizeof(gKeyAuth)-1,
&publicTemplate); &publicTemplate);
@ -377,17 +374,16 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
* public key instead (if crypto callbacks are enabled). * public key instead (if crypto callbacks are enabled).
*/ */
#ifndef NO_TLS_MUTUAL_AUTH #ifndef NO_TLS_MUTUAL_AUTH
if (!useECC) { {
#ifndef NO_RSA /* Export TPM public key as DER */
byte der[1024]; byte der[1024];
word32 derSz = sizeof(der); word32 derSz = (word32)sizeof(der);
rc = wc_RsaKeyToPublicDer_ex(&wolfRsaKey, der, derSz, 1); rc = wolfTPM2_ExportPublicKeyBuffer(&dev, !useECC ? &rsaKey : &eccKey,
ENCODING_TYPE_ASN1, der, &derSz);
if (rc < 0) { if (rc < 0) {
printf("Failed to export RSA public key!\n"); printf("Failed to export RSA public key!\n");
goto exit; goto exit;
} }
derSz = rc;
rc = 0;
/* Private key only exists on the TPM and crypto callbacks are used for /* Private key only exists on the TPM and crypto callbacks are used for
* signing. Public key is required to enable TLS client (mutual auth). * signing. Public key is required to enable TLS client (mutual auth).
@ -397,37 +393,6 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
printf("Failed to set RSA key!\n"); printf("Failed to set RSA key!\n");
goto exit; goto exit;
} }
#else
printf("Error: RSA not compiled in\n");
rc = -1;
goto exit;
#endif /* !NO_RSA */
}
else {
#ifdef HAVE_ECC
byte der[256];
word32 derSz = sizeof(der);
rc = wc_EccPublicKeyToDer(&wolfEccKey, der, derSz, 1);
if (rc < 0) {
printf("Failed to export ECC public key!\n");
goto exit;
}
derSz = rc;
rc = 0;
/* Private key only exists on the TPM and crypto callbacks are used for
* signing. Public key is required to enable TLS client (mutual auth).
* This API accepts public keys when crypto callbacks are enabled */
if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz,
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
printf("Failed to set ECC key!\n");
goto exit;
}
#else
printf("RSA not supported in this build\n");
rc = -1;
goto exit;
#endif /* HAVE_ECC */
} }
/* Client Certificate (Mutual Authentication) */ /* Client Certificate (Mutual Authentication) */
@ -611,11 +576,9 @@ exit:
wolfTPM2_UnloadHandle(&dev, &storageKey.handle); wolfTPM2_UnloadHandle(&dev, &storageKey.handle);
#ifndef NO_RSA #ifndef NO_RSA
wc_FreeRsaKey(&wolfRsaKey);
wolfTPM2_UnloadHandle(&dev, &rsaKey.handle); wolfTPM2_UnloadHandle(&dev, &rsaKey.handle);
#endif #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
wc_ecc_free(&wolfEccKey);
wolfTPM2_UnloadHandle(&dev, &eccKey.handle); wolfTPM2_UnloadHandle(&dev, &eccKey.handle);
#ifndef WOLFTPM2_USE_SW_ECDHE #ifndef WOLFTPM2_USE_SW_ECDHE
wolfTPM2_UnloadHandle(&dev, &ecdhKey.handle); wolfTPM2_UnloadHandle(&dev, &ecdhKey.handle);

View File

@ -101,11 +101,9 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
WOLFTPM2_KEY storageKey; WOLFTPM2_KEY storageKey;
#ifndef NO_RSA #ifndef NO_RSA
WOLFTPM2_KEY rsaKey; WOLFTPM2_KEY rsaKey;
RsaKey wolfRsaKey;
#endif #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
WOLFTPM2_KEY eccKey; WOLFTPM2_KEY eccKey;
ecc_key wolfEccKey;
#ifndef WOLFTPM2_USE_SW_ECDHE #ifndef WOLFTPM2_USE_SW_ECDHE
WOLFTPM2_KEY ecdhKey; WOLFTPM2_KEY ecdhKey;
#endif #endif
@ -152,11 +150,9 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
XMEMSET(&tpmCtx, 0, sizeof(tpmCtx)); XMEMSET(&tpmCtx, 0, sizeof(tpmCtx));
#ifndef NO_RSA #ifndef NO_RSA
XMEMSET(&rsaKey, 0, sizeof(rsaKey)); XMEMSET(&rsaKey, 0, sizeof(rsaKey));
XMEMSET(&wolfRsaKey, 0, sizeof(wolfRsaKey));
#endif #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
XMEMSET(&eccKey, 0, sizeof(eccKey)); XMEMSET(&eccKey, 0, sizeof(eccKey));
XMEMSET(&wolfEccKey, 0, sizeof(wolfEccKey));
#ifndef WOLFTPM2_USE_SW_ECDHE #ifndef WOLFTPM2_USE_SW_ECDHE
/* Ephemeral Key */ /* Ephemeral Key */
XMEMSET(&ecdhKey, 0, sizeof(ecdhKey)); XMEMSET(&ecdhKey, 0, sizeof(ecdhKey));
@ -239,7 +235,8 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
} }
#endif #endif
/* See if primary storage key already exists */ /* See if primary storage key already exists */
rc = getPrimaryStoragekey(&dev, &storageKey, TPM_ALG_RSA); rc = getPrimaryStoragekey(&dev, &storageKey,
useECC ? TPM_ALG_ECC : TPM_ALG_RSA);
if (rc != 0) goto exit; if (rc != 0) goto exit;
/* Start an authenticated session (salted / unbound) with parameter encryption */ /* Start an authenticated session (salted / unbound) with parameter encryption */
@ -267,7 +264,7 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
rc = getRSAkey(&dev, rc = getRSAkey(&dev,
&storageKey, &storageKey,
&rsaKey, &rsaKey,
&wolfRsaKey, NULL,
tpmDevId, tpmDevId,
(byte*)gKeyAuth, sizeof(gKeyAuth)-1, (byte*)gKeyAuth, sizeof(gKeyAuth)-1,
&publicTemplate); &publicTemplate);
@ -286,7 +283,7 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
rc = getECCkey(&dev, rc = getECCkey(&dev,
&storageKey, &storageKey,
&eccKey, &eccKey,
&wolfEccKey, NULL,
tpmDevId, tpmDevId,
(byte*)gKeyAuth, sizeof(gKeyAuth)-1, (byte*)gKeyAuth, sizeof(gKeyAuth)-1,
&publicTemplate); &publicTemplate);
@ -384,11 +381,30 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
} }
#endif #endif
#else #else
{
/* Export TPM public key as DER */
byte der[1024];
word32 derSz = (word32)sizeof(der);
rc = wolfTPM2_ExportPublicKeyBuffer(&dev, !useECC ? &rsaKey : &eccKey,
ENCODING_TYPE_ASN1, der, &derSz);
if (rc < 0) {
printf("Failed to export TPM public key!\n");
goto exit;
}
/* Private key only exists on the TPM and crypto callbacks are used for
* signing. Public key is required to enable TLS client (mutual auth).
* This API accepts public keys when crypto callbacks are enabled */
if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz,
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
printf("Failed to set RSA key!\n");
goto exit;
}
}
/* Server certificate */ /* Server certificate */
if (!useECC) { if (!useECC) {
#ifndef NO_RSA #ifndef NO_RSA
byte der[1024];
word32 derSz = sizeof(der);
const char* useCert = "./certs/server-rsa-cert.pem"; const char* useCert = "./certs/server-rsa-cert.pem";
if (useSelfSign) { if (useSelfSign) {
useCert = "./certs/tpm-rsa-cert.pem"; useCert = "./certs/tpm-rsa-cert.pem";
@ -401,23 +417,6 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
printf("Error loading RSA client cert\n"); printf("Error loading RSA client cert\n");
goto exit; goto exit;
} }
rc = wc_RsaKeyToPublicDer_ex(&wolfRsaKey, der, derSz, 1);
if (rc < 0) {
printf("Failed to export RSA public key!\n");
goto exit;
}
derSz = rc;
rc = 0;
/* Private key only exists on the TPM and crypto callbacks are used for
* signing. Public key is required to enable TLS client (mutual auth).
* This API accepts public keys when crypto callbacks are enabled */
if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz,
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
printf("Failed to set RSA key!\r\n");
goto exit;
}
#else #else
printf("Error: RSA not compiled in\n"); printf("Error: RSA not compiled in\n");
rc = -1; rc = -1;
@ -426,8 +425,6 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
} }
else { else {
#ifdef HAVE_ECC #ifdef HAVE_ECC
byte der[256];
word32 derSz = sizeof(der);
const char* useCert = "./certs/server-ecc-cert.pem"; const char* useCert = "./certs/server-ecc-cert.pem";
if (useSelfSign) { if (useSelfSign) {
useCert = "./certs/tpm-ecc-cert.pem"; useCert = "./certs/tpm-ecc-cert.pem";
@ -440,23 +437,6 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
printf("Error loading ECC client cert\n"); printf("Error loading ECC client cert\n");
goto exit; goto exit;
} }
rc = wc_EccPublicKeyToDer(&wolfEccKey, der, derSz, 1);
if (rc < 0) {
printf("Failed to export ECC public key!\n");
goto exit;
}
derSz = rc;
rc = 0;
/* Private key only exists on the TPM and crypto callbacks are used for
* signing. Public key is required to enable TLS server auth.
* This API accepts public keys when crypto callbacks are enabled */
if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz,
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
printf("Failed to set ECC key!\n");
goto exit;
}
#else #else
printf("Error: ECC not compiled in\n"); printf("Error: ECC not compiled in\n");
rc = -1; rc = -1;
@ -611,11 +591,9 @@ exit:
wolfTPM2_UnloadHandle(&dev, &storageKey.handle); wolfTPM2_UnloadHandle(&dev, &storageKey.handle);
#ifndef NO_RSA #ifndef NO_RSA
wc_FreeRsaKey(&wolfRsaKey);
wolfTPM2_UnloadHandle(&dev, &rsaKey.handle); wolfTPM2_UnloadHandle(&dev, &rsaKey.handle);
#endif #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
wc_ecc_free(&wolfEccKey);
wolfTPM2_UnloadHandle(&dev, &eccKey.handle); wolfTPM2_UnloadHandle(&dev, &eccKey.handle);
#ifndef WOLFTPM2_USE_SW_ECDHE #ifndef WOLFTPM2_USE_SW_ECDHE
wolfTPM2_UnloadHandle(&dev, &ecdhKey.handle); wolfTPM2_UnloadHandle(&dev, &ecdhKey.handle);

View File

@ -248,8 +248,14 @@ int wolfTPM2_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
word32 rsLen = sizeof(sigRS), keySz; word32 rsLen = sizeof(sigRS), keySz;
word32 inlen = info->pk.eccsign.inlen; word32 inlen = info->pk.eccsign.inlen;
/* truncate input to match key size */ /* get key size from wolf signing key */
keySz = wc_ecc_size(info->pk.eccsign.key); keySz = wc_ecc_size(info->pk.eccsign.key);
if (keySz == 0) {
/* if not populated fallback to key size for TPM key */
keySz = TPM2_GetCurveSize(
tlsCtx->eccKey->pub.publicArea.parameters.eccDetail.curveID);
}
/* truncate input to match key size */
if (inlen > keySz) if (inlen > keySz)
inlen = keySz; inlen = keySz;

View File

@ -2729,6 +2729,107 @@ int wolfTPM2_DecodeEccDer(const byte* der, word32 derSz, TPM2B_PUBLIC* pub,
} }
#endif /* HAVE_ECC */ #endif /* HAVE_ECC */
int wolfTPM2_ExportPublicKeyBuffer(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
int encodingType, byte* out, word32* outSz)
{
int rc;
word32 derSz = 0;
union keyUnion {
#ifndef NO_RSA
RsaKey rsa;
#endif
#ifdef HAVE_ECC
ecc_key ecc;
#endif
} key;
if (dev == NULL || tpmKey == NULL) {
return BAD_FUNC_ARG;
}
XMEMSET(&key, 0, sizeof(key));
/* determine the type of key in WOLFTPM2_KEY */
if (tpmKey->pub.publicArea.type == TPM_ALG_ECC) {
#ifdef HAVE_ECC
rc = wc_ecc_init(&key.ecc);
if (rc == 0) {
/* load public portion of key into wolf ECC Key */
rc = wolfTPM2_EccKey_TpmToWolf(dev, tpmKey, &key.ecc);
if (rc == 0) {
rc = wc_EccPublicKeyToDer(&key.ecc, out, *outSz, 1);
if (rc > 0) {
derSz = rc;
rc = 0;
}
else {
rc = BUFFER_E;
}
}
}
#else
rc = NOT_COMPILED_IN;
#endif
}
else if (tpmKey->pub.publicArea.type == TPM_ALG_RSA) {
#ifndef NO_RSA
rc = wc_InitRsaKey(&key.rsa, NULL);
if (rc == 0) {
/* load public portion of key into wolf RSA Key */
rc = wolfTPM2_RsaKey_TpmToWolf(dev, tpmKey, &key.rsa);
if (rc == 0) {
rc = wc_RsaKeyToPublicDer_ex(&key.rsa, out, *outSz, 1);
if (rc > 0) {
derSz = rc;
rc = 0;
}
else {
rc = BUFFER_E;
}
}
}
#else
rc = NOT_COMPILED_IN;
#endif
}
else {
#ifdef DEBUG_WOLFTPM
printf("Invalid tpmKey type!\n");
#endif
rc = BAD_FUNC_ARG;
}
/* Optionally convert to PEM */
if (rc == 0 && encodingType == ENCODING_TYPE_PEM) {
#ifdef WOLFSSL_DER_TO_PEM
WOLFTPM2_BUFFER tmp;
if (derSz > (word32)sizeof(tmp.buffer)) {
rc = BUFFER_E;
}
else {
/* move DER to temp variable */
tmp.size = derSz;
XMEMCPY(tmp.buffer, out, derSz);
XMEMSET(out, 0, *outSz);
rc = wc_DerToPem(tmp.buffer, tmp.size, out, *outSz, PUBLICKEY_TYPE);
if (rc > 0) {
*outSz = rc;
rc = 0;
}
else {
rc = BUFFER_E;
}
}
#else
rc = NOT_COMPILED_IN;
#endif
}
else if (rc == 0) {
*outSz = derSz;
}
return rc;
}
int wolfTPM2_ImportPublicKeyBuffer(WOLFTPM2_DEV* dev, int keyType, int wolfTPM2_ImportPublicKeyBuffer(WOLFTPM2_DEV* dev, int keyType,
WOLFTPM2_KEY* key, int encodingType, const char* input, word32 inSz, WOLFTPM2_KEY* key, int encodingType, const char* input, word32 inSz,
TPMA_OBJECT objectAttributes) TPMA_OBJECT objectAttributes)
@ -2991,61 +3092,8 @@ int wolfTPM2_RsaKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
int wolfTPM2_RsaKey_TpmToPemPub(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey, int wolfTPM2_RsaKey_TpmToPemPub(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
byte* pem, word32* pemSz) byte* pem, word32* pemSz)
{ {
int rc = TPM_RC_FAILURE; return wolfTPM2_ExportPublicKeyBuffer(dev, tpmKey,
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_DER_TO_PEM) && \ ENCODING_TYPE_PEM, pem, pemSz);
(defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA)
RsaKey rsaKey;
byte* derBuf = NULL;
int derSz = 0;
#endif
if (dev == NULL || tpmKey == NULL || pem == NULL || pemSz == NULL)
return BAD_FUNC_ARG;
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_DER_TO_PEM) && \
(defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA)
/* Prepare wolfCrypt key structure */
rc = wc_InitRsaKey(&rsaKey, NULL);
if (rc == 0) {
/* Convert the wolfTPM key to wolfCrypt format */
rc = wolfTPM2_RsaKey_TpmToWolf(dev, tpmKey, &rsaKey);
if (rc == 0) {
/* Get DER size - newer API can be called with NULL to get size */
rc = wc_RsaKeyToPublicDer(&rsaKey, NULL, 0);
if (rc > 0) {
derSz = rc;
rc = 0;
}
else if (rc == BAD_FUNC_ARG) {
/* for older wolfSSL estimate based on key size */
derSz = wc_RsaEncryptSize(&rsaKey) * 2;
rc = 0;
}
}
if (derSz > 0) {
derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (derBuf == NULL)
rc = MEMORY_E;
}
if (rc == 0) {
/* Convert the wolfCrypt key to DER format */
rc = wc_RsaKeyToPublicDer(&rsaKey, derBuf, derSz);
}
if (rc >= 0) {
/* Convert the DER key to PEM format */
derSz = rc;
rc = wc_DerToPem(derBuf, derSz, pem, *pemSz, PUBLICKEY_TYPE);
}
if (rc >= 0) {
*pemSz = rc;
rc = TPM_RC_SUCCESS;
}
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wc_FreeRsaKey(&rsaKey);
}
#endif
return rc;
} }
static word32 wolfTPM2_RsaKey_Exponent(byte* e, word32 eSz) static word32 wolfTPM2_RsaKey_Exponent(byte* e, word32 eSz)

View File

@ -1189,6 +1189,24 @@ WOLFTPM_API int wolfTPM2_ImportPublicKeyBuffer(WOLFTPM2_DEV* dev, int keyType,
WOLFTPM2_KEY* key, int encodingType, const char* input, word32 inSz, WOLFTPM2_KEY* key, int encodingType, const char* input, word32 inSz,
TPMA_OBJECT objectAttributes); TPMA_OBJECT objectAttributes);
/*!
\ingroup wolfTPM2_Wrappers
\brief Helper function to export a TPM RSA/ECC public key with PEM/DER formatting
\return TPM_RC_SUCCESS: successful - populates key->pub
\return TPM_RC_FAILURE: generic failure (check TPM IO and TPM return code)
\return BUFFER_E: insufficient space in provided buffer
\return BAD_FUNC_ARG: check the provided arguments
\param dev pointer to a TPM2_DEV struct
\param tpmKey pointer to a WOLFTPM2_KEY with populated key
\param encodingType ENCODING_TYPE_PEM or ENCODING_TYPE_ASN1 (DER)
\param out buffer to export public key
\param outSz pointer to length of the out buffer
*/
WOLFTPM_API int wolfTPM2_ExportPublicKeyBuffer(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
int encodingType, byte* out, word32* outSz);
#ifndef NO_RSA #ifndef NO_RSA
/*! /*!
\ingroup wolfTPM2_Wrappers \ingroup wolfTPM2_Wrappers
@ -1252,8 +1270,8 @@ WOLFTPM_API int wolfTPM2_RsaKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKe
/*! /*!
\ingroup wolfTPM2_Wrappers \ingroup wolfTPM2_Wrappers
\brief Convert a public RSA TPM key to PEM format public key \brief Convert a public RSA TPM key to PEM format public key.
Note: pem and tempBuf must be different buffers, of equal size Note: This API is a wrapper around wolfTPM2_ExportPublicKeyBuffer
\return TPM_RC_SUCCESS: successful \return TPM_RC_SUCCESS: successful
\return TPM_RC_FAILURE: generic failure (check TPM IO and TPM return code) \return TPM_RC_FAILURE: generic failure (check TPM IO and TPM return code)
@ -1264,6 +1282,7 @@ WOLFTPM_API int wolfTPM2_RsaKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKe
\param pem pointer to an array of byte type, used as temporary storage for PEM conversation \param pem pointer to an array of byte type, used as temporary storage for PEM conversation
\param pemSz pointer to integer variable, to store the used buffer size \param pemSz pointer to integer variable, to store the used buffer size
\sa wolfTPM2_ExportPublicKeyBuffer
\sa wolfTPM2_RsaKey_TpmToWolf \sa wolfTPM2_RsaKey_TpmToWolf
\sa wolfTPM2_RsaKey_WolfToTpm \sa wolfTPM2_RsaKey_WolfToTpm
*/ */