xtest: pkcs11: Add tests for more HMAC CKMs

Add tests for *_GENERAL MD5 and SHA based HMAC mechanisms.

Signed-off-by: Victor Chong <victor.chong@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
diff --git a/host/xtest/pkcs11_1000.c b/host/xtest/pkcs11_1000.c
index c6eef64..292b757 100644
--- a/host/xtest/pkcs11_1000.c
+++ b/host/xtest/pkcs11_1000.c
@@ -13,6 +13,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <utee_defines.h>
 #include <util.h>
 
 #include "xtest_test.h"
@@ -65,6 +66,40 @@
 static CK_MECHANISM cktest_hmac_sha512_mechanism = {
 	CKM_SHA512_HMAC, NULL, 0,
 };
+
+static const CK_ULONG cktest_general_mechanism_hmac_len = 8;
+
+static CK_MECHANISM cktest_hmac_general_md5_mechanism = {
+	CKM_MD5_HMAC_GENERAL,
+	(CK_VOID_PTR)&cktest_general_mechanism_hmac_len,
+	sizeof(CK_ULONG),
+};
+static CK_MECHANISM cktest_hmac_general_sha1_mechanism = {
+	CKM_SHA_1_HMAC_GENERAL,
+	(CK_VOID_PTR)&cktest_general_mechanism_hmac_len,
+	sizeof(CK_ULONG),
+};
+static CK_MECHANISM cktest_hmac_general_sha224_mechanism = {
+	CKM_SHA224_HMAC_GENERAL,
+	(CK_VOID_PTR)&cktest_general_mechanism_hmac_len,
+	sizeof(CK_ULONG),
+};
+static CK_MECHANISM cktest_hmac_general_sha256_mechanism = {
+	CKM_SHA256_HMAC_GENERAL,
+	(CK_VOID_PTR)&cktest_general_mechanism_hmac_len,
+	sizeof(CK_ULONG),
+};
+static CK_MECHANISM cktest_hmac_general_sha384_mechanism = {
+	CKM_SHA384_HMAC_GENERAL,
+	(CK_VOID_PTR)&cktest_general_mechanism_hmac_len,
+	sizeof(CK_ULONG),
+};
+static CK_MECHANISM cktest_hmac_general_sha512_mechanism = {
+	CKM_SHA512_HMAC_GENERAL,
+	(CK_VOID_PTR)&cktest_general_mechanism_hmac_len,
+	sizeof(CK_ULONG),
+};
+
 static CK_MECHANISM cktest_gensecret_keygen_mechanism = {
 	CKM_GENERIC_SECRET_KEY_GEN, NULL, 0,
 };
@@ -1619,8 +1654,52 @@
 			11, mac_data_sha384_in1, mac_data_sha384_out1, false),
 	CKTEST_MAC_TEST(cktest_hmac_sha512_key, &cktest_hmac_sha512_mechanism,
 			13, mac_data_sha512_in1, mac_data_sha512_out1, false),
+	CKTEST_MAC_TEST(cktest_hmac_md5_key,
+			&cktest_hmac_general_md5_mechanism, 4,
+			mac_data_md5_in1, mac_data_md5_out1, false),
+	CKTEST_MAC_TEST(cktest_hmac_sha1_key,
+			&cktest_hmac_general_sha1_mechanism, 5,
+			mac_data_sha1_in1, mac_data_sha1_out1, false),
+	CKTEST_MAC_TEST(cktest_hmac_sha224_key,
+			&cktest_hmac_general_sha224_mechanism, 8,
+			mac_data_sha224_in1, mac_data_sha224_out1, false),
+	CKTEST_MAC_TEST(cktest_hmac_sha256_key1,
+			&cktest_hmac_general_sha256_mechanism, 1,
+			mac_data_sha256_in1, mac_data_sha256_out1, false),
+	CKTEST_MAC_TEST(cktest_hmac_sha256_key2,
+			&cktest_hmac_general_sha256_mechanism, 7,
+			mac_data_sha256_in2, mac_data_sha256_out2, false),
+	CKTEST_MAC_TEST(cktest_hmac_sha384_key,
+			&cktest_hmac_general_sha384_mechanism, 11,
+			mac_data_sha384_in1, mac_data_sha384_out1, false),
+	CKTEST_MAC_TEST(cktest_hmac_sha512_key,
+			&cktest_hmac_general_sha512_mechanism, 13,
+			mac_data_sha512_in1, mac_data_sha512_out1, false),
 };
 
+static bool ckm_is_hmac_general(struct mac_test const *test)
+{
+	switch (test->mechanism->mechanism) {
+	case CKM_MD5_HMAC_GENERAL:
+	case CKM_SHA_1_HMAC_GENERAL:
+	case CKM_SHA224_HMAC_GENERAL:
+	case CKM_SHA256_HMAC_GENERAL:
+	case CKM_SHA384_HMAC_GENERAL:
+	case CKM_SHA512_HMAC_GENERAL:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static size_t get_mac_test_len(struct mac_test const *test)
+{
+	if (ckm_is_hmac_general(test))
+		return (size_t)cktest_general_mechanism_hmac_len;
+
+	return test->out_len;
+}
+
 static void xtest_pkcs11_test_1008(ADBG_Case_t *c)
 {
 	CK_RV rv = CKR_GENERAL_ERROR;
@@ -1700,7 +1779,7 @@
 				goto err_destr_obj;
 
 			(void)ADBG_EXPECT_BUFFER(c, test->out,
-						 test->out_len,
+						 get_mac_test_len(test),
 						 out, out_size);
 		}
 
@@ -1730,7 +1809,8 @@
 			goto err_destr_obj;
 
 		(void)ADBG_EXPECT_BUFFER(c, test->out,
-					 test->out_len, out, out_size);
+					 get_mac_test_len(test), out,
+					 out_size);
 
 		/* Test 3 signature in one shot */
 		if (test->in != NULL) {
@@ -1773,7 +1853,7 @@
 				goto err_destr_obj;
 
 			(void)ADBG_EXPECT_BUFFER(c, test->out,
-						 test->out_len,
+						 get_mac_test_len(test),
 						 out, out_size);
 		}
 
@@ -1843,7 +1923,8 @@
 				goto err_destr_obj;
 
 			rv = C_VerifyFinal(session,
-					   (void *)test->out, test->out_len);
+					   (void *)test->out,
+					   get_mac_test_len(test));
 			if (!ADBG_EXPECT_CK_OK(c, rv))
 				goto err_destr_obj;
 
@@ -1867,14 +1948,15 @@
 				goto err_destr_obj;
 		}
 
-		rv = C_VerifyFinal(session, (void *)test->out, test->out_len);
+		rv = C_VerifyFinal(session, (void *)test->out,
+				   get_mac_test_len(test));
 		if (!ADBG_EXPECT_CK_OK(c, rv))
 			goto err_destr_obj;
 
 		/* Error as Operation has already completed */
 		rv = C_Verify(session,
 			      (void *)test->in, test->in_len,
-			      (void *)test->out, test->out_len);
+			      (void *)test->out, get_mac_test_len(test));
 		if (!ADBG_EXPECT_CK_RESULT(c, CKR_OPERATION_NOT_INITIALIZED,
 					   rv))
 			goto err_destr_obj;
@@ -1887,14 +1969,16 @@
 
 			rv = C_Verify(session,
 				      (void *)test->in, test->in_len,
-				      (void *)test->out, test->out_len);
+				      (void *)test->out,
+				      get_mac_test_len(test));
 			if (!ADBG_EXPECT_CK_OK(c, rv))
 				goto err_destr_obj;
 
 			/* Try calling Verify again */
 			rv = C_Verify(session,
 				      (void *)test->in, test->in_len,
-				      (void *)test->out, test->out_len);
+				      (void *)test->out,
+				      get_mac_test_len(test));
 			if (!ADBG_EXPECT_CK_RESULT(c,
 						  CKR_OPERATION_NOT_INITIALIZED,
 						  rv))
@@ -1916,7 +2000,10 @@
 				goto err_destr_obj;
 
 			rv = C_VerifyFinal(session, (void *)test->out, 3);
-			if (!ADBG_EXPECT_CK_RESULT(c, CKR_SIGNATURE_LEN_RANGE,
+			if (!ADBG_EXPECT_CK_RESULT(c,
+						   ckm_is_hmac_general(test) ?
+						   CKR_OK :
+						   CKR_SIGNATURE_LEN_RANGE,
 						   rv))
 				goto err_destr_obj;
 		}
@@ -1936,6 +2023,18 @@
 			if (!ADBG_EXPECT_CK_RESULT(c, CKR_SIGNATURE_LEN_RANGE,
 						   rv))
 				goto err_destr_obj;
+
+			rv = C_VerifyInit(session, test->mechanism, key_handle);
+			if (!ADBG_EXPECT_CK_OK(c, rv))
+				goto err_destr_obj;
+
+			rv = C_Verify(session,
+				      (void *)test->in, test->in_len,
+				      (void *)test->out,
+				      TEE_MAX_HASH_SIZE + 1);
+			if (!ADBG_EXPECT_CK_RESULT(c, CKR_SIGNATURE_LEN_RANGE,
+						   rv))
+				goto err_destr_obj;
 		}
 
 		/* Test 6 verification - Invalid Operation sequence */
@@ -1946,7 +2045,8 @@
 
 			rv = C_Verify(session,
 				      (void *)test->in, test->in_len,
-				      (void *)test->out, test->out_len);
+				      (void *)test->out,
+				      get_mac_test_len(test));
 			if (!ADBG_EXPECT_CK_OK(c, rv))
 				goto err_destr_obj;