diff --git a/doc/guides/rel_notes/release_22_11.rst b/doc/guides/rel_notes/release_22_11.rst
index 8c021cf050..333f66bef3 100644
--- a/doc/guides/rel_notes/release_22_11.rst
+++ b/doc/guides/rel_notes/release_22_11.rst
@@ -55,6 +55,10 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Updated Marvell cnxk crypto driver.**
+
+  * Added AES-CCM support in lookaside protocol (IPsec) for CN9K & CN10K.
+
 
 Removed Items
 -------------
diff --git a/drivers/common/cnxk/cnxk_security.c b/drivers/common/cnxk/cnxk_security.c
index dca8742be3..8a0e4dea4c 100644
--- a/drivers/common/cnxk/cnxk_security.c
+++ b/drivers/common/cnxk/cnxk_security.c
@@ -58,6 +58,7 @@ ot_ipsec_sa_common_param_fill(union roc_ot_ipsec_sa_word2 *w2,
 {
 	struct rte_crypto_sym_xform *auth_xfrm, *cipher_xfrm;
 	const uint8_t *key = NULL;
+	uint8_t ccm_flag = 0;
 	uint32_t *tmp_salt;
 	uint64_t *tmp_key;
 	int i, length = 0;
@@ -113,6 +114,15 @@ ot_ipsec_sa_common_param_fill(union roc_ot_ipsec_sa_word2 *w2,
 			tmp_salt = (uint32_t *)salt_key;
 			*tmp_salt = rte_be_to_cpu_32(*tmp_salt);
 			break;
+		case RTE_CRYPTO_AEAD_AES_CCM:
+			w2->s.enc_type = ROC_IE_OT_SA_ENC_AES_CCM;
+			w2->s.auth_type = ROC_IE_OT_SA_AUTH_NULL;
+			ccm_flag = 0x07 & ~ROC_CPT_AES_CCM_CTR_LEN;
+			*salt_key = ccm_flag;
+			memcpy(PLT_PTR_ADD(salt_key, 1), &ipsec_xfrm->salt, 3);
+			tmp_salt = (uint32_t *)salt_key;
+			*tmp_salt = rte_be_to_cpu_32(*tmp_salt);
+			break;
 		default:
 			return -ENOTSUP;
 		}
@@ -204,6 +214,7 @@ ot_ipsec_sa_common_param_fill(union roc_ot_ipsec_sa_word2 *w2,
 	    w2->s.enc_type == ROC_IE_OT_SA_ENC_AES_CCM ||
 	    w2->s.enc_type == ROC_IE_OT_SA_ENC_AES_CTR ||
 	    w2->s.enc_type == ROC_IE_OT_SA_ENC_AES_GCM ||
+	    w2->s.enc_type == ROC_IE_OT_SA_ENC_AES_CCM ||
 	    w2->s.auth_type == ROC_IE_OT_SA_AUTH_AES_GMAC) {
 		switch (length) {
 		case ROC_CPT_AES128_KEY_LEN:
@@ -612,6 +623,7 @@ onf_ipsec_sa_common_param_fill(struct roc_ie_onf_sa_ctl *ctl, uint8_t *salt,
 	struct rte_crypto_sym_xform *auth_xfrm, *cipher_xfrm;
 	int rc, length, auth_key_len;
 	const uint8_t *key = NULL;
+	uint8_t ccm_flag = 0;
 
 	/* Set direction */
 	switch (ipsec_xfrm->direction) {
@@ -663,6 +675,14 @@ onf_ipsec_sa_common_param_fill(struct roc_ie_onf_sa_ctl *ctl, uint8_t *salt,
 			memcpy(salt, &ipsec_xfrm->salt, 4);
 			key = crypto_xfrm->aead.key.data;
 			break;
+		case RTE_CRYPTO_AEAD_AES_CCM:
+			ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CCM;
+			ctl->auth_type = ROC_IE_ON_SA_AUTH_NULL;
+			ccm_flag = 0x07 & ~ROC_CPT_AES_CCM_CTR_LEN;
+			*salt = ccm_flag;
+			memcpy(PLT_PTR_ADD(salt, 1), &ipsec_xfrm->salt, 3);
+			key = crypto_xfrm->aead.key.data;
+			break;
 		default:
 			return -ENOTSUP;
 		}
@@ -810,7 +830,7 @@ cnxk_ipsec_ivlen_get(enum rte_crypto_cipher_algorithm c_algo,
 {
 	uint8_t ivlen = 0;
 
-	if (aead_algo == RTE_CRYPTO_AEAD_AES_GCM)
+	if ((aead_algo == RTE_CRYPTO_AEAD_AES_GCM) || (aead_algo == RTE_CRYPTO_AEAD_AES_CCM))
 		ivlen = 8;
 
 	switch (c_algo) {
@@ -873,6 +893,7 @@ cnxk_ipsec_icvlen_get(enum rte_crypto_cipher_algorithm c_algo,
 
 	switch (aead_algo) {
 	case RTE_CRYPTO_AEAD_AES_GCM:
+	case RTE_CRYPTO_AEAD_AES_CCM:
 		icv = 16;
 		break;
 	default:
@@ -888,7 +909,7 @@ cnxk_ipsec_outb_roundup_byte(enum rte_crypto_cipher_algorithm c_algo,
 {
 	uint8_t roundup_byte = 4;
 
-	if (aead_algo == RTE_CRYPTO_AEAD_AES_GCM)
+	if ((aead_algo == RTE_CRYPTO_AEAD_AES_GCM) || (aead_algo == RTE_CRYPTO_AEAD_AES_CCM))
 		return roundup_byte;
 
 	switch (c_algo) {
@@ -1023,6 +1044,10 @@ on_ipsec_sa_ctl_set(struct rte_security_ipsec_xform *ipsec,
 			ctl->enc_type = ROC_IE_ON_SA_ENC_AES_GCM;
 			aes_key_len = crypto_xform->aead.key.length;
 			break;
+		case RTE_CRYPTO_AEAD_AES_CCM:
+			ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CCM;
+			aes_key_len = crypto_xform->aead.key.length;
+			break;
 		default:
 			plt_err("Unsupported AEAD algorithm");
 			return -ENOTSUP;
@@ -1087,6 +1112,7 @@ on_ipsec_sa_ctl_set(struct rte_security_ipsec_xform *ipsec,
 	    ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CCM ||
 	    ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CTR ||
 	    ctl->enc_type == ROC_IE_ON_SA_ENC_AES_GCM ||
+	    ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CCM ||
 	    ctl->auth_type == ROC_IE_ON_SA_AUTH_AES_GMAC) {
 		switch (aes_key_len) {
 		case 16:
@@ -1129,6 +1155,7 @@ on_fill_ipsec_common_sa(struct rte_security_ipsec_xform *ipsec,
 	struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
 	const uint8_t *cipher_key;
 	int cipher_key_len = 0;
+	uint8_t ccm_flag = 0;
 	int ret;
 
 	ret = on_ipsec_sa_ctl_set(ipsec, crypto_xform, &common_sa->ctl);
@@ -1146,6 +1173,11 @@ on_fill_ipsec_common_sa(struct rte_security_ipsec_xform *ipsec,
 	if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
 		if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM)
 			memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4);
+		else if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_CCM) {
+			ccm_flag = 0x07 & ~ROC_CPT_AES_CCM_CTR_LEN;
+			*common_sa->iv.gcm.nonce = ccm_flag;
+			memcpy(PLT_PTR_ADD(common_sa->iv.gcm.nonce, 1), &ipsec->salt, 3);
+		}
 		cipher_key = crypto_xform->aead.key.data;
 		cipher_key_len = crypto_xform->aead.key.length;
 	} else {
@@ -1194,7 +1226,7 @@ cnxk_on_ipsec_outb_sa_create(struct rte_security_ipsec_xform *ipsec,
 		return ret;
 
 	if (ctl->enc_type == ROC_IE_ON_SA_ENC_AES_GCM ||
-	    ctl->auth_type == ROC_IE_ON_SA_AUTH_NULL ||
+	    ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CCM || ctl->auth_type == ROC_IE_ON_SA_AUTH_NULL ||
 	    ctl->auth_type == ROC_IE_ON_SA_AUTH_AES_GMAC) {
 		template = &out_sa->aes_gcm.template;
 		ctx_len = offsetof(struct roc_ie_on_outb_sa, aes_gcm.template);
diff --git a/drivers/common/cnxk/roc_cpt.h b/drivers/common/cnxk/roc_cpt.h
index a3a65f1e94..0cebc05c74 100644
--- a/drivers/common/cnxk/roc_cpt.h
+++ b/drivers/common/cnxk/roc_cpt.h
@@ -43,12 +43,13 @@
 	 ROC_CN10K_CPT_INST_DW_M1 << (19 + 3 * 14))
 
 /* CPT helper macros */
-#define ROC_CPT_AH_HDR_LEN	 12
-#define ROC_CPT_AES_GCM_IV_LEN	 8
-#define ROC_CPT_AES_GCM_MAC_LEN	 16
-#define ROC_CPT_AES_CBC_IV_LEN	 16
-#define ROC_CPT_SHA1_HMAC_LEN	 12
-#define ROC_CPT_SHA2_HMAC_LEN	 16
+#define ROC_CPT_AH_HDR_LEN	12
+#define ROC_CPT_AES_GCM_IV_LEN	8
+#define ROC_CPT_AES_GCM_MAC_LEN 16
+#define ROC_CPT_AES_CCM_CTR_LEN 4
+#define ROC_CPT_AES_CBC_IV_LEN	16
+#define ROC_CPT_SHA1_HMAC_LEN	12
+#define ROC_CPT_SHA2_HMAC_LEN	16
 
 #define ROC_CPT_DES3_KEY_LEN	    24
 #define ROC_CPT_AES128_KEY_LEN	    16
diff --git a/drivers/crypto/cnxk/cn10k_ipsec_la_ops.h b/drivers/crypto/cnxk/cn10k_ipsec_la_ops.h
index 66cfe6ca98..e220863799 100644
--- a/drivers/crypto/cnxk/cn10k_ipsec_la_ops.h
+++ b/drivers/crypto/cnxk/cn10k_ipsec_la_ops.h
@@ -66,6 +66,7 @@ process_outb_sa(struct roc_cpt_lf *lf, struct rte_crypto_op *cop,
 #ifdef LA_IPSEC_DEBUG
 	if (sess->out_sa.w2.s.iv_src == ROC_IE_OT_SA_IV_SRC_FROM_SA) {
 		if (sess->out_sa.w2.s.enc_type == ROC_IE_OT_SA_ENC_AES_GCM ||
+		    sess->out_sa.w2.s.enc_type == ROC_IE_OT_SA_ENC_AES_CCM ||
 		    sess->out_sa.w2.s.auth_type == ROC_IE_OT_SA_AUTH_AES_GMAC)
 			ipsec_po_sa_aes_gcm_iv_set(sess, cop);
 		else
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev.h b/drivers/crypto/cnxk/cnxk_cryptodev.h
index 8870021725..a3dcfbfa6d 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev.h
@@ -11,7 +11,7 @@
 #include "roc_cpt.h"
 
 #define CNXK_CPT_MAX_CAPS	 35
-#define CNXK_SEC_CRYPTO_MAX_CAPS 13
+#define CNXK_SEC_CRYPTO_MAX_CAPS 14
 #define CNXK_SEC_MAX_CAPS	 9
 #define CNXK_AE_EC_ID_MAX	 8
 /**
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
index 705d67e91f..fdc646a6fc 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
@@ -775,6 +775,36 @@ static const struct rte_cryptodev_capabilities sec_caps_aes[] = {
 			}, }
 		}, }
 	},
+	{	/* AES CCM */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AEAD,
+			{.aead = {
+				.algo = RTE_CRYPTO_AEAD_AES_CCM,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 32,
+					.increment = 8
+				},
+				.digest_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				},
+				.aad_size = {
+					.min = 8,
+					.max = 12,
+					.increment = 4
+				},
+				.iv_size = {
+					.min = 12,
+					.max = 12,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
 	{	/* AES CTR */
 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
 		{.sym = {
@@ -1155,14 +1185,23 @@ cnxk_crypto_capabilities_get(struct cnxk_cpt_vf *vf)
 	return vf->crypto_caps;
 }
 
+static bool
+sec_caps_limit_check(int *cur_pos, int nb_caps)
+{
+	if (*cur_pos + nb_caps > CNXK_SEC_CRYPTO_MAX_CAPS) {
+		rte_panic("Could not add sec crypto caps");
+		return true;
+	}
+
+	return false;
+}
+
 static void
 sec_caps_add(struct rte_cryptodev_capabilities cnxk_caps[], int *cur_pos,
 	     const struct rte_cryptodev_capabilities *caps, int nb_caps)
 {
-	if (*cur_pos + nb_caps > CNXK_SEC_CRYPTO_MAX_CAPS) {
-		rte_panic("Could not add sec crypto caps");
+	if (sec_caps_limit_check(cur_pos, nb_caps))
 		return;
-	}
 
 	memcpy(&cnxk_caps[*cur_pos], caps, nb_caps * sizeof(caps[0]));
 	*cur_pos += nb_caps;
@@ -1175,10 +1214,8 @@ cn10k_sec_crypto_caps_update(struct rte_cryptodev_capabilities cnxk_caps[],
 	const struct rte_cryptodev_capabilities *cap;
 	unsigned int i;
 
-	if ((CNXK_SEC_CRYPTO_MAX_CAPS - *cur_pos) < 1) {
-		rte_panic("Could not add sec crypto caps");
+	if (sec_caps_limit_check(cur_pos, 1))
 		return;
-	}
 
 	/* NULL auth */
 	for (i = 0; i < RTE_DIM(caps_null); i++) {
diff --git a/drivers/crypto/cnxk/cnxk_ipsec.h b/drivers/crypto/cnxk/cnxk_ipsec.h
index 07ab2cf4ee..00873ca6ac 100644
--- a/drivers/crypto/cnxk/cnxk_ipsec.h
+++ b/drivers/crypto/cnxk/cnxk_ipsec.h
@@ -87,7 +87,8 @@ ipsec_xform_aead_verify(struct rte_security_ipsec_xform *ipsec_xform,
 	    crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT)
 		return -EINVAL;
 
-	if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
+	if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM ||
+	    crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_CCM) {
 		switch (crypto_xform->aead.key.length) {
 		case 16:
 		case 24:
