diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
index 35a83ce0f..b7065e73c 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -36,9 +36,7 @@
  * Keep sorted: first by key length, then by IV length
  */
 static const odp_crypto_cipher_capability_t cipher_capa_null[] = {
-{.key_len = 0, .iv_len = 0},
-/* Special case for GMAC */
-{.key_len = 0, .iv_len = 12} };
+{.key_len = 0, .iv_len = 0} };
 
 static const odp_crypto_cipher_capability_t cipher_capa_trides_cbc[] = {
 {.key_len = 24, .iv_len = 8} };
@@ -86,7 +84,8 @@ static const odp_crypto_auth_capability_t auth_capa_aes_gcm[] = {
 {.digest_len = 16, .key_len = 0, .aad_len = {.min = 8, .max = 12, .inc = 4} } };
 
 static const odp_crypto_auth_capability_t auth_capa_aes_gmac[] = {
-{.digest_len = 16, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} } };
+{.digest_len = 16, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0},
+	.iv_len = 12 } };
 
 /** Forward declaration of session structure */
 typedef struct odp_crypto_generic_session_t odp_crypto_generic_session_t;
@@ -121,6 +120,7 @@ struct odp_crypto_generic_session_t {
 
 	struct {
 		uint8_t  key[EVP_MAX_KEY_LENGTH];
+		uint8_t  iv_data[EVP_MAX_IV_LENGTH];
 		uint32_t key_length;
 		uint32_t bytes;
 		union {
@@ -641,10 +641,10 @@ odp_crypto_alg_err_t aes_gmac_gen(odp_packet_t pkt,
 	uint8_t block[EVP_MAX_MD_SIZE];
 	int ret;
 
-	if (param->cipher_iv_ptr)
-		iv_ptr = param->cipher_iv_ptr;
-	else if (session->p.cipher_iv.data)
-		iv_ptr = session->cipher.iv_data;
+	if (param->auth_iv_ptr)
+		iv_ptr = param->auth_iv_ptr;
+	else if (session->p.auth_iv.data)
+		iv_ptr = session->auth.iv_data;
 	else
 		return ODP_CRYPTO_ALG_ERR_IV_INVALID;
 
@@ -680,10 +680,10 @@ odp_crypto_alg_err_t aes_gmac_check(odp_packet_t pkt,
 	uint8_t block[EVP_MAX_MD_SIZE];
 	int ret;
 
-	if (param->cipher_iv_ptr)
-		iv_ptr = param->cipher_iv_ptr;
-	else if (session->p.cipher_iv.data)
-		iv_ptr = session->cipher.iv_data;
+	if (param->auth_iv_ptr)
+		iv_ptr = param->auth_iv_ptr;
+	else if (session->p.auth_iv.data)
+		iv_ptr = session->auth.iv_data;
 	else
 		return ODP_CRYPTO_ALG_ERR_IV_INVALID;
 
@@ -909,11 +909,21 @@ odp_crypto_session_create(odp_crypto_session_param_t *param,
 		goto err;
 	}
 
+	if (session->p.auth_iv.length > EVP_MAX_IV_LENGTH) {
+		ODP_DBG("Maximum auth IV length exceeded\n");
+		*status = ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER;
+		goto err;
+	}
+
 	/* Copy IV data */
 	if (session->p.cipher_iv.data)
 		memcpy(session->cipher.iv_data, session->p.cipher_iv.data,
 		       session->p.cipher_iv.length);
 
+	if (session->p.auth_iv.data)
+		memcpy(session->auth.iv_data, session->p.auth_iv.data,
+		       session->p.auth_iv.length);
+
 	/* Derive order */
 	if (ODP_CRYPTO_OP_ENCODE == param->op)
 		session->do_cipher_first =  param->auth_cipher_text;
@@ -1102,6 +1112,7 @@ odp_crypto_operation(odp_crypto_op_param_t *param,
 
 	packet_param.session = param->session;
 	packet_param.cipher_iv_ptr = param->cipher_iv_ptr;
+	packet_param.auth_iv_ptr = param->auth_iv_ptr;
 	packet_param.hash_result_offset = param->hash_result_offset;
 	packet_param.aad_ptr = param->aad_ptr;
 	packet_param.cipher_range = param->cipher_range;
diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c
index ab4fb5543..e19907a5f 100644
--- a/platform/linux-generic/odp_ipsec.c
+++ b/platform/linux-generic/odp_ipsec.c
@@ -478,6 +478,7 @@ static int ipsec_in_esp(odp_packet_t *pkt,
 				    state->in.hdr_len -
 				    ipsec_sa->icv_len;
 	param->cipher_iv_ptr = state->iv;
+	param->auth_iv_ptr = state->iv;
 
 	state->esp.aad.spi = esp.spi;
 	state->esp.aad.seq_no = esp.seq_no;
@@ -560,7 +561,7 @@ static int ipsec_in_ah(odp_packet_t *pkt,
 		return -1;
 	}
 
-	param->cipher_iv_ptr = state->iv;
+	param->auth_iv_ptr = state->iv;
 
 	state->in.hdr_len = (ah.ah_len + 2) * 4;
 	state->in.trl_len = 0;
@@ -1080,6 +1081,7 @@ static int ipsec_out_esp(odp_packet_t *pkt,
 	}
 
 	param->cipher_iv_ptr = state->iv;
+	param->auth_iv_ptr = state->iv;
 
 	memset(&esp, 0, sizeof(esp));
 	esp.spi = odp_cpu_to_be_32(ipsec_sa->spi);
@@ -1229,7 +1231,7 @@ static int ipsec_out_ah(odp_packet_t *pkt,
 		return -1;
 	}
 
-	param->cipher_iv_ptr = state->iv;
+	param->auth_iv_ptr = state->iv;
 
 	if (odp_packet_extend_head(pkt, hdr_len, NULL, NULL) < 0) {
 		status->error.alg = 1;
diff --git a/platform/linux-generic/odp_ipsec_sad.c b/platform/linux-generic/odp_ipsec_sad.c
index 11227a5fc..38cf77557 100644
--- a/platform/linux-generic/odp_ipsec_sad.c
+++ b/platform/linux-generic/odp_ipsec_sad.c
@@ -409,7 +409,7 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param)
 		ipsec_sa->use_counter_iv = 1;
 		ipsec_sa->esp_iv_len = 8;
 		ipsec_sa->esp_block_len = 16;
-		crypto_param.cipher_iv.length = 12;
+		crypto_param.auth_iv.length = 12;
 		break;
 	default:
 		break;
