mirror of https://github.com/wolfSSL/wolfTPM.git
Merge pull request #597 from aidangarske/tpm2-core-fixes-11899
Fix TPM2 core parsing key import and response handlingpull/603/head
commit
ed48b8dd23
|
|
@ -1921,6 +1921,10 @@ TPM_RC TPM2_Unseal(Unseal_In* in, Unseal_Out* out)
|
|||
(UINT16)sizeof(out->outData.buffer));
|
||||
}
|
||||
|
||||
/* Wipe the shared buffer so the unsealed plaintext does not linger in
|
||||
* the caller-owned context on any post-send path */
|
||||
TPM2_ForceZero(ctx->cmdBuf, sizeof(ctx->cmdBuf));
|
||||
|
||||
TPM2_ReleaseLock(ctx);
|
||||
}
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -1723,7 +1723,7 @@ TPM_RC TPM2_Packet_Parse(TPM_RC rc, TPM2_Packet* packet)
|
|||
* malicious or MITM responder could inflate respSz and cause
|
||||
* downstream parsers (bounded only by packet->size) to read
|
||||
* past the physical allocation. */
|
||||
if (respSz > (UINT32)packet->size) {
|
||||
if (respSz < TPM2_HEADER_SIZE || respSz > (UINT32)packet->size) {
|
||||
return TPM_RC_SIZE;
|
||||
}
|
||||
packet->size = respSz;
|
||||
|
|
|
|||
|
|
@ -484,7 +484,8 @@ int TPM2_TIS_GetBurstCount(TPM2_CTX* ctx, word16* burstCount)
|
|||
int TPM2_TIS_ValidateRspSz(int rspSz, int packetSize)
|
||||
{
|
||||
int rc = TPM_RC_SUCCESS;
|
||||
if (rspSz < 0 || rspSz >= MAX_RESPONSE_SIZE || rspSz > packetSize) {
|
||||
if (rspSz < TPM2_HEADER_SIZE || rspSz > MAX_RESPONSE_SIZE ||
|
||||
rspSz > packetSize) {
|
||||
rc = TPM_RC_FAILURE;
|
||||
}
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -549,6 +549,7 @@ WOLFTPM2_DEV* wolfTPM2_New(void)
|
|||
sizeof(WOLFTPM2_DEV), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (dev != NULL) {
|
||||
if (wolfTPM2_Init(dev, TPM2_IoCb, NULL) != TPM_RC_SUCCESS) {
|
||||
TPM2_ForceZero(dev, sizeof(WOLFTPM2_DEV));
|
||||
XFREE(dev, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
dev = NULL;
|
||||
}
|
||||
|
|
@ -1576,7 +1577,8 @@ int wolfTPM2_SpdmConnectNuvoton(WOLFTPM2_DEV* dev,
|
|||
return rc;
|
||||
}
|
||||
}
|
||||
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(HAVE_ECC)
|
||||
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(HAVE_ECC) && \
|
||||
defined(ECC_TIMING_RESISTANT)
|
||||
else {
|
||||
/* Auto-generate ephemeral P-384 key pair for mutual authentication */
|
||||
ecc_key hostKey;
|
||||
|
|
@ -1664,6 +1666,11 @@ int wolfTPM2_SpdmConnectNuvoton(WOLFTPM2_DEV* dev,
|
|||
tpmtPub, (word32)(p - tpmtPub));
|
||||
if (rc != 0) return rc;
|
||||
}
|
||||
#elif !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(HAVE_ECC)
|
||||
else {
|
||||
/* Requester key auto-generation requires timing-resistant ECC */
|
||||
return NOT_COMPILED_IN;
|
||||
}
|
||||
#endif /* !WOLFTPM2_NO_WOLFCRYPT && HAVE_ECC */
|
||||
|
||||
/* Perform the Nuvoton SPDM handshake */
|
||||
|
|
@ -1762,7 +1769,8 @@ int wolfTPM2_SpdmConnectNations(WOLFTPM2_DEV* dev,
|
|||
return rc;
|
||||
}
|
||||
}
|
||||
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(HAVE_ECC)
|
||||
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(HAVE_ECC) && \
|
||||
defined(ECC_TIMING_RESISTANT)
|
||||
else {
|
||||
/* Auto-generate ephemeral P-384 key pair for mutual authentication.
|
||||
* Nations: GIVE_PUB is not supported, but MUT_AUTH is still required.
|
||||
|
|
@ -1838,6 +1846,11 @@ int wolfTPM2_SpdmConnectNations(WOLFTPM2_DEV* dev,
|
|||
tpmtPub, (word32)(p - tpmtPub));
|
||||
if (rc != 0) return rc;
|
||||
}
|
||||
#elif !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(HAVE_ECC)
|
||||
else {
|
||||
/* Requester key auto-generation requires timing-resistant ECC */
|
||||
return NOT_COMPILED_IN;
|
||||
}
|
||||
#endif /* !WOLFTPM2_NO_WOLFCRYPT && HAVE_ECC */
|
||||
|
||||
/* Perform the TCG SPDM handshake */
|
||||
|
|
@ -3624,19 +3637,28 @@ static int SensitiveToPrivate(TPM2B_SENSITIVE* sens, TPM2B_PRIVATE* priv,
|
|||
if (parentKey != NULL) {
|
||||
symKey.size = parentKey->handle.symmetric.keyBits.sym;
|
||||
}
|
||||
else {
|
||||
else if (sym != NULL) {
|
||||
symKey.size = sym->keyBits.sym;
|
||||
}
|
||||
/* convert from bit to byte and round up */
|
||||
symKey.size = (symKey.size + 7) / 8;
|
||||
/* check for invalid value */
|
||||
if (symKey.size > sizeof(symKey.buffer)) {
|
||||
rc = BUFFER_E;
|
||||
else {
|
||||
rc = BAD_FUNC_ARG;
|
||||
}
|
||||
if (rc == 0) {
|
||||
/* convert from bit to byte and round up */
|
||||
symKey.size = (symKey.size + 7) / 8;
|
||||
/* check for invalid value */
|
||||
if (symKey.size > sizeof(symKey.buffer)) {
|
||||
rc = BUFFER_E;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (innerWrap) {
|
||||
/* TODO: Inner wrap support */
|
||||
if (innerWrap && !outerWrap) {
|
||||
/* A symmetric definition without an outer wrap seed would emit the
|
||||
* sensitive unprotected (inner-wrap-only is not implemented); reject
|
||||
* rather than return success with plaintext. When an outer wrap is
|
||||
* present it applies this symmetric encryption. */
|
||||
rc = NOT_COMPILED_IN;
|
||||
}
|
||||
|
||||
if (rc == 0 && outerWrap) {
|
||||
|
|
@ -4846,7 +4868,7 @@ int wolfTPM2_RsaPrivateKeyImportDer(WOLFTPM2_DEV* dev,
|
|||
int initRc = -1;
|
||||
RsaKey key[1];
|
||||
word32 idx = 0;
|
||||
word32 e;
|
||||
word32 e = 0;
|
||||
byte n[RSA_MAX_SIZE / 8];
|
||||
byte d[RSA_MAX_SIZE / 8];
|
||||
byte p[RSA_MAX_SIZE / 8];
|
||||
|
|
@ -4865,8 +4887,13 @@ int wolfTPM2_RsaPrivateKeyImportDer(WOLFTPM2_DEV* dev,
|
|||
if (rc == 0)
|
||||
rc = initRc = wc_InitRsaKey(key, NULL);
|
||||
|
||||
if (rc == 0)
|
||||
if (rc == 0) {
|
||||
#ifdef HAVE_PKCS8
|
||||
/* Skip a PKCS#8 wrapper if present (BEGIN PRIVATE KEY) */
|
||||
(void)wc_GetPkcs8TraditionalOffset((byte*)input, &idx, inSz);
|
||||
#endif
|
||||
rc = wc_RsaPrivateKeyDecode(input, &idx, key, inSz);
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
|
|
@ -4896,10 +4923,38 @@ int wolfTPM2_RsaPrivateKeyImportPem(WOLFTPM2_DEV* dev,
|
|||
const char* input, word32 inSz, char* pass,
|
||||
TPMI_ALG_RSA_SCHEME scheme, TPMI_ALG_HASH hashAlg)
|
||||
{
|
||||
(void)scheme;
|
||||
(void)hashAlg;
|
||||
return wolfTPM2_ImportPrivateKeyBuffer(dev, parentKey, TPM_ALG_RSA, keyBlob,
|
||||
ENCODING_TYPE_PEM, input, inSz, pass, 0, NULL, 0);
|
||||
int rc;
|
||||
byte* derBuf;
|
||||
word32 derSz;
|
||||
word32 derBufSz;
|
||||
|
||||
if (dev == NULL || parentKey == NULL || keyBlob == NULL ||
|
||||
input == NULL || inSz == 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* der size is base 64 decode length */
|
||||
if (inSz > (0xFFFFFFFFU / 3))
|
||||
return BAD_FUNC_ARG;
|
||||
derSz = inSz * 3 / 4 + 1;
|
||||
derBufSz = derSz;
|
||||
derBuf = (byte*)XMALLOC(derBufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (derBuf == NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
/* Convert PEM to DER, then import through the DER path so the requested
|
||||
* RSA scheme and hash are applied. The DER importer skips any PKCS#8
|
||||
* wrapper wc_KeyPemToDer leaves in place. */
|
||||
rc = wc_KeyPemToDer((byte*)input, inSz, derBuf, derBufSz, pass);
|
||||
if (rc >= 0) {
|
||||
derSz = (word32)rc;
|
||||
rc = wolfTPM2_RsaPrivateKeyImportDer(dev, parentKey, keyBlob,
|
||||
derBuf, derSz, scheme, hashAlg);
|
||||
}
|
||||
|
||||
TPM2_ForceZero(derBuf, derBufSz);
|
||||
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return rc;
|
||||
}
|
||||
#endif /* WOLFTPM2_PEM_DECODE */
|
||||
|
||||
|
|
|
|||
|
|
@ -6110,6 +6110,10 @@ static void test_TPM2_TIS_ValidateRspSz(void)
|
|||
AssertIntEQ(TPM2_TIS_ValidateRspSz(packetSize + 1, packetSize),
|
||||
TPM_RC_FAILURE);
|
||||
AssertIntEQ(TPM2_TIS_ValidateRspSz(MAX_RESPONSE_SIZE, MAX_RESPONSE_SIZE),
|
||||
TPM_RC_SUCCESS);
|
||||
AssertIntEQ(TPM2_TIS_ValidateRspSz(MAX_RESPONSE_SIZE + 1,
|
||||
MAX_RESPONSE_SIZE), TPM_RC_FAILURE);
|
||||
AssertIntEQ(TPM2_TIS_ValidateRspSz(TPM2_HEADER_SIZE - 1, packetSize),
|
||||
TPM_RC_FAILURE);
|
||||
AssertIntEQ(TPM2_TIS_ValidateRspSz(-1, packetSize),
|
||||
TPM_RC_FAILURE);
|
||||
|
|
|
|||
|
|
@ -412,6 +412,11 @@ typedef enum {
|
|||
TPM_RC_BINDING = RC_FMT1 + 0x025,
|
||||
TPM_RC_CURVE = RC_FMT1 + 0x026,
|
||||
TPM_RC_ECC_POINT = RC_FMT1 + 0x027,
|
||||
#ifdef WOLFTPM_V185
|
||||
/* Part 2 v1.85 Sec.6.6.3 Table 17 firmware/SVN-limited codes */
|
||||
TPM_RC_FW_LIMITED = RC_FMT1 + 0x028,
|
||||
TPM_RC_SVN_LIMITED = RC_FMT1 + 0x029,
|
||||
#endif
|
||||
/* TCG Part 2 Sec.6.6.3 Table 17 -- present since v1.16, not v1.85 */
|
||||
TPM_RC_PARMS = RC_FMT1 + 0x02A,
|
||||
#ifdef WOLFTPM_PQC
|
||||
|
|
@ -419,6 +424,11 @@ typedef enum {
|
|||
TPM_RC_EXT_MU = RC_FMT1 + 0x02B,
|
||||
TPM_RC_ONE_SHOT_SIGNATURE = RC_FMT1 + 0x02C,
|
||||
TPM_RC_SIGN_CONTEXT_KEY = RC_FMT1 + 0x02D,
|
||||
#endif
|
||||
#ifdef WOLFTPM_V185
|
||||
/* Part 2 v1.85 Sec.6.6.3 Table 17 channel protocol codes */
|
||||
TPM_RC_CHANNEL = RC_FMT1 + 0x030,
|
||||
TPM_RC_CHANNEL_KEY = RC_FMT1 + 0x031,
|
||||
#endif
|
||||
RC_MAX_FMT1 = RC_FMT1 + 0x03F,
|
||||
|
||||
|
|
@ -873,11 +883,12 @@ enum TPMA_OBJECT_mask {
|
|||
TPMA_OBJECT_restricted = 0x00010000,
|
||||
TPMA_OBJECT_decrypt = 0x00020000,
|
||||
TPMA_OBJECT_sign = 0x00040000,
|
||||
#ifndef WOLFTPM_V185
|
||||
/* Deprecated alias. Earlier versions of this header labeled bit 9
|
||||
* as derivedDataOrigin, which does not appear in the TCG spec.
|
||||
* Retained at the same bit value (now svnLimited per Part 2 v1.85)
|
||||
* for source compatibility with downstream code. */
|
||||
* In v1.85 builds bit 9 is exposed only as svnLimited. */
|
||||
TPMA_OBJECT_derivedDataOrigin = 0x00000200,
|
||||
#endif
|
||||
#ifdef WOLFTPM_V185
|
||||
/* Part 2 v1.85 Sec.8.3.2 Table 36 bits 8 and 9: firmwareLimited /
|
||||
* svnLimited mark keys whose lifetime is bound to the firmware
|
||||
|
|
|
|||
Loading…
Reference in New Issue