[dpdk-dev,v5] crypto/aesni_gcm: migration from MB library to ISA-L

Message ID 1484570243-218696-1-git-send-email-piotrx.t.azarewicz@intel.com
State Superseded, archived
Delegated to: Pablo de Lara Guarch
Headers show

Checks

Context Check Description
ci/Intel compilation fail apply patch file failure
ci/checkpatch success coding style OK

Commit Message

Piotr Azarewicz Jan. 16, 2017, 12:37 p.m.
Current Cryptodev AES-NI GCM PMD is implemented using Multi Buffer
Crypto library.This patch reimplement the device using ISA-L Crypto
library: https://github.com/01org/isa-l_crypto.

The migration entailed the following additional support for:
  * GMAC algorithm.
  * 256-bit cipher key.
  * Session-less mode.
  * Out-of place processing
  * Scatter-gatter support for chained mbufs (only out-of place and
    destination mbuf must be contiguous)

Verified current unit tests and added new unit tests to verify new
functionalities.

Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
---

To be applied on top of:
   [dpdk-dev] [PATCH v5 0/3] Chained Mbufs support in SW PMDs

v5 changes:
- rebase on top of dpdk-next-crypto
- remove the perftest output from commit message
- correction in aesni_gcm.rst
- fix typo

v4 changes:
- rebase on top of dpdk-next-crypto
- update the script test-build.sh

v3 changes:
- rebase on top of dpdk-next-crypto

v2 changes:
- implement native scatter-gatter support for chained mbufs (only out-of
place and destination mbuf must be contiguous)
- write unit test for session-less mode
- write unit test for out-of place processing
- add support for GMAC authentication algorithm

 app/test/test_cryptodev.c                        |  753 +++++++++++++++++++---
 app/test/test_cryptodev_gcm_test_vectors.h       |  491 +++++++++++++-
 devtools/test-build.sh                           |    4 +-
 doc/guides/cryptodevs/aesni_gcm.rst              |   24 +-
 doc/guides/rel_notes/release_17_02.rst           |   12 +
 drivers/crypto/aesni_gcm/Makefile                |    8 +-
 drivers/crypto/aesni_gcm/aesni_gcm_ops.h         |   95 +--
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c         |  324 +++++-----
 drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c     |   49 +-
 drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h |   15 +-
 mk/rte.app.mk                                    |    3 +-
 11 files changed, 1363 insertions(+), 415 deletions(-)

Comments

Thomas Monjalon Jan. 16, 2017, 2:42 p.m. | #1
2017-01-16 13:37, Piotr Azarewicz:
> v5 changes:
> - rebase on top of dpdk-next-crypto
> - remove the perftest output from commit message
> - correction in aesni_gcm.rst
> - fix typo

Why have you removed the perftest output?
Because it is not in favor of this patch?
Thomas Monjalon Jan. 16, 2017, 2:43 p.m. | #2
2017-01-16 13:37, Piotr Azarewicz:
>  app/test/test_cryptodev.c                        |  753 +++++++++++++++++++---
>  app/test/test_cryptodev_gcm_test_vectors.h       |  491 +++++++++++++-
>  devtools/test-build.sh                           |    4 +-
>  doc/guides/cryptodevs/aesni_gcm.rst              |   24 +-
>  doc/guides/rel_notes/release_17_02.rst           |   12 +
>  drivers/crypto/aesni_gcm/Makefile                |    8 +-
>  drivers/crypto/aesni_gcm/aesni_gcm_ops.h         |   95 +--
>  drivers/crypto/aesni_gcm/aesni_gcm_pmd.c         |  324 +++++-----
>  drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c     |   49 +-
>  drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h |   15 +-
>  mk/rte.app.mk                                    |    3 +-
>  11 files changed, 1363 insertions(+), 415 deletions(-)

That's the kind of patch where test and implementation could be split.
Mcnamara, John Jan. 16, 2017, 3:20 p.m. | #3
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> Sent: Monday, January 16, 2017 2:42 PM
> To: Azarewicz, PiotrX T <piotrx.t.azarewicz@intel.com>
> Cc: dev@dpdk.org; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>;
> Doherty, Declan <declan.doherty@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v5] crypto/aesni_gcm: migration from MB
> library to ISA-L
> 
> 2017-01-16 13:37, Piotr Azarewicz:
> > v5 changes:
> > - rebase on top of dpdk-next-crypto
> > - remove the perftest output from commit message
> > - correction in aesni_gcm.rst
> > - fix typo
> 
> Why have you removed the perftest output?
> Because it is not in favor of this patch?

Hi,

We removed the performance results because we are not allowed to publish them publically without legal approval. 

Also, and more importantly, the perftest results aren't reliable which is one of the reasons that we are developing the new dpdk-test-crypto-perf app (patch submitted).

Using the newer app we are seeing more of less the same performance, slightly higher for some packets sizes, slightly lower for some others.

John.
Declan Doherty Jan. 16, 2017, 4:05 p.m. | #4
On 16/01/17 12:37, Piotr Azarewicz wrote:
> Current Cryptodev AES-NI GCM PMD is implemented using Multi Buffer
> Crypto library.This patch reimplement the device using ISA-L Crypto
> library: https://github.com/01org/isa-l_crypto.
>
> The migration entailed the following additional support for:
>   * GMAC algorithm.
>   * 256-bit cipher key.
>   * Session-less mode.
>   * Out-of place processing
>   * Scatter-gatter support for chained mbufs (only out-of place and
>     destination mbuf must be contiguous)
>
> Verified current unit tests and added new unit tests to verify new
> functionalities.
>
> Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
> ---
>
...
>

Acked-by: Declan Doherty <declan.doherty@intel.com>
Piotr Azarewicz Jan. 17, 2017, 7:42 a.m. | #5
> 2017-01-16 13:37, Piotr Azarewicz:
> >  app/test/test_cryptodev.c                        |  753 +++++++++++++++++++---
> >  app/test/test_cryptodev_gcm_test_vectors.h       |  491 +++++++++++++-
> >  devtools/test-build.sh                           |    4 +-
> >  doc/guides/cryptodevs/aesni_gcm.rst              |   24 +-
> >  doc/guides/rel_notes/release_17_02.rst           |   12 +
> >  drivers/crypto/aesni_gcm/Makefile                |    8 +-
> >  drivers/crypto/aesni_gcm/aesni_gcm_ops.h         |   95 +--
> >  drivers/crypto/aesni_gcm/aesni_gcm_pmd.c         |  324 +++++-----
> >  drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c     |   49 +-
> >  drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h |   15 +-
> >  mk/rte.app.mk                                    |    3 +-
> >  11 files changed, 1363 insertions(+), 415 deletions(-)
> 
> That's the kind of patch where test and implementation could be split.

Okay I will.
Piotr Azarewicz Jan. 17, 2017, 11:19 a.m. | #6
Current Cryptodev AES-NI GCM PMD is implemented using Multi Buffer
Crypto library.This patch reimplement the device using ISA-L Crypto
library: https://github.com/01org/isa-l_crypto.

The migration entailed the following additional support for:
  * GMAC algorithm.
  * 256-bit cipher key.
  * Session-less mode.
  * Out-of place processing
  * Scatter-gatter support for chained mbufs (only out-of place and
    destination mbuf must be contiguous)

Verified current unit tests and added new unit tests to verify new
functionalities.

Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Acked-by: Declan Doherty <declan.doherty@intel.com>

v6 changes:
- rebase on top of dpdk-next-crypto
- split driver implementation and tests

v5 changes:
- rebase on top of dpdk-next-crypto
- remove the perftest output from commit message
- correction in aesni_gcm.rst
- fix typo

v4 changes:
- rebase on top of dpdk-next-crypto
- update the script test-build.sh

v3 changes:
- rebase on top of dpdk-next-crypto

v2 changes:
- implement native scatter-gatter support for chained mbufs (only out-of
place and destination mbuf must be contiguous)
- write unit test for session-less mode
- write unit test for out-of place processing
- add support for GMAC authentication algorithm

Piotr Azarewicz (2):
  crypto/aesni_gcm: migration from MB library to ISA-L
  app/test: add GCM additional tests

 app/test/test_cryptodev.c                        |  753 +++++++++++++++++++---
 app/test/test_cryptodev_gcm_test_vectors.h       |  491 +++++++++++++-
 devtools/test-build.sh                           |    4 +-
 doc/guides/cryptodevs/aesni_gcm.rst              |   24 +-
 doc/guides/rel_notes/release_17_02.rst           |   12 +
 drivers/crypto/aesni_gcm/Makefile                |    8 +-
 drivers/crypto/aesni_gcm/aesni_gcm_ops.h         |   95 +--
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c         |  320 +++++----
 drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c     |   49 +-
 drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h |   15 +-
 mk/rte.app.mk                                    |    3 +-
 11 files changed, 1361 insertions(+), 413 deletions(-)
Pablo de Lara Jan. 18, 2017, 12:37 p.m. | #7
> -----Original Message-----
> From: Azarewicz, PiotrX T
> Sent: Tuesday, January 17, 2017 11:19 AM
> To: De Lara Guarch, Pablo; dev@dpdk.org
> Subject: [PATCH v6 0/2] crypto/aesni_gcm: migration from MB library to
> ISA-L
> 
> Current Cryptodev AES-NI GCM PMD is implemented using Multi Buffer
> Crypto library.This patch reimplement the device using ISA-L Crypto
> library: https://github.com/01org/isa-l_crypto.
> 
> The migration entailed the following additional support for:
>   * GMAC algorithm.
>   * 256-bit cipher key.
>   * Session-less mode.
>   * Out-of place processing
>   * Scatter-gatter support for chained mbufs (only out-of place and
>     destination mbuf must be contiguous)
> 
> Verified current unit tests and added new unit tests to verify new
> functionalities.
> 
> Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
> Acked-by: Declan Doherty <declan.doherty@intel.com>

Applied to dpdk-next-crypto.
Thanks,

Pablo

Patch

diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
index 5786fde..e8d1eae 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -4317,16 +4317,48 @@  static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 }
 
 static int
+create_gcm_xforms(struct rte_crypto_op *op,
+		enum rte_crypto_cipher_operation cipher_op,
+		uint8_t *key, const uint8_t key_len,
+		const uint8_t aad_len, const uint8_t auth_len,
+		enum rte_crypto_auth_operation auth_op)
+{
+	TEST_ASSERT_NOT_NULL(rte_crypto_op_sym_xforms_alloc(op, 2),
+			"failed to allocate space for crypto transforms");
+
+	struct rte_crypto_sym_op *sym_op = op->sym;
+
+	/* Setup Cipher Parameters */
+	sym_op->xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+	sym_op->xform->cipher.algo = RTE_CRYPTO_CIPHER_AES_GCM;
+	sym_op->xform->cipher.op = cipher_op;
+	sym_op->xform->cipher.key.data = key;
+	sym_op->xform->cipher.key.length = key_len;
+
+	TEST_HEXDUMP(stdout, "key:", key, key_len);
+
+	/* Setup Authentication Parameters */
+	sym_op->xform->next->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+	sym_op->xform->next->auth.algo = RTE_CRYPTO_AUTH_AES_GCM;
+	sym_op->xform->next->auth.op = auth_op;
+	sym_op->xform->next->auth.digest_length = auth_len;
+	sym_op->xform->next->auth.add_auth_data_length = aad_len;
+	sym_op->xform->next->auth.key.length = 0;
+	sym_op->xform->next->auth.key.data = NULL;
+	sym_op->xform->next->next = NULL;
+
+	return 0;
+}
+
+static int
 create_gcm_operation(enum rte_crypto_cipher_operation op,
-		const uint8_t *auth_tag, const unsigned auth_tag_len,
-		const uint8_t *iv, const unsigned iv_len,
-		const uint8_t *aad, const unsigned aad_len,
-		const unsigned data_len, unsigned data_pad_len)
+		const struct gcm_test_data *tdata)
 {
 	struct crypto_testsuite_params *ts_params = &testsuite_params;
 	struct crypto_unittest_params *ut_params = &unittest_params;
 
-	unsigned iv_pad_len = 0, aad_buffer_len;
+	uint8_t *plaintext, *ciphertext;
+	unsigned int iv_pad_len, aad_pad_len, plaintext_pad_len;
 
 	/* Generate Crypto op data structure */
 	ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool,
@@ -4336,77 +4368,118 @@  static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 
 	struct rte_crypto_sym_op *sym_op = ut_params->op->sym;
 
-	if (ut_params->obuf) {
-		sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
-				ut_params->obuf, auth_tag_len);
-		TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
-				"no room to append digest");
-		sym_op->auth.digest.phys_addr = pktmbuf_mtophys_offset(
-				ut_params->obuf, data_pad_len);
-	} else {
-		sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
-				ut_params->ibuf, auth_tag_len);
-		TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
-				"no room to append digest");
-		sym_op->auth.digest.phys_addr = pktmbuf_mtophys_offset(
-				ut_params->ibuf, data_pad_len);
-	}
-	sym_op->auth.digest.length = auth_tag_len;
-
-	if (op == RTE_CRYPTO_CIPHER_OP_DECRYPT) {
-		rte_memcpy(sym_op->auth.digest.data, auth_tag, auth_tag_len);
-		TEST_HEXDUMP(stdout, "digest:",
-				sym_op->auth.digest.data,
-				sym_op->auth.digest.length);
-	}
+	/* Append aad data */
+	aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16);
+	sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+			aad_pad_len);
+	TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data,
+			"no room to append aad");
 
-	/* iv */
-	iv_pad_len = RTE_ALIGN_CEIL(iv_len, 16);
+	sym_op->auth.aad.length = tdata->aad.len;
+	sym_op->auth.aad.phys_addr =
+			rte_pktmbuf_mtophys(ut_params->ibuf);
+	memcpy(sym_op->auth.aad.data, tdata->aad.data, tdata->aad.len);
+	TEST_HEXDUMP(stdout, "aad:", sym_op->auth.aad.data,
+		sym_op->auth.aad.length);
 
+	/* Prepend iv */
+	iv_pad_len = RTE_ALIGN_CEIL(tdata->iv.len, 16);
 	sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(
 			ut_params->ibuf, iv_pad_len);
 	TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv");
 
 	memset(sym_op->cipher.iv.data, 0, iv_pad_len);
 	sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf);
-	sym_op->cipher.iv.length = iv_len;
+	sym_op->cipher.iv.length = tdata->iv.len;
 
-	rte_memcpy(sym_op->cipher.iv.data, iv, iv_len);
+	rte_memcpy(sym_op->cipher.iv.data, tdata->iv.data, tdata->iv.len);
+	TEST_HEXDUMP(stdout, "iv:", sym_op->cipher.iv.data,
+		sym_op->cipher.iv.length);
 
-	/*
-	 * Always allocate the aad up to the block size.
-	 * The cryptodev API calls out -
-	 *  - the array must be big enough to hold the AAD, plus any
-	 *   space to round this up to the nearest multiple of the
-	 *   block size (16 bytes).
-	 */
-	aad_buffer_len = ALIGN_POW2_ROUNDUP(aad_len, 16);
+	/* Append plaintext/ciphertext */
+	if (op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
+		plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16);
+		plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+				plaintext_pad_len);
+		TEST_ASSERT_NOT_NULL(plaintext, "no room to append plaintext");
 
-	sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_prepend(
-			ut_params->ibuf, aad_buffer_len);
-	TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data,
-			"no room to prepend aad");
-	sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys(
-			ut_params->ibuf);
-	sym_op->auth.aad.length = aad_len;
+		memcpy(plaintext, tdata->plaintext.data, tdata->plaintext.len);
+		TEST_HEXDUMP(stdout, "plaintext:", plaintext,
+				tdata->plaintext.len);
 
-	memset(sym_op->auth.aad.data, 0, aad_buffer_len);
-	rte_memcpy(sym_op->auth.aad.data, aad, aad_len);
+		if (ut_params->obuf) {
+			ciphertext = (uint8_t *)rte_pktmbuf_append(
+					ut_params->obuf,
+					plaintext_pad_len + aad_pad_len +
+					iv_pad_len);
+			TEST_ASSERT_NOT_NULL(ciphertext,
+					"no room to append ciphertext");
 
-	TEST_HEXDUMP(stdout, "iv:", sym_op->cipher.iv.data, iv_pad_len);
-	TEST_HEXDUMP(stdout, "aad:",
-			sym_op->auth.aad.data, aad_len);
+			memset(ciphertext + aad_pad_len + iv_pad_len, 0,
+					tdata->ciphertext.len);
+		}
+	} else {
+		plaintext_pad_len = RTE_ALIGN_CEIL(tdata->ciphertext.len, 16);
+		ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+				plaintext_pad_len);
+		TEST_ASSERT_NOT_NULL(ciphertext,
+				"no room to append ciphertext");
 
-	if (ut_params->obuf) {
-		rte_pktmbuf_prepend(ut_params->obuf, iv_pad_len);
-		rte_pktmbuf_prepend(ut_params->obuf, aad_buffer_len);
+		memcpy(ciphertext, tdata->ciphertext.data,
+				tdata->ciphertext.len);
+		TEST_HEXDUMP(stdout, "ciphertext:", ciphertext,
+				tdata->ciphertext.len);
+
+		if (ut_params->obuf) {
+			plaintext = (uint8_t *)rte_pktmbuf_append(
+					ut_params->obuf,
+					plaintext_pad_len + aad_pad_len +
+					iv_pad_len);
+			TEST_ASSERT_NOT_NULL(plaintext,
+					"no room to append plaintext");
+
+			memset(plaintext + aad_pad_len + iv_pad_len, 0,
+					tdata->plaintext.len);
+		}
 	}
 
-	sym_op->cipher.data.length = data_len;
-	sym_op->cipher.data.offset = aad_buffer_len + iv_pad_len;
+	/* Append digest data */
+	if (op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
+		sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
+				ut_params->obuf ? ut_params->obuf :
+						ut_params->ibuf,
+						tdata->auth_tag.len);
+		TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
+				"no room to append digest");
+		memset(sym_op->auth.digest.data, 0, tdata->auth_tag.len);
+		sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(
+				ut_params->obuf ? ut_params->obuf :
+						ut_params->ibuf,
+						plaintext_pad_len +
+						aad_pad_len + iv_pad_len);
+		sym_op->auth.digest.length = tdata->auth_tag.len;
+	} else {
+		sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
+				ut_params->ibuf, tdata->auth_tag.len);
+		TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
+				"no room to append digest");
+		sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(
+				ut_params->ibuf,
+				plaintext_pad_len + aad_pad_len + iv_pad_len);
+		sym_op->auth.digest.length = tdata->auth_tag.len;
 
-	sym_op->auth.data.offset = aad_buffer_len + iv_pad_len;
-	sym_op->auth.data.length = data_len;
+		rte_memcpy(sym_op->auth.digest.data, tdata->auth_tag.data,
+			tdata->auth_tag.len);
+		TEST_HEXDUMP(stdout, "digest:",
+			sym_op->auth.digest.data,
+			sym_op->auth.digest.length);
+	}
+
+	sym_op->cipher.data.length = tdata->plaintext.len;
+	sym_op->cipher.data.offset = aad_pad_len + iv_pad_len;
+
+	sym_op->auth.data.length = tdata->plaintext.len;
+	sym_op->auth.data.offset = aad_pad_len + iv_pad_len;
 
 	return 0;
 }
@@ -4418,9 +4491,9 @@  static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 	struct crypto_unittest_params *ut_params = &unittest_params;
 
 	int retval;
-
-	uint8_t *plaintext, *ciphertext, *auth_tag;
+	uint8_t *ciphertext, *auth_tag;
 	uint16_t plaintext_pad_len;
+	uint32_t i;
 
 	/* Create GCM session */
 	retval = create_gcm_session(ts_params->valid_devs[0],
@@ -4431,31 +4504,20 @@  static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 	if (retval < 0)
 		return retval;
 
-
-	ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+	if (tdata->aad.len > MBUF_SIZE) {
+		ut_params->ibuf = rte_pktmbuf_alloc(ts_params->large_mbuf_pool);
+		/* Populate full size of add data */
+		for (i = 32; i < GCM_MAX_AAD_LENGTH; i += 32)
+			memcpy(&tdata->aad.data[i], &tdata->aad.data[0], 32);
+	} else
+		ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
 
 	/* clear mbuf payload */
 	memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
 			rte_pktmbuf_tailroom(ut_params->ibuf));
 
-	/*
-	 * Append data which is padded to a multiple
-	 * of the algorithms block size
-	 */
-	plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16);
-
-	plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
-			plaintext_pad_len);
-	memcpy(plaintext, tdata->plaintext.data, tdata->plaintext.len);
-
-	TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->plaintext.len);
-
-	/* Create GCM opertaion */
-	retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT,
-			tdata->auth_tag.data, tdata->auth_tag.len,
-			tdata->iv.data, tdata->iv.len,
-			tdata->aad.data, tdata->aad.len,
-			tdata->plaintext.len, plaintext_pad_len);
+	/* Create GCM operation */
+	retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata);
 	if (retval < 0)
 		return retval;
 
@@ -4470,14 +4532,18 @@  static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 	TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
 			"crypto op processing failed");
 
+	plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16);
+
 	if (ut_params->op->sym->m_dst) {
 		ciphertext = rte_pktmbuf_mtod(ut_params->op->sym->m_dst,
 				uint8_t *);
 		auth_tag = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_dst,
 				uint8_t *, plaintext_pad_len);
 	} else {
-		ciphertext = plaintext;
-		auth_tag = plaintext + plaintext_pad_len;
+		ciphertext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_src,
+				uint8_t *,
+				ut_params->op->sym->cipher.data.offset);
+		auth_tag = ciphertext + plaintext_pad_len;
 	}
 
 	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len);
@@ -4543,15 +4609,68 @@  static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 }
 
 static int
+test_mb_AES_GCM_auth_encryption_test_case_256_1(void)
+{
+	return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_1);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_256_2(void)
+{
+	return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_2);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_256_3(void)
+{
+	return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_3);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_256_4(void)
+{
+	return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_4);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_256_5(void)
+{
+	return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_5);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_256_6(void)
+{
+	return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_6);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_256_7(void)
+{
+	return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_256_7);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_aad_1(void)
+{
+	return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_aad_1);
+}
+
+static int
+test_mb_AES_GCM_auth_encryption_test_case_aad_2(void)
+{
+	return test_mb_AES_GCM_authenticated_encryption(&gcm_test_case_aad_2);
+}
+
+static int
 test_mb_AES_GCM_authenticated_decryption(const struct gcm_test_data *tdata)
 {
 	struct crypto_testsuite_params *ts_params = &testsuite_params;
 	struct crypto_unittest_params *ut_params = &unittest_params;
 
 	int retval;
-
-	uint8_t *plaintext, *ciphertext;
-	uint16_t ciphertext_pad_len;
+	uint8_t *plaintext;
+	uint32_t i;
 
 	/* Create GCM session */
 	retval = create_gcm_session(ts_params->valid_devs[0],
@@ -4562,31 +4681,23 @@  static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 	if (retval < 0)
 		return retval;
 
-
 	/* alloc mbuf and set payload */
-	ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+	if (tdata->aad.len > MBUF_SIZE) {
+		ut_params->ibuf = rte_pktmbuf_alloc(ts_params->large_mbuf_pool);
+		/* Populate full size of add data */
+		for (i = 32; i < GCM_MAX_AAD_LENGTH; i += 32)
+			memcpy(&tdata->aad.data[i], &tdata->aad.data[0], 32);
+	} else
+		ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
 
 	memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
 			rte_pktmbuf_tailroom(ut_params->ibuf));
 
-	ciphertext_pad_len = RTE_ALIGN_CEIL(tdata->ciphertext.len, 16);
-
-	ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
-			ciphertext_pad_len);
-	memcpy(ciphertext, tdata->ciphertext.data, tdata->ciphertext.len);
-
-	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len);
-
-	/* Create GCM opertaion */
-	retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT,
-			tdata->auth_tag.data, tdata->auth_tag.len,
-			tdata->iv.data, tdata->iv.len,
-			tdata->aad.data, tdata->aad.len,
-			tdata->ciphertext.len, ciphertext_pad_len);
+	/* Create GCM operation */
+	retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata);
 	if (retval < 0)
 		return retval;
 
-
 	rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess);
 
 	ut_params->op->sym->m_src = ut_params->ibuf;
@@ -4602,7 +4713,9 @@  static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 		plaintext = rte_pktmbuf_mtod(ut_params->op->sym->m_dst,
 				uint8_t *);
 	else
-		plaintext = ciphertext;
+		plaintext = rte_pktmbuf_mtod_offset(ut_params->op->sym->m_src,
+				uint8_t *,
+				ut_params->op->sym->cipher.data.offset);
 
 	TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->ciphertext.len);
 
@@ -4662,6 +4775,358 @@  static int test_snow3g_decryption_oop(const struct snow3g_test_data *tdata)
 }
 
 static int
+test_mb_AES_GCM_auth_decryption_test_case_256_1(void)
+{
+	return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_1);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_256_2(void)
+{
+	return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_2);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_256_3(void)
+{
+	return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_3);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_256_4(void)
+{
+	return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_4);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_256_5(void)
+{
+	return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_5);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_256_6(void)
+{
+	return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_6);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_256_7(void)
+{
+	return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_256_7);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_aad_1(void)
+{
+	return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_aad_1);
+}
+
+static int
+test_mb_AES_GCM_auth_decryption_test_case_aad_2(void)
+{
+	return test_mb_AES_GCM_authenticated_decryption(&gcm_test_case_aad_2);
+}
+
+static int
+test_AES_GCM_authenticated_encryption_oop(const struct gcm_test_data *tdata)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_unittest_params *ut_params = &unittest_params;
+
+	int retval;
+	uint8_t *ciphertext, *auth_tag;
+	uint16_t plaintext_pad_len;
+
+	/* Create GCM session */
+	retval = create_gcm_session(ts_params->valid_devs[0],
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+			tdata->key.data, tdata->key.len,
+			tdata->aad.len, tdata->auth_tag.len,
+			RTE_CRYPTO_AUTH_OP_GENERATE);
+	if (retval < 0)
+		return retval;
+
+	ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+	ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+
+	/* clear mbuf payload */
+	memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+			rte_pktmbuf_tailroom(ut_params->ibuf));
+	memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0,
+			rte_pktmbuf_tailroom(ut_params->obuf));
+
+	/* Create GCM operation */
+	retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata);
+	if (retval < 0)
+		return retval;
+
+	rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess);
+
+	ut_params->op->sym->m_src = ut_params->ibuf;
+	ut_params->op->sym->m_dst = ut_params->obuf;
+
+	/* Process crypto operation */
+	TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op), "failed to process sym crypto op");
+
+	TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op processing failed");
+
+	plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16);
+
+	ciphertext = rte_pktmbuf_mtod_offset(ut_params->obuf, uint8_t *,
+			ut_params->op->sym->cipher.data.offset);
+	auth_tag = ciphertext + plaintext_pad_len;
+
+	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len);
+	TEST_HEXDUMP(stdout, "auth tag:", auth_tag, tdata->auth_tag.len);
+
+	/* Validate obuf */
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+			ciphertext,
+			tdata->ciphertext.data,
+			tdata->ciphertext.len,
+			"GCM Ciphertext data not as expected");
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+			auth_tag,
+			tdata->auth_tag.data,
+			tdata->auth_tag.len,
+			"GCM Generated auth tag not as expected");
+
+	return 0;
+
+}
+
+static int
+test_mb_AES_GCM_authenticated_encryption_oop(void)
+{
+	return test_AES_GCM_authenticated_encryption_oop(&gcm_test_case_5);
+}
+
+static int
+test_AES_GCM_authenticated_decryption_oop(const struct gcm_test_data *tdata)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_unittest_params *ut_params = &unittest_params;
+
+	int retval;
+	uint8_t *plaintext;
+
+	/* Create GCM session */
+	retval = create_gcm_session(ts_params->valid_devs[0],
+			RTE_CRYPTO_CIPHER_OP_DECRYPT,
+			tdata->key.data, tdata->key.len,
+			tdata->aad.len, tdata->auth_tag.len,
+			RTE_CRYPTO_AUTH_OP_VERIFY);
+	if (retval < 0)
+		return retval;
+
+	/* alloc mbuf and set payload */
+	ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+	ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+
+	memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+			rte_pktmbuf_tailroom(ut_params->ibuf));
+	memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0,
+			rte_pktmbuf_tailroom(ut_params->obuf));
+
+	/* Create GCM operation */
+	retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata);
+	if (retval < 0)
+		return retval;
+
+	rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess);
+
+	ut_params->op->sym->m_src = ut_params->ibuf;
+	ut_params->op->sym->m_dst = ut_params->obuf;
+
+	/* Process crypto operation */
+	TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op), "failed to process sym crypto op");
+
+	TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op processing failed");
+
+	plaintext = rte_pktmbuf_mtod_offset(ut_params->obuf, uint8_t *,
+			ut_params->op->sym->cipher.data.offset);
+
+	TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->ciphertext.len);
+
+	/* Validate obuf */
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+			plaintext,
+			tdata->plaintext.data,
+			tdata->plaintext.len,
+			"GCM plaintext data not as expected");
+
+	TEST_ASSERT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"GCM authentication failed");
+	return 0;
+}
+
+static int
+test_mb_AES_GCM_authenticated_decryption_oop(void)
+{
+	return test_AES_GCM_authenticated_decryption_oop(&gcm_test_case_5);
+}
+
+static int
+test_AES_GCM_authenticated_encryption_sessionless(
+		const struct gcm_test_data *tdata)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_unittest_params *ut_params = &unittest_params;
+
+	int retval;
+	uint8_t *ciphertext, *auth_tag;
+	uint16_t plaintext_pad_len;
+	uint8_t key[tdata->key.len + 1];
+
+	ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+
+	/* clear mbuf payload */
+	memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+			rte_pktmbuf_tailroom(ut_params->ibuf));
+
+	/* Create GCM operation */
+	retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata);
+	if (retval < 0)
+		return retval;
+
+	/* Create GCM xforms */
+	memcpy(key, tdata->key.data, tdata->key.len);
+	retval = create_gcm_xforms(ut_params->op,
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+			key, tdata->key.len,
+			tdata->aad.len, tdata->auth_tag.len,
+			RTE_CRYPTO_AUTH_OP_GENERATE);
+	if (retval < 0)
+		return retval;
+
+	ut_params->op->sym->m_src = ut_params->ibuf;
+
+	TEST_ASSERT_EQUAL(ut_params->op->sym->sess_type,
+			RTE_CRYPTO_SYM_OP_SESSIONLESS,
+			"crypto op session type not sessionless");
+
+	/* Process crypto operation */
+	TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op), "failed to process sym crypto op");
+
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+
+	TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op status not success");
+
+	plaintext_pad_len = RTE_ALIGN_CEIL(tdata->plaintext.len, 16);
+
+	ciphertext = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *,
+			ut_params->op->sym->cipher.data.offset);
+	auth_tag = ciphertext + plaintext_pad_len;
+
+	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, tdata->ciphertext.len);
+	TEST_HEXDUMP(stdout, "auth tag:", auth_tag, tdata->auth_tag.len);
+
+	/* Validate obuf */
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+			ciphertext,
+			tdata->ciphertext.data,
+			tdata->ciphertext.len,
+			"GCM Ciphertext data not as expected");
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+			auth_tag,
+			tdata->auth_tag.data,
+			tdata->auth_tag.len,
+			"GCM Generated auth tag not as expected");
+
+	return 0;
+
+}
+
+static int
+test_mb_AES_GCM_authenticated_encryption_sessionless(void)
+{
+	return test_AES_GCM_authenticated_encryption_sessionless(
+			&gcm_test_case_5);
+}
+
+static int
+test_AES_GCM_authenticated_decryption_sessionless(
+		const struct gcm_test_data *tdata)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_unittest_params *ut_params = &unittest_params;
+
+	int retval;
+	uint8_t *plaintext;
+	uint8_t key[tdata->key.len + 1];
+
+	/* alloc mbuf and set payload */
+	ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+
+	memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+			rte_pktmbuf_tailroom(ut_params->ibuf));
+
+	/* Create GCM operation */
+	retval = create_gcm_operation(RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata);
+	if (retval < 0)
+		return retval;
+
+	/* Create GCM xforms */
+	memcpy(key, tdata->key.data, tdata->key.len);
+	retval = create_gcm_xforms(ut_params->op,
+			RTE_CRYPTO_CIPHER_OP_DECRYPT,
+			key, tdata->key.len,
+			tdata->aad.len, tdata->auth_tag.len,
+			RTE_CRYPTO_AUTH_OP_VERIFY);
+	if (retval < 0)
+		return retval;
+
+	ut_params->op->sym->m_src = ut_params->ibuf;
+
+	TEST_ASSERT_EQUAL(ut_params->op->sym->sess_type,
+			RTE_CRYPTO_SYM_OP_SESSIONLESS,
+			"crypto op session type not sessionless");
+
+	/* Process crypto operation */
+	TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op), "failed to process sym crypto op");
+
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+
+	TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op status not success");
+
+	plaintext = rte_pktmbuf_mtod_offset(ut_params->ibuf, uint8_t *,
+			ut_params->op->sym->cipher.data.offset);
+
+	TEST_HEXDUMP(stdout, "plaintext:", plaintext, tdata->ciphertext.len);
+
+	/* Validate obuf */
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+			plaintext,
+			tdata->plaintext.data,
+			tdata->plaintext.len,
+			"GCM plaintext data not as expected");
+
+	TEST_ASSERT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"GCM authentication failed");
+	return 0;
+}
+
+static int
+test_mb_AES_GCM_authenticated_decryption_sessionless(void)
+{
+	return test_AES_GCM_authenticated_decryption_sessionless(
+			&gcm_test_case_5);
+}
+
+static int
 test_stats(void)
 {
 	struct crypto_testsuite_params *ts_params = &testsuite_params;
@@ -7102,6 +7567,86 @@  struct test_crypto_vector {
 		TEST_CASE_ST(ut_setup, ut_teardown,
 			test_mb_AES_GCM_authenticated_decryption_test_case_7),
 
+		/** AES GCM Authenticated Encryption 256 bits key */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_encryption_test_case_256_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_encryption_test_case_256_2),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_encryption_test_case_256_3),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_encryption_test_case_256_4),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_encryption_test_case_256_5),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_encryption_test_case_256_6),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_encryption_test_case_256_7),
+
+		/** AES GCM Authenticated Decryption 256 bits key */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_decryption_test_case_256_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_decryption_test_case_256_2),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_decryption_test_case_256_3),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_decryption_test_case_256_4),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_decryption_test_case_256_5),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_decryption_test_case_256_6),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_decryption_test_case_256_7),
+
+		/** AES GCM Authenticated Encryption big aad size */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_encryption_test_case_aad_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_encryption_test_case_aad_2),
+
+		/** AES GCM Authenticated Decryption big aad size */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_decryption_test_case_aad_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_auth_decryption_test_case_aad_2),
+
+		/** AES GMAC Authentication */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_test_case_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_verify_test_case_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_test_case_3),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_verify_test_case_3),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_test_case_4),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_verify_test_case_4),
+
+		/** Negative tests */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authentication_verify_AES128_GMAC_fail_data_corrupt),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authentication_verify_AES128_GMAC_fail_tag_corrupt),
+
+		/** Out of place tests */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_oop),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_oop),
+
+		/** Session-less tests */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_sessionless),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_sessionless),
+
+		/** Scatter-Gather */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_1seg),
+
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
diff --git a/app/test/test_cryptodev_gcm_test_vectors.h b/app/test/test_cryptodev_gcm_test_vectors.h
index 45ea3d4..5764edb 100644
--- a/app/test/test_cryptodev_gcm_test_vectors.h
+++ b/app/test/test_cryptodev_gcm_test_vectors.h
@@ -33,7 +33,17 @@ 
 #ifndef TEST_CRYPTODEV_GCM_TEST_VECTORS_H_
 #define TEST_CRYPTODEV_GCM_TEST_VECTORS_H_
 
-#define GMAC_LARGE_PLAINTEXT_LENGTH		65376
+#define GMAC_LARGE_PLAINTEXT_LENGTH		65344
+#define GCM_MAX_AAD_LENGTH			65536
+#define GCM_LARGE_AAD_LENGTH			65296
+
+static uint8_t gcm_aad_zero_text[GCM_MAX_AAD_LENGTH] = { 0 };
+
+static uint8_t gcm_aad_text[GCM_MAX_AAD_LENGTH] = {
+		0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+		0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+		0x00, 0xf1, 0xe2, 0xd3, 0xc4, 0xb5, 0xa6, 0x97,
+		0x88, 0x79, 0x6a, 0x5b, 0x4c, 0x3d, 0x2e, 0x1f };
 
 
 struct gcm_test_data {
@@ -48,7 +58,7 @@  struct gcm_test_data {
 	} iv;
 
 	struct {
-		uint8_t data[64];
+		uint8_t *data;
 		unsigned len;
 	} aad;
 
@@ -111,7 +121,7 @@  struct gmac_test_data {
 		.len = 12
 	},
 	.aad = {
-		.data = { 0 },
+		.data = gcm_aad_zero_text,
 		.len = 0
 	},
 	.plaintext = {
@@ -148,7 +158,7 @@  struct gmac_test_data {
 		.len = 12
 	},
 	.aad = {
-		.data = { 0 },
+		.data = gcm_aad_zero_text,
 		.len = 0
 	},
 	.plaintext = {
@@ -186,7 +196,7 @@  struct gmac_test_data {
 		.len = 12
 	},
 	.aad = {
-		.data = { 0 },
+		.data = gcm_aad_zero_text,
 		.len = 0
 	},
 	.plaintext = {
@@ -238,8 +248,7 @@  struct gmac_test_data {
 		.len = 12
 	},
 	.aad = {
-		.data = {
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		.data = gcm_aad_zero_text,
 		.len = 8
 	},
 	.plaintext = {
@@ -294,8 +303,7 @@  struct gmac_test_data {
 		.len = 12
 	},
 	.aad = {
-		.data = {
-			0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef },
+		.data = gcm_aad_text,
 		.len = 8
 	},
 	.plaintext = {
@@ -351,10 +359,7 @@  struct gmac_test_data {
 		.len = 12
 	},
 	.aad = {
-		.data = {
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00
-		},
+		.data = gcm_aad_zero_text,
 		.len = 12
 	},
 	.plaintext = {
@@ -409,10 +414,7 @@  struct gmac_test_data {
 		.len = 12
 	},
 	.aad = {
-		.data = {
-			0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
-			0xfe, 0xed, 0xfa, 0xce
-		},
+		.data = gcm_aad_text,
 		.len = 12
 	},
 	.plaintext = {
@@ -466,10 +468,7 @@  struct gmac_test_data {
 		.len = 12
 	},
 	.aad = {
-		.data = {
-			0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
-			0xfe, 0xed, 0xfa, 0xce
-		},
+		.data = gcm_aad_text,
 		.len = 12
 	},
 	.plaintext = {
@@ -1003,6 +1002,450 @@  struct gmac_test_data {
 	}
 };
 
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_1 = {
+	.key = {
+		.data = {
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		.len = 32
+	},
+	.iv = {
+		.data = {
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00 },
+		.len = 12
+	},
+	.aad = {
+		.data = gcm_aad_zero_text,
+		.len = 0
+	},
+	.plaintext = {
+		.data = { 0x00 },
+		.len = 0
+	},
+	.ciphertext = {
+		.data = { 0x00 },
+		.len = 0
+	},
+	.auth_tag = {
+		.data = {
+			0x53, 0x0F, 0x8A, 0xFB, 0xC7, 0x45, 0x36, 0xB9,
+			0xA9, 0x63, 0xB4, 0xF1, 0xC4, 0xCB, 0x73, 0x8B },
+		.len = 16
+	}
+};
+
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_2 = {
+	.key = {
+		.data = {
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		.len = 32
+	},
+	.iv = {
+		.data = {
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00 },
+		.len = 12
+	},
+	.aad = {
+		.data = gcm_aad_zero_text,
+		.len = 0
+	},
+	.plaintext = {
+		.data = {
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		.len = 16
+	},
+	.ciphertext = {
+		.data = {
+			0xCE, 0xA7, 0x40, 0x3D, 0x4D, 0x60, 0x6B, 0x6E,
+			0x07, 0x4E, 0xC5, 0xD3, 0xBA, 0xF3, 0x9D, 0x18 },
+		.len = 16
+	},
+	.auth_tag = {
+		.data = {
+			0xD0, 0xD1, 0xC8, 0xA7, 0x99, 0x99, 0x6B, 0xF0,
+			0x26, 0x5B, 0x98, 0xB5, 0xD4, 0x8A, 0xB9, 0x19 },
+		.len = 16
+	}
+};
+
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_3 = {
+	.key = {
+		.data = {
+			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+			0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+			0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a },
+		.len = 32
+	},
+	.iv = {
+		.data = {
+			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+			0xde, 0xca, 0xf8, 0x88 },
+		.len = 12
+	},
+	.aad = {
+		.data = gcm_aad_zero_text,
+		.len = 0
+	},
+	.plaintext = {
+		.data = {
+			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+			0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+			0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+			0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+			0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+			0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+			0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+			0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
+		.len = 64
+	},
+	.ciphertext = {
+		.data = {
+			0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA,
+			0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E,
+			0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04,
+			0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9,
+			0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5,
+			0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0,
+			0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB,
+			0xFA, 0x47, 0xC8, 0x2E, 0xF0, 0x68, 0xE1, 0x3E },
+		.len = 64
+	},
+	.auth_tag = {
+		.data = {
+			0x64, 0xAF, 0x1D, 0xFB, 0xE8, 0x0D, 0x37, 0xD8,
+			0x92, 0xC3, 0xB9, 0x1D, 0xD3, 0x08, 0xAB, 0xFC },
+		.len = 16
+	}
+};
+
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_4 = {
+	.key = {
+		.data = {
+			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+			0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+			0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a },
+		.len = 32
+	},
+	.iv = {
+		.data = {
+			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+			0xde, 0xca, 0xf8, 0x88 },
+		.len = 12
+	},
+	.aad = {
+		.data = gcm_aad_zero_text,
+		.len = 8
+	},
+	.plaintext = {
+		.data = {
+			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+			0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+			0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+			0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+			0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+			0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+			0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+			0xba, 0x63, 0x7b, 0x39 },
+		.len = 60
+	},
+	.ciphertext = {
+		.data = {
+			0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA,
+			0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E,
+			0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04,
+			0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9,
+			0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5,
+			0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0,
+			0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB,
+			0xFA, 0x47, 0xC8, 0x2E },
+		.len = 60
+	},
+	.auth_tag = {
+		.data = {
+			0x63, 0x16, 0x91, 0xAE, 0x17, 0x05, 0x5E, 0xA6,
+			0x6D, 0x0A, 0x51, 0xE2, 0x50, 0x21, 0x85, 0x4A },
+		.len = 16
+	}
+
+};
+
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_5 = {
+	.key = {
+		.data = {
+			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+			0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+			0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a },
+		.len = 32
+	},
+	.iv = {
+		.data = {
+			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+			0xde, 0xca, 0xf8, 0x88 },
+		.len = 12
+	},
+	.aad = {
+		.data = gcm_aad_text,
+		.len = 8
+	},
+	.plaintext = {
+		.data = {
+			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+			0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+			0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+			0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+			0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+			0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+			0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+			0xba, 0x63, 0x7b, 0x39 },
+		.len = 60
+	},
+	.ciphertext = {
+		.data = {
+			0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA,
+			0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E,
+			0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04,
+			0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9,
+			0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5,
+			0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0,
+			0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB,
+			0xFA, 0x47, 0xC8, 0x2E },
+		.len = 60
+	},
+	.auth_tag = {
+		.data = {
+			0xA7, 0x99, 0xAC, 0xB8, 0x27, 0xDA, 0xB1, 0x82,
+			0x79, 0xFD, 0x83, 0x73, 0x52, 0x4D, 0xDB, 0xF1 },
+		.len = 16
+	}
+
+};
+
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_6 = {
+	.key = {
+		.data = {
+			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+			0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+			0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a },
+		.len = 32
+	},
+	.iv = {
+		.data = {
+			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+			0xde, 0xca, 0xf8, 0x88 },
+		.len = 12
+	},
+	.aad = {
+		.data = gcm_aad_zero_text,
+		.len = 12
+	},
+	.plaintext = {
+		.data = {
+			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+			0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+			0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+			0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+			0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+			0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+			0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+			0xba, 0x63, 0x7b, 0x39 },
+		.len = 60
+	},
+	.ciphertext = {
+		.data = {
+			0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA,
+			0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E,
+			0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04,
+			0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9,
+			0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5,
+			0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0,
+			0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB,
+			0xFA, 0x47, 0xC8, 0x2E },
+		.len = 60
+	},
+	.auth_tag = {
+		.data = {
+			0x5D, 0xA5, 0x0E, 0x53, 0x64, 0x7F, 0x3F, 0xAE,
+			0x1A, 0x1F, 0xC0, 0xB0, 0xD8, 0xBE, 0xF2, 0x64 },
+		.len = 16
+	}
+};
+
+/** AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_256_7 = {
+	.key = {
+		.data = {
+			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+			0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+			0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a },
+		.len = 32
+	},
+	.iv = {
+		.data = {
+			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+			0xde, 0xca, 0xf8, 0x88 },
+		.len = 12
+	},
+	.aad = {
+		.data = gcm_aad_text,
+		.len = 12
+	},
+	.plaintext = {
+		.data = {
+			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+			0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+			0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+			0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+			0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+			0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+			0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+			0xba, 0x63, 0x7b, 0x39 },
+		.len = 60
+	},
+	.ciphertext = {
+		.data = {
+			0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA,
+			0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E,
+			0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04,
+			0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9,
+			0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5,
+			0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0,
+			0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB,
+			0xFA, 0x47, 0xC8, 0x2E },
+		.len = 60
+	},
+	.auth_tag = {
+		.data = {
+			0x4E, 0xD0, 0x91, 0x95, 0x83, 0xA9, 0x38, 0x72,
+			0x09, 0xA9, 0xCE, 0x5F, 0x89, 0x06, 0x4E, 0xC8 },
+		.len = 16
+	}
+};
+
+/** variable AAD AES-128 Test Vectors */
+static const struct gcm_test_data gcm_test_case_aad_1 = {
+	.key = {
+		.data = {
+			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+			0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+			0xde, 0xca, 0xf8, 0x88 },
+		.len = 12
+	},
+	.aad = {
+		.data = gcm_aad_text,
+		.len = GCM_LARGE_AAD_LENGTH
+	},
+	.plaintext = {
+		.data = {
+			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+			0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+			0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+			0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+			0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+			0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+			0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+			0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
+		.len = 64
+	},
+	.ciphertext = {
+		.data = {
+			0x42, 0x83, 0x1E, 0xC2, 0x21, 0x77, 0x74, 0x24,
+			0x4B, 0x72, 0x21, 0xB7, 0x84, 0xD0, 0xD4, 0x9C,
+			0xE3, 0xAA, 0x21, 0x2F, 0x2C, 0x02, 0xA4, 0xE0,
+			0x35, 0xC1, 0x7E, 0x23, 0x29, 0xAC, 0xA1, 0x2E,
+			0x21, 0xD5, 0x14, 0xB2, 0x54, 0x66, 0x93, 0x1C,
+			0x7D, 0x8F, 0x6A, 0x5A, 0xAC, 0x84, 0xAA, 0x05,
+			0x1B, 0xA3, 0x0B, 0x39, 0x6A, 0x0A, 0xAC, 0x97,
+			0x3D, 0x58, 0xE0, 0x91, 0x47, 0x3F, 0x59, 0x85
+			},
+		.len = 64
+	},
+	.auth_tag = {
+		.data = {
+			0xCA, 0x70, 0xAF, 0x96, 0xA8, 0x5D, 0x40, 0x47,
+			0x0C, 0x3C, 0x48, 0xF5, 0xF0, 0xF5, 0xA5, 0x7D
+			},
+		.len = 16
+	}
+};
+
+/** variable AAD AES-256 Test Vectors */
+static const struct gcm_test_data gcm_test_case_aad_2 = {
+	.key = {
+		.data = {
+			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+			0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+			0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a },
+		.len = 32
+	},
+	.iv = {
+		.data = {
+			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+			0xde, 0xca, 0xf8, 0x88 },
+		.len = 12
+	},
+	.aad = {
+		.data = gcm_aad_text,
+		.len = GCM_LARGE_AAD_LENGTH
+	},
+	.plaintext = {
+		.data = {
+			0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+			0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+			0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+			0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+			0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+			0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+			0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+			0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
+		.len = 64
+	},
+	.ciphertext = {
+		.data = {
+			0x05, 0xA2, 0x39, 0xA5, 0xE1, 0x1A, 0x74, 0xEA,
+			0x6B, 0x2A, 0x55, 0xF6, 0xD7, 0x88, 0x44, 0x7E,
+			0x93, 0x7E, 0x23, 0x64, 0x8D, 0xF8, 0xD4, 0x04,
+			0x3B, 0x40, 0xEF, 0x6D, 0x7C, 0x6B, 0xF3, 0xB9,
+			0x50, 0x15, 0x97, 0x5D, 0xB8, 0x28, 0xA1, 0xD5,
+			0x22, 0xDE, 0x36, 0x26, 0xD0, 0x6A, 0x7A, 0xC0,
+			0xB5, 0x14, 0x36, 0xAF, 0x3A, 0xC6, 0x50, 0xAB,
+			0xFA, 0x47, 0xC8, 0x2E, 0xF0, 0x68, 0xE1, 0x3E
+			},
+		.len = 64
+	},
+	.auth_tag = {
+		.data = {
+			0xBA, 0x06, 0xDA, 0xA1, 0x91, 0xE1, 0xFE, 0x22,
+			0x59, 0xDA, 0x67, 0xAF, 0x9D, 0xA5, 0x43, 0x94
+			},
+		.len = 16
+	}
+};
+
 /** GMAC Test Vectors */
 static uint8_t gmac_plaintext[GMAC_LARGE_PLAINTEXT_LENGTH] = {
 			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
@@ -1781,8 +2224,8 @@  struct cryptodev_perf_test_data {
 	},
 	.gmac_tag = {
 		.data = {
-			0x88, 0x82, 0xb4, 0x93, 0x8f, 0x04, 0xcd, 0x06,
-			0xfd, 0xac, 0x6d, 0x8b, 0x9c, 0x9e, 0x8f, 0xec
+			0x3f, 0x07, 0xcb, 0xb9, 0x86, 0x3a, 0xea, 0xc2,
+			0x2f, 0x3a, 0x2a, 0x93, 0xd8, 0x09, 0x6b, 0xda
 		},
 		.len = 16
 	}
@@ -1802,7 +2245,7 @@  struct cryptodev_perf_test_data {
 		.len = 12
 	},
 	.aad = {
-		.data = { 0 },
+		.data = gcm_aad_zero_text,
 		.len = 0
 	},
 	.plaintext = {
diff --git a/devtools/test-build.sh b/devtools/test-build.sh
index a979309..d0c1a34 100755
--- a/devtools/test-build.sh
+++ b/devtools/test-build.sh
@@ -44,6 +44,7 @@  default_path=$PATH
 # - DPDK_DEP_SSL (y/[n])
 # - DPDK_DEP_SZE (y/[n])
 # - DPDK_DEP_ZLIB (y/[n])
+# - DPDK_DEP_ISAL (y/[n])
 # - DPDK_MAKE_JOBS (int)
 # - DPDK_NOTIFY (notify-send)
 # - LIBSSO_SNOW3G_PATH
@@ -126,6 +127,7 @@  reset_env ()
 	unset DPDK_DEP_SSL
 	unset DPDK_DEP_SZE
 	unset DPDK_DEP_ZLIB
+	unset DPDK_DEP_ISAL
 	unset AESNI_MULTI_BUFFER_LIB_PATH
 	unset LIBSSO_SNOW3G_PATH
 	unset LIBSSO_KASUMI_PATH
@@ -176,7 +178,7 @@  config () # <directory> <target> <options>
 		sed -ri               's,(PCAP=)n,\1y,' $1/.config
 		test -z "$AESNI_MULTI_BUFFER_LIB_PATH" || \
 		sed -ri       's,(PMD_AESNI_MB=)n,\1y,' $1/.config
-		test -z "$AESNI_MULTI_BUFFER_LIB_PATH" || \
+		test "$DPDK_DEP_ISAL" != y || \
 		sed -ri      's,(PMD_AESNI_GCM=)n,\1y,' $1/.config
 		test -z "$LIBSSO_SNOW3G_PATH" || \
 		sed -ri         's,(PMD_SNOW3G=)n,\1y,' $1/.config
diff --git a/doc/guides/cryptodevs/aesni_gcm.rst b/doc/guides/cryptodevs/aesni_gcm.rst
index 04bf43c..e4b4108 100644
--- a/doc/guides/cryptodevs/aesni_gcm.rst
+++ b/doc/guides/cryptodevs/aesni_gcm.rst
@@ -32,10 +32,8 @@  AES-NI GCM Crypto Poll Mode Driver
 
 
 The AES-NI GCM PMD (**librte_pmd_aesni_gcm**) provides poll mode crypto driver
-support for utilizing Intel multi buffer library (see AES-NI Multi-buffer PMD documentation
-to learn more about it, including installation).
-
-The AES-NI GCM PMD has current only been tested on Fedora 21 64-bit with gcc.
+support for utilizing Intel ISA-L crypto library, which provides operation acceleration
+through the AES-NI instruction sets for AES-GCM authenticated cipher algorithm.
 
 Features
 --------
@@ -49,16 +47,21 @@  Cipher algorithms:
 Authentication algorithms:
 
 * RTE_CRYPTO_AUTH_AES_GCM
+* RTE_CRYPTO_AUTH_AES_GMAC
+
+Installation
+------------
+
+To build DPDK with the AESNI_GCM_PMD the user is required to install
+the ``libisal_crypto`` library in the build environment.
+For download and more details please visit `<https://github.com/01org/isa-l_crypto>`_.
 
 Initialization
 --------------
 
 In order to enable this virtual crypto PMD, user must:
 
-* Export the environmental variable AESNI_MULTI_BUFFER_LIB_PATH with the path where
-  the library was extracted.
-
-* Build the multi buffer library (go to Installation section in AES-NI MB PMD documentation).
+* Install the ISA-L crypto library (explained in Installation section).
 
 * Set CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=y in config/common_base.
 
@@ -86,9 +89,6 @@  Example:
 Limitations
 -----------
 
-* Chained mbufs are not supported.
+* Chained mbufs are supported but only out-of-place (destination mbuf must be contiguous).
 * Hash only is not supported.
 * Cipher only is not supported.
-* Only in-place is currently supported (destination address is the same as source address).
-* Only supports session-oriented API implementation (session-less APIs are not supported).
-*  Not performance tuned.
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 5ab7019..3b982b2 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -67,6 +67,18 @@  New Features
 
   * Support for single operations (cipher only and authentication only).
 
+* **Updated the AES-NI GCM PMD.**
+
+  The AES-NI GCM PMD was migrated from MB library to ISA-L library.
+  The migration entailed the following additional support for:
+
+  * GMAC algorithm.
+  * 256-bit cipher key.
+  * Session-less mode.
+  * Out-of place processing
+  * Scatter-gatter support for chained mbufs (only out-of place and destination
+    mbuf must be contiguous)
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/crypto/aesni_gcm/Makefile b/drivers/crypto/aesni_gcm/Makefile
index 5898cae..fb17fbf 100644
--- a/drivers/crypto/aesni_gcm/Makefile
+++ b/drivers/crypto/aesni_gcm/Makefile
@@ -31,9 +31,6 @@ 
 include $(RTE_SDK)/mk/rte.vars.mk
 
 ifneq ($(MAKECMDGOALS),clean)
-ifeq ($(AESNI_MULTI_BUFFER_LIB_PATH),)
-$(error "Please define AESNI_MULTI_BUFFER_LIB_PATH environment variable")
-endif
 endif
 
 # library name
@@ -50,10 +47,7 @@  LIBABIVER := 1
 EXPORT_MAP := rte_pmd_aesni_gcm_version.map
 
 # external library dependencies
-CFLAGS += -I$(AESNI_MULTI_BUFFER_LIB_PATH)
-CFLAGS += -I$(AESNI_MULTI_BUFFER_LIB_PATH)/include
-LDLIBS += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
-LDLIBS += -lcrypto
+LDLIBS += -lisal_crypto
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm_pmd.c
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_ops.h b/drivers/crypto/aesni_gcm/aesni_gcm_ops.h
index c399068..e9de654 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_ops.h
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_ops.h
@@ -37,91 +37,26 @@ 
 #define LINUX
 #endif
 
-#include <gcm_defines.h>
-#include <aux_funcs.h>
+#include <isa-l_crypto/aes_gcm.h>
 
-/** Supported vector modes */
-enum aesni_gcm_vector_mode {
-	RTE_AESNI_GCM_NOT_SUPPORTED = 0,
-	RTE_AESNI_GCM_SSE,
-	RTE_AESNI_GCM_AVX,
-	RTE_AESNI_GCM_AVX2
-};
-
-typedef void (*aes_keyexp_128_enc_t)(void *key, void *enc_exp_keys);
+typedef void (*aesni_gcm_init_t)(struct gcm_data *my_ctx_data,
+		uint8_t *iv,
+		uint8_t const *aad,
+		uint64_t aad_len);
 
-typedef void (*aesni_gcm_t)(gcm_data *my_ctx_data, u8 *out, const u8 *in,
-		u64 plaintext_len, u8 *iv, const u8 *aad, u64 aad_len,
-		u8 *auth_tag, u64 auth_tag_len);
+typedef void (*aesni_gcm_update_t)(struct gcm_data *my_ctx_data,
+		uint8_t *out,
+		const uint8_t *in,
+		uint64_t plaintext_len);
 
-typedef void (*aesni_gcm_precomp_t)(gcm_data *my_ctx_data, u8 *hash_subkey);
+typedef void (*aesni_gcm_finalize_t)(struct gcm_data *my_ctx_data,
+		uint8_t *auth_tag,
+		uint64_t auth_tag_len);
 
-/** GCM library function pointer table */
 struct aesni_gcm_ops {
-	struct {
-		struct {
-			aes_keyexp_128_enc_t aes128_enc;
-			/**< AES128 enc key expansion */
-		} keyexp;
-		/**< Key expansion functions */
-	} aux; /**< Auxiliary functions */
-
-	struct {
-		aesni_gcm_t enc;	/**< GCM encode function pointer */
-		aesni_gcm_t dec;	/**< GCM decode function pointer */
-		aesni_gcm_precomp_t precomp;	/**< GCM pre-compute */
-	} gcm; /**< GCM functions */
+	aesni_gcm_init_t init;
+	aesni_gcm_update_t update;
+	aesni_gcm_finalize_t finalize;
 };
 
-
-static const struct aesni_gcm_ops gcm_ops[] = {
-	[RTE_AESNI_GCM_NOT_SUPPORTED] = {
-		.aux = {
-			.keyexp = {
-				NULL
-			}
-		},
-		.gcm = {
-			NULL
-		}
-	},
-	[RTE_AESNI_GCM_SSE] = {
-		.aux = {
-			.keyexp = {
-				aes_keyexp_128_enc_sse
-			}
-		},
-		.gcm = {
-			aesni_gcm_enc_sse,
-			aesni_gcm_dec_sse,
-			aesni_gcm_precomp_sse
-		}
-	},
-	[RTE_AESNI_GCM_AVX] = {
-		.aux = {
-			.keyexp = {
-				aes_keyexp_128_enc_avx,
-			}
-		},
-		.gcm = {
-			aesni_gcm_enc_avx_gen2,
-			aesni_gcm_dec_avx_gen2,
-			aesni_gcm_precomp_avx_gen2
-		}
-	},
-	[RTE_AESNI_GCM_AVX2] = {
-		.aux = {
-			.keyexp = {
-				aes_keyexp_128_enc_avx2,
-			}
-		},
-		.gcm = {
-			aesni_gcm_enc_avx_gen4,
-			aesni_gcm_dec_avx_gen4,
-			aesni_gcm_precomp_avx_gen4
-		}
-	}
-};
-
-
 #endif /* _AESNI_GCM_OPS_H_ */
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index 5af22f7..8b2d792 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -30,8 +30,6 @@ 
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <openssl/aes.h>
-
 #include <rte_common.h>
 #include <rte_config.h>
 #include <rte_hexdump.h>
@@ -44,6 +42,34 @@ 
 
 #include "aesni_gcm_pmd_private.h"
 
+/** GCM encode functions pointer table */
+static const struct aesni_gcm_ops aesni_gcm_enc[] = {
+		[AESNI_GCM_KEY_128] = {
+				aesni_gcm128_init,
+				aesni_gcm128_enc_update,
+				aesni_gcm128_enc_finalize
+		},
+		[AESNI_GCM_KEY_256] = {
+				aesni_gcm256_init,
+				aesni_gcm256_enc_update,
+				aesni_gcm256_enc_finalize
+		}
+};
+
+/** GCM decode functions pointer table */
+static const struct aesni_gcm_ops aesni_gcm_dec[] = {
+		[AESNI_GCM_KEY_128] = {
+				aesni_gcm128_init,
+				aesni_gcm128_dec_update,
+				aesni_gcm128_dec_finalize
+		},
+		[AESNI_GCM_KEY_256] = {
+				aesni_gcm256_init,
+				aesni_gcm256_dec_update,
+				aesni_gcm256_dec_finalize
+		}
+};
+
 /**
  * Global static parameter used to create a unique name for each AES-NI multi
  * buffer crypto device.
@@ -65,112 +91,68 @@ 
 	return 0;
 }
 
-static int
-aesni_gcm_calculate_hash_sub_key(uint8_t *hsubkey, unsigned hsubkey_length,
-		uint8_t *aeskey, unsigned aeskey_length)
-{
-	uint8_t key[aeskey_length] __rte_aligned(16);
-	AES_KEY enc_key;
-
-	if (hsubkey_length % 16 != 0 && aeskey_length % 16 != 0)
-		return -EFAULT;
-
-	memcpy(key, aeskey, aeskey_length);
-
-	if (AES_set_encrypt_key(key, aeskey_length << 3, &enc_key) != 0)
-		return -EFAULT;
-
-	AES_encrypt(hsubkey, hsubkey, &enc_key);
-
-	return 0;
-}
-
-/** Get xform chain order */
-static int
-aesni_gcm_get_mode(const struct rte_crypto_sym_xform *xform)
-{
-	/*
-	 * GCM only supports authenticated encryption or authenticated
-	 * decryption, all other options are invalid, so we must have exactly
-	 * 2 xform structs chained together
-	 */
-	if (xform->next == NULL || xform->next->next != NULL)
-		return -1;
-
-	if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
-			xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
-		return AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION;
-	}
-
-	if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
-			xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
-		return AESNI_GCM_OP_AUTHENTICATED_DECRYPTION;
-	}
-
-	return -1;
-}
-
 /** Parse crypto xform chain and set private session parameters */
 int
-aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *gcm_ops,
-		struct aesni_gcm_session *sess,
+aesni_gcm_set_session_parameters(struct aesni_gcm_session *sess,
 		const struct rte_crypto_sym_xform *xform)
 {
-	const struct rte_crypto_sym_xform *auth_xform = NULL;
-	const struct rte_crypto_sym_xform *cipher_xform = NULL;
+	const struct rte_crypto_sym_xform *auth_xform;
+	const struct rte_crypto_sym_xform *cipher_xform;
 
-	uint8_t hsubkey[16] __rte_aligned(16) = { 0 };
-
-	/* Select Crypto operation - hash then cipher / cipher then hash */
-	switch (aesni_gcm_get_mode(xform)) {
-	case AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION:
-		sess->op = AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION;
+	if (xform->next == NULL || xform->next->next != NULL) {
+		GCM_LOG_ERR("Two and only two chained xform required");
+		return -EINVAL;
+	}
 
-		cipher_xform = xform;
+	if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
+			xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
 		auth_xform = xform->next;
-		break;
-	case AESNI_GCM_OP_AUTHENTICATED_DECRYPTION:
-		sess->op = AESNI_GCM_OP_AUTHENTICATED_DECRYPTION;
-
+		cipher_xform = xform;
+	} else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
+			xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
 		auth_xform = xform;
 		cipher_xform = xform->next;
-		break;
-	default:
-		GCM_LOG_ERR("Unsupported operation chain order parameter");
+	} else {
+		GCM_LOG_ERR("Cipher and auth xform required");
 		return -EINVAL;
 	}
 
-	/* We only support AES GCM */
-	if (cipher_xform->cipher.algo != RTE_CRYPTO_CIPHER_AES_GCM &&
-			auth_xform->auth.algo != RTE_CRYPTO_AUTH_AES_GCM)
+	if (!(cipher_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_GCM &&
+		(auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GCM ||
+			auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC))) {
+		GCM_LOG_ERR("We only support AES GCM and AES GMAC");
 		return -EINVAL;
+	}
 
-	/* Select cipher direction */
-	if (sess->op == AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION &&
-			cipher_xform->cipher.op !=
-					RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
-		GCM_LOG_ERR("xform chain (CIPHER/AUTH) and cipher operation "
-				"(DECRYPT) specified are an invalid selection");
-		return -EINVAL;
-	} else if (sess->op == AESNI_GCM_OP_AUTHENTICATED_DECRYPTION &&
-			cipher_xform->cipher.op !=
-					RTE_CRYPTO_CIPHER_OP_DECRYPT) {
-		GCM_LOG_ERR("xform chain (AUTH/CIPHER) and cipher operation "
-				"(ENCRYPT) specified are an invalid selection");
+	/* Select Crypto operation */
+	if (cipher_xform->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
+			auth_xform->auth.op == RTE_CRYPTO_AUTH_OP_GENERATE)
+		sess->op = AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION;
+	else if (cipher_xform->cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT &&
+			auth_xform->auth.op == RTE_CRYPTO_AUTH_OP_VERIFY)
+		sess->op = AESNI_GCM_OP_AUTHENTICATED_DECRYPTION;
+	else {
+		GCM_LOG_ERR("Cipher/Auth operations: Encrypt/Generate or"
+				" Decrypt/Verify are valid only");
 		return -EINVAL;
 	}
 
-	/* Expand GCM AES128 key */
-	(*gcm_ops->aux.keyexp.aes128_enc)(cipher_xform->cipher.key.data,
-			sess->gdata.expanded_keys);
+	/* Check key length and calculate GCM pre-compute. */
+	switch (cipher_xform->cipher.key.length) {
+	case 16:
+		aesni_gcm128_pre(cipher_xform->cipher.key.data, &sess->gdata);
+		sess->key = AESNI_GCM_KEY_128;
 
-	/* Calculate hash sub key here */
-	aesni_gcm_calculate_hash_sub_key(hsubkey, sizeof(hsubkey),
-			cipher_xform->cipher.key.data,
-			cipher_xform->cipher.key.length);
+		break;
+	case 32:
+		aesni_gcm256_pre(cipher_xform->cipher.key.data, &sess->gdata);
+		sess->key = AESNI_GCM_KEY_256;
 
-	/* Calculate GCM pre-compute */
-	(*gcm_ops->gcm.precomp)(&sess->gdata, hsubkey);
+		break;
+	default:
+		GCM_LOG_ERR("Unsupported cipher key length");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -194,10 +176,10 @@ 
 			return sess;
 
 		sess = (struct aesni_gcm_session *)
-			((struct rte_cryptodev_session *)_sess)->_private;
+			((struct rte_cryptodev_sym_session *)_sess)->_private;
 
-		if (unlikely(aesni_gcm_set_session_parameters(qp->ops,
-				sess, op->xform) != 0)) {
+		if (unlikely(aesni_gcm_set_session_parameters(sess,
+				op->xform) != 0)) {
 			rte_mempool_put(qp->sess_mp, _sess);
 			sess = NULL;
 		}
@@ -217,19 +199,45 @@ 
  *
  */
 static int
-process_gcm_crypto_op(struct aesni_gcm_qp *qp, struct rte_crypto_sym_op *op,
+process_gcm_crypto_op(struct rte_crypto_sym_op *op,
 		struct aesni_gcm_session *session)
 {
 	uint8_t *src, *dst;
-	struct rte_mbuf *m = op->m_src;
+	struct rte_mbuf *m_src = op->m_src;
+	uint32_t offset = op->cipher.data.offset;
+	uint32_t part_len, total_len, data_len;
+
+	RTE_ASSERT(m_src != NULL);
+
+	while (offset >= m_src->data_len) {
+		offset -= m_src->data_len;
+		m_src = m_src->next;
+
+		RTE_ASSERT(m_src != NULL);
+	}
+
+	data_len = m_src->data_len - offset;
+	part_len = (data_len < op->cipher.data.length) ? data_len :
+			op->cipher.data.length;
+
+	/* Destination buffer is required when segmented source buffer */
+	RTE_ASSERT((part_len == op->cipher.data.length) ||
+			((part_len != op->cipher.data.length) &&
+					(op->m_dst != NULL)));
+	/* Segmented destination buffer is not supported */
+	RTE_ASSERT((op->m_dst == NULL) ||
+			((op->m_dst != NULL) &&
+					rte_pktmbuf_is_contiguous(op->m_dst)));
+
 
-	src = rte_pktmbuf_mtod(m, uint8_t *) + op->cipher.data.offset;
 	dst = op->m_dst ?
 			rte_pktmbuf_mtod_offset(op->m_dst, uint8_t *,
 					op->cipher.data.offset) :
-			rte_pktmbuf_mtod_offset(m, uint8_t *,
+			rte_pktmbuf_mtod_offset(op->m_src, uint8_t *,
 					op->cipher.data.offset);
 
+	src = rte_pktmbuf_mtod_offset(m_src, uint8_t *, offset);
+
 	/* sanity checks */
 	if (op->cipher.iv.length != 16 && op->cipher.iv.length != 12 &&
 			op->cipher.iv.length != 0) {
@@ -246,48 +254,81 @@ 
 		*iv_padd = rte_bswap32(1);
 	}
 
-	if (op->auth.aad.length != 12 && op->auth.aad.length != 8 &&
-			op->auth.aad.length != 0) {
-		GCM_LOG_ERR("iv");
-		return -1;
-	}
-
 	if (op->auth.digest.length != 16 &&
 			op->auth.digest.length != 12 &&
-			op->auth.digest.length != 8 &&
-			op->auth.digest.length != 0) {
-		GCM_LOG_ERR("iv");
+			op->auth.digest.length != 8) {
+		GCM_LOG_ERR("digest");
 		return -1;
 	}
 
 	if (session->op == AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION) {
 
-		(*qp->ops->gcm.enc)(&session->gdata, dst, src,
-				(uint64_t)op->cipher.data.length,
+		aesni_gcm_enc[session->key].init(&session->gdata,
 				op->cipher.iv.data,
 				op->auth.aad.data,
-				(uint64_t)op->auth.aad.length,
+				(uint64_t)op->auth.aad.length);
+
+		aesni_gcm_enc[session->key].update(&session->gdata, dst, src,
+				(uint64_t)part_len);
+		total_len = op->cipher.data.length - part_len;
+
+		while (total_len) {
+			dst += part_len;
+			m_src = m_src->next;
+
+			RTE_ASSERT(m_src != NULL);
+
+			src = rte_pktmbuf_mtod(m_src, uint8_t *);
+			part_len = (m_src->data_len < total_len) ?
+					m_src->data_len : total_len;
+
+			aesni_gcm_enc[session->key].update(&session->gdata,
+					dst, src,
+					(uint64_t)part_len);
+			total_len -= part_len;
+		}
+
+		aesni_gcm_enc[session->key].finalize(&session->gdata,
 				op->auth.digest.data,
 				(uint64_t)op->auth.digest.length);
-	} else if (session->op == AESNI_GCM_OP_AUTHENTICATED_DECRYPTION) {
-		uint8_t *auth_tag = (uint8_t *)rte_pktmbuf_append(m,
+	} else { /* session->op == AESNI_GCM_OP_AUTHENTICATED_DECRYPTION */
+		uint8_t *auth_tag = (uint8_t *)rte_pktmbuf_append(op->m_dst ?
+				op->m_dst : op->m_src,
 				op->auth.digest.length);
 
 		if (!auth_tag) {
-			GCM_LOG_ERR("iv");
+			GCM_LOG_ERR("auth_tag");
 			return -1;
 		}
 
-		(*qp->ops->gcm.dec)(&session->gdata, dst, src,
-				(uint64_t)op->cipher.data.length,
+		aesni_gcm_dec[session->key].init(&session->gdata,
 				op->cipher.iv.data,
 				op->auth.aad.data,
-				(uint64_t)op->auth.aad.length,
+				(uint64_t)op->auth.aad.length);
+
+		aesni_gcm_dec[session->key].update(&session->gdata, dst, src,
+				(uint64_t)part_len);
+		total_len = op->cipher.data.length - part_len;
+
+		while (total_len) {
+			dst += part_len;
+			m_src = m_src->next;
+
+			RTE_ASSERT(m_src != NULL);
+
+			src = rte_pktmbuf_mtod(m_src, uint8_t *);
+			part_len = (m_src->data_len < total_len) ?
+					m_src->data_len : total_len;
+
+			aesni_gcm_dec[session->key].update(&session->gdata,
+					dst, src,
+					(uint64_t)part_len);
+			total_len -= part_len;
+		}
+
+		aesni_gcm_dec[session->key].finalize(&session->gdata,
 				auth_tag,
 				(uint64_t)op->auth.digest.length);
-	} else {
-		GCM_LOG_ERR("iv");
-		return -1;
 	}
 
 	return 0;
@@ -377,21 +418,7 @@ 
 			break;
 		}
 
-#ifdef RTE_LIBRTE_PMD_AESNI_GCM_DEBUG
-		if (!rte_pktmbuf_is_contiguous(ops[i]->sym->m_src) ||
-				(ops[i]->sym->m_dst != NULL &&
-				!rte_pktmbuf_is_contiguous(
-						ops[i]->sym->m_dst))) {
-			ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
-			GCM_LOG_ERR("PMD supports only contiguous mbufs, "
-				"op (%p) provides noncontiguous mbuf as "
-				"source/destination buffer.\n", ops[i]);
-			qp->qp_stats.enqueue_err_count++;
-			break;
-		}
-#endif
-
-		retval = process_gcm_crypto_op(qp, ops[i]->sym, sess);
+		retval = process_gcm_crypto_op(ops[i]->sym, sess);
 		if (retval < 0) {
 			ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
 			qp->qp_stats.enqueue_err_count++;
@@ -429,7 +456,6 @@ 
 	struct rte_cryptodev *dev;
 	char crypto_dev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
 	struct aesni_gcm_private *internals;
-	enum aesni_gcm_vector_mode vector_mode;
 
 	/* Check CPU for support for AES instruction set */
 	if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_AES)) {
@@ -437,18 +463,6 @@ 
 		return -EFAULT;
 	}
 
-	/* Check CPU for supported vector instruction set */
-	if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2))
-		vector_mode = RTE_AESNI_GCM_AVX2;
-	else if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX))
-		vector_mode = RTE_AESNI_GCM_AVX;
-	else if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_SSE4_1))
-		vector_mode = RTE_AESNI_GCM_SSE;
-	else {
-		GCM_LOG_ERR("Vector instructions are not supported by CPU");
-		return -EFAULT;
-	}
-
 	/* create a unique device name */
 	if (create_unique_device_name(crypto_dev_name,
 			RTE_CRYPTODEV_NAME_MAX_LEN) != 0) {
@@ -473,27 +487,11 @@ 
 
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
-			RTE_CRYPTODEV_FF_CPU_AESNI;
+			RTE_CRYPTODEV_FF_CPU_AESNI |
+			RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
 
-	switch (vector_mode) {
-	case RTE_AESNI_GCM_SSE:
-		dev->feature_flags |= RTE_CRYPTODEV_FF_CPU_SSE;
-		break;
-	case RTE_AESNI_GCM_AVX:
-		dev->feature_flags |= RTE_CRYPTODEV_FF_CPU_AVX;
-		break;
-	case RTE_AESNI_GCM_AVX2:
-		dev->feature_flags |= RTE_CRYPTODEV_FF_CPU_AVX2;
-		break;
-	default:
-		break;
-	}
-
-	/* Set vector instructions mode supported */
 	internals = dev->data->dev_private;
 
-	internals->vector_mode = vector_mode;
-
 	internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;
 	internals->max_nb_sessions = init_params->max_nb_sessions;
 
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
index c51f82a..2362006 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
@@ -39,17 +39,17 @@ 
 #include "aesni_gcm_pmd_private.h"
 
 static const struct rte_cryptodev_capabilities aesni_gcm_pmd_capabilities[] = {
-	{	/* AES GCM (AUTH) */
+	{	/* AES GMAC (AUTH) */
 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
 		{.sym = {
 			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
 			{.auth = {
-				.algo = RTE_CRYPTO_AUTH_AES_GCM,
+				.algo = RTE_CRYPTO_AUTH_AES_GMAC,
 				.block_size = 16,
 				.key_size = {
 					.min = 16,
-					.max = 16,
-					.increment = 0
+					.max = 32,
+					.increment = 16
 				},
 				.digest_size = {
 					.min = 8,
@@ -57,9 +57,34 @@ 
 					.increment = 4
 				},
 				.aad_size = {
+					.min = 0,
+					.max = 65535,
+					.increment = 1
+				}
+			}, }
+		}, }
+	},
+	{	/* AES GCM (AUTH) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_AES_GCM,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 32,
+					.increment = 16
+				},
+				.digest_size = {
 					.min = 8,
-					.max = 12,
+					.max = 16,
 					.increment = 4
+				},
+				.aad_size = {
+					.min = 0,
+					.max = 65535,
+					.increment = 1
 				}
 			}, }
 		}, }
@@ -73,8 +98,8 @@ 
 				.block_size = 16,
 				.key_size = {
 					.min = 16,
-					.max = 16,
-					.increment = 0
+					.max = 32,
+					.increment = 16
 				},
 				.iv_size = {
 					.min = 12,
@@ -221,7 +246,6 @@ 
 		 int socket_id)
 {
 	struct aesni_gcm_qp *qp = NULL;
-	struct aesni_gcm_private *internals = dev->data->dev_private;
 
 	/* Free memory prior to re-allocation if needed. */
 	if (dev->data->queue_pairs[qp_id] != NULL)
@@ -239,8 +263,6 @@ 
 	if (aesni_gcm_pmd_qp_set_unique_name(dev, qp))
 		goto qp_setup_cleanup;
 
-	qp->ops = &gcm_ops[internals->vector_mode];
-
 	qp->processed_pkts = aesni_gcm_pmd_qp_create_processed_pkts_ring(qp,
 			qp_conf->nb_descriptors, socket_id);
 	if (qp->processed_pkts == NULL)
@@ -291,18 +313,15 @@ 
 
 /** Configure a aesni gcm session from a crypto xform chain */
 static void *
-aesni_gcm_pmd_session_configure(struct rte_cryptodev *dev,
+aesni_gcm_pmd_session_configure(struct rte_cryptodev *dev __rte_unused,
 		struct rte_crypto_sym_xform *xform,	void *sess)
 {
-	struct aesni_gcm_private *internals = dev->data->dev_private;
-
 	if (unlikely(sess == NULL)) {
 		GCM_LOG_ERR("invalid session struct");
 		return NULL;
 	}
 
-	if (aesni_gcm_set_session_parameters(&gcm_ops[internals->vector_mode],
-			sess, xform) != 0) {
+	if (aesni_gcm_set_session_parameters(sess, xform) != 0) {
 		GCM_LOG_ERR("failed configure session parameters");
 		return NULL;
 	}
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
index 9878d6e..0496b44 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
@@ -58,8 +58,6 @@ 
 
 /** private data structure for each virtual AESNI GCM device */
 struct aesni_gcm_private {
-	enum aesni_gcm_vector_mode vector_mode;
-	/**< Vector mode */
 	unsigned max_nb_queue_pairs;
 	/**< Max number of queue pairs supported by device */
 	unsigned max_nb_sessions;
@@ -71,8 +69,6 @@  struct aesni_gcm_qp {
 	/**< Queue Pair Identifier */
 	char name[RTE_CRYPTODEV_NAME_LEN];
 	/**< Unique Queue Pair Name */
-	const struct aesni_gcm_ops *ops;
-	/**< Architecture dependent function pointer table of the gcm APIs */
 	struct rte_ring *processed_pkts;
 	/**< Ring for placing process packets */
 	struct rte_mempool *sess_mp;
@@ -87,10 +83,17 @@  enum aesni_gcm_operation {
 	AESNI_GCM_OP_AUTHENTICATED_DECRYPTION
 };
 
+enum aesni_gcm_key {
+	AESNI_GCM_KEY_128,
+	AESNI_GCM_KEY_256
+};
+
 /** AESNI GCM private session structure */
 struct aesni_gcm_session {
 	enum aesni_gcm_operation op;
 	/**< GCM operation type */
+	enum aesni_gcm_key key;
+	/**< GCM key type */
 	struct gcm_data gdata __rte_cache_aligned;
 	/**< GCM parameters */
 };
@@ -98,7 +101,6 @@  struct aesni_gcm_session {
 
 /**
  * Setup GCM session parameters
- * @param	ops	gcm ops function pointer table
  * @param	sess	aesni gcm session structure
  * @param	xform	crypto transform chain
  *
@@ -107,8 +109,7 @@  struct aesni_gcm_session {
  * - On failure returns error code < 0
  */
 extern int
-aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *ops,
-		struct aesni_gcm_session *sess,
+aesni_gcm_set_session_parameters(struct aesni_gcm_session *sess,
 		const struct rte_crypto_sym_xform *xform);
 
 
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index f75f0e2..ed3eab5 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -134,8 +134,7 @@  _LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD)    += -lrte_pmd_vmxnet3_uio
 ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)    += -lrte_pmd_aesni_mb
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)    += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM)   += -lrte_pmd_aesni_gcm -lcrypto
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM)   += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM)   += -lrte_pmd_aesni_gcm -lisal_crypto
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OPENSSL)     += -lrte_pmd_openssl -lcrypto
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += -lrte_pmd_null_crypto
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT)         += -lrte_pmd_qat -lcrypto