diff --git a/doc/guides/cryptodevs/dpaa2_sec.rst b/doc/guides/cryptodevs/dpaa2_sec.rst
index 83565d7175..275ccf28de 100644
--- a/doc/guides/cryptodevs/dpaa2_sec.rst
+++ b/doc/guides/cryptodevs/dpaa2_sec.rst
@@ -121,6 +121,7 @@ Hash algorithms:
 * ``RTE_CRYPTO_AUTH_SHA384_HMAC``
 * ``RTE_CRYPTO_AUTH_SHA512_HMAC``
 * ``RTE_CRYPTO_AUTH_MD5_HMAC``
+* ``RTE_CRYPTO_AUTH_AES_XCBC_MAC``
 
 AEAD algorithms:
 
diff --git a/doc/guides/cryptodevs/features/dpaa2_sec.ini b/doc/guides/cryptodevs/features/dpaa2_sec.ini
index 02c1bf4185..9828d1528e 100644
--- a/doc/guides/cryptodevs/features/dpaa2_sec.ini
+++ b/doc/guides/cryptodevs/features/dpaa2_sec.ini
@@ -46,6 +46,7 @@ SHA384 HMAC  = Y
 SHA512       = Y
 SHA512 HMAC  = Y
 SNOW3G UIA2  = Y
+AES XCBC MAC = Y
 ZUC EIA3     = Y
 
 ;
diff --git a/drivers/common/dpaax/caamflib/desc/algo.h b/drivers/common/dpaax/caamflib/desc/algo.h
index 41cac5abd0..cf43d9c14c 100644
--- a/drivers/common/dpaax/caamflib/desc/algo.h
+++ b/drivers/common/dpaax/caamflib/desc/algo.h
@@ -873,4 +873,67 @@ cnstr_shdsc_gcm_decap(uint32_t *descbuf, bool ps, bool swap,
 	return PROGRAM_FINALIZE(p);
 }
 
+/**
+ * cnstr_shdsc_aes_xcbc_mac - AES_XCBC_MAC
+ * @descbuf: pointer to descriptor-under-construction buffer
+ * @ps: if 36/40bit addressing is desired, this parameter must be true
+ * @swap: must be true when core endianness doesn't match SEC endianness
+ * @share: sharing type of shared descriptor
+ * @authdata: pointer to authentication transform definitions;
+ *		   message digest algorithm: OP_ALG_ALGSEL_AES.
+ * @do_icv: 0 if ICV checking is not desired, any other value if ICV checking
+ *          is needed for all the packets processed by this shared descriptor
+ * @trunc_len: Length of the truncated ICV to be written in the output buffer,
+ *             0 if no truncation is needed
+ *
+ * Note: There's no support for keys longer than the block size of the
+ * underlying hash function, according to the selected algorithm.
+ *
+ * Return: size of descriptor written in words or negative number on error
+ */
+static inline int
+cnstr_shdsc_aes_xcbc_mac(uint32_t *descbuf, bool ps, bool swap,
+		enum rta_share_type share,
+		struct alginfo *authdata, uint8_t do_icv,
+		uint8_t trunc_len)
+{
+	struct program prg;
+	struct program *p = &prg;
+	uint8_t opicv, dir;
+
+	opicv = do_icv ? ICV_CHECK_ENABLE : ICV_CHECK_DISABLE;
+	dir = do_icv ? DIR_DEC : DIR_ENC;
+
+	PROGRAM_CNTXT_INIT(p, descbuf, 0);
+	if (swap)
+		PROGRAM_SET_BSWAP(p);
+	if (ps)
+		PROGRAM_SET_36BIT_ADDR(p);
+	SHR_HDR(p, share, 1, SC);
+
+	KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
+		INLINE_KEY(authdata));
+
+	/* compute sequences */
+	if (opicv == ICV_CHECK_ENABLE)
+		MATHB(p, SEQINSZ, SUB, trunc_len, VSEQINSZ, 4, IMMED2);
+	else
+		MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
+
+	/* Do operation */
+	ALG_OPERATION(p, authdata->algtype, authdata->algmode,
+		OP_ALG_AS_INITFINAL, opicv, dir);
+
+	/* Do load (variable length) */
+	SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
+
+	if (opicv == ICV_CHECK_ENABLE) {
+		LOAD(p, trunc_len, ICV2SZ, 0, 4, IMMED);
+		SEQFIFOLOAD(p, ICV2, trunc_len, LAST2);
+	} else
+		SEQSTORE(p, CONTEXT2, 0, trunc_len, 0);
+
+	return PROGRAM_FINALIZE(p);
+}
+
 #endif /* __DESC_ALGO_H__ */
diff --git a/drivers/common/dpaax/caamflib/desc/ipsec.h b/drivers/common/dpaax/caamflib/desc/ipsec.h
index 83dd93f587..668d21649d 100644
--- a/drivers/common/dpaax/caamflib/desc/ipsec.h
+++ b/drivers/common/dpaax/caamflib/desc/ipsec.h
@@ -865,6 +865,7 @@ cnstr_shdsc_ipsec_decap(uint32_t *descbuf, bool ps, bool swap,
  * cnstr_shdsc_ipsec_encap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
  *     AES-XCBC-MAC-96 ESP encapsulation shared descriptor.
  * @descbuf: pointer to buffer used for descriptor construction
+ * @share: sharing type of shared descriptor
  * @pdb: pointer to the PDB to be used with this descriptor
  *       This structure will be copied inline to the descriptor under
  *       construction. No error checking will be made. Refer to the
@@ -893,6 +894,7 @@ cnstr_shdsc_ipsec_decap(uint32_t *descbuf, bool ps, bool swap,
  */
 static inline int
 cnstr_shdsc_ipsec_encap_des_aes_xcbc(uint32_t *descbuf,
+				     enum rta_share_type share,
 				     struct ipsec_encap_pdb *pdb,
 				     struct alginfo *cipherdata,
 				     struct alginfo *authdata)
@@ -914,7 +916,7 @@ cnstr_shdsc_ipsec_encap_des_aes_xcbc(uint32_t *descbuf,
 	REFERENCE(write_swapped_seqin_ptr);
 
 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
-	phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
+	phdr = SHR_HDR(p, share, hdr, 0);
 	__rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
 	COPY_DATA(p, pdb->ip_hdr, pdb->ip_hdr_len);
 	SET_LABEL(p, hdr);
@@ -1001,6 +1003,7 @@ cnstr_shdsc_ipsec_encap_des_aes_xcbc(uint32_t *descbuf,
  * cnstr_shdsc_ipsec_decap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
  *     AES-XCBC-MAC-96 ESP decapsulation shared descriptor.
  * @descbuf: pointer to buffer used for descriptor construction
+ * @share: sharing type of shared descriptor
  * @pdb: pointer to the PDB to be used with this descriptor
  *       This structure will be copied inline to the descriptor under
  *       construction. No error checking will be made. Refer to the
@@ -1030,6 +1033,7 @@ cnstr_shdsc_ipsec_encap_des_aes_xcbc(uint32_t *descbuf,
  */
 static inline int
 cnstr_shdsc_ipsec_decap_des_aes_xcbc(uint32_t *descbuf,
+				     enum rta_share_type share,
 				     struct ipsec_decap_pdb *pdb,
 				     struct alginfo *cipherdata,
 				     struct alginfo *authdata)
@@ -1057,7 +1061,7 @@ cnstr_shdsc_ipsec_decap_des_aes_xcbc(uint32_t *descbuf,
 	REFERENCE(write_swapped_seqout_ptr);
 
 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
-	phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
+	phdr = SHR_HDR(p, share, hdr, 0);
 	__rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
 	SET_LABEL(p, hdr);
 	pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
@@ -1557,7 +1561,7 @@ cnstr_shdsc_authenc(uint32_t *descbuf, bool ps, bool swap,
 	    cipherdata->keylen, INLINE_KEY(cipherdata));
 
 	/* Do operation */
-	ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC,
+	ALG_OPERATION(p, authdata->algtype, authdata->algmode,
 		      OP_ALG_AS_INITFINAL,
 		      dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
 		      dir);
@@ -1569,7 +1573,13 @@ cnstr_shdsc_authenc(uint32_t *descbuf, bool ps, bool swap,
 
 	SET_LABEL(p, keyjmp);
 
-	ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC_PRECOMP,
+	if (authdata->algmode == OP_ALG_AAI_HMAC)
+		ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC_PRECOMP,
+		      OP_ALG_AS_INITFINAL,
+		      dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
+		      dir);
+	else
+		ALG_OPERATION(p, authdata->algtype, authdata->algmode,
 		      OP_ALG_AS_INITFINAL,
 		      dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
 		      dir);
diff --git a/drivers/common/dpaax/caamflib/rta/operation_cmd.h b/drivers/common/dpaax/caamflib/rta/operation_cmd.h
index 9a1788c0f9..04732aa3d2 100644
--- a/drivers/common/dpaax/caamflib/rta/operation_cmd.h
+++ b/drivers/common/dpaax/caamflib/rta/operation_cmd.h
@@ -243,7 +243,11 @@ rta_operation(struct program *program, uint32_t cipher_algo,
 
 	for (i = 0; i < alg_table_sz[rta_sec_era]; i++) {
 		if (alg_table[i].chipher_algo == cipher_algo) {
-			opcode |= cipher_algo | alg_table[i].class;
+			if ((aai ==  OP_ALG_AAI_XCBC_MAC) ||
+					(aai == OP_ALG_AAI_CBC_XCBCMAC))
+				opcode |= cipher_algo | OP_TYPE_CLASS2_ALG;
+			else
+				opcode |= cipher_algo | alg_table[i].class;
 			/* nothing else to verify */
 			if (alg_table[i].aai_func == NULL) {
 				found = 1;
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index 6ff0d833e9..a7ff5dba92 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -2134,8 +2134,17 @@ dpaa2_sec_auth_init(struct rte_cryptodev *dev,
 					   !session->dir,
 					   session->digest_length);
 		break;
-	case RTE_CRYPTO_AUTH_AES_GMAC:
 	case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
+		authdata.algtype = OP_ALG_ALGSEL_AES;
+		authdata.algmode = OP_ALG_AAI_XCBC_MAC;
+		session->auth_alg = RTE_CRYPTO_AUTH_AES_XCBC_MAC;
+		bufsize = cnstr_shdsc_aes_xcbc_mac(
+					priv->flc_desc[DESC_INITFINAL].desc,
+					1, 0, SHR_NEVER, &authdata,
+					!session->dir,
+					session->digest_length);
+		break;
+	case RTE_CRYPTO_AUTH_AES_GMAC:
 	case RTE_CRYPTO_AUTH_AES_CMAC:
 	case RTE_CRYPTO_AUTH_AES_CBC_MAC:
 	case RTE_CRYPTO_AUTH_KASUMI_F9:
@@ -2406,6 +2415,10 @@ dpaa2_sec_aead_chain_init(struct rte_cryptodev *dev,
 		session->auth_alg = RTE_CRYPTO_AUTH_SHA512_HMAC;
 		break;
 	case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
+		authdata.algtype = OP_ALG_ALGSEL_AES;
+		authdata.algmode = OP_ALG_AAI_XCBC_MAC;
+		session->auth_alg = RTE_CRYPTO_AUTH_AES_XCBC_MAC;
+		break;
 	case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
 	case RTE_CRYPTO_AUTH_NULL:
 	case RTE_CRYPTO_AUTH_SHA1:
@@ -2750,6 +2763,10 @@ dpaa2_sec_ipsec_proto_init(struct rte_crypto_cipher_xform *cipher_xform,
 		authdata->algtype = OP_PCL_IPSEC_HMAC_SHA2_512_256;
 		authdata->algmode = OP_ALG_AAI_HMAC;
 		break;
+	case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
+		authdata->algtype = OP_PCL_IPSEC_AES_XCBC_MAC_96;
+		authdata->algmode = OP_ALG_AAI_XCBC_MAC;
+		break;
 	case RTE_CRYPTO_AUTH_AES_CMAC:
 		authdata->algtype = OP_PCL_IPSEC_AES_CMAC_96;
 		break;
@@ -2757,7 +2774,6 @@ dpaa2_sec_ipsec_proto_init(struct rte_crypto_cipher_xform *cipher_xform,
 		authdata->algtype = OP_PCL_IPSEC_HMAC_NULL;
 		break;
 	case RTE_CRYPTO_AUTH_SHA224_HMAC:
-	case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
 	case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
 	case RTE_CRYPTO_AUTH_SHA1:
 	case RTE_CRYPTO_AUTH_SHA256:
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h b/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h
index 26f3d79db4..35cf5b5dad 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h
@@ -504,6 +504,28 @@ static const struct rte_cryptodev_capabilities dpaa2_sec_capabilities[] = {
 			}, }
 		}, }
 	},
+	{	/* AES XCBC HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC,
+				.block_size = 16,
+				.key_size = {
+					.min = 1,
+					.max = 16,
+					.increment = 1
+				},
+				.digest_size = {
+					.min = 12,
+					.max = 16,
+					.increment = 4
+				},
+				.aad_size = { 0 },
+				.iv_size = { 0 }
+			}, }
+		}, }
+	},
 	{	/* NULL (CIPHER) */
 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
 		{.sym = {
