[1/8] validation: crypto: add tests for checking message digests

Message ID 20170406113944.31310-1-maxim.uvarov@linaro.org
State New
Headers show
Series
  • [1/8] validation: crypto: add tests for checking message digests
Related show

Commit Message

Maxim Uvarov April 6, 2017, 11:39 a.m.
From: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>


Currently ODP testsuite only verifies generation of digests. Let's also
verify that checking the digest actually works. Test that check function
will accept valid digest and that it will reject wrong digests.

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>

---
/** Email created from pull request 10 (lumag:crypto-update)
 ** https://github.com/Linaro/odp/pull/10
 ** Patch: https://github.com/Linaro/odp/pull/10.patch
 ** Base sha: e91cf8bb39da24d2a7dbfbb328aa35d1c4cab4ea
 ** Merge commit sha: 2f5b8229a5006f9dffa717fb31aa784093b8ae76
 **/
 test/common_plat/validation/api/crypto/crypto.h    |  12 +-
 .../validation/api/crypto/odp_crypto_test_inp.c    | 172 +++++++++++++++++++--
 2 files changed, 169 insertions(+), 15 deletions(-)

Patch

diff --git a/test/common_plat/validation/api/crypto/crypto.h b/test/common_plat/validation/api/crypto/crypto.h
index c25cbb3..49ca512 100644
--- a/test/common_plat/validation/api/crypto/crypto.h
+++ b/test/common_plat/validation/api/crypto/crypto.h
@@ -22,10 +22,14 @@  void crypto_test_enc_alg_aes128_gcm(void);
 void crypto_test_enc_alg_aes128_gcm_ovr_iv(void);
 void crypto_test_dec_alg_aes128_gcm(void);
 void crypto_test_dec_alg_aes128_gcm_ovr_iv(void);
-void crypto_test_alg_hmac_md5(void);
-void crypto_test_alg_hmac_sha1(void);
-void crypto_test_alg_hmac_sha256(void);
-void crypto_test_alg_hmac_sha512(void);
+void crypto_test_gen_alg_hmac_md5(void);
+void crypto_test_check_alg_hmac_md5(void);
+void crypto_test_gen_alg_hmac_sha1(void);
+void crypto_test_check_alg_hmac_sha1(void);
+void crypto_test_gen_alg_hmac_sha256(void);
+void crypto_test_check_alg_hmac_sha256(void);
+void crypto_test_gen_alg_hmac_sha512(void);
+void crypto_test_check_alg_hmac_sha512(void);
 
 /* test arrays: */
 extern odp_testinfo_t crypto_suite[];
diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
index 42149ac..9af7ba3 100644
--- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
+++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
@@ -65,6 +65,7 @@  static const char *cipher_alg_name(odp_cipher_alg_t cipher)
  * buffer can be used.
  * */
 static void alg_test(odp_crypto_op_t op,
+		     odp_bool_t should_fail,
 		     odp_cipher_alg_t cipher_alg,
 		     odp_crypto_iv_t ses_iv,
 		     uint8_t *op_iv_ptr,
@@ -239,6 +240,10 @@  static void alg_test(odp_crypto_op_t op,
 		op_params.override_iv_ptr = op_iv_ptr;
 
 	op_params.hash_result_offset = plaintext_len;
+	if (0 != digest_len) {
+		memcpy(data_addr + op_params.hash_result_offset,
+		       digest, digest_len);
+	}
 
 	rc = odp_crypto_operation(&op_params, &posted, &result);
 	if (rc < 0) {
@@ -259,8 +264,15 @@  static void alg_test(odp_crypto_op_t op,
 		odp_crypto_compl_free(compl_event);
 	}
 
-	CU_ASSERT(result.ok);
 	CU_ASSERT(result.pkt == pkt);
+	CU_ASSERT(result.ctx == (void *)0xdeadbeef);
+
+	if (should_fail) {
+		CU_ASSERT(!result.ok);
+		goto cleanup;
+	}
+
+	CU_ASSERT(result.ok);
 
 	if (cipher_alg != ODP_CIPHER_ALG_NULL)
 		CU_ASSERT(!memcmp(data_addr, ciphertext, ciphertext_len));
@@ -268,8 +280,6 @@  static void alg_test(odp_crypto_op_t op,
 	if (op == ODP_CRYPTO_OP_ENCODE && auth_alg != ODP_AUTH_ALG_NULL)
 		CU_ASSERT(!memcmp(data_addr + op_params.hash_result_offset,
 				  digest, digest_len));
-
-	CU_ASSERT(result.ctx == (void *)0xdeadbeef);
 cleanup:
 	rc = odp_crypto_session_destroy(session);
 	CU_ASSERT(!rc);
@@ -453,6 +463,7 @@  void crypto_test_enc_alg_3des_cbc(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 0,
 			 ODP_CIPHER_ALG_3DES_CBC,
 			 iv,
 			 NULL,
@@ -488,6 +499,7 @@  void crypto_test_enc_alg_3des_cbc_ovr_iv(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 0,
 			 ODP_CIPHER_ALG_3DES_CBC,
 			 iv,
 			 tdes_cbc_reference_iv[i],
@@ -527,6 +539,7 @@  void crypto_test_dec_alg_3des_cbc(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_DECODE,
+			 0,
 			 ODP_CIPHER_ALG_3DES_CBC,
 			 iv,
 			 NULL,
@@ -564,6 +577,7 @@  void crypto_test_dec_alg_3des_cbc_ovr_iv(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_DECODE,
+			 0,
 			 ODP_CIPHER_ALG_3DES_CBC,
 			 iv,
 			 tdes_cbc_reference_iv[i],
@@ -610,6 +624,7 @@  void crypto_test_enc_alg_aes128_gcm(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 0,
 			 ODP_CIPHER_ALG_AES_GCM,
 			 iv,
 			 NULL,
@@ -653,6 +668,7 @@  void crypto_test_enc_alg_aes128_gcm_ovr_iv(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 0,
 			 ODP_CIPHER_ALG_AES_GCM,
 			 iv,
 			 aes128_gcm_reference_iv[i],
@@ -699,6 +715,7 @@  void crypto_test_dec_alg_aes128_gcm(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_DECODE,
+			 0,
 			 ODP_CIPHER_ALG_AES_GCM,
 			 iv,
 			 NULL,
@@ -743,6 +760,7 @@  void crypto_test_dec_alg_aes128_gcm_ovr_iv(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_DECODE,
+			 0,
 			 ODP_CIPHER_ALG_AES_GCM,
 			 iv,
 			 aes128_gcm_reference_iv[i],
@@ -790,6 +808,7 @@  void crypto_test_enc_alg_aes128_cbc(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 0,
 			 ODP_CIPHER_ALG_AES_CBC,
 			 iv,
 			 NULL,
@@ -825,6 +844,7 @@  void crypto_test_enc_alg_aes128_cbc_ovr_iv(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 0,
 			 ODP_CIPHER_ALG_AES_CBC,
 			 iv,
 			 aes128_cbc_reference_iv[i],
@@ -864,6 +884,7 @@  void crypto_test_dec_alg_aes128_cbc(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_DECODE,
+			 0,
 			 ODP_CIPHER_ALG_AES_CBC,
 			 iv,
 			 NULL,
@@ -901,6 +922,7 @@  void crypto_test_dec_alg_aes128_cbc_ovr_iv(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_DECODE,
+			 0,
 			 ODP_CIPHER_ALG_AES_CBC,
 			 iv,
 			 aes128_cbc_reference_iv[i],
@@ -927,7 +949,7 @@  static int check_alg_hmac_md5(void)
  * In addition the test verifies if the implementation can use the
  * packet buffer as completion event buffer.
  * */
-void crypto_test_alg_hmac_md5(void)
+void crypto_test_gen_alg_hmac_md5(void)
 {
 	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
 			 auth_key   = { .data = NULL, .length = 0 };
@@ -946,6 +968,7 @@  void crypto_test_alg_hmac_md5(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 0,
 			 ODP_CIPHER_ALG_NULL,
 			 iv,
 			 iv.data,
@@ -961,6 +984,59 @@  void crypto_test_alg_hmac_md5(void)
 	}
 }
 
+void crypto_test_check_alg_hmac_md5(void)
+{
+	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
+			 auth_key   = { .data = NULL, .length = 0 };
+	odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
+	uint8_t wrong_digest[HMAC_MD5_DIGEST_LEN];
+
+	unsigned int test_vec_num = (sizeof(hmac_md5_reference_length) /
+				     sizeof(hmac_md5_reference_length[0]));
+	unsigned int i;
+
+	memset(wrong_digest, 0xa5, sizeof(wrong_digest));
+
+	for (i = 0; i < test_vec_num; i++) {
+		auth_key.data = hmac_md5_reference_key[i];
+		auth_key.length = sizeof(hmac_md5_reference_key[i]);
+
+		if (!check_auth_options(ODP_AUTH_ALG_MD5_HMAC, auth_key.length,
+					HMAC_MD5_96_CHECK_LEN))
+			continue;
+
+		alg_test(ODP_CRYPTO_OP_DECODE,
+			 0,
+			 ODP_CIPHER_ALG_NULL,
+			 iv,
+			 iv.data,
+			 cipher_key,
+			 ODP_AUTH_ALG_MD5_HMAC,
+			 auth_key,
+			 NULL, NULL,
+			 hmac_md5_reference_plaintext[i],
+			 hmac_md5_reference_length[i],
+			 NULL, 0,
+			 hmac_md5_reference_digest[i],
+			 HMAC_MD5_96_CHECK_LEN);
+
+		alg_test(ODP_CRYPTO_OP_DECODE,
+			 1,
+			 ODP_CIPHER_ALG_NULL,
+			 iv,
+			 iv.data,
+			 cipher_key,
+			 ODP_AUTH_ALG_MD5_HMAC,
+			 auth_key,
+			 NULL, NULL,
+			 hmac_md5_reference_plaintext[i],
+			 hmac_md5_reference_length[i],
+			 NULL, 0,
+			 wrong_digest,
+			 HMAC_MD5_96_CHECK_LEN);
+	}
+}
+
 static int check_alg_hmac_sha256(void)
 {
 	return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA256_HMAC);
@@ -973,7 +1049,7 @@  static int check_alg_hmac_sha256(void)
  * In addition the test verifies if the implementation can use the
  * packet buffer as completion event buffer.
  * */
-void crypto_test_alg_hmac_sha256(void)
+void crypto_test_gen_alg_hmac_sha256(void)
 {
 	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
 			 auth_key   = { .data = NULL, .length = 0 };
@@ -994,6 +1070,47 @@  void crypto_test_alg_hmac_sha256(void)
 			continue;
 
 		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 0,
+			 ODP_CIPHER_ALG_NULL,
+			 iv,
+			 iv.data,
+			 cipher_key,
+			 ODP_AUTH_ALG_SHA256_HMAC,
+			 auth_key,
+			 NULL, NULL,
+			 hmac_sha256_reference_plaintext[i],
+			 hmac_sha256_reference_length[i],
+			 NULL, 0,
+			 hmac_sha256_reference_digest[i],
+			 HMAC_SHA256_128_CHECK_LEN);
+	}
+}
+
+void crypto_test_check_alg_hmac_sha256(void)
+{
+	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
+			 auth_key   = { .data = NULL, .length = 0 };
+	odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
+	uint8_t wrong_digest[HMAC_SHA256_DIGEST_LEN];
+
+	unsigned int test_vec_num = (sizeof(hmac_sha256_reference_length) /
+				     sizeof(hmac_sha256_reference_length[0]));
+
+	unsigned int i;
+
+	memset(wrong_digest, 0xa5, sizeof(wrong_digest));
+
+	for (i = 0; i < test_vec_num; i++) {
+		auth_key.data = hmac_sha256_reference_key[i];
+		auth_key.length = sizeof(hmac_sha256_reference_key[i]);
+
+		if (!check_auth_options(ODP_AUTH_ALG_SHA256_HMAC,
+					auth_key.length,
+					HMAC_SHA256_128_CHECK_LEN))
+			continue;
+
+		alg_test(ODP_CRYPTO_OP_DECODE,
+			 0,
 			 ODP_CIPHER_ALG_NULL,
 			 iv,
 			 iv.data,
@@ -1006,6 +1123,21 @@  void crypto_test_alg_hmac_sha256(void)
 			 NULL, 0,
 			 hmac_sha256_reference_digest[i],
 			 HMAC_SHA256_128_CHECK_LEN);
+
+		alg_test(ODP_CRYPTO_OP_DECODE,
+			 1,
+			 ODP_CIPHER_ALG_NULL,
+			 iv,
+			 iv.data,
+			 cipher_key,
+			 ODP_AUTH_ALG_SHA256_HMAC,
+			 auth_key,
+			 NULL, NULL,
+			 hmac_sha256_reference_plaintext[i],
+			 hmac_sha256_reference_length[i],
+			 NULL, 0,
+			 wrong_digest,
+			 HMAC_SHA256_128_CHECK_LEN);
 	}
 }
 
@@ -1014,7 +1146,12 @@  static int check_alg_hmac_sha1(void)
 	return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA1_HMAC);
 }
 
-void crypto_test_alg_hmac_sha1(void)
+void crypto_test_gen_alg_hmac_sha1(void)
+{
+	printf(" TEST NOT IMPLEMENTED YET ");
+}
+
+void crypto_test_check_alg_hmac_sha1(void)
 {
 	printf(" TEST NOT IMPLEMENTED YET ");
 }
@@ -1024,7 +1161,12 @@  static int check_alg_hmac_sha512(void)
 	return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA512_HMAC);
 }
 
-void crypto_test_alg_hmac_sha512(void)
+void crypto_test_gen_alg_hmac_sha512(void)
+{
+	printf(" TEST NOT IMPLEMENTED YET ");
+}
+
+void crypto_test_check_alg_hmac_sha512(void)
 {
 	printf(" TEST NOT IMPLEMENTED YET ");
 }
@@ -1078,13 +1220,21 @@  odp_testinfo_t crypto_suite[] = {
 				  check_alg_aes_gcm),
 	ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes128_gcm_ovr_iv,
 				  check_alg_aes_gcm),
-	ODP_TEST_INFO_CONDITIONAL(crypto_test_alg_hmac_md5,
+	ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_md5,
+				  check_alg_hmac_md5),
+	ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_md5,
 				  check_alg_hmac_md5),
-	ODP_TEST_INFO_CONDITIONAL(crypto_test_alg_hmac_sha1,
+	ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha1,
 				  check_alg_hmac_sha1),
-	ODP_TEST_INFO_CONDITIONAL(crypto_test_alg_hmac_sha256,
+	ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha1,
+				  check_alg_hmac_sha1),
+	ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha256,
+				  check_alg_hmac_sha256),
+	ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha256,
 				  check_alg_hmac_sha256),
-	ODP_TEST_INFO_CONDITIONAL(crypto_test_alg_hmac_sha512,
+	ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha512,
+				  check_alg_hmac_sha512),
+	ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha512,
 				  check_alg_hmac_sha512),
 	ODP_TEST_INFO_NULL,
 };

From e9d43a75b348fdaab2a5ab96802cd118101902c3 Mon Sep 17 00:00:00 2001
From: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
Date: Wed, 8 Mar 2017 11:22:13 +0300
Subject: [PATCH 2/8] validation: crypto: correct comment for HMAC-SHA-256
 tests

Comment for HMAC-SHA-256 tests talks about HMAC-MD5 and respective
lengths. Correct it to mention SHA-256 and proper digest lengths.

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
---
/** Email created from pull request 10 (lumag:crypto-update)
 ** https://github.com/Linaro/odp/pull/10
 ** Patch: https://github.com/Linaro/odp/pull/10.patch
 ** Base sha: e91cf8bb39da24d2a7dbfbb328aa35d1c4cab4ea
 ** Merge commit sha: 2f5b8229a5006f9dffa717fb31aa784093b8ae76
 **/
 test/common_plat/validation/api/crypto/odp_crypto_test_inp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
index 9af7ba3..e1fc6d4 100644
--- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
+++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
@@ -1042,8 +1042,8 @@  static int check_alg_hmac_sha256(void)
 	return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA256_HMAC);
 }
 
-/* This test verifies the correctness of HMAC_MD5 digest operation.
- * The output check length is truncated to 12 bytes (96 bits) as
+/* This test verifies the correctness of HMAC_SHA256 digest operation.
+ * The output check length is truncated to 16 bytes (128 bits) as
  * returned by the crypto operation API call.
  * Note that hash digest is a one-way operation.
  * In addition the test verifies if the implementation can use the

From 38b2909219f35033e35e951536ff00da7d4f8580 Mon Sep 17 00:00:00 2001
From: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
Date: Wed, 8 Mar 2017 11:22:13 +0300
Subject: [PATCH 3/8] validation: crypto: add HMAC-SHA-1-96 test cases

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
---
/** Email created from pull request 10 (lumag:crypto-update)
 ** https://github.com/Linaro/odp/pull/10
 ** Patch: https://github.com/Linaro/odp/pull/10.patch
 ** Base sha: e91cf8bb39da24d2a7dbfbb328aa35d1c4cab4ea
 ** Merge commit sha: 2f5b8229a5006f9dffa717fb31aa784093b8ae76
 **/
 .../validation/api/crypto/odp_crypto_test_inp.c    | 99 +++++++++++++++++++++-
 .../validation/api/crypto/test_vectors.h           | 44 ++++++++++
 .../validation/api/crypto/test_vectors_len.h       |  6 ++
 3 files changed, 147 insertions(+), 2 deletions(-)

diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
index e1fc6d4..971d141 100644
--- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
+++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
@@ -28,6 +28,8 @@  static const char *auth_alg_name(odp_auth_alg_t auth)
 		return "ODP_AUTH_ALG_NULL";
 	case ODP_AUTH_ALG_MD5_HMAC:
 		return "ODP_AUTH_ALG_MD5_HMAC";
+	case ODP_AUTH_ALG_SHA1_HMAC:
+		return "ODP_AUTH_ALG_SHA1_HMAC";
 	case ODP_AUTH_ALG_SHA256_HMAC:
 		return "ODP_AUTH_ALG_SHA256_HMAC";
 	case ODP_AUTH_ALG_AES_GCM:
@@ -129,9 +131,13 @@  static void alg_test(odp_crypto_op_t op,
 	if (auth_alg == ODP_AUTH_ALG_NULL &&
 	    !(capa.auths.bit.null))
 		rc = -1;
+	if (auth_alg == ODP_AUTH_ALG_SHA1_HMAC &&
+	    !(capa.auths.bit.sha1_hmac))
+		rc = -1;
 	if (auth_alg == ODP_AUTH_ALG_SHA256_HMAC &&
 	    !(capa.auths.bit.sha256_hmac))
 		rc = -1;
+		rc = -1;
 
 	CU_ASSERT(!rc);
 	CU_ASSERT((~capa.auths.all_bits & capa.hw_auths.all_bits) == 0);
@@ -1146,14 +1152,103 @@  static int check_alg_hmac_sha1(void)
 	return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA1_HMAC);
 }
 
+/* This test verifies the correctness of HMAC_SHA1 digest operation.
+ * The output check length is truncated to 12 bytes (96 bits) as
+ * returned by the crypto operation API call.
+ * Note that hash digest is a one-way operation.
+ * In addition the test verifies if the implementation can use the
+ * packet buffer as completion event buffer.
+ * */
 void crypto_test_gen_alg_hmac_sha1(void)
 {
-	printf(" TEST NOT IMPLEMENTED YET ");
+	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
+			 auth_key   = { .data = NULL, .length = 0 };
+	odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
+
+	unsigned int test_vec_num = (sizeof(hmac_sha1_reference_length) /
+				     sizeof(hmac_sha1_reference_length[0]));
+
+	unsigned int i;
+
+	for (i = 0; i < test_vec_num; i++) {
+		auth_key.data = hmac_sha1_reference_key[i];
+		auth_key.length = sizeof(hmac_sha1_reference_key[i]);
+
+		if (!check_auth_options(ODP_AUTH_ALG_SHA1_HMAC,
+					auth_key.length,
+					HMAC_SHA1_96_CHECK_LEN))
+			continue;
+
+		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 0,
+			 ODP_CIPHER_ALG_NULL,
+			 iv,
+			 iv.data,
+			 cipher_key,
+			 ODP_AUTH_ALG_SHA1_HMAC,
+			 auth_key,
+			 NULL, NULL,
+			 hmac_sha1_reference_plaintext[i],
+			 hmac_sha1_reference_length[i],
+			 NULL, 0,
+			 hmac_sha1_reference_digest[i],
+			 HMAC_SHA1_96_CHECK_LEN);
+	}
 }
 
 void crypto_test_check_alg_hmac_sha1(void)
 {
-	printf(" TEST NOT IMPLEMENTED YET ");
+	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
+			 auth_key   = { .data = NULL, .length = 0 };
+	odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
+	uint8_t wrong_digest[HMAC_SHA1_DIGEST_LEN];
+
+	unsigned int test_vec_num = (sizeof(hmac_sha1_reference_length) /
+				     sizeof(hmac_sha1_reference_length[0]));
+
+	unsigned int i;
+
+	memset(wrong_digest, 0xa5, sizeof(wrong_digest));
+
+	for (i = 0; i < test_vec_num; i++) {
+		auth_key.data = hmac_sha1_reference_key[i];
+		auth_key.length = sizeof(hmac_sha1_reference_key[i]);
+
+		if (!check_auth_options(ODP_AUTH_ALG_SHA1_HMAC,
+					auth_key.length,
+					HMAC_SHA1_96_CHECK_LEN))
+			continue;
+
+		alg_test(ODP_CRYPTO_OP_DECODE,
+			 0,
+			 ODP_CIPHER_ALG_NULL,
+			 iv,
+			 iv.data,
+			 cipher_key,
+			 ODP_AUTH_ALG_SHA1_HMAC,
+			 auth_key,
+			 NULL, NULL,
+			 hmac_sha1_reference_plaintext[i],
+			 hmac_sha1_reference_length[i],
+			 NULL, 0,
+			 hmac_sha1_reference_digest[i],
+			 HMAC_SHA1_96_CHECK_LEN);
+
+		alg_test(ODP_CRYPTO_OP_DECODE,
+			 1,
+			 ODP_CIPHER_ALG_NULL,
+			 iv,
+			 iv.data,
+			 cipher_key,
+			 ODP_AUTH_ALG_SHA1_HMAC,
+			 auth_key,
+			 NULL, NULL,
+			 hmac_sha1_reference_plaintext[i],
+			 hmac_sha1_reference_length[i],
+			 NULL, 0,
+			 wrong_digest,
+			 HMAC_SHA1_96_CHECK_LEN);
+	}
 }
 
 static int check_alg_hmac_sha512(void)
diff --git a/test/common_plat/validation/api/crypto/test_vectors.h b/test/common_plat/validation/api/crypto/test_vectors.h
index da4610f..ce4ca8f 100644
--- a/test/common_plat/validation/api/crypto/test_vectors.h
+++ b/test/common_plat/validation/api/crypto/test_vectors.h
@@ -350,4 +350,48 @@  static uint8_t hmac_sha256_reference_digest[][HMAC_SHA256_DIGEST_LEN] = {
 	  0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7 }
 };
 
+static uint8_t hmac_sha1_reference_key[][HMAC_SHA1_KEY_LEN] = {
+	{ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	  0x0b, 0x0b, 0x0b, 0x0b },
+
+	/* "Jefe" */
+	{ 0x4a, 0x65, 0x66, 0x65 },
+
+	{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+	  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+	  0xaa, 0xaa, 0xaa, 0xaa }
+};
+
+static uint32_t hmac_sha1_reference_length[] = { 8, 28, 50 };
+
+static uint8_t
+hmac_sha1_reference_plaintext[][HMAC_SHA1_MAX_DATA_LEN] = {
+	/* "Hi There" */
+	{ 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65},
+
+	/* what do ya want for nothing?*/
+	{ 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
+	  0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
+	  0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
+	  0x69, 0x6e, 0x67, 0x3f },
+
+	{ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd }
+};
+
+static uint8_t hmac_sha1_reference_digest[][HMAC_SHA1_DIGEST_LEN] = {
+	{ 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05,
+	  0x72, 0x64, 0xe2, 0x8b, 0xc0, 0xb6 },
+
+	{ 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb,
+	  0x2f, 0xa2, 0xd2, 0x74, 0x16, 0xd5 },
+
+	{ 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac,
+	  0x11, 0xcd, 0x91, 0xa3, 0x9a, 0xf4 },
+};
+
 #endif
diff --git a/test/common_plat/validation/api/crypto/test_vectors_len.h b/test/common_plat/validation/api/crypto/test_vectors_len.h
index 4fbb5cd..609f430 100644
--- a/test/common_plat/validation/api/crypto/test_vectors_len.h
+++ b/test/common_plat/validation/api/crypto/test_vectors_len.h
@@ -35,4 +35,10 @@ 
 #define HMAC_SHA256_DIGEST_LEN     32
 #define HMAC_SHA256_128_CHECK_LEN  16
 
+/* HMAC-SHA1 */
+#define HMAC_SHA1_KEY_LEN        20
+#define HMAC_SHA1_MAX_DATA_LEN   128
+#define HMAC_SHA1_DIGEST_LEN     20
+#define HMAC_SHA1_96_CHECK_LEN   12
+
 #endif

From 23856401dfa13c25a1b624def2cc0d084694d567 Mon Sep 17 00:00:00 2001
From: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
Date: Wed, 8 Mar 2017 11:22:13 +0300
Subject: [PATCH 4/8] validation: crypto: add HMAC-SHA-512 test cases

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
---
/** Email created from pull request 10 (lumag:crypto-update)
 ** https://github.com/Linaro/odp/pull/10
 ** Patch: https://github.com/Linaro/odp/pull/10.patch
 ** Base sha: e91cf8bb39da24d2a7dbfbb328aa35d1c4cab4ea
 ** Merge commit sha: 2f5b8229a5006f9dffa717fb31aa784093b8ae76
 **/
 .../validation/api/crypto/odp_crypto_test_inp.c    | 97 +++++++++++++++++++++-
 .../validation/api/crypto/test_vectors.h           | 50 +++++++++++
 .../validation/api/crypto/test_vectors_len.h       |  6 ++
 3 files changed, 151 insertions(+), 2 deletions(-)

diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
index 971d141..5c6c081 100644
--- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
+++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
@@ -32,6 +32,8 @@  static const char *auth_alg_name(odp_auth_alg_t auth)
 		return "ODP_AUTH_ALG_SHA1_HMAC";
 	case ODP_AUTH_ALG_SHA256_HMAC:
 		return "ODP_AUTH_ALG_SHA256_HMAC";
+	case ODP_AUTH_ALG_SHA512_HMAC:
+		return "ODP_AUTH_ALG_SHA512_HMAC";
 	case ODP_AUTH_ALG_AES_GCM:
 		return "ODP_AUTH_ALG_AES_GCM";
 	default:
@@ -137,6 +139,8 @@  static void alg_test(odp_crypto_op_t op,
 	if (auth_alg == ODP_AUTH_ALG_SHA256_HMAC &&
 	    !(capa.auths.bit.sha256_hmac))
 		rc = -1;
+	if (auth_alg == ODP_AUTH_ALG_SHA512_HMAC &&
+	    !(capa.auths.bit.sha512_hmac))
 		rc = -1;
 
 	CU_ASSERT(!rc);
@@ -1256,14 +1260,103 @@  static int check_alg_hmac_sha512(void)
 	return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA512_HMAC);
 }
 
+/* This test verifies the correctness of HMAC_SHA512 digest operation.
+ * The output check length is truncated to 32 bytes (256 bits) as
+ * returned by the crypto operation API call.
+ * Note that hash digest is a one-way operation.
+ * In addition the test verifies if the implementation can use the
+ * packet buffer as completion event buffer.
+ * */
 void crypto_test_gen_alg_hmac_sha512(void)
 {
-	printf(" TEST NOT IMPLEMENTED YET ");
+	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
+			 auth_key   = { .data = NULL, .length = 0 };
+	odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
+
+	unsigned int test_vec_num = (sizeof(hmac_sha512_reference_length) /
+				     sizeof(hmac_sha512_reference_length[0]));
+
+	unsigned int i;
+
+	for (i = 0; i < test_vec_num; i++) {
+		auth_key.data = hmac_sha512_reference_key[i];
+		auth_key.length = sizeof(hmac_sha512_reference_key[i]);
+
+		if (!check_auth_options(ODP_AUTH_ALG_SHA512_HMAC,
+					auth_key.length,
+					HMAC_SHA512_256_CHECK_LEN))
+			continue;
+
+		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 0,
+			 ODP_CIPHER_ALG_NULL,
+			 iv,
+			 iv.data,
+			 cipher_key,
+			 ODP_AUTH_ALG_SHA512_HMAC,
+			 auth_key,
+			 NULL, NULL,
+			 hmac_sha512_reference_plaintext[i],
+			 hmac_sha512_reference_length[i],
+			 NULL, 0,
+			 hmac_sha512_reference_digest[i],
+			 HMAC_SHA512_256_CHECK_LEN);
+	}
 }
 
 void crypto_test_check_alg_hmac_sha512(void)
 {
-	printf(" TEST NOT IMPLEMENTED YET ");
+	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
+			 auth_key   = { .data = NULL, .length = 0 };
+	odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
+	uint8_t wrong_digest[HMAC_SHA512_DIGEST_LEN];
+
+	unsigned int test_vec_num = (sizeof(hmac_sha512_reference_length) /
+				     sizeof(hmac_sha512_reference_length[0]));
+
+	unsigned int i;
+
+	memset(wrong_digest, 0xa5, sizeof(wrong_digest));
+
+	for (i = 0; i < test_vec_num; i++) {
+		auth_key.data = hmac_sha512_reference_key[i];
+		auth_key.length = sizeof(hmac_sha512_reference_key[i]);
+
+		if (!check_auth_options(ODP_AUTH_ALG_SHA512_HMAC,
+					auth_key.length,
+					HMAC_SHA512_256_CHECK_LEN))
+			continue;
+
+		alg_test(ODP_CRYPTO_OP_DECODE,
+			 0,
+			 ODP_CIPHER_ALG_NULL,
+			 iv,
+			 iv.data,
+			 cipher_key,
+			 ODP_AUTH_ALG_SHA512_HMAC,
+			 auth_key,
+			 NULL, NULL,
+			 hmac_sha512_reference_plaintext[i],
+			 hmac_sha512_reference_length[i],
+			 NULL, 0,
+			 hmac_sha512_reference_digest[i],
+			 HMAC_SHA512_256_CHECK_LEN);
+
+		alg_test(ODP_CRYPTO_OP_DECODE,
+			 1,
+			 ODP_CIPHER_ALG_NULL,
+			 iv,
+			 iv.data,
+			 cipher_key,
+			 ODP_AUTH_ALG_SHA512_HMAC,
+			 auth_key,
+			 NULL, NULL,
+			 hmac_sha512_reference_plaintext[i],
+			 hmac_sha512_reference_length[i],
+			 NULL, 0,
+			 wrong_digest,
+			 HMAC_SHA512_256_CHECK_LEN);
+	}
 }
 
 int crypto_suite_sync_init(void)
diff --git a/test/common_plat/validation/api/crypto/test_vectors.h b/test/common_plat/validation/api/crypto/test_vectors.h
index ce4ca8f..4fddbc4 100644
--- a/test/common_plat/validation/api/crypto/test_vectors.h
+++ b/test/common_plat/validation/api/crypto/test_vectors.h
@@ -394,4 +394,54 @@  static uint8_t hmac_sha1_reference_digest[][HMAC_SHA1_DIGEST_LEN] = {
 	  0x11, 0xcd, 0x91, 0xa3, 0x9a, 0xf4 },
 };
 
+static uint8_t hmac_sha512_reference_key[][HMAC_SHA512_KEY_LEN] = {
+	{ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	  0x0b, 0x0b, 0x0b, 0x0b },
+
+	/* "Jefe" */
+	{ 0x4a, 0x65, 0x66, 0x65 },
+
+	{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+	  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+	  0xaa, 0xaa, 0xaa, 0xaa }
+};
+
+static uint32_t hmac_sha512_reference_length[] = { 8, 28, 50 };
+
+static uint8_t
+hmac_sha512_reference_plaintext[][HMAC_SHA512_MAX_DATA_LEN] = {
+	/* "Hi There" */
+	{ 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65},
+
+	/* what do ya want for nothing?*/
+	{ 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
+	  0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
+	  0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
+	  0x69, 0x6e, 0x67, 0x3f },
+
+	{ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd }
+};
+
+static uint8_t hmac_sha512_reference_digest[][HMAC_SHA512_DIGEST_LEN] = {
+	{ 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
+	  0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
+	  0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
+	  0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde },
+
+	{ 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
+	  0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
+	  0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
+	  0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54 },
+
+	{ 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84,
+	  0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9,
+	  0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36,
+	  0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39 }
+};
+
 #endif
diff --git a/test/common_plat/validation/api/crypto/test_vectors_len.h b/test/common_plat/validation/api/crypto/test_vectors_len.h
index 609f430..3b25ea9 100644
--- a/test/common_plat/validation/api/crypto/test_vectors_len.h
+++ b/test/common_plat/validation/api/crypto/test_vectors_len.h
@@ -41,4 +41,10 @@ 
 #define HMAC_SHA1_DIGEST_LEN     20
 #define HMAC_SHA1_96_CHECK_LEN   12
 
+/* HMAC-SHA512 */
+#define HMAC_SHA512_KEY_LEN        64
+#define HMAC_SHA512_MAX_DATA_LEN   128
+#define HMAC_SHA512_DIGEST_LEN     64
+#define HMAC_SHA512_256_CHECK_LEN  32
+
 #endif

From 0ece890722d21f74fe8f19aa50bd8779fc7fc308 Mon Sep 17 00:00:00 2001
From: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
Date: Wed, 8 Mar 2017 05:08:00 +0300
Subject: [PATCH 5/8] linux-generic: crypto: unify auth code

Authentication code contains similar functions. Instead of replicating
them further (e.g. for SHA-1 or SHA-3) factor out common code blocks,
moving all difference to session data.

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
---
/** Email created from pull request 10 (lumag:crypto-update)
 ** https://github.com/Linaro/odp/pull/10
 ** Patch: https://github.com/Linaro/odp/pull/10.patch
 ** Base sha: e91cf8bb39da24d2a7dbfbb328aa35d1c4cab4ea
 ** Merge commit sha: 2f5b8229a5006f9dffa717fb31aa784093b8ae76
 **/
 .../linux-generic/include/odp_crypto_internal.h    |  14 +--
 platform/linux-generic/odp_crypto.c                | 126 ++++-----------------
 2 files changed, 28 insertions(+), 112 deletions(-)

diff --git a/platform/linux-generic/include/odp_crypto_internal.h b/platform/linux-generic/include/odp_crypto_internal.h
index f85b76e..515cefa 100644
--- a/platform/linux-generic/include/odp_crypto_internal.h
+++ b/platform/linux-generic/include/odp_crypto_internal.h
@@ -60,16 +60,10 @@  struct odp_crypto_generic_session {
 	} cipher;
 
 	struct {
-		union {
-			struct {
-				uint8_t  key[16];
-				uint32_t bytes;
-			} md5;
-			struct {
-				uint8_t  key[32];
-				uint32_t bytes;
-			} sha256;
-		} data;
+		uint8_t  key[EVP_MAX_KEY_LENGTH];
+		uint32_t key_length;
+		uint32_t bytes;
+		const EVP_MD *evp_md;
 		crypto_func_t func;
 	} auth;
 };
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
index 2ba504b..4d59b82 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -110,8 +110,8 @@  null_crypto_routine(odp_crypto_op_param_t *param ODP_UNUSED,
 }
 
 static
-odp_crypto_alg_err_t md5_gen(odp_crypto_op_param_t *param,
-			     odp_crypto_generic_session_t *session)
+odp_crypto_alg_err_t auth_gen(odp_crypto_op_param_t *param,
+			      odp_crypto_generic_session_t *session)
 {
 	uint8_t *data  = odp_packet_data(param->out_pkt);
 	uint8_t *icv   = data;
@@ -123,94 +123,28 @@  odp_crypto_alg_err_t md5_gen(odp_crypto_op_param_t *param,
 	icv  += param->hash_result_offset;
 
 	/* Hash it */
-	HMAC(EVP_md5(),
-	     session->auth.data.md5.key,
-	     16,
+	HMAC(session->auth.evp_md,
+	     session->auth.key,
+	     session->auth.key_length,
 	     data,
 	     len,
 	     hash,
 	     NULL);
 
 	/* Copy to the output location */
-	memcpy(icv, hash, session->auth.data.md5.bytes);
+	memcpy(icv, hash, session->auth.bytes);
 
 	return ODP_CRYPTO_ALG_ERR_NONE;
 }
 
 static
-odp_crypto_alg_err_t md5_check(odp_crypto_op_param_t *param,
-			       odp_crypto_generic_session_t *session)
-{
-	uint8_t *data  = odp_packet_data(param->out_pkt);
-	uint8_t *icv   = data;
-	uint32_t len   = param->auth_range.length;
-	uint32_t bytes = session->auth.data.md5.bytes;
-	uint8_t  hash_in[EVP_MAX_MD_SIZE];
-	uint8_t  hash_out[EVP_MAX_MD_SIZE];
-
-	/* Adjust pointer for beginning of area to auth */
-	data += param->auth_range.offset;
-	icv  += param->hash_result_offset;
-
-	/* Copy current value out and clear it before authentication */
-	memset(hash_in, 0, sizeof(hash_in));
-	memcpy(hash_in, icv, bytes);
-	memset(icv, 0, bytes);
-	memset(hash_out, 0, sizeof(hash_out));
-
-	/* Hash it */
-	HMAC(EVP_md5(),
-	     session->auth.data.md5.key,
-	     16,
-	     data,
-	     len,
-	     hash_out,
-	     NULL);
-
-	/* Verify match */
-	if (0 != memcmp(hash_in, hash_out, bytes))
-		return ODP_CRYPTO_ALG_ERR_ICV_CHECK;
-
-	/* Matched */
-	return ODP_CRYPTO_ALG_ERR_NONE;
-}
-
-static
-odp_crypto_alg_err_t sha256_gen(odp_crypto_op_param_t *param,
+odp_crypto_alg_err_t auth_check(odp_crypto_op_param_t *param,
 				odp_crypto_generic_session_t *session)
 {
 	uint8_t *data  = odp_packet_data(param->out_pkt);
 	uint8_t *icv   = data;
 	uint32_t len   = param->auth_range.length;
-	uint8_t  hash[EVP_MAX_MD_SIZE];
-
-	/* Adjust pointer for beginning of area to auth */
-	data += param->auth_range.offset;
-	icv  += param->hash_result_offset;
-
-	/* Hash it */
-	HMAC(EVP_sha256(),
-	     session->auth.data.sha256.key,
-	     32,
-	     data,
-	     len,
-	     hash,
-	     NULL);
-
-	/* Copy to the output location */
-	memcpy(icv, hash, session->auth.data.sha256.bytes);
-
-	return ODP_CRYPTO_ALG_ERR_NONE;
-}
-
-static
-odp_crypto_alg_err_t sha256_check(odp_crypto_op_param_t *param,
-				  odp_crypto_generic_session_t *session)
-{
-	uint8_t *data  = odp_packet_data(param->out_pkt);
-	uint8_t *icv   = data;
-	uint32_t len   = param->auth_range.length;
-	uint32_t bytes = session->auth.data.sha256.bytes;
+	uint32_t bytes = session->auth.bytes;
 	uint8_t  hash_in[EVP_MAX_MD_SIZE];
 	uint8_t  hash_out[EVP_MAX_MD_SIZE];
 
@@ -225,9 +159,9 @@  odp_crypto_alg_err_t sha256_check(odp_crypto_op_param_t *param,
 	memset(hash_out, 0, sizeof(hash_out));
 
 	/* Hash it */
-	HMAC(EVP_sha256(),
-	     session->auth.data.sha256.key,
-	     32,
+	HMAC(session->auth.evp_md,
+	     session->auth.key,
+	     session->auth.key_length,
 	     data,
 	     len,
 	     hash_out,
@@ -587,38 +521,26 @@  static int process_des_param(odp_crypto_generic_session_t *session)
 	return 0;
 }
 
-static int process_md5_param(odp_crypto_generic_session_t *session,
-			     uint32_t bits)
+static int process_auth_param(odp_crypto_generic_session_t *session,
+			      uint32_t bits,
+			      uint32_t key_length,
+			      const EVP_MD *evp_md)
 {
 	/* Set function */
 	if (ODP_CRYPTO_OP_ENCODE == session->p.op)
-		session->auth.func = md5_gen;
+		session->auth.func = auth_gen;
 	else
-		session->auth.func = md5_check;
-
-	/* Number of valid bytes */
-	session->auth.data.md5.bytes = bits / 8;
-
-	/* Convert keys */
-	memcpy(session->auth.data.md5.key, session->p.auth_key.data, 16);
-
-	return 0;
-}
+		session->auth.func = auth_check;
 
-static int process_sha256_param(odp_crypto_generic_session_t *session,
-				uint32_t bits)
-{
-	/* Set function */
-	if (ODP_CRYPTO_OP_ENCODE == session->p.op)
-		session->auth.func = sha256_gen;
-	else
-		session->auth.func = sha256_check;
+	session->auth.evp_md = evp_md;
 
 	/* Number of valid bytes */
-	session->auth.data.sha256.bytes = bits / 8;
+	session->auth.bytes = bits / 8;
 
 	/* Convert keys */
-	memcpy(session->auth.data.sha256.key, session->p.auth_key.data, 32);
+	session->auth.key_length = key_length;
+	memcpy(session->auth.key, session->p.auth_key.data,
+	       session->auth.key_length);
 
 	return 0;
 }
@@ -816,12 +738,12 @@  odp_crypto_session_create(odp_crypto_session_param_t *param,
 	case ODP_AUTH_ALG_MD5_HMAC:
 	     /* deprecated */
 	case ODP_AUTH_ALG_MD5_96:
-		rc = process_md5_param(session, 96);
+		rc = process_auth_param(session, 96, 16, EVP_md5());
 		break;
 	case ODP_AUTH_ALG_SHA256_HMAC:
 	     /* deprecated */
 	case ODP_AUTH_ALG_SHA256_128:
-		rc = process_sha256_param(session, 128);
+		rc = process_auth_param(session, 128, 32, EVP_sha256());
 		break;
 	case ODP_AUTH_ALG_AES_GCM:
 	     /* deprecated */

From e35131d66c425f184263fb33b6c9e81d4a6daa17 Mon Sep 17 00:00:00 2001
From: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
Date: Wed, 8 Mar 2017 10:38:09 +0300
Subject: [PATCH 6/8] linux-generic: crypto: switch to EVP interface for cipher
 algorithms

Switch AES-CBC and 3DES-CBC to use generic (EVP) interface instad of low
level interface (as recommended by OpenSSL documentation). This allows
to use the same code path for all non-AEAD ciphers. The only AEAD cipher
(AES-GCM) already uses EVP interface. Generalization of that code can
happen if there will be more AEAD ciphers.

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
---
/** Email created from pull request 10 (lumag:crypto-update)
 ** https://github.com/Linaro/odp/pull/10
 ** Patch: https://github.com/Linaro/odp/pull/10.patch
 ** Base sha: e91cf8bb39da24d2a7dbfbb328aa35d1c4cab4ea
 ** Merge commit sha: 2f5b8229a5006f9dffa717fb31aa784093b8ae76
 **/
 .../linux-generic/include/odp_crypto_internal.h    |  16 +-
 platform/linux-generic/odp_crypto.c                | 232 +++++----------------
 2 files changed, 52 insertions(+), 196 deletions(-)

diff --git a/platform/linux-generic/include/odp_crypto_internal.h b/platform/linux-generic/include/odp_crypto_internal.h
index 515cefa..033fa6d 100644
--- a/platform/linux-generic/include/odp_crypto_internal.h
+++ b/platform/linux-generic/include/odp_crypto_internal.h
@@ -11,8 +11,6 @@ 
 extern "C" {
 #endif
 
-#include <openssl/des.h>
-#include <openssl/aes.h>
 #include <openssl/evp.h>
 
 #define MAX_IV_LEN      64
@@ -43,19 +41,7 @@  struct odp_crypto_generic_session {
 		/* Copy of session IV data */
 		uint8_t iv_data[MAX_IV_LEN];
 
-		union {
-			struct {
-				DES_key_schedule ks1;
-				DES_key_schedule ks2;
-				DES_key_schedule ks3;
-			} des;
-			struct {
-				AES_KEY key;
-			} aes;
-			struct {
-				EVP_CIPHER_CTX *ctx;
-			} aes_gcm;
-		} data;
+		EVP_CIPHER_CTX ctx;
 		crypto_func_t func;
 	} cipher;
 
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
index 4d59b82..ad4d169 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -176,90 +176,6 @@  odp_crypto_alg_err_t auth_check(odp_crypto_op_param_t *param,
 }
 
 static
-odp_crypto_alg_err_t aes_encrypt(odp_crypto_op_param_t *param,
-				 odp_crypto_generic_session_t *session)
-{
-	uint8_t *data  = odp_packet_data(param->out_pkt);
-	uint32_t len   = param->cipher_range.length;
-	unsigned char iv_enc[AES_BLOCK_SIZE];
-	void *iv_ptr;
-
-	if (param->override_iv_ptr)
-		iv_ptr = param->override_iv_ptr;
-	else if (session->p.iv.data)
-		iv_ptr = session->cipher.iv_data;
-	else
-		return ODP_CRYPTO_ALG_ERR_IV_INVALID;
-
-	/*
-	 * Create a copy of the IV.  The DES library modifies IV
-	 * and if we are processing packets on parallel threads
-	 * we could get corruption.
-	 */
-	memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE);
-
-	/* Adjust pointer for beginning of area to cipher */
-	data += param->cipher_range.offset;
-	/* Encrypt it */
-	AES_cbc_encrypt(data, data, len, &session->cipher.data.aes.key,
-			iv_enc, AES_ENCRYPT);
-
-	return ODP_CRYPTO_ALG_ERR_NONE;
-}
-
-static
-odp_crypto_alg_err_t aes_decrypt(odp_crypto_op_param_t *param,
-				 odp_crypto_generic_session_t *session)
-{
-	uint8_t *data  = odp_packet_data(param->out_pkt);
-	uint32_t len   = param->cipher_range.length;
-	unsigned char iv_enc[AES_BLOCK_SIZE];
-	void *iv_ptr;
-
-	if (param->override_iv_ptr)
-		iv_ptr = param->override_iv_ptr;
-	else if (session->p.iv.data)
-		iv_ptr = session->cipher.iv_data;
-	else
-		return ODP_CRYPTO_ALG_ERR_IV_INVALID;
-
-	/*
-	 * Create a copy of the IV.  The DES library modifies IV
-	 * and if we are processing packets on parallel threads
-	 * we could get corruption.
-	 */
-	memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE);
-
-	/* Adjust pointer for beginning of area to cipher */
-	data += param->cipher_range.offset;
-	/* Encrypt it */
-	AES_cbc_encrypt(data, data, len, &session->cipher.data.aes.key,
-			iv_enc, AES_DECRYPT);
-
-	return ODP_CRYPTO_ALG_ERR_NONE;
-}
-
-static int process_aes_param(odp_crypto_generic_session_t *session)
-{
-	/* Verify IV len is either 0 or 16 */
-	if (!((0 == session->p.iv.length) || (16 == session->p.iv.length)))
-		return -1;
-
-	/* Set function */
-	if (ODP_CRYPTO_OP_ENCODE == session->p.op) {
-		session->cipher.func = aes_encrypt;
-		AES_set_encrypt_key(session->p.cipher_key.data, 128,
-				    &session->cipher.data.aes.key);
-	} else {
-		session->cipher.func = aes_decrypt;
-		AES_set_decrypt_key(session->p.cipher_key.data, 128,
-				    &session->cipher.data.aes.key);
-	}
-
-	return 0;
-}
-
-static
 odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param,
 				     odp_crypto_generic_session_t *session)
 {
@@ -269,7 +185,6 @@  odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param,
 	uint8_t *aad_tail = data + param->cipher_range.offset +
 		param->cipher_range.length;
 	uint32_t auth_len = param->auth_range.length;
-	unsigned char iv_enc[AES_BLOCK_SIZE];
 	void *iv_ptr;
 	uint8_t *tag = data + param->hash_result_offset;
 
@@ -286,21 +201,14 @@  odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param,
 	    param->cipher_range.offset + plain_len)
 		return ODP_CRYPTO_ALG_ERR_DATA_SIZE;
 
-	/*
-	 * Create a copy of the IV.  The DES library modifies IV
-	 * and if we are processing packets on parallel threads
-	 * we could get corruption.
-	 */
-	memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE);
-
 	/* Adjust pointer for beginning of area to cipher/auth */
 	uint8_t *plaindata = data + param->cipher_range.offset;
 
 	/* Encrypt it */
-	EVP_CIPHER_CTX *ctx = session->cipher.data.aes_gcm.ctx;
+	EVP_CIPHER_CTX *ctx = &session->cipher.ctx;
 	int cipher_len = 0;
 
-	EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_enc);
+	EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr);
 
 	/* Authenticate header data (if any) without encrypting them */
 	if (aad_head < plaindata) {
@@ -334,7 +242,6 @@  odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param,
 	uint8_t *aad_tail = data + param->cipher_range.offset +
 		param->cipher_range.length;
 	uint32_t auth_len = param->auth_range.length;
-	unsigned char iv_enc[AES_BLOCK_SIZE];
 	void *iv_ptr;
 	uint8_t *tag   = data + param->hash_result_offset;
 
@@ -351,20 +258,13 @@  odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param,
 	    param->cipher_range.offset + cipher_len)
 		return ODP_CRYPTO_ALG_ERR_DATA_SIZE;
 
-	/*
-	 * Create a copy of the IV.  The DES library modifies IV
-	 * and if we are processing packets on parallel threads
-	 * we could get corruption.
-	 */
-	memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE);
-
 	/* Adjust pointer for beginning of area to cipher/auth */
 	uint8_t *cipherdata = data + param->cipher_range.offset;
 	/* Encrypt it */
-	EVP_CIPHER_CTX *ctx = session->cipher.data.aes_gcm.ctx;
+	EVP_CIPHER_CTX *ctx = &session->cipher.ctx;
 	int plain_len = 0;
 
-	EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_enc);
+	EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr);
 
 	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag);
 
@@ -392,14 +292,15 @@  odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param,
 
 static int process_aes_gcm_param(odp_crypto_generic_session_t *session)
 {
+	EVP_CIPHER_CTX *ctx = &session->cipher.ctx;
+
+	EVP_CIPHER_CTX_init(ctx);
+
 	/* Verify Key len is 16 */
 	if (session->p.cipher_key.length != 16)
 		return -1;
 
 	/* Set function */
-	EVP_CIPHER_CTX *ctx =
-		session->cipher.data.aes_gcm.ctx = EVP_CIPHER_CTX_new();
-
 	if (ODP_CRYPTO_OP_ENCODE == session->p.op) {
 		session->cipher.func = aes_gcm_encrypt;
 		EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
@@ -422,13 +323,14 @@  static int process_aes_gcm_param(odp_crypto_generic_session_t *session)
 }
 
 static
-odp_crypto_alg_err_t des_encrypt(odp_crypto_op_param_t *param,
-				 odp_crypto_generic_session_t *session)
+odp_crypto_alg_err_t cipher_crypt(odp_crypto_op_param_t *param,
+				  odp_crypto_generic_session_t *session)
 {
 	uint8_t *data  = odp_packet_data(param->out_pkt);
 	uint32_t len   = param->cipher_range.length;
-	DES_cblock iv;
 	void *iv_ptr;
+	int cipher_len = 0;
+	int rc;
 
 	if (param->override_iv_ptr)
 		iv_ptr = param->override_iv_ptr;
@@ -437,86 +339,55 @@  odp_crypto_alg_err_t des_encrypt(odp_crypto_op_param_t *param,
 	else
 		return ODP_CRYPTO_ALG_ERR_IV_INVALID;
 
-	/*
-	 * Create a copy of the IV.  The DES library modifies IV
-	 * and if we are processing packets on parallel threads
-	 * we could get corruption.
-	 */
-	memcpy(iv, iv_ptr, sizeof(iv));
-
-	/* Adjust pointer for beginning of area to cipher */
-	data += param->cipher_range.offset;
-	/* Encrypt it */
-	DES_ede3_cbc_encrypt(data,
-			     data,
-			     len,
-			     &session->cipher.data.des.ks1,
-			     &session->cipher.data.des.ks2,
-			     &session->cipher.data.des.ks3,
-			     &iv,
-			     1);
-
-	return ODP_CRYPTO_ALG_ERR_NONE;
-}
-
-static
-odp_crypto_alg_err_t des_decrypt(odp_crypto_op_param_t *param,
-				 odp_crypto_generic_session_t *session)
-{
-	uint8_t *data  = odp_packet_data(param->out_pkt);
-	uint32_t len   = param->cipher_range.length;
-	DES_cblock iv;
-	void *iv_ptr;
-
-	if (param->override_iv_ptr)
-		iv_ptr = param->override_iv_ptr;
-	else if (session->p.iv.data)
-		iv_ptr = session->cipher.iv_data;
-	else
+	rc = EVP_CipherInit_ex(&session->cipher.ctx,
+			       NULL, NULL, NULL, iv_ptr, -1);
+	if (odp_unlikely(1 != rc))
 		return ODP_CRYPTO_ALG_ERR_IV_INVALID;
 
-	/*
-	 * Create a copy of the IV.  The DES library modifies IV
-	 * and if we are processing packets on parallel threads
-	 * we could get corruption.
-	 */
-	memcpy(iv, iv_ptr, sizeof(iv));
-
 	/* Adjust pointer for beginning of area to cipher */
 	data += param->cipher_range.offset;
 
-	/* Decrypt it */
-	DES_ede3_cbc_encrypt(data,
-			     data,
-			     len,
-			     &session->cipher.data.des.ks1,
-			     &session->cipher.data.des.ks2,
-			     &session->cipher.data.des.ks3,
-			     &iv,
-			     0);
+	/* En/Decrypt it */
+	EVP_CipherUpdate(&session->cipher.ctx,
+			 data,
+			 &cipher_len,
+			 data,
+			 len);
+
+	EVP_CipherFinal_ex(&session->cipher.ctx,
+			   data + cipher_len,
+			   &cipher_len);
 
 	return ODP_CRYPTO_ALG_ERR_NONE;
 }
 
-static int process_des_param(odp_crypto_generic_session_t *session)
+static int process_cipher_param(odp_crypto_generic_session_t *session,
+				const EVP_CIPHER *cipher)
 {
+	int rc;
+
+	/* Verify Key len is 16 */
+	if ((uint32_t)EVP_CIPHER_key_length(cipher) !=
+			session->p.cipher_key.length)
+		return -1;
+
 	/* Verify IV len is either 0 or 8 */
-	if (!((0 == session->p.iv.length) || (8 == session->p.iv.length)))
+	if (!((0 == session->p.iv.length) ||
+	      ((uint32_t)EVP_CIPHER_iv_length(cipher) == session->p.iv.length)))
 		return -1;
 
 	/* Set function */
-	if (ODP_CRYPTO_OP_ENCODE == session->p.op)
-		session->cipher.func = des_encrypt;
-	else
-		session->cipher.func = des_decrypt;
-
-	/* Convert keys */
-	DES_set_key((DES_cblock *)&session->p.cipher_key.data[0],
-		    &session->cipher.data.des.ks1);
-	DES_set_key((DES_cblock *)&session->p.cipher_key.data[8],
-		    &session->cipher.data.des.ks2);
-	DES_set_key((DES_cblock *)&session->p.cipher_key.data[16],
-		    &session->cipher.data.des.ks3);
+	session->cipher.func = cipher_crypt;
+
+	EVP_CIPHER_CTX_init(&session->cipher.ctx);
+	rc = EVP_CipherInit_ex(&session->cipher.ctx,
+			       cipher,
+			       NULL,
+			       session->p.cipher_key.data,
+			       NULL,
+			       (ODP_CRYPTO_OP_ENCODE == session->p.op) ? 1 : 0);
+	if (odp_unlikely(1 != rc))
+		return -1;
 
 	return 0;
 }
@@ -701,12 +572,12 @@  odp_crypto_session_create(odp_crypto_session_param_t *param,
 		break;
 	case ODP_CIPHER_ALG_DES:
 	case ODP_CIPHER_ALG_3DES_CBC:
-		rc = process_des_param(session);
+		rc = process_cipher_param(session, EVP_des_ede3_cbc());
 		break;
 	case ODP_CIPHER_ALG_AES_CBC:
 	     /* deprecated */
 	case ODP_CIPHER_ALG_AES128_CBC:
-		rc = process_aes_param(session);
+		rc = process_cipher_param(session, EVP_aes_128_cbc());
 		break;
 	case ODP_CIPHER_ALG_AES_GCM:
 	     /* deprecated */
@@ -778,9 +649,8 @@  int odp_crypto_session_destroy(odp_crypto_session_t session)
 	odp_crypto_generic_session_t *generic;
 
 	generic = (odp_crypto_generic_session_t *)(intptr_t)session;
-	if (generic->p.cipher_alg == ODP_CIPHER_ALG_AES128_GCM ||
-	    generic->p.cipher_alg == ODP_CIPHER_ALG_AES_GCM)
-		EVP_CIPHER_CTX_free(generic->cipher.data.aes_gcm.ctx);
+	if (ODP_CIPHER_ALG_NULL != generic->p.cipher_alg)
+		EVP_CIPHER_CTX_cleanup(&generic->cipher.ctx);
 	memset(generic, 0, sizeof(*generic));
 	free_session(generic);
 	return 0;

From 95fb678e923aa0d32512905ad4f321f33d69bc5e Mon Sep 17 00:00:00 2001
From: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
Date: Wed, 8 Mar 2017 11:40:51 +0300
Subject: [PATCH 7/8] linux-generic: crypto: add SHA-1 authentication support

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
---
/** Email created from pull request 10 (lumag:crypto-update)
 ** https://github.com/Linaro/odp/pull/10
 ** Patch: https://github.com/Linaro/odp/pull/10.patch
 ** Base sha: e91cf8bb39da24d2a7dbfbb328aa35d1c4cab4ea
 ** Merge commit sha: 2f5b8229a5006f9dffa717fb31aa784093b8ae76
 **/
 platform/linux-generic/odp_crypto.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
index ad4d169..6663e48 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -54,6 +54,9 @@  static const odp_crypto_cipher_capability_t cipher_capa_aes_gcm[] = {
 static const odp_crypto_auth_capability_t auth_capa_md5_hmac[] = {
 {.digest_len = 12, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} } };
 
+static const odp_crypto_auth_capability_t auth_capa_sha1_hmac[] = {
+{.digest_len = 12, .key_len = 20, .aad_len = {.min = 0, .max = 0, .inc = 0} } };
+
 static const odp_crypto_auth_capability_t auth_capa_sha256_hmac[] = {
 {.digest_len = 16, .key_len = 32, .aad_len = {.min = 0, .max = 0, .inc = 0} } };
 
@@ -432,7 +435,7 @@  int odp_crypto_capability(odp_crypto_capability_t *capa)
 
 	capa->auths.bit.null         = 1;
 	capa->auths.bit.md5_hmac     = 1;
-	capa->auths.bit.sha1_hmac    = 0;
+	capa->auths.bit.sha1_hmac    = 1;
 	capa->auths.bit.sha256_hmac  = 1;
 	capa->auths.bit.sha512_hmac  = 0;
 	capa->auths.bit.aes_gcm      = 1;
@@ -506,6 +509,10 @@  int odp_crypto_auth_capability(odp_auth_alg_t auth,
 		src = auth_capa_md5_hmac;
 		num = sizeof(auth_capa_md5_hmac) / size;
 		break;
+	case ODP_AUTH_ALG_SHA1_HMAC:
+		src = auth_capa_sha1_hmac;
+		num = sizeof(auth_capa_sha1_hmac) / size;
+		break;
 	case ODP_AUTH_ALG_SHA256_HMAC:
 		src = auth_capa_sha256_hmac;
 		num = sizeof(auth_capa_sha256_hmac) / size;
@@ -611,6 +618,9 @@  odp_crypto_session_create(odp_crypto_session_param_t *param,
 	case ODP_AUTH_ALG_MD5_96:
 		rc = process_auth_param(session, 96, 16, EVP_md5());
 		break;
+	case ODP_AUTH_ALG_SHA1_HMAC:
+		rc = process_auth_param(session, 96, 20, EVP_sha1());
+		break;
 	case ODP_AUTH_ALG_SHA256_HMAC:
 	     /* deprecated */
 	case ODP_AUTH_ALG_SHA256_128:

From 1e10cfe1f819b9e14464263de8e823b9942f8a20 Mon Sep 17 00:00:00 2001
From: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
Date: Wed, 8 Mar 2017 11:40:51 +0300
Subject: [PATCH 8/8] linux-generic: crypto: add HMAC-SHA-512 authentication
 support

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>
---
/** Email created from pull request 10 (lumag:crypto-update)
 ** https://github.com/Linaro/odp/pull/10
 ** Patch: https://github.com/Linaro/odp/pull/10.patch
 ** Base sha: e91cf8bb39da24d2a7dbfbb328aa35d1c4cab4ea
 ** Merge commit sha: 2f5b8229a5006f9dffa717fb31aa784093b8ae76
 **/
 platform/linux-generic/odp_crypto.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
index 6663e48..9ce98a1 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -60,6 +60,9 @@  static const odp_crypto_auth_capability_t auth_capa_sha1_hmac[] = {
 static const odp_crypto_auth_capability_t auth_capa_sha256_hmac[] = {
 {.digest_len = 16, .key_len = 32, .aad_len = {.min = 0, .max = 0, .inc = 0} } };
 
+static const odp_crypto_auth_capability_t auth_capa_sha512_hmac[] = {
+{.digest_len = 32, .key_len = 64, .aad_len = {.min = 0, .max = 0, .inc = 0} } };
+
 static const odp_crypto_auth_capability_t auth_capa_aes_gcm[] = {
 {.digest_len = 16, .key_len = 0, .aad_len = {.min = 8, .max = 12, .inc = 4} } };
 
@@ -437,7 +440,7 @@  int odp_crypto_capability(odp_crypto_capability_t *capa)
 	capa->auths.bit.md5_hmac     = 1;
 	capa->auths.bit.sha1_hmac    = 1;
 	capa->auths.bit.sha256_hmac  = 1;
-	capa->auths.bit.sha512_hmac  = 0;
+	capa->auths.bit.sha512_hmac  = 1;
 	capa->auths.bit.aes_gcm      = 1;
 
 	/* Deprecated */
@@ -517,6 +520,10 @@  int odp_crypto_auth_capability(odp_auth_alg_t auth,
 		src = auth_capa_sha256_hmac;
 		num = sizeof(auth_capa_sha256_hmac) / size;
 		break;
+	case ODP_AUTH_ALG_SHA512_HMAC:
+		src = auth_capa_sha512_hmac;
+		num = sizeof(auth_capa_sha512_hmac) / size;
+		break;
 	case ODP_AUTH_ALG_AES_GCM:
 		src = auth_capa_aes_gcm;
 		num = sizeof(auth_capa_aes_gcm) / size;
@@ -626,6 +633,9 @@  odp_crypto_session_create(odp_crypto_session_param_t *param,
 	case ODP_AUTH_ALG_SHA256_128:
 		rc = process_auth_param(session, 128, 32, EVP_sha256());
 		break;
+	case ODP_AUTH_ALG_SHA512_HMAC:
+		rc = process_auth_param(session, 256, 64, EVP_sha512());
+		break;
 	case ODP_AUTH_ALG_AES_GCM:
 	     /* deprecated */
 	case ODP_AUTH_ALG_AES128_GCM: