diff mbox series

[2/8] crypto/cnxk: add lookaside IPsec AES-CBC-HMAC-SHA1 support

Message ID 20210831140127.31775-3-ktejasree@marvell.com (mailing list archive)
State Superseded, archived
Headers show
Series add lookaside IPsec additional features | expand

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Tejasree Kondoj Aug. 31, 2021, 2:01 p.m. UTC
Adding lookaside IPsec AES-CBC-HMAC-SHA1 support to cnxk driver.

Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
---
 doc/guides/cryptodevs/cnxk.rst                |  1 +
 doc/guides/rel_notes/release_21_11.rst        |  4 ++
 drivers/common/cnxk/cnxk_security.c           | 68 ++++++++++++++++++-
 drivers/crypto/cnxk/cn10k_ipsec.c             | 63 ++++++++++++++++-
 .../crypto/cnxk/cnxk_cryptodev_capabilities.c | 44 ++++++++++++
 5 files changed, 176 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/doc/guides/cryptodevs/cnxk.rst b/doc/guides/cryptodevs/cnxk.rst
index 98c7118d68..a40295c087 100644
--- a/doc/guides/cryptodevs/cnxk.rst
+++ b/doc/guides/cryptodevs/cnxk.rst
@@ -231,6 +231,7 @@  Features supported
 * ESP
 * Tunnel mode
 * AES-128/192/256-GCM
+* AES-128/192/256-CBC-SHA1-HMAC
 
 Limitations
 -----------
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index d707a554ef..0d9ce123aa 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -20,6 +20,10 @@  DPDK Release 21.11
       make doc-guides-html
       xdg-open build/doc/html/guides/rel_notes/release_21_11.html
 
+* **Updated Marvell cn10k_crypto PMD.**
+
+  * Added AES-CBC-SHA1-HMAC in lookaside protocol (IPsec).
+
 
 New Features
 ------------
diff --git a/drivers/common/cnxk/cnxk_security.c b/drivers/common/cnxk/cnxk_security.c
index 6c6728f570..fe64e70c81 100644
--- a/drivers/common/cnxk/cnxk_security.c
+++ b/drivers/common/cnxk/cnxk_security.c
@@ -6,12 +6,43 @@ 
 
 #include "cnxk_security.h"
 
+static void
+ipsec_hmac_opad_ipad_gen(struct rte_crypto_sym_xform *auth_xform,
+			 uint8_t *hmac_opad_ipad)
+{
+	const uint8_t *key = auth_xform->auth.key.data;
+	uint32_t length = auth_xform->auth.key.length;
+	uint8_t opad[128] = {[0 ... 127] = 0x5c};
+	uint8_t ipad[128] = {[0 ... 127] = 0x36};
+	uint32_t i;
+
+	/* HMAC OPAD and IPAD */
+	for (i = 0; i < 127 && i < length; i++) {
+		opad[i] = opad[i] ^ key[i];
+		ipad[i] = ipad[i] ^ key[i];
+	}
+
+	/* Precompute hash of HMAC OPAD and IPAD to avoid
+	 * per packet computation
+	 */
+	switch (auth_xform->auth.algo) {
+	case RTE_CRYPTO_AUTH_SHA1_HMAC:
+		roc_hash_sha1_gen(opad, (uint32_t *)&hmac_opad_ipad[0]);
+		roc_hash_sha1_gen(ipad, (uint32_t *)&hmac_opad_ipad[24]);
+		break;
+	default:
+		break;
+	}
+}
+
 static int
 ot_ipsec_sa_common_param_fill(union roc_ot_ipsec_sa_word2 *w2,
 			      uint8_t *cipher_key, uint8_t *salt_key,
+			      uint8_t *hmac_opad_ipad,
 			      struct rte_security_ipsec_xform *ipsec_xfrm,
 			      struct rte_crypto_sym_xform *crypto_xfrm)
 {
+	struct rte_crypto_sym_xform *auth_xfrm, *cipher_xfrm;
 	const uint8_t *key;
 	uint32_t *tmp_salt;
 	uint64_t *tmp_key;
@@ -21,9 +52,13 @@  ot_ipsec_sa_common_param_fill(union roc_ot_ipsec_sa_word2 *w2,
 	switch (ipsec_xfrm->direction) {
 	case RTE_SECURITY_IPSEC_SA_DIR_INGRESS:
 		w2->s.dir = ROC_IE_OT_SA_DIR_INBOUND;
+		auth_xfrm = crypto_xfrm;
+		cipher_xfrm = crypto_xfrm->next;
 		break;
 	case RTE_SECURITY_IPSEC_SA_DIR_EGRESS:
 		w2->s.dir = ROC_IE_OT_SA_DIR_OUTBOUND;
+		cipher_xfrm = crypto_xfrm;
+		auth_xfrm = crypto_xfrm->next;
 		break;
 	default:
 		return -EINVAL;
@@ -70,7 +105,32 @@  ot_ipsec_sa_common_param_fill(union roc_ot_ipsec_sa_word2 *w2,
 			return -ENOTSUP;
 		}
 	} else {
-		return -ENOTSUP;
+		switch (cipher_xfrm->cipher.algo) {
+		case RTE_CRYPTO_CIPHER_AES_CBC:
+			w2->s.enc_type = ROC_IE_OT_SA_ENC_AES_CBC;
+			break;
+		default:
+			return -ENOTSUP;
+		}
+
+		switch (auth_xfrm->auth.algo) {
+		case RTE_CRYPTO_AUTH_SHA1_HMAC:
+			w2->s.auth_type = ROC_IE_OT_SA_AUTH_SHA1;
+			break;
+		default:
+			return -ENOTSUP;
+		}
+
+		key = cipher_xfrm->cipher.key.data;
+		length = cipher_xfrm->cipher.key.length;
+
+		ipsec_hmac_opad_ipad_gen(auth_xfrm, hmac_opad_ipad);
+
+		tmp_key = (uint64_t *)hmac_opad_ipad;
+		for (i = 0;
+		     i < (int)(ROC_CTX_MAX_OPAD_IPAD_LEN / sizeof(uint64_t));
+		     i++)
+			tmp_key[i] = rte_be_to_cpu_64(tmp_key[i]);
 	}
 
 	/* Set encapsulation type */
@@ -129,7 +189,8 @@  cnxk_ot_ipsec_inb_sa_fill(struct roc_ot_ipsec_inb_sa *sa,
 
 	w2.u64 = 0;
 	rc = ot_ipsec_sa_common_param_fill(&w2, sa->cipher_key, sa->w8.s.salt,
-					   ipsec_xfrm, crypto_xfrm);
+					   sa->hmac_opad_ipad, ipsec_xfrm,
+					   crypto_xfrm);
 	if (rc)
 		return rc;
 
@@ -196,7 +257,8 @@  cnxk_ot_ipsec_outb_sa_fill(struct roc_ot_ipsec_outb_sa *sa,
 
 	w2.u64 = 0;
 	rc = ot_ipsec_sa_common_param_fill(&w2, sa->cipher_key, sa->iv.s.salt,
-					   ipsec_xfrm, crypto_xfrm);
+					   sa->hmac_opad_ipad, ipsec_xfrm,
+					   crypto_xfrm);
 	if (rc)
 		return rc;
 
diff --git a/drivers/crypto/cnxk/cn10k_ipsec.c b/drivers/crypto/cnxk/cn10k_ipsec.c
index 1d567bf188..408a682b21 100644
--- a/drivers/crypto/cnxk/cn10k_ipsec.c
+++ b/drivers/crypto/cnxk/cn10k_ipsec.c
@@ -17,6 +17,37 @@ 
 
 #include "roc_api.h"
 
+static int
+ipsec_xform_cipher_verify(struct rte_crypto_sym_xform *xform)
+{
+	if (xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
+		switch (xform->cipher.key.length) {
+		case 16:
+		case 24:
+		case 32:
+			break;
+		default:
+			return -ENOTSUP;
+		}
+		return 0;
+	}
+
+	return -ENOTSUP;
+}
+
+static int
+ipsec_xform_auth_verify(struct rte_crypto_sym_xform *xform)
+{
+	uint16_t keylen = xform->auth.key.length;
+
+	if (xform->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC) {
+		if (keylen >= 20 && keylen <= 64)
+			return 0;
+	}
+
+	return -ENOTSUP;
+}
+
 static int
 ipsec_xform_aead_verify(struct rte_security_ipsec_xform *ipsec_xfrm,
 			struct rte_crypto_sym_xform *crypto_xfrm)
@@ -48,6 +79,9 @@  static int
 cn10k_ipsec_xform_verify(struct rte_security_ipsec_xform *ipsec_xfrm,
 			 struct rte_crypto_sym_xform *crypto_xfrm)
 {
+	struct rte_crypto_sym_xform *auth_xform, *cipher_xform;
+	int ret;
+
 	if ((ipsec_xfrm->direction != RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
 	    (ipsec_xfrm->direction != RTE_SECURITY_IPSEC_SA_DIR_EGRESS))
 		return -EINVAL;
@@ -67,7 +101,34 @@  cn10k_ipsec_xform_verify(struct rte_security_ipsec_xform *ipsec_xfrm,
 	if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD)
 		return ipsec_xform_aead_verify(ipsec_xfrm, crypto_xfrm);
 
-	return -ENOTSUP;
+	if (crypto_xfrm->next == NULL)
+		return -EINVAL;
+
+	if (ipsec_xfrm->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
+		/* Ingress */
+		if (crypto_xfrm->type != RTE_CRYPTO_SYM_XFORM_AUTH ||
+		    crypto_xfrm->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER)
+			return -EINVAL;
+		auth_xform = crypto_xfrm;
+		cipher_xform = crypto_xfrm->next;
+	} else {
+		/* Egress */
+		if (crypto_xfrm->type != RTE_CRYPTO_SYM_XFORM_CIPHER ||
+		    crypto_xfrm->next->type != RTE_CRYPTO_SYM_XFORM_AUTH)
+			return -EINVAL;
+		cipher_xform = crypto_xfrm;
+		auth_xform = crypto_xfrm->next;
+	}
+
+	ret = ipsec_xform_cipher_verify(cipher_xform);
+	if (ret)
+		return ret;
+
+	ret = ipsec_xform_auth_verify(auth_xform);
+	if (ret)
+		return ret;
+
+	return 0;
 }
 
 static uint64_t
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
index ab37f9c43b..47274b2c24 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
@@ -754,6 +754,49 @@  static const struct rte_cryptodev_capabilities sec_caps_aes[] = {
 			}, }
 		}, }
 	},
+	{	/* AES CBC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_AES_CBC,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 32,
+					.increment = 8
+				},
+				.iv_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+};
+
+static const struct rte_cryptodev_capabilities sec_caps_sha1_sha2[] = {
+	{	/* SHA1 HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+				.block_size = 64,
+				.key_size = {
+					.min = 20,
+					.max = 64,
+					.increment = 1
+				},
+				.digest_size = {
+					.min = 12,
+					.max = 12,
+					.increment = 0
+				},
+			}, }
+		}, }
+	},
 };
 
 static const struct rte_security_capability sec_caps_templ[] = {
@@ -839,6 +882,7 @@  sec_crypto_caps_populate(struct rte_cryptodev_capabilities cnxk_caps[],
 	int cur_pos = 0;
 
 	SEC_CAPS_ADD(cnxk_caps, &cur_pos, hw_caps, aes);
+	SEC_CAPS_ADD(cnxk_caps, &cur_pos, hw_caps, sha1_sha2);
 
 	sec_caps_add(cnxk_caps, &cur_pos, caps_end, RTE_DIM(caps_end));
 }