@@ -979,6 +979,318 @@ static void test_TPM2_ConstantCompare(void)
979979 printf ("Test TPM Wrapper:\tConstantCompare:\tPassed\n" );
980980}
981981
982+ static void test_TPM2_AesCfbRoundtrip (void )
983+ {
984+ #if !defined(WOLFTPM2_NO_WOLFCRYPT ) && !defined(NO_AES ) && \
985+ defined(WOLFSSL_AES_CFB )
986+ int rc ;
987+ int i ;
988+ const int keySizes [3 ] = {16 , 24 , 32 };
989+ byte key [32 ];
990+ byte iv [16 ];
991+ byte pt [64 ];
992+ byte ct [64 ];
993+
994+ XMEMSET (key , 0xA5 , sizeof (key ));
995+ XMEMSET (iv , 0x5A , sizeof (iv ));
996+ for (i = 0 ; i < (int )sizeof (pt ); i ++ ) {
997+ pt [i ] = (byte )i ;
998+ }
999+
1000+ /* Encrypt -> decrypt round trip for each supported key size */
1001+ for (i = 0 ; i < 3 ; i ++ ) {
1002+ XMEMCPY (ct , pt , sizeof (pt ));
1003+ rc = TPM2_AesCfbEncrypt (key , keySizes [i ], iv , ct , sizeof (ct ));
1004+ AssertIntEQ (0 , rc );
1005+ AssertIntNE (0 , XMEMCMP (ct , pt , sizeof (pt )));
1006+ rc = TPM2_AesCfbDecrypt (key , keySizes [i ], iv , ct , sizeof (ct ));
1007+ AssertIntEQ (0 , rc );
1008+ AssertIntEQ (0 , XMEMCMP (ct , pt , sizeof (pt )));
1009+ }
1010+
1011+ /* NULL-IV path must be accepted (zero-fill default) */
1012+ XMEMCPY (ct , pt , sizeof (pt ));
1013+ rc = TPM2_AesCfbEncrypt (key , 16 , NULL , ct , sizeof (ct ));
1014+ AssertIntEQ (0 , rc );
1015+ rc = TPM2_AesCfbDecrypt (key , 16 , NULL , ct , sizeof (ct ));
1016+ AssertIntEQ (0 , rc );
1017+ AssertIntEQ (0 , XMEMCMP (ct , pt , sizeof (pt )));
1018+
1019+ /* Reject invalid key size */
1020+ rc = TPM2_AesCfbEncrypt (key , 15 , iv , ct , sizeof (ct ));
1021+ AssertIntNE (0 , rc );
1022+ rc = TPM2_AesCfbDecrypt (key , 15 , iv , ct , sizeof (ct ));
1023+ AssertIntNE (0 , rc );
1024+
1025+ printf ("Test TPM Wrapper:\tAesCfbRoundtrip:\tPassed\n" );
1026+ #else
1027+ printf ("Test TPM Wrapper:\tAesCfbRoundtrip:\tSkipped\n" );
1028+ #endif
1029+ }
1030+
1031+ /* Cover KDFa multi-iteration loop (keySz > hash digest size) and
1032+ * SHA-384 / SHA-512 code paths, with non-empty context inputs. */
1033+ static void test_TPM2_KDFa_MultiHash (void )
1034+ {
1035+ #ifndef WOLFTPM2_NO_WOLFCRYPT
1036+ int rc ;
1037+ size_t iAlg ;
1038+ size_t iSz ;
1039+ const UINT32 sizes [] = {1 , 31 , 32 , 33 , 64 , 96 };
1040+ const byte keyIn [32 ] = {
1041+ 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
1042+ 0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F ,
1043+ 0x10 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 , 0x17 ,
1044+ 0x18 , 0x19 , 0x1A , 0x1B , 0x1C , 0x1D , 0x1E , 0x1F };
1045+ const char label [] = "MULTIHASHLABEL" ;
1046+ const byte ctxU [8 ] = {0xAA , 0xBB , 0xCC , 0xDD , 0xEE , 0xFF , 0x00 , 0x11 };
1047+ const byte ctxV [8 ] = {0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 };
1048+ static const TPM_ALG_ID algs [] = {
1049+ TPM_ALG_SHA256 ,
1050+ #ifdef WOLFSSL_SHA384
1051+ TPM_ALG_SHA384 ,
1052+ #endif
1053+ #ifdef WOLFSSL_SHA512
1054+ TPM_ALG_SHA512 ,
1055+ #endif
1056+ };
1057+ byte key1 [96 ];
1058+ byte key2 [96 ];
1059+
1060+ for (iAlg = 0 ; iAlg < sizeof (algs )/sizeof (algs [0 ]); iAlg ++ ) {
1061+ for (iSz = 0 ; iSz < sizeof (sizes )/sizeof (sizes [0 ]); iSz ++ ) {
1062+ UINT32 sz = sizes [iSz ];
1063+ rc = TPM2_KDFa_ex (algs [iAlg ], keyIn , sizeof (keyIn ), label ,
1064+ ctxU , sizeof (ctxU ), ctxV , sizeof (ctxV ), key1 , sz );
1065+ AssertIntEQ ((int )sz , rc );
1066+ rc = TPM2_KDFa_ex (algs [iAlg ], keyIn , sizeof (keyIn ), label ,
1067+ ctxU , sizeof (ctxU ), ctxV , sizeof (ctxV ), key2 , sz );
1068+ AssertIntEQ ((int )sz , rc );
1069+ AssertIntEQ (0 , XMEMCMP (key1 , key2 , sz ));
1070+ }
1071+ }
1072+
1073+ printf ("Test TPM Wrapper:\tKDFa multi-hash:\tPassed\n" );
1074+ #else
1075+ printf ("Test TPM Wrapper:\tKDFa multi-hash:\tSkipped\n" );
1076+ #endif
1077+ }
1078+
1079+ static void test_TPM2_KDFe_MultiHash (void )
1080+ {
1081+ #ifndef WOLFTPM2_NO_WOLFCRYPT
1082+ int rc ;
1083+ size_t iAlg ;
1084+ size_t iSz ;
1085+ const UINT32 sizes [] = {1 , 31 , 32 , 33 , 64 , 96 };
1086+ const byte Z [32 ] = {
1087+ 0x20 , 0x21 , 0x22 , 0x23 , 0x24 , 0x25 , 0x26 , 0x27 ,
1088+ 0x28 , 0x29 , 0x2A , 0x2B , 0x2C , 0x2D , 0x2E , 0x2F ,
1089+ 0x30 , 0x31 , 0x32 , 0x33 , 0x34 , 0x35 , 0x36 , 0x37 ,
1090+ 0x38 , 0x39 , 0x3A , 0x3B , 0x3C , 0x3D , 0x3E , 0x3F };
1091+ const char label [] = "IDENTITY" ;
1092+ const byte partyU [8 ] = {0x10 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 , 0x17 };
1093+ const byte partyV [8 ] = {0x80 , 0x81 , 0x82 , 0x83 , 0x84 , 0x85 , 0x86 , 0x87 };
1094+ static const TPM_ALG_ID algs [] = {
1095+ TPM_ALG_SHA256 ,
1096+ #ifdef WOLFSSL_SHA384
1097+ TPM_ALG_SHA384 ,
1098+ #endif
1099+ #ifdef WOLFSSL_SHA512
1100+ TPM_ALG_SHA512 ,
1101+ #endif
1102+ };
1103+ byte key1 [96 ];
1104+ byte key2 [96 ];
1105+
1106+ for (iAlg = 0 ; iAlg < sizeof (algs )/sizeof (algs [0 ]); iAlg ++ ) {
1107+ for (iSz = 0 ; iSz < sizeof (sizes )/sizeof (sizes [0 ]); iSz ++ ) {
1108+ UINT32 sz = sizes [iSz ];
1109+ rc = TPM2_KDFe_ex (algs [iAlg ], Z , sizeof (Z ), label ,
1110+ partyU , sizeof (partyU ), partyV , sizeof (partyV ), key1 , sz );
1111+ AssertIntEQ ((int )sz , rc );
1112+ rc = TPM2_KDFe_ex (algs [iAlg ], Z , sizeof (Z ), label ,
1113+ partyU , sizeof (partyU ), partyV , sizeof (partyV ), key2 , sz );
1114+ AssertIntEQ ((int )sz , rc );
1115+ AssertIntEQ (0 , XMEMCMP (key1 , key2 , sz ));
1116+ }
1117+ }
1118+
1119+ printf ("Test TPM Wrapper:\tKDFe multi-hash:\tPassed\n" );
1120+ #else
1121+ printf ("Test TPM Wrapper:\tKDFe multi-hash:\tSkipped\n" );
1122+ #endif
1123+ }
1124+
1125+ /* Exercise HmacCompute concat path (data2 != NULL) and multi-hash
1126+ * branches. Reference result is computed by feeding the same bytes in
1127+ * one call (data1 || data2) and comparing. */
1128+ static void test_TPM2_HmacCompute_MultiHash (void )
1129+ {
1130+ #if !defined(WOLFTPM2_NO_WOLFCRYPT ) && !defined(NO_HMAC )
1131+ int rc ;
1132+ size_t iAlg ;
1133+ static const TPM_ALG_ID algs [] = {
1134+ TPM_ALG_SHA256 ,
1135+ #ifdef WOLFSSL_SHA384
1136+ TPM_ALG_SHA384 ,
1137+ #endif
1138+ #ifdef WOLFSSL_SHA512
1139+ TPM_ALG_SHA512 ,
1140+ #endif
1141+ };
1142+ const byte hmacKey [16 ] = {
1143+ 0x10 , 0x20 , 0x30 , 0x40 , 0x50 , 0x60 , 0x70 , 0x80 ,
1144+ 0x90 , 0xA0 , 0xB0 , 0xC0 , 0xD0 , 0xE0 , 0xF0 , 0x01 };
1145+ const byte data1 [] = "concat-HMAC-left-half" ;
1146+ const byte data2 [] = "concat-HMAC-right-half" ;
1147+ byte full [sizeof (data1 ) - 1 + sizeof (data2 ) - 1 ];
1148+ byte d_split [TPM_MAX_DIGEST_SIZE ];
1149+ byte d_full [TPM_MAX_DIGEST_SIZE ];
1150+ word32 splitSz ;
1151+ word32 fullSz ;
1152+
1153+ XMEMCPY (full , data1 , sizeof (data1 ) - 1 );
1154+ XMEMCPY (full + sizeof (data1 ) - 1 , data2 , sizeof (data2 ) - 1 );
1155+
1156+ for (iAlg = 0 ; iAlg < sizeof (algs )/sizeof (algs [0 ]); iAlg ++ ) {
1157+ splitSz = sizeof (d_split );
1158+ fullSz = sizeof (d_full );
1159+ rc = TPM2_HmacCompute (algs [iAlg ], hmacKey , sizeof (hmacKey ),
1160+ data1 , sizeof (data1 ) - 1 ,
1161+ data2 , sizeof (data2 ) - 1 ,
1162+ d_split , & splitSz );
1163+ AssertIntEQ (0 , rc );
1164+ rc = TPM2_HmacCompute (algs [iAlg ], hmacKey , sizeof (hmacKey ),
1165+ full , sizeof (full ),
1166+ NULL , 0 ,
1167+ d_full , & fullSz );
1168+ AssertIntEQ (0 , rc );
1169+ AssertIntEQ ((int )fullSz , (int )splitSz );
1170+ AssertIntEQ (0 , XMEMCMP (d_split , d_full , splitSz ));
1171+ }
1172+
1173+ printf ("Test TPM Wrapper:\tHmacCompute multi-hash:\tPassed\n" );
1174+ #else
1175+ printf ("Test TPM Wrapper:\tHmacCompute multi-hash:\tSkipped\n" );
1176+ #endif
1177+ }
1178+
1179+ static void test_TPM2_HashCompute_MultiHash (void )
1180+ {
1181+ #ifndef WOLFTPM2_NO_WOLFCRYPT
1182+ int rc ;
1183+ size_t i ;
1184+ static const struct { TPM_ALG_ID alg ; int dsz ; } cases [] = {
1185+ { TPM_ALG_SHA256 , 32 },
1186+ #ifdef WOLFSSL_SHA384
1187+ { TPM_ALG_SHA384 , 48 },
1188+ #endif
1189+ #ifdef WOLFSSL_SHA512
1190+ { TPM_ALG_SHA512 , 64 },
1191+ #endif
1192+ };
1193+ const byte msg [] = "wolfTPM-unit-test-hash" ;
1194+ byte d1 [TPM_MAX_DIGEST_SIZE ];
1195+ byte d2 [TPM_MAX_DIGEST_SIZE ];
1196+ word32 sz1 ;
1197+ word32 sz2 ;
1198+
1199+ for (i = 0 ; i < sizeof (cases )/sizeof (cases [0 ]); i ++ ) {
1200+ sz1 = sizeof (d1 );
1201+ sz2 = sizeof (d2 );
1202+ rc = TPM2_HashCompute (cases [i ].alg , msg , sizeof (msg ) - 1 , d1 , & sz1 );
1203+ AssertIntEQ (0 , rc );
1204+ AssertIntEQ (cases [i ].dsz , (int )sz1 );
1205+ rc = TPM2_HashCompute (cases [i ].alg , msg , sizeof (msg ) - 1 , d2 , & sz2 );
1206+ AssertIntEQ (0 , rc );
1207+ AssertIntEQ (0 , XMEMCMP (d1 , d2 , sz1 ));
1208+ }
1209+
1210+ printf ("Test TPM Wrapper:\tHashCompute multi-hash:\tPassed\n" );
1211+ #else
1212+ printf ("Test TPM Wrapper:\tHashCompute multi-hash:\tSkipped\n" );
1213+ #endif
1214+ }
1215+
1216+ /* Negative / input-validation coverage for KDFa_ex and KDFe_ex. */
1217+ static void test_TPM2_KDF_Errors (void )
1218+ {
1219+ #ifndef WOLFTPM2_NO_WOLFCRYPT
1220+ int rc ;
1221+ byte key [32 ];
1222+ const byte buf [16 ] = {0 };
1223+ const char label [] = "LABEL" ;
1224+
1225+ /* KDFa: NULL key returns BAD_FUNC_ARG */
1226+ rc = TPM2_KDFa_ex (TPM_ALG_SHA256 , buf , sizeof (buf ), label ,
1227+ NULL , 0 , NULL , 0 , NULL , sizeof (key ));
1228+ AssertIntEQ (BAD_FUNC_ARG , rc );
1229+
1230+ /* KDFa: unsupported hash returns NOT_COMPILED_IN */
1231+ rc = TPM2_KDFa_ex (TPM_ALG_NULL , buf , sizeof (buf ), label ,
1232+ NULL , 0 , NULL , 0 , key , sizeof (key ));
1233+ AssertIntEQ (NOT_COMPILED_IN , rc );
1234+
1235+ /* KDFe: NULL key returns BAD_FUNC_ARG */
1236+ rc = TPM2_KDFe_ex (TPM_ALG_SHA256 , buf , sizeof (buf ), label ,
1237+ NULL , 0 , NULL , 0 , NULL , sizeof (key ));
1238+ AssertIntEQ (BAD_FUNC_ARG , rc );
1239+
1240+ /* KDFe: NULL Z returns BAD_FUNC_ARG */
1241+ rc = TPM2_KDFe_ex (TPM_ALG_SHA256 , NULL , 0 , label ,
1242+ NULL , 0 , NULL , 0 , key , sizeof (key ));
1243+ AssertIntEQ (BAD_FUNC_ARG , rc );
1244+
1245+ /* KDFe: unsupported hash returns NOT_COMPILED_IN */
1246+ rc = TPM2_KDFe_ex (TPM_ALG_NULL , buf , sizeof (buf ), label ,
1247+ NULL , 0 , NULL , 0 , key , sizeof (key ));
1248+ AssertIntEQ (NOT_COMPILED_IN , rc );
1249+
1250+ printf ("Test TPM Wrapper:\tKDF error paths:\tPassed\n" );
1251+ #else
1252+ printf ("Test TPM Wrapper:\tKDF error paths:\tSkipped\n" );
1253+ #endif
1254+ }
1255+
1256+ /* Round-trip TPM2_GetHashType -> TPM2_GetTpmHashType for each TPM
1257+ * hash algorithm compiled into wolfCrypt. Unknown inputs map to
1258+ * TPM_ALG_ERROR. */
1259+ static void test_TPM2_GetTpmHashType (void )
1260+ {
1261+ #ifndef WOLFTPM2_NO_WOLFCRYPT
1262+ static const TPMI_ALG_HASH algs [] = {
1263+ #ifndef NO_SHA
1264+ TPM_ALG_SHA1 ,
1265+ #endif
1266+ TPM_ALG_SHA256 ,
1267+ #ifdef WOLFSSL_SHA384
1268+ TPM_ALG_SHA384 ,
1269+ #endif
1270+ #ifdef WOLFSSL_SHA512
1271+ TPM_ALG_SHA512 ,
1272+ #endif
1273+ };
1274+ size_t i ;
1275+ int wcType ;
1276+ TPMI_ALG_HASH roundTrip ;
1277+
1278+ for (i = 0 ; i < sizeof (algs )/sizeof (algs [0 ]); i ++ ) {
1279+ wcType = TPM2_GetHashType (algs [i ]);
1280+ AssertIntNE ((int )WC_HASH_TYPE_NONE , wcType );
1281+ roundTrip = TPM2_GetTpmHashType (wcType );
1282+ AssertIntEQ (algs [i ], roundTrip );
1283+ }
1284+
1285+ /* Unknown wolfCrypt hash type returns TPM_ALG_ERROR */
1286+ AssertIntEQ (TPM_ALG_ERROR , TPM2_GetTpmHashType (0xFFFF ));
1287+
1288+ printf ("Test TPM Wrapper:\tGetTpmHashType:\tPassed\n" );
1289+ #else
1290+ printf ("Test TPM Wrapper:\tGetTpmHashType:\tSkipped\n" );
1291+ #endif
1292+ }
1293+
9821294static void test_TPM2_ResponseHmacVerification (void )
9831295{
9841296#if !defined(WOLFTPM2_NO_WOLFCRYPT ) && !defined(NO_HMAC )
@@ -1894,6 +2206,13 @@ int unit_tests(int argc, char *argv[])
18942206 test_TPM2_HmacCompute ();
18952207 test_TPM2_HashCompute ();
18962208 test_TPM2_ConstantCompare ();
2209+ test_TPM2_AesCfbRoundtrip ();
2210+ test_TPM2_KDFa_MultiHash ();
2211+ test_TPM2_KDFe_MultiHash ();
2212+ test_TPM2_HmacCompute_MultiHash ();
2213+ test_TPM2_HashCompute_MultiHash ();
2214+ test_TPM2_KDF_Errors ();
2215+ test_TPM2_GetTpmHashType ();
18972216 test_TPM2_ResponseHmacVerification ();
18982217 test_TPM2_CalcHmac ();
18992218 test_TPM2_ParamEnc_XOR_Vector ();
0 commit comments