Skip to content

Commit

Permalink
Added wolfTPM2_GetKeyTemplate_EK for getting EK for non standard RS…
Browse files Browse the repository at this point in the history
…A key sizes and ECC curves.
  • Loading branch information
dgarske committed Jul 5, 2024
1 parent ee67f17 commit 7bdfd25
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 56 deletions.
64 changes: 36 additions & 28 deletions examples/endorsement/get_ek_certs.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@
#include <examples/endorsement/endorsement.h>
#include <hal/tpm_io.h>
#include <examples/tpm_test.h>

#ifndef WOLFTPM2_NO_WOLFCRYPT
#include <wolfssl/wolfcrypt/asn.h>
#endif

/******************************************************************************/
/* --- BEGIN TPM2.0 Endorsement certificate tool -- */
Expand All @@ -62,10 +64,14 @@ int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[])
WOLFTPM2_KEY endorse;
uint8_t certBuf[MAX_CERT_SZ];
uint32_t certSz;
uint32_t keyBits;
TPM_ECC_CURVE curveID;
TPM_ALG_ID alg;
uint32_t keyBits = 0;
TPM_ECC_CURVE curveID = TPM_ECC_NONE;
TPM_ALG_ID alg = TPM_ALG_NULL;
TPM_ALG_ID nameAlg = TPM_ALG_NULL;
TPMT_PUBLIC publicTemplate;
#ifndef WOLFTPM2_NO_WOLFCRYPT
DecodedCert cert;
#endif

XMEMSET(&endorse, 0, sizeof(endorse));
XMEMSET(&handles, 0, sizeof(handles));
Expand Down Expand Up @@ -112,39 +118,48 @@ int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[])
case TPM2_NV_RSA_EK_CERT: /* EK (Low Range): RSA 2048 */
case TPM2_NV_EK_RSA2048: /* EK (High Range) */
alg = TPM_ALG_RSA;
nameAlg = TPM_ALG_SHA256;
keyBits = 2048;
break;
case TPM2_NV_EK_RSA3072:
alg = TPM_ALG_RSA;
nameAlg = TPM_ALG_SHA384;
keyBits = 3072;
break;
case TPM2_NV_EK_RSA4096:
alg = TPM_ALG_RSA;
nameAlg = TPM_ALG_SHA512;
keyBits = 4096;
break;
case TPM2_NV_ECC_EK_CERT: /* EK (Low Range): ECC P256 */
case TPM2_NV_EK_ECC_P256: /* EK (High Range) */
alg = TPM_ALG_ECC;
curveID = TPM_ECC_NIST_P256;
nameAlg = TPM_ALG_SHA256;
keyBits = 256;
break;
case TPM2_NV_EK_ECC_P384:
alg = TPM_ALG_ECC;
curveID = TPM_ECC_NIST_P384;
nameAlg = TPM_ALG_SHA384;
keyBits = 384;
break;
case TPM2_NV_EK_ECC_P521:
alg = TPM_ALG_ECC;
curveID = TPM_ECC_NIST_P521;
nameAlg = TPM_ALG_SHA512;
keyBits = 521;
break;
case TPM2_NV_EK_ECC_SM2:
alg = TPM_ALG_SM2;
curveID = TPM_ECC_SM2_P256;
nameAlg = TPM_ALG_SHA256;
keyBits = 256;
break;
default:
alg = TPM_ALG_NULL;
curveID = TPM_ECC_NONE;
nameAlg = TPM_ALG_NULL;
keyBits = 0;
break;
}
Expand All @@ -165,30 +180,10 @@ int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[])
#endif
}

#ifndef WOLFTPM2_NO_WOLFCRYPT
/* Attempt to parse certificate */

#endif

XMEMSET(&publicTemplate, 0, sizeof(publicTemplate));
if (alg == TPM_ALG_RSA) {
rc = wolfTPM2_GetKeyTemplate_RSA_EK(&publicTemplate);
if (rc == 0) {
/* Adjust for RSA key size */
publicTemplate.unique.rsa.size = keyBits / 8;
publicTemplate.parameters.rsaDetail.keyBits = keyBits;
}
}
else if (alg == TPM_ALG_ECC) {
rc = wolfTPM2_GetKeyTemplate_ECC_EK(&publicTemplate);
if (rc == 0) {
/* Adjust for curve */
publicTemplate.unique.ecc.x.size = keyBits / 8;
publicTemplate.unique.ecc.y.size = keyBits / 8;
publicTemplate.parameters.eccDetail.curveID = curveID;
}
}
else {
rc = wolfTPM2_GetKeyTemplate_EK(&publicTemplate, alg, keyBits, curveID,
nameAlg);
if (rc != 0) {
printf("Invalid EK algorithm\n");
rc = BAD_FUNC_ARG;
}
if (rc == 0) {
Expand All @@ -203,8 +198,21 @@ int TPM2_EndorsementCert_Example(void* userCtx, int argc, char *argv[])
TPM2_PrintPublicArea(&endorse.pub);
#endif

/* TODO: Confirm the certificate public key matches this
* public key */

wolfTPM2_UnloadHandle(&dev, &endorse.handle);
}

#ifndef WOLFTPM2_NO_WOLFCRYPT
if (rc == 0) {
/* Attempt to parse certificate */
wc_InitDecodedCert(&cert, certBuf, certSz, NULL);
rc = wc_ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL);
printf("Parse Cert result: %d\n", rc);
wc_FreeDecodedCert(&cert);
}
#endif
}

exit:
Expand Down
73 changes: 51 additions & 22 deletions src/tpm2_wrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,12 @@ static int wolfTPM2_EncryptSecret_RSA(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* tpm
hashType = WC_HASH_TYPE_SHA256;
mgf = WC_MGF1SHA256;
}
#ifdef WOLFSSL_SHA384
else if (publicArea->nameAlg == TPM_ALG_SHA384) {
hashType = WC_HASH_TYPE_SHA384;
mgf = WC_MGF1SHA384;
}
#endif
else {
return NOT_COMPILED_IN;
}
Expand Down Expand Up @@ -5711,7 +5717,8 @@ int GetKeyTemplateRSA(TPMT_PUBLIC* publicTemplate,
((objectAttributes & TPMA_OBJECT_decrypt) &&
(objectAttributes & TPMA_OBJECT_restricted))) {
publicTemplate->parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES;
publicTemplate->parameters.rsaDetail.symmetric.keyBits.aes = 128;
publicTemplate->parameters.rsaDetail.symmetric.keyBits.aes =
(keyBits > 2048) ? 256 : 128;
publicTemplate->parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_CFB;
}
else {
Expand Down Expand Up @@ -5750,7 +5757,8 @@ int GetKeyTemplateECC(TPMT_PUBLIC* publicTemplate,
((objectAttributes & TPMA_OBJECT_decrypt) &&
(objectAttributes & TPMA_OBJECT_restricted))) {
publicTemplate->parameters.eccDetail.symmetric.algorithm = TPM_ALG_AES;
publicTemplate->parameters.eccDetail.symmetric.keyBits.aes = 128;
publicTemplate->parameters.eccDetail.symmetric.keyBits.aes =
(curveSz >= 48) ? 256 : 128;
publicTemplate->parameters.eccDetail.symmetric.mode.aes = TPM_ALG_CFB;
}
else {
Expand Down Expand Up @@ -5857,40 +5865,61 @@ int wolfTPM2_GetKeyTemplate_KeySeal(TPMT_PUBLIC* publicTemplate, TPM_ALG_ID name
return TPM_RC_SUCCESS;
}

int wolfTPM2_GetKeyTemplate_RSA_EK(TPMT_PUBLIC* publicTemplate)
int wolfTPM2_GetKeyTemplate_EK(TPMT_PUBLIC* publicTemplate, TPM_ALG_ID alg,
int keyBits, TPM_ECC_CURVE curveID, TPM_ALG_ID nameAlg)
{
int ret;
int rc;
TPMA_OBJECT objectAttributes = (
TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent |
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_adminWithPolicy |
TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt);

ret = GetKeyTemplateRSA(publicTemplate, TPM_ALG_SHA256,
objectAttributes, 2048, 0, TPM_ALG_NULL, TPM_ALG_NULL);
if (ret == 0) {
if (alg == TPM_ALG_RSA) {
rc = GetKeyTemplateRSA(publicTemplate, nameAlg,
objectAttributes, keyBits, 0, TPM_ALG_NULL, TPM_ALG_NULL);
}
else if (alg == TPM_ALG_ECC) {
rc = GetKeyTemplateECC(publicTemplate, nameAlg,
objectAttributes, curveID, TPM_ALG_NULL, TPM_ALG_NULL);

}
else {
rc = BAD_FUNC_ARG; /* not yet supported */
}

if (nameAlg == TPM_ALG_SHA256) {
publicTemplate->authPolicy.size = sizeof(TPM_20_EK_AUTH_POLICY);
XMEMCPY(publicTemplate->authPolicy.buffer,
TPM_20_EK_AUTH_POLICY, publicTemplate->authPolicy.size);
}
return ret;
#ifdef WOLFSSL_SHA384
else if (nameAlg == TPM_ALG_SHA384) {
publicTemplate->authPolicy.size = sizeof(TPM_20_EK_AUTH_POLICY_SHA384);
XMEMCPY(publicTemplate->authPolicy.buffer,
TPM_20_EK_AUTH_POLICY_SHA384, publicTemplate->authPolicy.size);
}
#endif
#ifdef WOLFSSL_SHA512
else if (nameAlg == TPM_ALG_SHA512) {
publicTemplate->authPolicy.size = sizeof(TPM_20_EK_AUTH_POLICY_SHA512);
XMEMCPY(publicTemplate->authPolicy.buffer,
TPM_20_EK_AUTH_POLICY_SHA512, publicTemplate->authPolicy.size);
}
#endif

return rc;
}

int wolfTPM2_GetKeyTemplate_ECC_EK(TPMT_PUBLIC* publicTemplate)
int wolfTPM2_GetKeyTemplate_RSA_EK(TPMT_PUBLIC* publicTemplate)
{
int ret;
TPMA_OBJECT objectAttributes = (
TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent |
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_adminWithPolicy |
TPMA_OBJECT_restricted | TPMA_OBJECT_decrypt);
return wolfTPM2_GetKeyTemplate_EK(publicTemplate, TPM_ALG_RSA, 2048,
TPM_ALG_NULL, TPM_ALG_SHA256);
}

ret = GetKeyTemplateECC(publicTemplate, TPM_ALG_SHA256,
objectAttributes, TPM_ECC_NIST_P256, TPM_ALG_NULL, TPM_ALG_NULL);
if (ret == 0) {
publicTemplate->authPolicy.size = sizeof(TPM_20_EK_AUTH_POLICY);
XMEMCPY(publicTemplate->authPolicy.buffer,
TPM_20_EK_AUTH_POLICY, publicTemplate->authPolicy.size);
}
return ret;
int wolfTPM2_GetKeyTemplate_ECC_EK(TPMT_PUBLIC* publicTemplate)
{
return wolfTPM2_GetKeyTemplate_EK(publicTemplate, TPM_ALG_ECC, 256,
TPM_ECC_NIST_P256, TPM_ALG_SHA256);
}

int wolfTPM2_GetKeyTemplate_RSA_SRK(TPMT_PUBLIC* publicTemplate)
Expand Down
35 changes: 29 additions & 6 deletions wolftpm/tpm2.h
Original file line number Diff line number Diff line change
Expand Up @@ -1672,14 +1672,37 @@ typedef struct TPM2_AUTH_SESSION {
#define TPM2_NV_EK_CHAIN (TPM_20_TCG_NV_SPACE + 0x100)

/* Predetermined TPM 2.0 Endorsement policy auth template for SHA2-256 */
/* Can also be read from NV Index 0x01C07F01 */
/* SHA256 (can be read from NV index 0x01C07F01) */
static const BYTE TPM_20_EK_AUTH_POLICY[] = {
0x83, 0x71, 0x97, 0x67, 0x44, 0x84, 0xb3, 0xf8, 0x1a, 0x90, 0xcc,
0x8d, 0x46, 0xa5, 0xd7, 0x24, 0xfd, 0x52, 0xd7, 0x6e, 0x06, 0x52,
0x0b, 0x64, 0xf2, 0xa1, 0xda, 0x1b, 0x33, 0x14, 0x69, 0xaa,
0x83, 0x71, 0x97, 0x67, 0x44, 0x84, 0xB3, 0xF8,
0x1A, 0x90, 0xCC, 0x8D, 0x46, 0xA5, 0xD7, 0x24,
0xFD, 0x52, 0xD7, 0x6E, 0x06, 0x52, 0x0B, 0x64,
0xF2, 0xA1, 0xDA, 0x1B, 0x33, 0x14, 0x69, 0xAA
};


#ifdef WOLFSSL_SHA384
/* SHA384 (can be read from NV index 0x01C07F02) */
static const BYTE TPM_20_EK_AUTH_POLICY_SHA384[] = {
0x8B, 0xBF, 0x22, 0x66, 0x53, 0x7C, 0x17, 0x1C,
0xB5, 0x6E, 0x40, 0x3C, 0x4D, 0xC1, 0xD4, 0xB6,
0x4F, 0x43, 0x26, 0x11, 0xDC, 0x38, 0x6E, 0x6F,
0x53, 0x20, 0x50, 0xC3, 0x27, 0x8C, 0x93, 0x0E,
0x14, 0x3E, 0x8B, 0xB1, 0x13, 0x38, 0x24, 0xCC,
0xB4, 0x31, 0x05, 0x38, 0x71, 0xC6, 0xDB, 0x53
};
#endif
#ifdef WOLFSSL_SHA512
/* SHA512 (can be read from NV index 0x01C07F03) */
static const BYTE TPM_20_EK_AUTH_POLICY_SHA512[] = {
0x1E, 0x3B, 0x76, 0x50, 0x2C, 0x8A, 0x14, 0x25,
0xAA, 0x0B, 0x7B, 0x3F, 0xC6, 0x46, 0xA1, 0xB0,
0xFA, 0xE0, 0x63, 0xB0, 0x3B, 0x53, 0x68, 0xF9,
0xC4, 0xCD, 0xDE, 0xCA, 0xFF, 0x08, 0x91, 0xDD,
0x68, 0x2B, 0xAC, 0x1A, 0x85, 0xD4, 0xD8, 0x32,
0xB7, 0x81, 0xEA, 0x45, 0x19, 0x15, 0xDE, 0x5F,
0xC5, 0xBF, 0x0D, 0xC4, 0xA1, 0x91, 0x7C, 0xD4,
0x2F, 0xA0, 0x41, 0xE3, 0xF9, 0x98, 0xE0, 0xEE
};
#endif

/* HAL IO Callbacks */
struct TPM2_CTX;
Expand Down
22 changes: 22 additions & 0 deletions wolftpm/tpm2_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -2674,6 +2674,26 @@ WOLFTPM_API int wolfTPM2_GetKeyTemplate_KeyedHash(TPMT_PUBLIC* publicTemplate,
*/
WOLFTPM_API int wolfTPM2_GetKeyTemplate_KeySeal(TPMT_PUBLIC* publicTemplate, TPM_ALG_ID nameAlg);

/*!
\ingroup wolfTPM2_Wrappers
\brief Prepares a TPM public template for generating the TPM Endorsement Key
\return TPM_RC_SUCCESS: successful
\return BAD_FUNC_ARG: check the provided arguments
\param publicTemplate pointer to an empty structure of TPMT_PUBLIC type, to store the new template
\param alg can be only TPM_ALG_RSA or TPM_ALG_ECC, see Note above
\param keyBits integer value, specifying bits for the key, typically 2048 (RSA) or 256 (ECC)
\param curveId use one of the accepted TPM_ECC_CURVE values like TPM_ECC_NIST_P256 (only used when alg=TPM_ALG_ECC)
\param nameAlg integer value of TPMI_ALG_HASH type, specifying a valid TPM2 hashing algorithm (typically TPM_ALG_SHA256)
\sa wolfTPM2_GetKeyTemplate_ECC_EK
\sa wolfTPM2_GetKeyTemplate_RSA_SRK
\sa wolfTPM2_GetKeyTemplate_RSA_AIK
*/
WOLFTPM_API int wolfTPM2_GetKeyTemplate_EK(TPMT_PUBLIC* publicTemplate, TPM_ALG_ID alg,
int keyBits, TPM_ECC_CURVE curveID, TPM_ALG_ID nameAlg);

/*!
\ingroup wolfTPM2_Wrappers
\brief Prepares a TPM public template for generating the TPM Endorsement Key of RSA type
Expand All @@ -2683,6 +2703,7 @@ WOLFTPM_API int wolfTPM2_GetKeyTemplate_KeySeal(TPMT_PUBLIC* publicTemplate, TPM
\param publicTemplate pointer to an empty structure of TPMT_PUBLIC type, to store the new template
\sa wolfTPM2_GetKeyTemplate_EK
\sa wolfTPM2_GetKeyTemplate_ECC_EK
\sa wolfTPM2_GetKeyTemplate_RSA_SRK
\sa wolfTPM2_GetKeyTemplate_RSA_AIK
Expand All @@ -2698,6 +2719,7 @@ WOLFTPM_API int wolfTPM2_GetKeyTemplate_RSA_EK(TPMT_PUBLIC* publicTemplate);
\param publicTemplate pointer to an empty structure of TPMT_PUBLIC type, to store the new template
\sa wolfTPM2_GetKeyTemplate_EK
\sa wolfTPM2_GetKeyTemplate_RSA_EK
\sa wolfTPM2_GetKeyTemplate_ECC_SRK
\sa wolfTPM2_GetKeyTemplate_ECC_AIK
Expand Down

0 comments on commit 7bdfd25

Please sign in to comment.