diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index df227a177..081b5df8d 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -55,6 +55,11 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+     ** fips_validation enhancement.**
+
+     fips_vadation sample application is added SGL and NIST GCMVS complaint
+     GMAC test method support.
+
 
 Removed Items
 -------------
diff --git a/examples/fips_validation/fips_validation.h b/examples/fips_validation/fips_validation.h
index ecf3d54dd..b786e33d9 100644
--- a/examples/fips_validation/fips_validation.h
+++ b/examples/fips_validation/fips_validation.h
@@ -155,6 +155,11 @@ struct sha_interim_data {
 	enum rte_crypto_auth_algorithm algo;
 };
 
+struct gcm_interim_data {
+	uint8_t is_gmac;
+	uint8_t gen_iv;
+};
+
 struct fips_test_interim_info {
 	FILE *fp_rd;
 	FILE *fp_wr;
@@ -173,6 +178,7 @@ struct fips_test_interim_info {
 		struct tdes_interim_data tdes_data;
 		struct ccm_interim_data ccm_data;
 		struct sha_interim_data sha_data;
+		struct gcm_interim_data gcm_data;
 	} interim_info;
 
 	enum fips_test_op op;
@@ -258,4 +264,24 @@ parse_write_hex_str(struct fips_val *src);
 int
 update_info_vec(uint32_t count);
 
+typedef int (*fips_test_one_case_t)(void);
+typedef int (*fips_prepare_op_t)(void);
+typedef int (*fips_prepare_xform_t)(struct rte_crypto_sym_xform *);
+
+struct fips_test_ops {
+	fips_prepare_xform_t prepare_xform;
+	fips_prepare_op_t prepare_op;
+	fips_test_one_case_t test;
+};
+
+extern struct fips_test_ops test_ops;
+
+int prepare_aead_op(void);
+
+int prepare_auth_op(void);
+
+int prepare_gcm_xform(struct rte_crypto_sym_xform *xform);
+
+int prepare_gmac_xform(struct rte_crypto_sym_xform *xform);
+
 #endif
diff --git a/examples/fips_validation/fips_validation_gcm.c b/examples/fips_validation/fips_validation_gcm.c
index 47576e9a3..df3caa267 100644
--- a/examples/fips_validation/fips_validation_gcm.c
+++ b/examples/fips_validation/fips_validation_gcm.c
@@ -7,6 +7,7 @@
 #include <stdio.h>
 
 #include <rte_cryptodev.h>
+#include <rte_malloc.h>
 
 #include "fips_validation.h"
 
@@ -30,22 +31,93 @@
 
 #define OP_ENC_STR	"Encrypt"
 #define OP_DEC_STR	"Decrypt"
+/* External/Internal IV generation, specified in file name, following NIST
+ * GCMVS Section 6.1
+ */
+#define OP_ENC_EXT_STR	"ExtIV"
+#define OP_ENC_INT_STR	"IntIV"
 
 #define NEG_TEST_STR	"FAIL"
 
+/**
+ * GMAC is essentially zero length plaintext and uses AAD as input data.
+ * NIST does not have GMAC specific test vector but using zero length "PTlen"
+ * and uses AAD as input.
+ **/
+static int
+parser_read_gcm_pt_len(const char *key, char *src,
+		__rte_unused struct fips_val *val)
+{
+	int ret = parser_read_uint32_bit_val(key, src, &vec.pt);
+
+	if (ret < 0)
+		return ret;
+
+	if (vec.pt.len == 0) {
+		info.interim_info.gcm_data.is_gmac = 1;
+		test_ops.prepare_op = prepare_auth_op;
+		test_ops.prepare_xform = prepare_gmac_xform;
+	} else {
+		info.interim_info.gcm_data.is_gmac = 0;
+		test_ops.prepare_op = prepare_aead_op;
+		test_ops.prepare_xform = prepare_gcm_xform;
+	}
+
+	return ret;
+}
+
+static int
+parse_gcm_aad_str(const char *key, char *src,
+		__rte_unused struct fips_val *val)
+{
+	/* For GMAC test vector, AAD is treated as input */
+	if (info.interim_info.gcm_data.is_gmac) {
+		vec.pt.len = vec.aead.aad.len;
+		return parse_uint8_known_len_hex_str(key, src, &vec.pt);
+	} else /* gcm */
+		return parse_uint8_known_len_hex_str(key, src, &vec.aead.aad);
+}
+
+static int
+parse_gcm_pt_ct_str(const char *key, char *src, struct fips_val *val)
+{
+	/* According to NIST GCMVS section 6.1, IUT should generate IV data */
+	if (info.interim_info.gcm_data.gen_iv && vec.iv.len) {
+		uint32_t i;
+
+		if (!vec.iv.val) {
+			vec.iv.val = rte_malloc(0, vec.iv.len, 0);
+			if (!vec.iv.val)
+				return -ENOMEM;
+		}
+
+		for (i = 0; i < vec.iv.len; i++) {
+			int random = rand();
+			vec.iv.val[i] = (uint8_t)random;
+		}
+	}
+
+	/* if PTlen == 0, pt or ct will be handled by AAD later */
+	if (info.interim_info.gcm_data.is_gmac)
+		return 0;
+
+	return parse_uint8_known_len_hex_str(key, src, val);
+}
+
 struct fips_test_callback gcm_dec_vectors[] = {
 		{KEY_STR, parse_uint8_known_len_hex_str, &vec.aead.key},
 		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
-		{CT_STR, parse_uint8_known_len_hex_str, &vec.ct},
-		{AAD_STR, parse_uint8_known_len_hex_str, &vec.aead.aad},
+		{CT_STR, parse_gcm_pt_ct_str, &vec.ct},
+		{AAD_STR, parse_gcm_aad_str, &vec.aead.aad},
 		{TAG_STR, parse_uint8_known_len_hex_str,
 				&vec.aead.digest},
 		{NULL, NULL, NULL} /**< end pointer */
 };
+
 struct fips_test_callback gcm_interim_vectors[] = {
 		{KEYLEN_STR, parser_read_uint32_bit_val, &vec.aead.key},
 		{IVLEN_STR, parser_read_uint32_bit_val, &vec.iv},
-		{PTLEN_STR, parser_read_uint32_bit_val, &vec.pt},
+		{PTLEN_STR, parser_read_gcm_pt_len, &vec.pt},
 		{PTLEN_STR, parser_read_uint32_bit_val, &vec.ct},
 		/**< The NIST test vectors use 'PTlen' to denote input text
 		 *  length in case of decrypt & encrypt operations.
@@ -59,8 +131,8 @@ struct fips_test_callback gcm_interim_vectors[] = {
 struct fips_test_callback gcm_enc_vectors[] = {
 		{KEY_STR, parse_uint8_known_len_hex_str, &vec.aead.key},
 		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
-		{PT_STR, parse_uint8_known_len_hex_str, &vec.pt},
-		{AAD_STR, parse_uint8_known_len_hex_str, &vec.aead.aad},
+		{PT_STR, parse_gcm_pt_ct_str, &vec.pt},
+		{AAD_STR, parse_gcm_aad_str, &vec.aead.aad},
 		{NULL, NULL, NULL} /**< end pointer */
 };
 
@@ -70,12 +142,28 @@ parse_test_gcm_writeback(struct fips_val *val)
 	struct fips_val tmp_val;
 
 	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+		/* According to NIST GCMVS section 6.1, IUT should provide
+		 * generate IV data
+		 */
+		if (info.interim_info.gcm_data.gen_iv) {
+			fprintf(info.fp_wr, "%s", IV_STR);
+			tmp_val.val = vec.iv.val;
+			tmp_val.len = vec.iv.len;
+
+			parse_write_hex_str(&tmp_val);
+			rte_free(vec.iv.val);
+			vec.iv.val = NULL;
+		}
+
 		fprintf(info.fp_wr, "%s", CT_STR);
 
-		tmp_val.val = val->val;
-		tmp_val.len = vec.pt.len;
+		if (!info.interim_info.gcm_data.is_gmac) {
+			tmp_val.val = val->val;
+			tmp_val.len = vec.pt.len;
 
-		parse_write_hex_str(&tmp_val);
+			parse_write_hex_str(&tmp_val);
+		} else
+			fprintf(info.fp_wr, "\n");
 
 		fprintf(info.fp_wr, "%s", TAG_STR);
 
@@ -86,11 +174,14 @@ parse_test_gcm_writeback(struct fips_val *val)
 	} else {
 		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
 			fprintf(info.fp_wr, "%s", PT_STR);
+			if (!info.interim_info.gcm_data.is_gmac) {
+				fprintf(info.fp_wr, "%s", PT_STR);
+				tmp_val.val = val->val;
+				tmp_val.len = vec.pt.len;
 
-			tmp_val.val = val->val;
-			tmp_val.len = vec.pt.len;
-
-			parse_write_hex_str(&tmp_val);
+				parse_write_hex_str(&tmp_val);
+			} else
+				fprintf(info.fp_wr, "\n");
 		} else
 			fprintf(info.fp_wr, "%s\n", NEG_TEST_STR);
 	}
@@ -108,12 +199,13 @@ parse_test_gcm_init(void)
 	for (i = 0; i < info.nb_vec_lines; i++) {
 		char *line = info.vec[i];
 
-
 		tmp = strstr(line, OP_STR);
 		if (tmp) {
 			if (strstr(line, OP_ENC_STR)) {
 				info.op = FIPS_TEST_ENC_AUTH_GEN;
 				info.callbacks = gcm_enc_vectors;
+				if (strstr(info.file_name, OP_ENC_INT_STR))
+					info.interim_info.gcm_data.gen_iv = 1;
 			} else if (strstr(line, OP_DEC_STR)) {
 				info.op = FIPS_TEST_DEC_AUTH_VERIF;
 				info.callbacks = gcm_dec_vectors;
diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c
index fadca6e0c..8c32202dc 100644
--- a/examples/fips_validation/main.c
+++ b/examples/fips_validation/main.c
@@ -477,15 +477,7 @@ main(int argc, char *argv[])
 #define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
 #define CRYPTODEV_FIPS_MAX_RETRIES	16
 
-typedef int (*fips_test_one_case_t)(void);
-typedef int (*fips_prepare_op_t)(void);
-typedef int (*fips_prepare_xform_t)(struct rte_crypto_sym_xform *);
-
-struct fips_test_ops {
-	fips_prepare_xform_t prepare_xform;
-	fips_prepare_op_t prepare_op;
-	fips_test_one_case_t test;
-} test_ops;
+struct fips_test_ops test_ops;
 
 static int
 prepare_data_mbufs(struct fips_val *val)
@@ -609,7 +601,7 @@ prepare_cipher_op(void)
 	return 0;
 }
 
-static int
+int
 prepare_auth_op(void)
 {
 	struct rte_crypto_sym_op *sym = env.op->sym;
@@ -617,6 +609,14 @@ prepare_auth_op(void)
 
 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
 
+	if (vec.iv.len) {
+		uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *,
+				IV_OFF);
+		memset(iv, 0, vec.iv.len);
+		if (vec.iv.val)
+			memcpy(iv, vec.iv.val, vec.iv.len);
+	}
+
 	ret = prepare_data_mbufs(&vec.pt);
 	if (ret < 0)
 		return ret;
@@ -647,7 +647,7 @@ prepare_auth_op(void)
 	return 0;
 }
 
-static int
+int
 prepare_aead_op(void)
 {
 	struct rte_crypto_sym_op *sym = env.op->sym;
@@ -837,7 +837,7 @@ prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
 	return 0;
 }
 
-static int
+int
 prepare_gcm_xform(struct rte_crypto_sym_xform *xform)
 {
 	const struct rte_cryptodev_symmetric_capability *cap;
@@ -883,6 +883,47 @@ prepare_gcm_xform(struct rte_crypto_sym_xform *xform)
 	return 0;
 }
 
+int
+prepare_gmac_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	auth_xform->algo = RTE_CRYPTO_AUTH_AES_GMAC;
+	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_AUTH_OP_GENERATE :
+			RTE_CRYPTO_AUTH_OP_VERIFY;
+	auth_xform->iv.offset = IV_OFF;
+	auth_xform->iv.length = vec.iv.len;
+	auth_xform->digest_length = vec.aead.digest.len;
+	auth_xform->key.data = vec.aead.key.val;
+	auth_xform->key.length = vec.aead.key.len;
+
+	cap_idx.algo.auth = auth_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_auth(cap,
+			auth_xform->key.length,
+			auth_xform->digest_length, 0) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
+				info.device_name, auth_xform->key.length,
+				auth_xform->digest_length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
 static int
 prepare_cmac_xform(struct rte_crypto_sym_xform *xform)
 {
