[PATCH 2/2] crypto/cnxk: add SNOW5G and ZUC256 support

Nithinsen Kaithakadan nkaithakadan at marvell.com
Tue Mar 24 04:48:19 CET 2026


As part of this patch:
- Implemented driver support in cnxk for SNOW5G NEA4/NIA4
  and ZUC NEA6/NIA6 algorithms.
- Added capability structures for ZUC256/SNOW5G algorithms.

Signed-off-by: Nithinsen Kaithakadan <nkaithakadan at marvell.com>
---
 drivers/common/cnxk/hw/cpt.h                  |   4 +-
 drivers/common/cnxk/roc_se.c                  |  40 ++++++-
 drivers/common/cnxk/roc_se.h                  |  16 ++-
 drivers/crypto/cnxk/cnxk_cryptodev.h          |   2 +-
 .../crypto/cnxk/cnxk_cryptodev_capabilities.c | 103 +++++++++++++++++-
 drivers/crypto/cnxk/cnxk_cryptodev_ops.c      |   3 +
 drivers/crypto/cnxk/cnxk_se.h                 |  25 ++++-
 7 files changed, 177 insertions(+), 16 deletions(-)

diff --git a/drivers/common/cnxk/hw/cpt.h b/drivers/common/cnxk/hw/cpt.h
index 6e577b6277..eb795f61ac 100644
--- a/drivers/common/cnxk/hw/cpt.h
+++ b/drivers/common/cnxk/hw/cpt.h
@@ -81,7 +81,9 @@ union cpt_eng_caps {
 		uint64_t __io reserved_15_20 : 6;
 		uint64_t __io sm3 : 1;
 		uint64_t __io sm4 : 1;
-		uint64_t __io reserved_23_34 : 12;
+		uint64_t __io reserved_23_24 : 2;
+		uint64_t __io zuc256_snow5g : 1;
+		uint64_t __io reserved_26_34 : 9;
 		uint64_t __io sg_ver2 : 1;
 		uint64_t __io sm2 : 1;
 		uint64_t __io pdcp_chain_zuc256 : 1;
diff --git a/drivers/common/cnxk/roc_se.c b/drivers/common/cnxk/roc_se.c
index bdb42567c7..d841a926a4 100644
--- a/drivers/common/cnxk/roc_se.c
+++ b/drivers/common/cnxk/roc_se.c
@@ -91,6 +91,7 @@ cpt_ciph_type_set(roc_se_cipher_type type, struct roc_se_ctx *ctx, uint16_t key_
 		fc_type = ROC_SE_FC_GEN;
 		break;
 	case ROC_SE_ZUC_EEA3:
+	case ROC_SE_ZUC_NEA6:
 		if (unlikely(key_len != 16)) {
 			/*
 			 * ZUC 256 is not supported with older microcode
@@ -115,6 +116,11 @@ cpt_ciph_type_set(roc_se_cipher_type type, struct roc_se_ctx *ctx, uint16_t key_
 		else
 			fc_type = ROC_SE_PDCP;
 		break;
+	case ROC_SE_SNOW5G_NEA4:
+		if (unlikely(key_len != 32))
+			return -1;
+		fc_type = ROC_SE_PDCP;
+		break;
 	case ROC_SE_AES_CTR_EEA2:
 		if (chained_op)
 			fc_type = ROC_SE_PDCP_CHAIN;
@@ -287,7 +293,7 @@ roc_se_auth_key_set(struct roc_se_ctx *se_ctx, roc_se_auth_type type, const uint
 
 	chained_op = se_ctx->ciph_then_auth || se_ctx->auth_then_ciph;
 
-	if ((type >= ROC_SE_ZUC_EIA3) && (type <= ROC_SE_KASUMI_F9_ECB)) {
+	if ((type >= ROC_SE_ZUC_EIA3) && (type <= ROC_SE_ZUC_NIA6)) {
 		uint32_t keyx[4];
 		int key_type;
 
@@ -316,7 +322,20 @@ roc_se_auth_key_set(struct roc_se_ctx *se_ctx, roc_se_auth_type type, const uint
 			se_ctx->zsk_flags = 0x1;
 			opcode_major = ROC_SE_MAJOR_OP_PDCP_CHAIN;
 			break;
+		case ROC_SE_SNOW5G_NIA4:
+			pctx->w0.s.state_conf = ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
+			pctx->w0.s.auth_type = ROC_SE_PDCP_CHAIN_ALG_TYPE_SNOW5G;
+			pctx->w0.s.mac_len = mac_len;
+			pctx->w0.s.auth_key_len = 3;
+			memcpy(pctx->st.auth_key, key, key_len);
+
+			se_ctx->fc_type = ROC_SE_PDCP;
+			se_ctx->pdcp_auth_alg = ROC_SE_PDCP_ALG_TYPE_SNOW5G;
+			se_ctx->zsk_flags = 0x1;
+			opcode_major = ROC_SE_MAJOR_OP_PDCP_CHAIN;
+			break;
 		case ROC_SE_ZUC_EIA3:
+		case ROC_SE_ZUC_NIA6:
 			if (unlikely(key_len != 16)) {
 				/*
 				 * ZUC 256 is not supported with older microcode
@@ -336,13 +355,16 @@ roc_se_auth_key_set(struct roc_se_ctx *se_ctx, roc_se_auth_type type, const uint
 			pctx->w0.s.auth_type = ROC_SE_PDCP_CHAIN_ALG_TYPE_ZUC;
 			pctx->w0.s.mac_len = mac_len;
 			memcpy(pctx->st.auth_key, key, key_len);
-			if (key_len == 32)
+
+			if (!roc_model_is_cn20k() && key_len == 32)
 				roc_se_zuc_bytes_swap(pctx->st.auth_key, key_len);
+
 			cpt_zuc_const_update(pctx->st.auth_zuc_const, key_len, mac_len);
 			se_ctx->fc_type = ROC_SE_PDCP_CHAIN;
 
 			if (!chained_op)
 				se_ctx->fc_type = ROC_SE_PDCP;
+
 			se_ctx->pdcp_auth_alg = ROC_SE_PDCP_ALG_TYPE_ZUC;
 			se_ctx->zsk_flags = 0x1;
 			opcode_major = ROC_SE_MAJOR_OP_PDCP_CHAIN;
@@ -547,7 +569,16 @@ roc_se_ciph_key_set(struct roc_se_ctx *se_ctx, roc_se_cipher_type type, const ui
 		se_ctx->pdcp_ci_alg = ROC_SE_PDCP_ALG_TYPE_SNOW3G;
 		se_ctx->zsk_flags = 0;
 		goto success;
+	case ROC_SE_SNOW5G_NEA4:
+		pctx->w0.s.state_conf = ROC_SE_PDCP_CHAIN_CTX_KEY_IV;
+		pctx->w0.s.cipher_type = ROC_SE_PDCP_CHAIN_ALG_TYPE_SNOW5G;
+		pctx->w0.s.ci_key_len = 3;
+		memcpy(pctx->st.ci_key, key, key_len);
+		se_ctx->pdcp_ci_alg = ROC_SE_PDCP_ALG_TYPE_SNOW5G;
+		se_ctx->zsk_flags = 0;
+		goto success;
 	case ROC_SE_ZUC_EEA3:
+	case ROC_SE_ZUC_NEA6:
 		key_type = cpt_pdcp_chain_key_type_get(key_len);
 		if (key_type < 0)
 			return key_type;
@@ -556,11 +587,12 @@ roc_se_ciph_key_set(struct roc_se_ctx *se_ctx, roc_se_cipher_type type, const ui
 		pctx->w0.s.cipher_type = ROC_SE_PDCP_CHAIN_ALG_TYPE_ZUC;
 		memcpy(pctx->st.ci_key, key, key_len);
 		if (key_len == 32) {
-			roc_se_zuc_bytes_swap(pctx->st.ci_key, key_len);
 			if (roc_model_is_cn20k())
 				memcpy(pctx->st.ci_zuc_const, zuc_key256_v2, 16);
-			else
+			else {
 				memcpy(pctx->st.ci_zuc_const, zuc_key256, 16);
+				roc_se_zuc_bytes_swap(pctx->st.ci_key, key_len);
+			}
 		} else
 			memcpy(pctx->st.ci_zuc_const, zuc_key128, 32);
 		se_ctx->pdcp_ci_alg = ROC_SE_PDCP_ALG_TYPE_ZUC;
diff --git a/drivers/common/cnxk/roc_se.h b/drivers/common/cnxk/roc_se.h
index 03a6eabfd3..499e71ce85 100644
--- a/drivers/common/cnxk/roc_se.h
+++ b/drivers/common/cnxk/roc_se.h
@@ -101,6 +101,8 @@ typedef enum {
 	ROC_SE_AES_CMAC_EIA2 = 0x92,
 	ROC_SE_KASUMI_F9_CBC = 0x93,
 	ROC_SE_KASUMI_F9_ECB = 0x94,
+	ROC_SE_SNOW5G_NIA4 = 0x95,
+	ROC_SE_ZUC_NIA6 = 0x96,
 } roc_se_auth_type;
 
 typedef enum {
@@ -129,6 +131,8 @@ typedef enum {
 	ROC_SE_KASUMI_F8_ECB = 0x94,
 	ROC_SE_AES_DOCSISBPI = 0x95,
 	ROC_SE_DES_DOCSISBPI = 0x96,
+	ROC_SE_SNOW5G_NEA4 = 0x97,
+	ROC_SE_ZUC_NEA6 = 0x98,
 } roc_se_cipher_type;
 
 typedef enum {
@@ -257,10 +261,8 @@ struct roc_se_pdcp_ctx {
 	union {
 		uint64_t u64;
 		struct {
-			uint64_t cipher_type : 2;
-			uint64_t rsvd58_59 : 2;
-			uint64_t auth_type : 2;
-			uint64_t rsvd62_63 : 2;
+			uint64_t cipher_type : 4;
+			uint64_t auth_type : 4;
 			uint64_t mac_len : 4;
 			uint64_t ci_key_len : 2;
 			uint64_t auth_key_len : 2;
@@ -307,8 +309,10 @@ struct roc_se_iov_ptr {
 #define ROC_SE_PDCP_ALG_TYPE_SNOW3G	  1
 #define ROC_SE_PDCP_ALG_TYPE_AES_CTR	  2
 #define ROC_SE_PDCP_ALG_TYPE_AES_CMAC	  3
+#define ROC_SE_PDCP_ALG_TYPE_SNOW5G	  4
 #define ROC_SE_PDCP_CHAIN_ALG_TYPE_SNOW3G 1
 #define ROC_SE_PDCP_CHAIN_ALG_TYPE_ZUC	  3
+#define ROC_SE_PDCP_CHAIN_ALG_TYPE_SNOW5G 5
 
 #define ROC_SE_PDCP_CHAIN_CTX_LFSR   0
 #define ROC_SE_PDCP_CHAIN_CTX_KEY_IV 1
@@ -348,8 +352,8 @@ struct roc_se_ctx {
 	uint64_t hmac : 1;
 	uint64_t zsk_flags : 3;
 	uint64_t k_ecb : 1;
-	uint64_t pdcp_ci_alg : 2;
-	uint64_t pdcp_auth_alg : 2;
+	uint64_t pdcp_ci_alg : 3;
+	uint64_t pdcp_auth_alg : 3;
 	uint64_t ciph_then_auth : 1;
 	uint64_t auth_then_ciph : 1;
 	uint64_t eia2 : 1;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev.h b/drivers/crypto/cnxk/cnxk_cryptodev.h
index 088149badb..f88162ad3c 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev.h
@@ -11,7 +11,7 @@
 #include "roc_ae.h"
 #include "roc_cpt.h"
 
-#define CNXK_CPT_MAX_CAPS		 56
+#define CNXK_CPT_MAX_CAPS		 60
 #define CNXK_SEC_IPSEC_CRYPTO_MAX_CAPS	 16
 #define CNXK_SEC_TLS_1_3_CRYPTO_MAX_CAPS 3
 #define CNXK_SEC_TLS_1_2_CRYPTO_MAX_CAPS 7
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
index 5c1542909e..be6d383717 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
@@ -724,6 +724,99 @@ static const struct rte_cryptodev_capabilities caps_zuc_snow3g[] = {
 	},
 };
 
+static const struct rte_cryptodev_capabilities caps_zuc256_snow5g[] = {
+	{	/* SNOW 5G (NEA4) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_SNOW5G_NEA4,
+				.block_size = 16,
+				.key_size = {
+					.min = 32,
+					.max = 32,
+					.increment = 0
+				},
+				.iv_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* SNOW 5G (NIA4) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SNOW5G_NIA4,
+				.block_size = 16,
+				.key_size = {
+					.min = 32,
+					.max = 32,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 4,
+					.max = 16,
+					.increment = 0
+				},
+				.iv_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* ZUC 256 (NEA6) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_ZUC_NEA6,
+				.block_size = 16,
+				.key_size = {
+					.min = 32,
+					.max = 32,
+					.increment = 0
+				},
+				.iv_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* ZUC 256 (NIA6) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_ZUC_NIA6,
+				.block_size = 16,
+				.key_size = {
+					.min = 32,
+					.max = 32,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 4,
+					.max = 16,
+					.increment = 0
+				},
+				.iv_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+};
+
 static const struct rte_cryptodev_capabilities caps_aes[] = {
 	{	/* AES GMAC (AUTH) */
 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
@@ -1917,7 +2010,8 @@ cn10k_20k_crypto_caps_update(struct rte_cryptodev_capabilities cnxk_caps[])
 	while ((caps = &cnxk_caps[i++])->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) {
 		if ((caps->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC) &&
 		    (caps->sym.xform_type == RTE_CRYPTO_SYM_XFORM_CIPHER) &&
-		    (caps->sym.cipher.algo == RTE_CRYPTO_CIPHER_ZUC_EEA3)) {
+		    ((caps->sym.cipher.algo == RTE_CRYPTO_CIPHER_ZUC_EEA3) ||
+		     (caps->sym.cipher.algo == RTE_CRYPTO_CIPHER_ZUC_NEA6))) {
 
 			caps->sym.cipher.key_size.max = 32;
 			caps->sym.cipher.key_size.increment = 16;
@@ -1930,8 +2024,8 @@ cn10k_20k_crypto_caps_update(struct rte_cryptodev_capabilities cnxk_caps[])
 
 		if ((caps->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC) &&
 		    (caps->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AUTH) &&
-		    (caps->sym.auth.algo == RTE_CRYPTO_AUTH_ZUC_EIA3)) {
-
+		    ((caps->sym.auth.algo == RTE_CRYPTO_AUTH_ZUC_EIA3) ||
+		     (caps->sym.auth.algo == RTE_CRYPTO_AUTH_ZUC_NIA6))) {
 			caps->sym.auth.key_size.max = 32;
 			caps->sym.auth.key_size.increment = 16;
 			caps->sym.auth.digest_size.max = 16;
@@ -1985,6 +2079,9 @@ crypto_caps_populate(struct rte_cryptodev_capabilities cnxk_caps[],
 	if (roc_model_is_cn10k() || roc_model_is_cn20k())
 		cn10k_20k_crypto_caps_add(cnxk_caps, hw_caps, &cur_pos);
 
+	if (roc_model_is_cn20k())
+		CPT_CAPS_ADD(cnxk_caps, &cur_pos, hw_caps, zuc256_snow5g);
+
 	cpt_caps_add(cnxk_caps, &cur_pos, caps_null, RTE_DIM(caps_null));
 	cpt_caps_add(cnxk_caps, &cur_pos, caps_end, RTE_DIM(caps_end));
 
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
index b431b78005..2f9eb322dc 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
@@ -611,6 +611,7 @@ is_valid_pdcp_cipher_alg(struct rte_crypto_sym_xform *c_xfrm,
 {
 	switch (c_xfrm->cipher.algo) {
 	case RTE_CRYPTO_CIPHER_SNOW3G_UEA2:
+	case RTE_CRYPTO_CIPHER_SNOW5G_NEA4:
 	case RTE_CRYPTO_CIPHER_ZUC_EEA3:
 		break;
 	case RTE_CRYPTO_CIPHER_AES_CTR:
@@ -736,6 +737,7 @@ cnxk_sess_fill(struct roc_cpt *roc_cpt, struct rte_crypto_sym_xform *xform,
 				}
 				break;
 			case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
+			case RTE_CRYPTO_AUTH_SNOW5G_NIA4:
 			case RTE_CRYPTO_AUTH_ZUC_EIA3:
 			case RTE_CRYPTO_AUTH_AES_CMAC:
 				if (!is_valid_pdcp_cipher_alg(c_xfrm, sess))
@@ -771,6 +773,7 @@ cnxk_sess_fill(struct roc_cpt *roc_cpt, struct rte_crypto_sym_xform *xform,
 			}
 			break;
 		case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
+		case RTE_CRYPTO_AUTH_SNOW5G_NIA4:
 		case RTE_CRYPTO_AUTH_ZUC_EIA3:
 		case RTE_CRYPTO_AUTH_AES_CMAC:
 			if (!is_valid_pdcp_cipher_alg(c_xfrm, sess))
diff --git a/drivers/crypto/cnxk/cnxk_se.h b/drivers/crypto/cnxk/cnxk_se.h
index db25fd90d8..8dbf3e73c7 100644
--- a/drivers/crypto/cnxk/cnxk_se.h
+++ b/drivers/crypto/cnxk/cnxk_se.h
@@ -131,7 +131,8 @@ pdcp_iv_copy(uint8_t *iv_d, const uint8_t *iv_s, const uint8_t pdcp_alg_type, co
 			iv_temp[j] = iv_s_temp[3 - j];
 		memcpy(iv_d, iv_temp, 16);
 	} else if ((pdcp_alg_type == ROC_SE_PDCP_ALG_TYPE_ZUC) ||
-		   pdcp_alg_type == ROC_SE_PDCP_ALG_TYPE_AES_CTR) {
+		   (pdcp_alg_type == ROC_SE_PDCP_ALG_TYPE_AES_CTR) ||
+		   (pdcp_alg_type == ROC_SE_PDCP_ALG_TYPE_SNOW5G)) {
 		memcpy(iv_d, iv_s, 16);
 		if (pack_iv) {
 			uint8_t iv_d23, iv_d24;
@@ -2243,12 +2244,24 @@ fill_sess_cipher(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess)
 		zsk_flag = ROC_SE_ZS_EA;
 		zs_cipher = ROC_SE_ZS_EA;
 		break;
+	case RTE_CRYPTO_CIPHER_SNOW5G_NEA4:
+		enc_type = ROC_SE_SNOW5G_NEA4;
+		cipher_key_len = 32;
+		zsk_flag = ROC_SE_ZS_EA;
+		zs_cipher = ROC_SE_ZS_EA;
+		break;
 	case RTE_CRYPTO_CIPHER_ZUC_EEA3:
 		enc_type = ROC_SE_ZUC_EEA3;
 		cipher_key_len = c_form->key.length;
 		zsk_flag = ROC_SE_ZS_EA;
 		zs_cipher = ROC_SE_ZS_EA;
 		break;
+	case RTE_CRYPTO_CIPHER_ZUC_NEA6:
+		enc_type = ROC_SE_ZUC_NEA6;
+		cipher_key_len = 32;
+		zsk_flag = ROC_SE_ZS_EA;
+		zs_cipher = ROC_SE_ZS_EA;
+		break;
 	case RTE_CRYPTO_CIPHER_AES_XTS:
 		enc_type = ROC_SE_AES_XTS;
 		cipher_key_len = 16;
@@ -2437,11 +2450,21 @@ fill_sess_auth(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess)
 		zsk_flag = ROC_SE_ZS_IA;
 		zs_auth = ROC_SE_ZS_IA;
 		break;
+	case RTE_CRYPTO_AUTH_SNOW5G_NIA4:
+		auth_type = ROC_SE_SNOW5G_NIA4;
+		zsk_flag = ROC_SE_ZS_IA;
+		zs_auth = ROC_SE_ZS_IA;
+		break;
 	case RTE_CRYPTO_AUTH_ZUC_EIA3:
 		auth_type = ROC_SE_ZUC_EIA3;
 		zsk_flag = ROC_SE_ZS_IA;
 		zs_auth = ROC_SE_ZS_IA;
 		break;
+	case RTE_CRYPTO_AUTH_ZUC_NIA6:
+		auth_type = ROC_SE_ZUC_NIA6;
+		zsk_flag = ROC_SE_ZS_IA;
+		zs_auth = ROC_SE_ZS_IA;
+		break;
 	case RTE_CRYPTO_AUTH_NULL:
 		auth_type = 0;
 		is_null = 1;
-- 
2.34.1



More information about the dev mailing list