@@ -5731,6 +5731,17 @@ static TPM_RC FwCmd_Sign(FWTPM_CTX* ctx, TPM2_Packet* cmd,
57315731 if (rc == 0 )
57325732 TPM2_Packet_ParseU16 (cmd , & sigHashAlg );
57335733 }
5734+ /* TPMS_SCHEME_ECDAA carries an additional UINT16 count after
5735+ * hashAlg per Part 2 Sec. 11.2.1.5. */
5736+ if (rc == 0 && sigScheme == TPM_ALG_ECDAA ) {
5737+ UINT16 ecdaaCount ;
5738+ if (cmd -> pos + 2 > cmdSize )
5739+ rc = TPM_RC_COMMAND_SIZE ;
5740+ if (rc == 0 ) {
5741+ TPM2_Packet_ParseU16 (cmd , & ecdaaCount );
5742+ (void )ecdaaCount ;
5743+ }
5744+ }
57345745 }
57355746
57365747 if (rc == 0 ) {
@@ -11121,6 +11132,17 @@ static TPM_RC FwParseAttestParams(TPM2_Packet* cmd, int cmdSize,
1112111132 * sigHashAlg = TPM_ALG_NULL ;
1112211133 if (* sigScheme != TPM_ALG_NULL )
1112311134 TPM2_Packet_ParseU16 (cmd , sigHashAlg );
11135+ /* TPMS_SCHEME_ECDAA carries an additional UINT16 count after
11136+ * hashAlg per Part 2 Sec. 11.2.1.5. */
11137+ if (* sigScheme == TPM_ALG_ECDAA ) {
11138+ UINT16 ecdaaCount ;
11139+ if (cmd -> pos + 2 > cmdSize )
11140+ rc = TPM_RC_COMMAND_SIZE ;
11141+ if (rc == 0 ) {
11142+ TPM2_Packet_ParseU16 (cmd , & ecdaaCount );
11143+ (void )ecdaaCount ;
11144+ }
11145+ }
1112411146 }
1112511147
1112611148 return rc ;
@@ -11426,6 +11448,17 @@ static TPM_RC FwCmd_CertifyCreation(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1142611448 sigHashAlg = TPM_ALG_NULL ;
1142711449 if (sigScheme != TPM_ALG_NULL )
1142811450 TPM2_Packet_ParseU16 (cmd , & sigHashAlg );
11451+ /* TPMS_SCHEME_ECDAA carries an additional UINT16 count after
11452+ * hashAlg per Part 2 Sec. 11.2.1.5. */
11453+ if (sigScheme == TPM_ALG_ECDAA ) {
11454+ UINT16 ecdaaCount ;
11455+ if (cmd -> pos + 2 > cmdSize )
11456+ rc = TPM_RC_COMMAND_SIZE ;
11457+ if (rc == 0 ) {
11458+ TPM2_Packet_ParseU16 (cmd , & ecdaaCount );
11459+ (void )ecdaaCount ;
11460+ }
11461+ }
1142911462 }
1143011463
1143111464 /* creationTicket verification per TPM 2.0 Part 3 Section 18.3 */
@@ -11588,6 +11621,7 @@ static TPM_RC FwCmd_NV_Certify(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1158811621 TPM2B_DATA qualifyingData ;
1158911622 UINT16 sigScheme , sigHashAlg ;
1159011623 UINT16 readSize , readOffset ;
11624+ int digestMode = 0 ;
1159111625 FWTPM_Object * sigObj ;
1159211626 FWTPM_NvIndex * nv ;
1159311627 FWTPM_DECLARE_BUF (attestBuf , FWTPM_MAX_ATTEST_BUF );
@@ -11646,12 +11680,20 @@ static TPM_RC FwCmd_NV_Certify(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1164611680 }
1164711681 }
1164811682 if (rc == 0 ) {
11649- if (readSize == 0 )
11683+ /* Per Part 3 Sec. 31.16.1: when both size and offset are zero, the
11684+ * response must contain a TPMS_NV_DIGEST_CERTIFY_INFO with the
11685+ * digest of the entire NV index, instead of TPMS_NV_CERTIFY_INFO. */
11686+ if (readSize == 0 && readOffset == 0 ) {
11687+ digestMode = 1 ;
11688+ readSize = nv -> nvPublic .dataSize ;
11689+ }
11690+ else if (readSize == 0 ) {
1165011691 readSize = nv -> nvPublic .dataSize - readOffset ;
11692+ }
1165111693 if ((UINT32 )(readOffset + readSize ) > nv -> nvPublic .dataSize ) {
1165211694 rc = TPM_RC_NV_RANGE ;
1165311695 }
11654- if (rc == 0 && readSize > FWTPM_MAX_NV_DATA ) {
11696+ if (rc == 0 && ! digestMode && readSize > FWTPM_MAX_NV_DATA ) {
1165511697 rc = TPM_RC_SIZE ;
1165611698 }
1165711699 }
@@ -11687,26 +11729,67 @@ static TPM_RC FwCmd_NV_Certify(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1168711729
1168811730 /* Build TPMS_ATTEST for NV */
1168911731 if (rc == 0 ) {
11732+ UINT16 attestType = digestMode ?
11733+ TPM_ST_ATTEST_NV_DIGEST : TPM_ST_ATTEST_NV ;
1169011734 XMEMSET (attestBuf , 0 , FWTPM_MAX_ATTEST_BUF );
1169111735 attestPkt .buf = attestBuf ;
1169211736 attestPkt .pos = 0 ;
1169311737 attestPkt .size = (int )FWTPM_MAX_ATTEST_BUF ;
1169411738
11695- FwAppendAttestCommonHeader (& attestPkt , TPM_ST_ATTEST_NV ,
11739+ FwAppendAttestCommonHeader (& attestPkt , attestType ,
1169611740 & sigObj -> name , & qualifyingData );
1169711741
11698- /* attested.nv: indexName + offset + nvContents */
11699- TPM2_Packet_AppendU16 (& attestPkt , nvName .size );
11700- TPM2_Packet_AppendBytes (& attestPkt , (byte * )nvName .name ,
11701- nvName .size );
11702- TPM2_Packet_AppendU16 (& attestPkt , readOffset );
11703- TPM2_Packet_AppendU16 (& attestPkt , readSize );
11704- TPM2_Packet_AppendBytes (& attestPkt , nv -> data + readOffset ,
11705- readSize );
11742+ if (digestMode ) {
11743+ /* attested.nvDigest: indexName + nvDigest
11744+ * nvDigest is hash of entire NV index using signing scheme hash */
11745+ UINT16 hashAlg = sigHashAlg ;
11746+ byte nvDigest [TPM_MAX_DIGEST_SIZE ];
11747+ int hashSz ;
11748+ enum wc_HashType wcDigH ;
11749+
11750+ /* Resolve hash from signing key when scheme/hash is NULL.
11751+ * keyScheme is filled in by the by-pointer interface but
11752+ * unused here - we only need the resolved hashAlg. */
11753+ if (hashAlg == TPM_ALG_NULL ) {
11754+ UINT16 keyScheme = TPM_ALG_NULL ;
11755+ FwResolveSignScheme (sigObj , & keyScheme , & hashAlg );
11756+ (void )keyScheme ;
11757+ }
11758+ wcDigH = FwGetWcHashType (hashAlg );
11759+ hashSz = TPM2_GetHashDigestSize (hashAlg );
11760+ if (wcDigH == WC_HASH_TYPE_NONE || hashSz <= 0 ) {
11761+ rc = TPM_RC_HASH ;
11762+ }
11763+ if (rc == 0 ) {
11764+ if (wc_Hash (wcDigH , nv -> data , nv -> nvPublic .dataSize ,
11765+ nvDigest , hashSz ) != 0 ) {
11766+ rc = TPM_RC_FAILURE ;
11767+ }
11768+ }
11769+ if (rc == 0 ) {
11770+ TPM2_Packet_AppendU16 (& attestPkt , nvName .size );
11771+ TPM2_Packet_AppendBytes (& attestPkt , (byte * )nvName .name ,
11772+ nvName .size );
11773+ TPM2_Packet_AppendU16 (& attestPkt , (UINT16 )hashSz );
11774+ TPM2_Packet_AppendBytes (& attestPkt , nvDigest , hashSz );
11775+ }
11776+ }
11777+ else {
11778+ /* attested.nv: indexName + offset + nvContents */
11779+ TPM2_Packet_AppendU16 (& attestPkt , nvName .size );
11780+ TPM2_Packet_AppendBytes (& attestPkt , (byte * )nvName .name ,
11781+ nvName .size );
11782+ TPM2_Packet_AppendU16 (& attestPkt , readOffset );
11783+ TPM2_Packet_AppendU16 (& attestPkt , readSize );
11784+ TPM2_Packet_AppendBytes (& attestPkt , nv -> data + readOffset ,
11785+ readSize );
11786+ }
1170611787
1170711788 /* Build response */
11708- rc = FwBuildAttestResponse (ctx , rsp , cmdTag , sigObj ,
11709- sigScheme , sigHashAlg , attestBuf , attestPkt .pos );
11789+ if (rc == 0 ) {
11790+ rc = FwBuildAttestResponse (ctx , rsp , cmdTag , sigObj ,
11791+ sigScheme , sigHashAlg , attestBuf , attestPkt .pos );
11792+ }
1171011793 }
1171111794 FWTPM_FREE_BUF (attestBuf );
1171211795 return rc ;
0 commit comments