@@ -573,13 +573,13 @@ TPM_RC FwDeriveEccPrimaryKey(TPMI_ALG_HASH nameAlg,
573573 rc = TPM_RC_FAILURE ;
574574 break ;
575575 }
576- /* Check d != 0 (all zeros) */
577- allZero = 1 ;
578- for (i = 0 ; i < keySz ; i ++ ) {
579- if (dBuf [i ] != 0 ) {
580- allZero = 0 ;
581- break ;
576+ /* Constant-time check d != 0 (all zeros) */
577+ {
578+ volatile byte orAccum = 0 ;
579+ for (i = 0 ; i < keySz ; i ++ ) {
580+ orAccum |= dBuf [i ];
582581 }
582+ allZero = (orAccum == 0 );
583583 }
584584 if (!allZero ) {
585585 valid = 1 ; /* Accept — range check done by import */
@@ -1060,6 +1060,12 @@ int FwWrapPrivate(FWTPM_Object* parent,
10601060 wc_HmacFree (hmac );
10611061
10621062 /* Pack into TPM2B_PRIVATE */
1063+ if (rc == 0 ) {
1064+ int totalSz = 2 + WC_SHA256_DIGEST_SIZE + 2 + sensSz ;
1065+ if (totalSz > (int )sizeof (outPriv -> buffer )) {
1066+ rc = TPM_RC_SIZE ;
1067+ }
1068+ }
10631069 if (rc == 0 ) {
10641070 /* integritySize(2) + integrity(32) + encSensSize(2) + encSens(N) */
10651071 outPriv -> buffer [pos ++ ] = 0 ;
@@ -1079,6 +1085,8 @@ int FwWrapPrivate(FWTPM_Object* parent,
10791085
10801086 TPM2_ForceZero (aesKey , sizeof (aesKey ));
10811087 TPM2_ForceZero (aesIV , sizeof (aesIV ));
1088+ TPM2_ForceZero (hmacDigest , sizeof (hmacDigest ));
1089+ TPM2_ForceZero (sensBuf , FWTPM_MAX_PRIVKEY_DER + 128 );
10821090 FWTPM_FREE_BUF (sensBuf );
10831091 FWTPM_FREE_VAR (aes );
10841092 FWTPM_FREE_VAR (hmac );
@@ -1284,6 +1292,11 @@ TPM_RC FwDecryptSeed(FWTPM_CTX* ctx,
12841292 if (rc == 0 ) {
12851293 XMEMCPY (xBuf , encSeedBuf + p , xSz );
12861294 p += xSz ;
1295+ if (p + 2 > encSeedSz ) {
1296+ rc = TPM_RC_SIZE ;
1297+ }
1298+ }
1299+ if (rc == 0 ) {
12871300 ySz = FwLoadU16BE (encSeedBuf + p );
12881301 p += 2 ;
12891302 if (ySz > MAX_ECC_BYTES || p + ySz > encSeedSz ) {
@@ -1433,6 +1446,9 @@ TPM_RC FwEncryptSeed(FWTPM_CTX* ctx,
14331446 wc_FreeRsaKey (rsaKey );
14341447 }
14351448 FWTPM_FREE_VAR (rsaKey );
1449+ if (rc != 0 ) {
1450+ TPM2_ForceZero (seedBuf , seedBufSz );
1451+ }
14361452 }
14371453 else
14381454#endif /* !NO_RSA */
@@ -1551,6 +1567,9 @@ TPM_RC FwEncryptSeed(FWTPM_CTX* ctx,
15511567 TPM2_ForceZero (sharedZ , sizeof (sharedZ ));
15521568 FWTPM_FREE_VAR (parentPub );
15531569 FWTPM_FREE_VAR (ephemKey );
1570+ if (rc != 0 ) {
1571+ TPM2_ForceZero (seedBuf , seedBufSz );
1572+ }
15541573 }
15551574 else
15561575#endif /* HAVE_ECC */
@@ -1677,6 +1696,11 @@ TPM_RC FwImportVerifyAndDecrypt(
16771696 if (rc == 0 ) {
16781697 * plainSensSzOut = encSensSz ;
16791698 }
1699+ else {
1700+ /* Zero caller's output buffer on any failure — it may contain
1701+ * partially decrypted sensitive data. */
1702+ TPM2_ForceZero (plainSens , plainSensBufSz );
1703+ }
16801704
16811705 TPM2_ForceZero (hmacCalc , sizeof (hmacCalc ));
16821706 FWTPM_FREE_VAR (aesObj );
@@ -1856,7 +1880,15 @@ TPM_RC FwImportReconstructKey(
18561880 primeBuf , (word32 )primeSz );
18571881 }
18581882 if (rc == 0 ) {
1859- rc = mp_div (& rsaKey -> n , & rsaKey -> q , & rsaKey -> p , NULL );
1883+ mp_int rem ;
1884+ rc = mp_init (& rem );
1885+ if (rc == 0 ) {
1886+ rc = mp_div (& rsaKey -> n , & rsaKey -> q , & rsaKey -> p , & rem );
1887+ if (rc == 0 && !mp_iszero (& rem )) {
1888+ rc = TPM_RC_BINDING ; /* q does not divide n evenly */
1889+ }
1890+ mp_forcezero (& rem );
1891+ }
18601892 }
18611893 if (rc == 0 ) {
18621894 rc = FwRsaComputeCRT (rsaKey );
@@ -2509,6 +2541,7 @@ TPM_RC FwCredentialDeriveKeys(
25092541 kdfRc = TPM2_KDFa_ex (TPM_ALG_SHA256 , seed , seedSz ,
25102542 "INTEGRITY" , NULL , 0 , NULL , 0 , hmacKey , hmacKeySz );
25112543 if (kdfRc != hmacKeySz ) {
2544+ TPM2_ForceZero (symKey , symKeySz );
25122545 return TPM_RC_FAILURE ;
25132546 }
25142547 return TPM_RC_SUCCESS ;
@@ -2676,6 +2709,8 @@ TPM_RC FwCredentialUnwrap(
26762709 }
26772710
26782711 TPM2_ForceZero (decBuf , FWTPM_MAX_NV_DATA + 2 );
2712+ TPM2_ForceZero (computedHmac , sizeof (computedHmac ));
2713+ TPM2_ForceZero (integrityHmac , sizeof (integrityHmac ));
26792714 FWTPM_FREE_BUF (decBuf );
26802715 FWTPM_FREE_VAR (aes );
26812716 FWTPM_FREE_VAR (hmac );
0 commit comments