diff --git a/doc/guides/cryptodevs/mlx5.rst b/doc/guides/cryptodevs/mlx5.rst
index c316bfdc58..5b874824db 100644
--- a/doc/guides/cryptodevs/mlx5.rst
+++ b/doc/guides/cryptodevs/mlx5.rst
@@ -52,6 +52,9 @@ wrapping.
 The credential and the AES-XTS keys should be provided to the hardware, as ciphertext
 encrypted by the KEK.
 
+A keytag (64 bits) should be appended to the AES-XTS keys (before wrapping),
+and will be validated when the hardware attempts to access it.
+
 When crypto engines are defined to work in wrapped import method, they come out
 of the factory in Commissioning mode, and thus, cannot be used for crypto operations
 yet. A dedicated tool is used for changing the mode from Commissioning to
@@ -113,6 +116,10 @@ Driver options
   The identifier of the credential, default value is 0 represents the operational
   register credential.
 
+- ``keytag`` parameter [int]
+
+  The plaintext of the keytag appanded to the AES-XTS keys, default value is 0.
+
 
 Supported NICs
 --------------
diff --git a/drivers/crypto/mlx5/mlx5_crypto.c b/drivers/crypto/mlx5/mlx5_crypto.c
index a16578b3af..b24e68532c 100644
--- a/drivers/crypto/mlx5/mlx5_crypto.c
+++ b/drivers/crypto/mlx5/mlx5_crypto.c
@@ -498,56 +498,52 @@ mlx5_crypto_args_check_handler(const char *key, const char *val, void *opaque)
 		attr->session_import_kek_ptr = (uint32_t)tmp;
 	else if (strcmp(key, "credential_id") == 0)
 		attr->credential_pointer = (uint32_t)tmp;
+	else if (strcmp(key, "keytag") == 0)
+		devarg_prms->keytag = tmp;
 	else
 		DRV_LOG(WARNING, "Invalid key %s.", key);
 	return 0;
 }
 
-static struct mlx5_devx_obj *
-mlx5_crypto_config_login(struct rte_devargs *devargs,
-			 struct ibv_context *ctx)
+static int
+mlx5_crypto_parse_devargs(struct rte_devargs *devargs,
+			  struct mlx5_crypto_devarg_params *devarg_prms)
 {
-	/*
-	 * Set credential pointer and session import KEK pointer to a default
-	 * value of 0.
-	 */
-	struct mlx5_crypto_devarg_params login = {
-			.login_devarg = false,
-			.login_attr = {
-					.credential_pointer = 0,
-					.session_import_kek_ptr = 0,
-			}
-	};
+	struct mlx5_devx_crypto_login_attr *attr = &devarg_prms->login_attr;
 	struct rte_kvargs *kvlist;
 
+	/* Default values. */
+	attr->credential_pointer = 0;
+	attr->session_import_kek_ptr = 0;
+	devarg_prms->keytag = 0;
 	if (devargs == NULL) {
 		DRV_LOG(ERR,
 	"No login devargs in order to enable crypto operations in the device.");
 		rte_errno = EINVAL;
-		return NULL;
+		return -1;
 	}
 	kvlist = rte_kvargs_parse(devargs->args, NULL);
 	if (kvlist == NULL) {
 		DRV_LOG(ERR, "Failed to parse devargs.");
 		rte_errno = EINVAL;
-		return NULL;
+		return -1;
 	}
 	if (rte_kvargs_process(kvlist, NULL, mlx5_crypto_args_check_handler,
-			   &login) != 0) {
+			   devarg_prms) != 0) {
 		DRV_LOG(ERR, "Devargs handler function Failed.");
 		rte_kvargs_free(kvlist);
 		rte_errno = EINVAL;
-		return NULL;
+		return -1;
 	}
 	rte_kvargs_free(kvlist);
-	if (login.login_devarg == false) {
+	if (devarg_prms->login_devarg == false) {
 		DRV_LOG(ERR,
 	"No login credential devarg in order to enable crypto operations "
 	"in the device.");
 		rte_errno = EINVAL;
-		return NULL;
+		return -1;
 	}
-	return mlx5_devx_cmd_create_crypto_login_obj(ctx, &login.login_attr);
+	return 0;
 }
 
 /**
@@ -607,6 +603,7 @@ mlx5_crypto_pci_probe(struct rte_pci_driver *pci_drv,
 	struct ibv_context *ctx;
 	struct mlx5_devx_obj *login;
 	struct mlx5_crypto_priv *priv;
+	struct mlx5_crypto_devarg_params devarg_prms = { 0 };
 	struct mlx5_hca_attr attr = { 0 };
 	struct rte_cryptodev_pmd_init_params init_params = {
 		.name = "",
@@ -615,6 +612,8 @@ mlx5_crypto_pci_probe(struct rte_pci_driver *pci_drv,
 		.max_nb_queue_pairs =
 				RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
 	};
+	int ret;
+
 	RTE_SET_USED(pci_drv);
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
 		DRV_LOG(ERR, "Non-primary process type is not supported.");
@@ -644,7 +643,13 @@ mlx5_crypto_pci_probe(struct rte_pci_driver *pci_drv,
 		rte_errno = ENOTSUP;
 		return -ENOTSUP;
 	}
-	login = mlx5_crypto_config_login(pci_dev->device.devargs, ctx);
+	ret = mlx5_crypto_parse_devargs(pci_dev->device.devargs, &devarg_prms);
+	if (ret) {
+		DRV_LOG(ERR, "Failed to parse devargs.");
+		return -rte_errno;
+	}
+	login = mlx5_devx_cmd_create_crypto_login_obj(ctx,
+						      &devarg_prms.login_attr);
 	if (login == NULL) {
 		DRV_LOG(ERR, "Failed to configure login.");
 		return -rte_errno;
@@ -684,6 +689,7 @@ mlx5_crypto_pci_probe(struct rte_pci_driver *pci_drv,
 	}
 	priv->mr_scache.reg_mr_cb = mlx5_common_verbs_reg_mr;
 	priv->mr_scache.dereg_mr_cb = mlx5_common_verbs_dereg_mr;
+	priv->keytag = rte_cpu_to_be_64(devarg_prms.keytag);
 	/* Register callback function for global shared MR cache management. */
 	if (TAILQ_EMPTY(&mlx5_crypto_priv_list))
 		rte_mem_event_callback_register("MLX5_MEM_EVENT_CB",
diff --git a/drivers/crypto/mlx5/mlx5_crypto.h b/drivers/crypto/mlx5/mlx5_crypto.h
index 9df982b23e..a513e9ee36 100644
--- a/drivers/crypto/mlx5/mlx5_crypto.h
+++ b/drivers/crypto/mlx5/mlx5_crypto.h
@@ -30,6 +30,7 @@ struct mlx5_crypto_priv {
 	struct rte_cryptodev_config dev_config;
 	struct mlx5_mr_share_cache mr_scache; /* Global shared MR cache. */
 	struct mlx5_devx_obj *login_obj;
+	uint64_t keytag;
 };
 
 struct mlx5_crypto_qp {
@@ -49,10 +50,10 @@ struct mlx5_crypto_dek {
 	bool size_is_48; /* Whether the key\data size is 48 bytes or not. */
 } __rte_cache_aligned;
 
-
 struct mlx5_crypto_devarg_params {
 	bool login_devarg;
 	struct mlx5_devx_crypto_login_attr login_attr;
+	uint64_t keytag;
 };
 
 int
