mirror of https://github.com/wolfSSL/wolfTPM.git
Add support for pre-provisioned TPM using the "TPM 2.0 Keys for Device Identity and Attestation" specification. Build macro: `WOLFTPM_MFG_IDENTITY`.
parent
c4880bee18
commit
63bb85ae9d
42
src/tpm2.c
42
src/tpm2.c
|
@ -5261,16 +5261,38 @@ TPM_RC TPM2_GetProductInfo(uint8_t* info, uint16_t size)
|
|||
{
|
||||
TPM_RC rc;
|
||||
TPM2_CTX* ctx = TPM2_GetActiveCtx();
|
||||
|
||||
TPM2_Packet packet;
|
||||
TPM2_Packet_Init(ctx, &packet);
|
||||
TPM2_Packet_AppendU32(&packet, 0x100);
|
||||
TPM2_Packet_AppendU32(&packet, 3);
|
||||
TPM2_Packet_AppendU32(&packet, 1);
|
||||
TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_GetCapability);
|
||||
|
||||
rc = TPM2_SendCommand(ctx, &packet);
|
||||
if (rc == TPM_RC_SUCCESS) memcpy(info, &packet.buf[25], size);
|
||||
|
||||
if (ctx == NULL || info == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
rc = TPM2_AcquireLock(ctx);
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
TPM2_Packet packet;
|
||||
TPM2_Packet_Init(ctx, &packet);
|
||||
TPM2_Packet_AppendU32(&packet, TPM_CAP_VENDOR_PROPERTY);
|
||||
TPM2_Packet_AppendU32(&packet, 3); /* cTPM_SUBCAP_VENDOR_GET_PRODUCT_INFO */
|
||||
TPM2_Packet_AppendU32(&packet, 1); /* only 1 property */
|
||||
TPM2_Packet_Finalize(&packet, TPM_ST_NO_SESSIONS, TPM_CC_GetCapability);
|
||||
|
||||
/* send command */
|
||||
rc = TPM2_SendCommand(ctx, &packet);
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
/* Product info is:
|
||||
* Serial Number (7 bytes)
|
||||
* Pad (1 byte)
|
||||
* Product ID (PIN) (2 bytes)
|
||||
* Master Product ID (MPIN) (2 bytes)
|
||||
* Product Internal Revision (1 byte)
|
||||
* Pad (3 bytes)
|
||||
* Firmware kernel version (4 bytes)
|
||||
*/
|
||||
|
||||
/* start of product info starts at byte 26 */
|
||||
if (size > packet.size - 26)
|
||||
size = packet.size - 26;
|
||||
XMEMCPY(info, &packet.buf[25], size);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#endif /* WOLFTPM_ST33 || WOLFTPM_AUTODETECT */
|
||||
|
|
112
src/tpm2_wrap.c
112
src/tpm2_wrap.c
|
@ -4421,6 +4421,42 @@ int wolfTPM2_NVReadAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv,
|
|||
return rc;
|
||||
}
|
||||
|
||||
int wolfTPM2_NVReadCert(WOLFTPM2_DEV* dev, TPM_HANDLE handle,
|
||||
uint8_t* buffer, uint32_t* len)
|
||||
{
|
||||
int rc;
|
||||
WOLFTPM2_NV nv;
|
||||
TPMS_NV_PUBLIC nvPublic;
|
||||
|
||||
XMEMSET(&nvPublic, 0, sizeof(nvPublic));
|
||||
XMEMSET(&nv, 0, sizeof(nv));
|
||||
|
||||
/* Get or check size of NV */
|
||||
rc = wolfTPM2_NVReadPublic(dev, handle, &nvPublic);
|
||||
if (rc == 0) {
|
||||
if (buffer == NULL) {
|
||||
/* just return size */
|
||||
*len = nvPublic.dataSize;
|
||||
return 0;
|
||||
}
|
||||
if (nvPublic.dataSize > *len) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG_WOLFTPM
|
||||
printf("NV public read of handle 0x%x failed %d: %s\n",
|
||||
handle, rc, wolfTPM2_GetRCString(rc));
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Perform read of NV without auth password */
|
||||
nv.handle.hndl = handle;
|
||||
rc = wolfTPM2_NVReadAuth(dev, &nv, handle, buffer, len, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* older API kept for compatibility, recommend using wolfTPM2_NVReadAuth */
|
||||
int wolfTPM2_NVRead(WOLFTPM2_DEV* dev, TPM_HANDLE authHandle,
|
||||
word32 nvIndex, byte* dataBuf, word32* pDataSz, word32 offset)
|
||||
|
@ -7003,4 +7039,80 @@ int wolfTPM2_PolicyAuthorizeMake(TPM_ALG_ID pcrAlg,
|
|||
/* --- END Policy Support -- */
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* --- BEGIN Provisioned TPM Support -- */
|
||||
/******************************************************************************/
|
||||
|
||||
/* pre-provisioned IAK and IDevID key/cert from TPM vendor */
|
||||
#ifdef WOLFTPM_MFG_IDENTITY
|
||||
|
||||
#ifdef TEST_SAMPLE
|
||||
static const uint8_t* TPM2_IAK_SAMPLE_MASTER_PASSWORD = {
|
||||
0xFE, 0xEF, 0x8C, 0xDF, 0x1B, 0x77, 0xBD, 0x00,
|
||||
0x30, 0x58, 0x5E, 0x47, 0xB8, 0x21, 0x46, 0x0B
|
||||
};
|
||||
#endif
|
||||
|
||||
int wolfTPM2_SetIdentityAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* handle,
|
||||
uint8_t* masterPassword, uint16_t masterPasswordSz)
|
||||
{
|
||||
int rc;
|
||||
uint8_t serialNum[7];
|
||||
wc_HashAlg hash_ctx;
|
||||
enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
|
||||
uint8_t digest[TPM_SHA256_DIGEST_SIZE];
|
||||
|
||||
/* Get TPM serial number */
|
||||
rc = TPM2_GetProductInfo(serialNum, (uint16_t)sizeof(serialNum));
|
||||
if (rc != 0) {
|
||||
#ifdef DEBUG_WOLFTPM
|
||||
printf("TPM2_GetProductInfo failed %d: %s\n",
|
||||
rc, wolfTPM2_GetRCString(rc));
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Hash both values */
|
||||
rc = wc_HashInit(&hash_ctx, hashType);
|
||||
if (rc == 0) {
|
||||
rc = wc_HashUpdate(&hash_ctx, hashType, serialNum, sizeof(serialNum));
|
||||
if (rc == 0)
|
||||
#ifdef TEST_SAMPLE
|
||||
rc = wc_HashUpdate(&hash_ctx, hashType,
|
||||
TPM2_IAK_SAMPLE_MASTER_PASSWORD,
|
||||
sizeof(TPM2_IAK_SAMPLE_MASTER_PASSWORD));
|
||||
(void)masterPassword;
|
||||
(void)masterPasswordSs;
|
||||
#else
|
||||
rc = wc_HashUpdate(&hash_ctx, hashType,
|
||||
masterPassword, masterPasswordSz);
|
||||
#endif
|
||||
if (rc == 0) {
|
||||
rc = wc_HashFinal(&hash_ctx, hashType, digest);
|
||||
}
|
||||
|
||||
wc_HashFree(&hash_ctx, hashType);
|
||||
}
|
||||
|
||||
/* Hash Final truncate to 16 bytes */
|
||||
/* Use 16-byte for auth when accessing key */
|
||||
handle->auth.size = 16;
|
||||
XMEMCPY(handle->auth.buffer, &digest[16], 16);
|
||||
|
||||
(void)dev;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* WOLFTPM_MFG_IDENTITY */
|
||||
|
||||
/******************************************************************************/
|
||||
/* --- END Provisioned TPM Support -- */
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* !WOLFTPM2_NO_WRAPPER */
|
||||
|
|
|
@ -1911,6 +1911,9 @@ WOLFTPM_API int wolfTPM2_NVWriteAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv,
|
|||
WOLFTPM_API int wolfTPM2_NVReadAuth(WOLFTPM2_DEV* dev, WOLFTPM2_NV* nv,
|
||||
word32 nvIndex, byte* dataBuf, word32* pDataSz, word32 offset);
|
||||
|
||||
WOLFTPM_API int wolfTPM2_NVReadCert(WOLFTPM2_DEV* dev, TPM_HANDLE handle,
|
||||
uint8_t* buffer, uint32_t* len);
|
||||
|
||||
/*!
|
||||
\ingroup wolfTPM2_Wrappers
|
||||
\brief Increments an NV one-way counter
|
||||
|
@ -3539,6 +3542,23 @@ WOLFTPM_API int wolfTPM2_PolicyAuthorizeMake(TPM_ALG_ID pcrAlg,
|
|||
const byte* policyRef, word32 policyRefSz);
|
||||
|
||||
|
||||
/* pre-provisioned IAK and IDevID key/cert from TPM vendor */
|
||||
#ifdef WOLFTPM_MFG_IDENTITY
|
||||
|
||||
/* Initial attestation key (IAK) and an initial device ID (IDevID) */
|
||||
/* Default is: ECDSA SECP384P1, SHA2-384 */
|
||||
#define TPM2_IAK_KEY_HANDLE 0x81080000
|
||||
#define TPM2_IAK_CERT_HANDLE 0x1C20100
|
||||
|
||||
#define TPM2_IDEVID_KEY_HANDLE 0x81080001
|
||||
#define TPM2_IDEVID_CERT_HANDLE 0x1C20101
|
||||
|
||||
WOLFTPM_API int wolfTPM2_SetIdentityAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* handle,
|
||||
uint8_t* masterPassword, uint16_t masterPasswordSz);
|
||||
|
||||
#endif /* WOLFTPM_MFG_IDENTITY */
|
||||
|
||||
|
||||
/* Internal API's */
|
||||
WOLFTPM_LOCAL int GetKeyTemplateRSA(TPMT_PUBLIC* publicTemplate,
|
||||
TPM_ALG_ID nameAlg, TPMA_OBJECT objectAttributes, int keyBits, long exponent,
|
||||
|
|
Loading…
Reference in New Issue