diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h
index 6a4304d8b..2109509ff 100644
--- a/include/odp/api/spec/crypto.h
+++ b/include/odp/api/spec/crypto.h
@@ -333,6 +333,14 @@ typedef struct odp_crypto_session_param_t {
 	 */
 	uint32_t auth_digest_len;
 
+	/** Additional Authenticated Data (AAD) length in bytes
+	 *
+	 *  AAD length is constant for all operations (packets) of the session.
+	 *  Set to zero when AAD is not used. Use odp_crypto_auth_capability()
+	 *  for supported AAD lengths. The default value is zero.
+	 */
+	uint32_t auth_aad_len;
+
 	/** Async mode completion event queue
 	 *
 	 *  The completion queue is used to return completions from
@@ -401,12 +409,11 @@ typedef struct odp_crypto_op_param_t {
 
 	/** Additional Authenticated Data (AAD) */
 	struct {
-		/** Pointer to ADD */
+		/** Pointer to AAD. AAD length is defined by 'auth_aad_len'
+		 *  session parameter.
+		 */
 		uint8_t *ptr;
 
-		/** AAD length in bytes. Use odp_crypto_auth_capability() for
-		 *  supported AAD lengths. */
-		uint32_t length;
 	} aad;
 
 	/** Data range to apply cipher */
@@ -442,12 +449,11 @@ typedef struct odp_crypto_packet_op_param_t {
 
 	/** Additional Authenticated Data (AAD) */
 	struct {
-		/** Pointer to ADD */
+		/** Pointer to AAD. AAD length is defined by 'auth_aad_len'
+		 *  session parameter.
+		 */
 		uint8_t *ptr;
 
-		/** AAD length in bytes. Use odp_crypto_auth_capability() for
-		 *  supported AAD lengths. */
-		uint32_t length;
 	} aad;
 
 	/** Data range to apply cipher */
diff --git a/platform/linux-generic/include/odp_ipsec_internal.h b/platform/linux-generic/include/odp_ipsec_internal.h
index b50b65be6..06447870b 100644
--- a/platform/linux-generic/include/odp_ipsec_internal.h
+++ b/platform/linux-generic/include/odp_ipsec_internal.h
@@ -177,6 +177,12 @@ typedef struct odp_ipsec_sa_lookup_s {
 	void    *dst_addr;
 } ipsec_sa_lookup_t;
 
+/** IPSEC AAD */
+typedef struct ODP_PACKED {
+	odp_u32be_t spi;     /**< Security Parameter Index */
+	odp_u32be_t seq_no;  /**< Sequence Number */
+} ipsec_aad_t;
+
 /**
  * Obtain SA reference
  */
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
index 67dd3249d..b5f538dd7 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -479,7 +479,7 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_packet_t pkt,
 {
 	EVP_CIPHER_CTX *ctx;
 	const uint8_t *aad_head = param->aad.ptr;
-	uint32_t aad_len = param->aad.length;
+	uint32_t aad_len = session->p.auth_aad_len;
 	void *iv_ptr;
 	int dummy_len = 0;
 	uint8_t block[EVP_MAX_MD_SIZE];
@@ -526,7 +526,7 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_packet_t pkt,
 {
 	EVP_CIPHER_CTX *ctx;
 	const uint8_t *aad_head = param->aad.ptr;
-	uint32_t aad_len = param->aad.length;
+	uint32_t aad_len = session->p.auth_aad_len;
 	int dummy_len = 0;
 	void *iv_ptr;
 	uint8_t block[EVP_MAX_MD_SIZE];
@@ -1058,7 +1058,6 @@ odp_crypto_operation(odp_crypto_op_param_t *param,
 	packet_param.override_iv_ptr = param->override_iv_ptr;
 	packet_param.hash_result_offset = param->hash_result_offset;
 	packet_param.aad.ptr = param->aad.ptr;
-	packet_param.aad.length = param->aad.length;
 	packet_param.cipher_range = param->cipher_range;
 	packet_param.auth_range = param->auth_range;
 
diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c
index 0ebc65341..aaa566ca8 100644
--- a/platform/linux-generic/odp_ipsec.c
+++ b/platform/linux-generic/odp_ipsec.c
@@ -20,11 +20,6 @@
 
 #include <string.h>
 
-typedef struct ODP_PACKED {
-	odp_u32be_t spi;     /**< Security Parameter Index */
-	odp_u32be_t seq_no;  /**< Sequence Number */
-} ipsec_aad_t;
-
 int odp_ipsec_capability(odp_ipsec_capability_t *capa)
 {
 	int rc;
@@ -358,7 +353,6 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
 		aad.seq_no = esp.seq_no;
 
 		param.aad.ptr = (uint8_t *)&aad;
-		param.aad.length = sizeof(aad);
 
 		param.auth_range.offset = ipsec_offset;
 		param.auth_range.length = odp_be_to_cpu_16(ip->tot_len) -
@@ -431,7 +425,6 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
 		aad.seq_no = ah.seq_no;
 
 		param.aad.ptr = (uint8_t *)&aad;
-		param.aad.length = sizeof(aad);
 
 		param.auth_range.offset = ip_offset;
 		param.auth_range.length = odp_be_to_cpu_16(ip->tot_len);
@@ -798,7 +791,6 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
 		aad.seq_no = esp.seq_no;
 
 		param.aad.ptr = (uint8_t *)&aad;
-		param.aad.length = sizeof(aad);
 
 		memset(&esptrl, 0, sizeof(esptrl));
 		esptrl.pad_len = encrypt_len - ip_data_len - _ODP_ESPTRL_LEN;
@@ -874,7 +866,6 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
 		aad.seq_no = ah.seq_no;
 
 		param.aad.ptr = (uint8_t *)&aad;
-		param.aad.length = sizeof(aad);
 
 		/* For GMAC */
 		if (ipsec_sa->use_counter_iv) {
diff --git a/platform/linux-generic/odp_ipsec_sad.c b/platform/linux-generic/odp_ipsec_sad.c
index f1fde5e69..0287d6f73 100644
--- a/platform/linux-generic/odp_ipsec_sad.c
+++ b/platform/linux-generic/odp_ipsec_sad.c
@@ -195,6 +195,7 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param)
 	ipsec_sa_t *ipsec_sa;
 	odp_crypto_session_param_t crypto_param;
 	odp_crypto_ses_create_err_t ses_create_rc;
+	uint32_t aad_len = 0;
 
 	ipsec_sa = ipsec_sa_reserve();
 	if (NULL == ipsec_sa) {
@@ -334,6 +335,7 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param)
 #endif
 	case ODP_AUTH_ALG_AES_GCM:
 		ipsec_sa->icv_len = 16;
+		aad_len = sizeof(ipsec_aad_t);
 		break;
 	case ODP_AUTH_ALG_AES_GMAC:
 		if (ODP_CIPHER_ALG_NULL != crypto_param.cipher_alg)
@@ -353,6 +355,7 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param)
 		odp_atomic_init_u64(&ipsec_sa->out.counter, 1);
 
 	crypto_param.auth_digest_len = ipsec_sa->icv_len;
+	crypto_param.auth_aad_len    = aad_len;
 
 	if (param->crypto.cipher_key_extra.length) {
 		if (param->crypto.cipher_key_extra.length >
diff --git a/test/validation/api/crypto/odp_crypto_test_inp.c b/test/validation/api/crypto/odp_crypto_test_inp.c
index 87f0ed930..cba472ded 100644
--- a/test/validation/api/crypto/odp_crypto_test_inp.c
+++ b/test/validation/api/crypto/odp_crypto_test_inp.c
@@ -82,7 +82,6 @@ static int alg_op(odp_packet_t pkt,
 		  odp_packet_data_range_t *cipher_range,
 		  odp_packet_data_range_t *auth_range,
 		  uint8_t *aad,
-		  uint32_t aad_len,
 		  unsigned int plaintext_len)
 {
 	int rc;
@@ -104,7 +103,6 @@ static int alg_op(odp_packet_t pkt,
 		op_params.override_iv_ptr = op_iv_ptr;
 
 	op_params.aad.ptr = aad;
-	op_params.aad.length = aad_len;
 
 	op_params.hash_result_offset = plaintext_len;
 
@@ -159,7 +157,6 @@ static int alg_packet_op(odp_packet_t pkt,
 			 odp_packet_data_range_t *cipher_range,
 			 odp_packet_data_range_t *auth_range,
 			 uint8_t *aad,
-			 uint32_t aad_len,
 			 unsigned int plaintext_len)
 {
 	int rc;
@@ -178,7 +175,6 @@ static int alg_packet_op(odp_packet_t pkt,
 		op_params.override_iv_ptr = op_iv_ptr;
 
 	op_params.aad.ptr = aad;
-	op_params.aad.length = aad_len;
 
 	op_params.hash_result_offset = plaintext_len;
 
@@ -218,7 +214,6 @@ static int alg_packet_op_enq(odp_packet_t pkt,
 			     odp_packet_data_range_t *cipher_range,
 			     odp_packet_data_range_t *auth_range,
 			     uint8_t *aad,
-			     uint32_t aad_len,
 			     unsigned int plaintext_len)
 {
 	int rc;
@@ -238,7 +233,6 @@ static int alg_packet_op_enq(odp_packet_t pkt,
 		op_params.override_iv_ptr = op_iv_ptr;
 
 	op_params.aad.ptr = aad;
-	op_params.aad.length = aad_len;
 
 	op_params.hash_result_offset = plaintext_len;
 
@@ -440,6 +434,7 @@ static void alg_test(odp_crypto_op_t op,
 	ses_params.iv = iv;
 	ses_params.auth_key = auth_key;
 	ses_params.auth_digest_len = ref->digest_length;
+	ses_params.auth_aad_len = ref->aad_length;
 
 	rc = odp_crypto_session_create(&ses_params, &session, &status);
 	CU_ASSERT_FATAL(!rc);
@@ -476,20 +471,17 @@ static void alg_test(odp_crypto_op_t op,
 		rc = alg_op(pkt, &ok, session,
 			    ovr_iv ? ref->iv : NULL,
 			    &cipher_range, &auth_range,
-			    ref->aad, ref->aad_length,
-			    ref->length);
+			    ref->aad, ref->length);
 	else if (ODP_CRYPTO_ASYNC == suite_context.op_mode)
 		rc = alg_packet_op_enq(pkt, &ok, session,
 				       ovr_iv ? ref->iv : NULL,
 				       &cipher_range, &auth_range,
-				       ref->aad, ref->aad_length,
-				       ref->length);
+				       ref->aad, ref->length);
 	else
 		rc = alg_packet_op(pkt, &ok, session,
 				   ovr_iv ? ref->iv : NULL,
 				   &cipher_range, &auth_range,
-				   ref->aad, ref->aad_length,
-				   ref->length);
+				   ref->aad, ref->length);
 	if (rc < 0) {
 		goto cleanup;
 	}
