6745 - Fix RSA exponent byte order in wolfTPM2_RsaKey_TpmToWolf

pull/547/head
aidan garske 2026-07-07 13:19:17 -07:00
parent c29d5ecf3a
commit 9a56a4632d
2 changed files with 51 additions and 7 deletions

View File

@ -4615,11 +4615,12 @@ int wolfTPM2_RsaKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
exponent = tpmKey->pub.publicArea.parameters.rsaDetail.exponent;
if (exponent == 0)
exponent = RSA_DEFAULT_PUBLIC_EXPONENT;
e[3] = (exponent >> 24) & 0xFF;
e[2] = (exponent >> 16) & 0xFF;
e[1] = (exponent >> 8) & 0xFF;
e[0] = exponent & 0xFF;
eSz = e[3] ? 4 : e[2] ? 3 : e[1] ? 2 : e[0] ? 1 : 0; /* calc size */
/* big-endian, matching wc_RsaPublicKeyDecodeRaw and RsaKey_Exponent */
e[0] = (exponent >> 24) & 0xFF;
e[1] = (exponent >> 16) & 0xFF;
e[2] = (exponent >> 8) & 0xFF;
e[3] = exponent & 0xFF;
eSz = e[0] ? 4 : e[1] ? 3 : e[2] ? 2 : e[3] ? 1 : 0; /* significant bytes */
/* load public key */
nSz = tpmKey->pub.publicArea.unique.rsa.size;
@ -4628,8 +4629,8 @@ int wolfTPM2_RsaKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
}
XMEMCPY(n, tpmKey->pub.publicArea.unique.rsa.buffer, nSz);
/* load public key portion into wolf RsaKey */
rc = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, wolfKey);
/* load public key portion into wolf RsaKey (pass trailing significant e) */
rc = wc_RsaPublicKeyDecodeRaw(n, nSz, e + (sizeof(e) - eSz), eSz, wolfKey);
return rc;
}

View File

@ -2695,6 +2695,48 @@ static void test_wolfTPM2_SetIdentityAuth_RequiresPassword(void)
}
#endif /* WOLFTPM_MFG_IDENTITY && !SLB9672 && !SLB9673 */
/* wolfTPM2_RsaKey_TpmToWolf must preserve the exponent for multi-byte
* non-palindromic values. The exponent bytes are big-endian on the wolfCrypt
* side, so a little-endian build would corrupt e.g. 0x010003. */
static void test_wolfTPM2_RsaKey_TpmToWolf_Exponent(void)
{
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_RSA) && \
!defined(WOLFTPM2_NO_WRAPPER)
int rc;
WOLFTPM2_DEV dev;
WOLFTPM2_KEY tpmKey;
RsaKey wolfKey;
byte eOut[8];
byte nOut[256];
word32 eOutSz = (word32)sizeof(eOut);
word32 nOutSz = (word32)sizeof(nOut);
word32 exponent = 0x010003; /* non-palindromic multi-byte exponent */
XMEMSET(&dev, 0, sizeof(dev));
XMEMSET(&tpmKey, 0, sizeof(tpmKey));
tpmKey.pub.publicArea.type = TPM_ALG_RSA;
tpmKey.pub.publicArea.parameters.rsaDetail.exponent = exponent;
tpmKey.pub.publicArea.unique.rsa.size = 128;
XMEMSET(tpmKey.pub.publicArea.unique.rsa.buffer, 0xC7, 128);
rc = wc_InitRsaKey(&wolfKey, NULL);
AssertIntEQ(0, rc);
rc = wolfTPM2_RsaKey_TpmToWolf(&dev, &tpmKey, &wolfKey);
AssertIntEQ(0, rc);
rc = wc_RsaFlattenPublicKey(&wolfKey, eOut, &eOutSz, nOut, &nOutSz);
AssertIntEQ(0, rc);
/* Round-trip: decoded exponent must equal the original TPM exponent */
AssertIntEQ((int)exponent, (int)wolfTPM2_RsaKey_Exponent(eOut, eOutSz));
wc_FreeRsaKey(&wolfKey);
printf("Test TPM Wrapper: %-40s Passed\n", "RsaKey_TpmToWolf exponent:");
#endif
}
/* The ECDH shared-secret copy must reject a TPM response x-coordinate larger
* than the caller's output buffer. TPM2_Packet_ParseEccPoint clamps only to
* MAX_ECC_KEY_BYTES, so a MITM/crafted response can report a point.x.size
@ -6255,6 +6297,7 @@ int unit_tests(int argc, char *argv[])
!defined(WOLFTPM_SLB9672) && !defined(WOLFTPM_SLB9673)
test_wolfTPM2_SetIdentityAuth_RequiresPassword();
#endif
test_wolfTPM2_RsaKey_TpmToWolf_Exponent();
test_wolfTPM2_EccZToBuffer();
test_wolfTPM2_LoadEccPublicKey_Ex();
test_TPM2_KeyedHashScheme_XorSerialize();