Fixes for Public PEM functions. Cleanups.

pull/174/head
David Garske 2021-07-12 17:12:22 -07:00
parent bc9434aec9
commit 8455beaae4
7 changed files with 121 additions and 75 deletions

10
.gitignore vendored
View File

@ -26,8 +26,10 @@ src/.deps
src/.libs
RemoteSystemsTempFiles
*.o
*.dep
*.deps
*.libs
IDE/IAR-EWARM/settings
wolftpm/options.h
examples/wrap/wrap_test
@ -75,12 +77,16 @@ certs/server-*.pem
certs/client-*.der
certs/client-*.pem
certs/serial.old
*.dep
IDE/IAR-EWARM/settings
# Test files
quote.blob
keyblob.bin
ecc_test_blob.raw
rsa_test_blob.raw
ak.name
cred.blob
ek.pub
srk.pub
# Generated Documentation
docs/html

View File

@ -43,7 +43,6 @@ Note:
Using the `keygen` example we can create the necessary TPM 2.0 Attestation Key and TPM 2.0 Primary Storage Key that will be used as a Primary Attestation Key(PAK).
```
$ ./examples/keygen/keygen -rsa
TPM2.0 Key generation example
Key Blob: keyblob.bin
@ -55,7 +54,6 @@ RSA AIK template
Creating new RSA key...
Created new key (pub 280, priv 222 bytes)
Wrote 508 bytes to keyblob.bin
```
### Make Credential Example Usage
@ -63,7 +61,6 @@ Wrote 508 bytes to keyblob.bin
Using the `make_credential` example an attestation server can generate remote attestation challenge. The secret is 32 bytes of randomly generated seed that could be used for a symmetric key in some remote attestation schemes.
```
$ ./examples/attestation/make_credential
Using default values
Demo how to create a credential blob for remote attestation
@ -74,7 +71,6 @@ Reading the private part of the key
AK loaded at 0x80000001
TPM2_MakeCredential success
Wrote credential blob and secret to cred.blob, 514 bytes
```
The transfer of the PAK and AK public parts between the client and attestation server is not part of the `make_credential` example, because the exchange is implementation specific.
@ -84,7 +80,6 @@ The transfer of the PAK and AK public parts between the client and attestation s
Using the `activate_credential` example a client can decrypt the remote attestation challenge. The secret will be exposed in plain and can be exchanged with the attestation server.
```
$ ./examples/attestation/activate_credential
Using default values
Demo how to create a credential blob for remote attestation
@ -99,7 +94,6 @@ TPM2_StartAuthSession: sessionHandle 0x3000000
TPM2_policyCommandCode success
Read credential blob and secret from cred.blob, 514 bytes
TPM2_ActivateCredential success
```
The transfer of the challenge response containing the secret in plain (or used as a symmetric key seed) is not part of the `activate_credential` example, because the exchange is also implementation specific.

View File

@ -182,7 +182,8 @@ int TPM2_ActivateCredential_Example(void* userCtx, int argc, char *argv[])
sizeof(cmdIn.activCred.secret), fp);
XFCLOSE(fp);
}
printf("Read credential blob and secret from %s, %d bytes\n", input, dataSize);
printf("Read credential blob and secret from %s, %d bytes\n",
input, dataSize);
#else
printf("Can not load credential. File support not enabled\n");
goto exit;

View File

@ -129,7 +129,8 @@ int TPM2_MakeCredential_Example(void* userCtx, int argc, char *argv[])
goto exit;
}
/* Prepare the key for use by the TPM */
XMEMCPY(&cmdIn.loadExtIn.inPublic, &primary.pub, sizeof(cmdIn.loadExtIn.inPublic));
XMEMCPY(&cmdIn.loadExtIn.inPublic, &primary.pub,
sizeof(cmdIn.loadExtIn.inPublic));
cmdIn.loadExtIn.hierarchy = TPM_RH_NULL;
rc = TPM2_LoadExternal(&cmdIn.loadExtIn, &cmdOut.loadExtOut);
if (rc != TPM_RC_SUCCESS) {
@ -175,7 +176,8 @@ int TPM2_MakeCredential_Example(void* userCtx, int argc, char *argv[])
sizeof(cmdOut.makeCred.secret), fp);
XFCLOSE(fp);
}
printf("Wrote credential blob and secret to %s, %d bytes\n", output, dataSize);
printf("Wrote credential blob and secret to %s, %d bytes\n",
output, dataSize);
#else
printf("Can not store credential. File support not enabled\n");
#endif

View File

@ -101,7 +101,7 @@ static int symChoice(const char* arg, TPM_ALG_ID* algSym, int* keyBits,
}
*keyBits = atoi(&arg[SYM_EXTRA_OPTS_KEY_BITS_POS]);
if(*keyBits != 128 && *keyBits != 192 && *keyBits != 256) {
if (*keyBits != 128 && *keyBits != 192 && *keyBits != 256) {
return TPM_RC_FAILURE;
}
@ -116,7 +116,6 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
WOLFTPM2_KEY storage; /* SRK */
WOLFTPM2_KEY *primary = NULL;
WOLFTPM2_KEY aesKey; /* Symmetric key */
WOLFTPM2_KEY newKey; /* child or attestation key */
WOLFTPM2_KEYBLOB newKeyBlob; /* newKey as WOLFTPM2_KEYBLOB */
WOLFTPM2_KEYBLOB primaryBlob; /* Primary key as WOLFTPM2_KEYBLOB */
TPMT_PUBLIC publicTemplate;
@ -194,7 +193,6 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
XMEMSET(&endorse, 0, sizeof(endorse));
XMEMSET(&storage, 0, sizeof(storage));
XMEMSET(&aesKey, 0, sizeof(aesKey));
XMEMSET(&newKey, 0, sizeof(newKey));
XMEMSET(&newKeyBlob, 0, sizeof(newKeyBlob));
XMEMSET(&primaryBlob, 0, sizeof(primaryBlob));
XMEMSET(&tpmSession, 0, sizeof(tpmSession));
@ -215,7 +213,7 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
goto exit;
}
if(endorseKey) {
if (endorseKey) {
rc = wolfTPM2_CreateEK(&dev, &endorse, TPM_ALG_RSA);
endorse.handle.policyAuth = 1; /* EK requires Policy auth, not Password */
pubFilename = ekPubFile;
@ -329,7 +327,7 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
}
}
#else
if(alg == TPM_ALG_SYMCIPHER) {
if (alg == TPM_ALG_SYMCIPHER) {
printf("The Public Part of a symmetric key contains only meta data\n");
}
printf("Key Public Blob %d\n", newKeyBlob.pub.size);
@ -341,32 +339,31 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
/* Save EK public key as PEM format file to the disk */
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_FILESYSTEM)
if (pemFiles) {
byte pem[MAX_RSA_KEY_BYTES], tempBuf[MAX_RSA_KEY_BYTES];
int pemSz, tempSz = sizeof(tempBuf);
byte pem[MAX_RSA_KEY_BYTES];
word32 pemSz;
if (endorseKey) {
pemFilename = pemFileEk;
}
else {
pemFilename = pemFileSrk;
}
rc = wolfTPM2_RsaKey_TpmToPem(&dev, primary, pem, &pemSz, tempBuf, tempSz);
pemFilename = (endorseKey) ? pemFileEk : pemFileSrk;
pemSz = (word32)sizeof(pem);
rc = wolfTPM2_RsaKey_TpmToPemPub(&dev, primary, pem, &pemSz);
if (rc == 0) {
rc = writeKeyPubPem(pemFilename, pem, (word32)pemSz);
rc = writeKeyPubPem(pemFilename, pem, pemSz);
}
if (bAIK) {
pemFilename = pemFileAk;
}
else {
pemFilename = pemFileKey;
}
rc = wolfTPM2_RsaKey_TpmToPem(&dev, &newKey, pem, &pemSz, tempBuf, tempSz);
pemFilename = (bAIK) ? pemFileAk : pemFileKey;
pemSz = (word32)sizeof(pem);
rc = wolfTPM2_RsaKey_TpmToPemPub(&dev, (WOLFTPM2_KEY*)&newKeyBlob,
pem, &pemSz);
if (rc == 0) {
rc = writeKeyPubPem(pemFilename, pem, (word32)pemSz);
rc = writeKeyPubPem(pemFilename, pem, pemSz);
}
wolfTPM2_UnloadHandle(&dev, &newKeyBlob.handle);
#if 0
/* example for loading public pem to TPM */
rc = wolfTPM2_RsaKey_PubPemToTpm(&dev, (WOLFTPM2_KEY*)&newKeyBlob, pem, pemSz);
printf("wolfTPM2_RsaKey_PubPemToTpm rc=%d\n", rc);
rc = 0;
#endif
}
#else
printf("Unable to store EK pub as PEM file. Lack of file support\n");

View File

@ -1784,29 +1784,58 @@ int wolfTPM2_RsaKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
return rc;
}
int wolfTPM2_RsaKey_TpmToPem(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
byte* pem, int* pemSz, byte* tempBuf, int tempSz)
int wolfTPM2_RsaKey_TpmToPemPub(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
byte* pem, word32* pemSz)
{
int rc = TPM_RC_FAILURE;
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_DER_TO_PEM)
int derSz;
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)
/* Prepare wolfCrypt key structure */
rc = wc_InitRsaKey(&rsaKey, NULL);
if (rc != 0) return rc;
/* Convert the wolfTPM key to wolfCrypt format */
rc = wolfTPM2_RsaKey_TpmToWolf(dev, tpmKey, &rsaKey);
if (rc != 0) return rc;
/* Convert the wolfCrypt key to DER format */
rc = wc_RsaKeyToPublicDer(&rsaKey, tempBuf, tempSz);
if (rc <= 0) return rc;
derSz = rc;
/* Convert the DER key to PEM format */
rc = wc_DerToPem(tempBuf, derSz, pem, tempSz, PUBLICKEY_TYPE);
if (rc <= 0) return rc;
*pemSz = rc;
rc = TPM_RC_SUCCESS;
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;
}
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;
}
@ -1878,27 +1907,49 @@ int wolfTPM2_RsaKey_WolfToTpm(WOLFTPM2_DEV* dev, RsaKey* wolfKey,
}
int wolfTPM2_RsaKey_PubPemToTpm(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
byte* pem, int pemSz, byte* tempBuf, int tempSz)
const byte* pem, word32 pemSz)
{
int rc = TPM_RC_FAILURE;
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_CERT_EXT) && \
defined(WOLFSSL_PUB_PEM_TO_DER) && defined(WOLFSSL_PEM_TO_DER)
word32 idx;
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_PEM_TO_DER) && \
(defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER))
RsaKey rsaKey;
#endif
if (dev == NULL || tpmKey == NULL || pem == NULL)
return BAD_FUNC_ARG;
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFSSL_PEM_TO_DER) && \
(defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER))
/* Prepare wolfCrypt key structure */
rc = wc_InitRsaKey(&rsaKey, NULL);
if (rc != 0) return rc;
/* Convert PEM format key from file to DER */
rc = wc_PubKeyPemToDer(pem, pemSz, tempBuf, tempSz);
if (rc != 0) return rc;
/* Convert DER to wolfCrypt file */
idx = 0;
rc = wc_RsaPublicKeyDecode(tempBuf, &idx, &rsaKey, tempSz);
if (rc != 0) return rc;
/* Load into the TPM */
rc = wolfTPM2_RsaKey_WolfToTpm(dev, &rsaKey, tpmKey);
if (rc == 0) {
/* allocate buffer for DER */
word32 derSz = pemSz; /* DER is always smaller */
byte* derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (derBuf == NULL) {
rc = MEMORY_E;
}
if (rc == 0) {
/* Convert PEM format key from file to DER - inline okay */
rc = wc_PubKeyPemToDer(pem, pemSz, derBuf, derSz);
}
if (rc >= 0) {
/* Convert DER to wolfCrypt file */
word32 idx = 0;
derSz = (word32)rc;
rc = wc_RsaPublicKeyDecode(derBuf, &idx, &rsaKey, derSz);
}
if (rc == 0) {
/* Load into the TPM */
rc = wolfTPM2_RsaKey_WolfToTpm(dev, &rsaKey, tpmKey);
}
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wc_FreeRsaKey(&rsaKey);
}
#else
(void)pemSz;
#endif
return rc;
}
#endif /* !NO_RSA */

View File

@ -1042,16 +1042,13 @@ WOLFTPM_API int wolfTPM2_RsaKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKe
\param keyBlob pointer to a struct of WOLFTPM2_KEY type, holding a TPM key
\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 tempBuf pointer to an array of byte type, used as temporary storage for conversation
\param tempSz integer, specifying the size of the tempSz
\sa wolfTPM2_RsaKey_TpmToWolf
\sa wolfTPM2_RsaKey_WolfToTpm
*/
WOLFTPM_API int wolfTPM2_RsaKey_TpmToPem(WOLFTPM2_DEV* dev,
WOLFTPM_API int wolfTPM2_RsaKey_TpmToPemPub(WOLFTPM2_DEV* dev,
WOLFTPM2_KEY* keyBlob,
byte* pem, int* pemSz,
byte* tempBuf, int tempSz);
byte* pem, word32* pemSz);
/*!
\ingroup wolfTPM2_Wrappers
@ -1102,15 +1099,13 @@ WOLFTPM_API int wolfTPM2_RsaKey_WolfToTpm_ex(WOLFTPM2_DEV* dev,
\param tpmKey pointer to an empty struct of WOLFTPM2_KEY type, to hold the imported TPM key
\param pem pointer to an array of byte type, containing a PEM formated public key material
\param pemSz pointer to integer variable, specifying the size of PEM key data
\param tempBuf pointer to an array of byte type, to be used as temporary storage
\param tempSz integer variable, specifying the size of the buffer
\sa wolfTPM2_RsaKey_WolfToTpm
\sa wolfTPM2_RsaKey_TpmToPem
\sa wolfTPM2_RsaKey_TpmToWolf
*/
int wolfTPM2_RsaKey_PubPemToTpm(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
byte* pem, int pemSz, byte* tempBuf, int tempSz);
WOLFTPM_API int wolfTPM2_RsaKey_PubPemToTpm(WOLFTPM2_DEV* dev,
WOLFTPM2_KEY* tpmKey, const byte* pem, word32 pemSz);
#endif
#ifdef HAVE_ECC
/*!