diff mbox series

[API-NEXT,v3,10/10] test: validation: add IPsec API testsuite

Message ID 1494540010-25779-11-git-send-email-odpbot@yandex.ru
State Superseded
Headers show
Series [API-NEXT,v3,1/10] api: ipsec: add soft limit expiration event | expand

Commit Message

Github ODP bot May 11, 2017, 10 p.m. UTC
From: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>


Add several basic tests for IPsec API.

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>

---
/** Email created from pull request 28 (lumag:ipsec)
 ** https://github.com/Linaro/odp/pull/28
 ** Patch: https://github.com/Linaro/odp/pull/28.patch
 ** Base sha: 900dd9e2d3d2ae751ab2bc4e11dbd48ea7ed7030
 ** Merge commit sha: 1589f97414ab144b3cb1e65667d311783fdba670
 **/
 test/common_plat/validation/api/ipsec/Makefile.am  |   5 +-
 test/common_plat/validation/api/ipsec/ipsec.c      | 534 ++++++++++++++++++++-
 test/common_plat/validation/api/ipsec/ipsec.h      |  54 ++-
 .../validation/api/ipsec/ipsec_test_in.c           | 444 +++++++++++++++++
 .../validation/api/ipsec/ipsec_test_out.c          | 154 ++++++
 .../validation/api/ipsec/test_vectors.h            | 414 ++++++++++++++++
 6 files changed, 1596 insertions(+), 9 deletions(-)
 create mode 100644 test/common_plat/validation/api/ipsec/ipsec_test_in.c
 create mode 100644 test/common_plat/validation/api/ipsec/ipsec_test_out.c
 create mode 100644 test/common_plat/validation/api/ipsec/test_vectors.h
diff mbox series

Patch

diff --git a/test/common_plat/validation/api/ipsec/Makefile.am b/test/common_plat/validation/api/ipsec/Makefile.am
index 106b8dc..0432222 100644
--- a/test/common_plat/validation/api/ipsec/Makefile.am
+++ b/test/common_plat/validation/api/ipsec/Makefile.am
@@ -1,7 +1,10 @@ 
 include ../Makefile.inc
 
 noinst_LTLIBRARIES = libtestipsec.la
-libtestipsec_la_SOURCES = ipsec.c
+libtestipsec_la_SOURCES = \
+	ipsec_test_in.c \
+	ipsec_test_out.c \
+	ipsec.c
 
 test_PROGRAMS = ipsec_main$(EXEEXT)
 dist_ipsec_main_SOURCES = ipsec_main.c
diff --git a/test/common_plat/validation/api/ipsec/ipsec.c b/test/common_plat/validation/api/ipsec/ipsec.c
index 7834803..3cea814 100644
--- a/test/common_plat/validation/api/ipsec/ipsec.c
+++ b/test/common_plat/validation/api/ipsec/ipsec.c
@@ -10,6 +10,383 @@ 
 
 #include "ipsec.h"
 
+#include "test_vectors.h"
+
+struct suite_context_s suite_context;
+
+#define PKT_POOL_NUM  64
+#define PKT_POOL_LEN  (1 * 1024)
+
+int ipsec_check(odp_bool_t in, odp_bool_t ah, odp_cipher_alg_t cipher, odp_auth_alg_t auth)
+{
+	odp_ipsec_capability_t capa;
+
+	if (odp_ipsec_capability(&capa) < 0)
+		return ODP_TEST_INACTIVE;
+
+	if ((ODP_IPSEC_OP_MODE_SYNC == suite_context.pref_mode &&
+	     ODP_SUPPORT_NO == capa.op_mode_sync) ||
+	    (ODP_IPSEC_OP_MODE_ASYNC == suite_context.pref_mode &&
+	     ODP_SUPPORT_NO == capa.op_mode_async) ||
+	    (ODP_IPSEC_OP_MODE_INLINE == suite_context.pref_mode &&
+	     ODP_SUPPORT_NO == capa.op_mode_inline_in && in) ||
+	    (ODP_IPSEC_OP_MODE_INLINE == suite_context.pref_mode &&
+	     ODP_SUPPORT_NO == capa.op_mode_inline_out && !in))
+		return ODP_TEST_INACTIVE;
+
+	if (ah && (ODP_SUPPORT_NO == capa.proto_ah))
+		return ODP_TEST_INACTIVE;
+
+	/* Cipher algorithms */
+	switch (cipher) {
+	case ODP_CIPHER_ALG_NULL:
+		if (!capa.ciphers.bit.null)
+			return ODP_TEST_INACTIVE;
+		break;
+	case ODP_CIPHER_ALG_DES:
+		if (!capa.ciphers.bit.des)
+			return ODP_TEST_INACTIVE;
+		break;
+	case ODP_CIPHER_ALG_3DES_CBC:
+		if (!capa.ciphers.bit.trides_cbc)
+			return ODP_TEST_INACTIVE;
+		break;
+	case ODP_CIPHER_ALG_AES_CBC:
+		if (!capa.ciphers.bit.aes_cbc)
+			return ODP_TEST_INACTIVE;
+		break;
+	case ODP_CIPHER_ALG_AES_GCM:
+		if (!capa.ciphers.bit.aes_gcm)
+			return ODP_TEST_INACTIVE;
+		break;
+	default:
+		fprintf(stderr, "Unsupported cipher algorithm\n");
+		return ODP_TEST_INACTIVE;
+	}
+
+	/* Authentication algorithms */
+	switch (auth) {
+	case ODP_AUTH_ALG_NULL:
+		if (!capa.auths.bit.null)
+			return ODP_TEST_INACTIVE;
+		break;
+	case ODP_AUTH_ALG_MD5_HMAC:
+		if (!capa.auths.bit.md5_hmac)
+			return ODP_TEST_INACTIVE;
+		break;
+	case ODP_AUTH_ALG_SHA1_HMAC:
+		if (!capa.auths.bit.sha1_hmac)
+			return ODP_TEST_INACTIVE;
+		break;
+	case ODP_AUTH_ALG_SHA256_HMAC:
+		if (!capa.auths.bit.sha256_hmac)
+			return ODP_TEST_INACTIVE;
+		break;
+	case ODP_AUTH_ALG_SHA512_HMAC:
+		if (!capa.auths.bit.sha512_hmac)
+			return ODP_TEST_INACTIVE;
+		break;
+	case ODP_AUTH_ALG_AES_GCM:
+		if (!capa.auths.bit.aes_gcm)
+			return ODP_TEST_INACTIVE;
+		break;
+	default:
+		fprintf(stderr, "Unsupported authentication algorithm\n");
+		return ODP_TEST_INACTIVE;
+	}
+
+	return ODP_TEST_ACTIVE;
+}
+
+void ipsec_sa_param_fill(odp_ipsec_sa_param_t *param,
+			 odp_bool_t in,
+			 odp_bool_t ah,
+			 uint32_t spi,
+			 odp_cipher_alg_t cipher_alg,
+			 const odp_crypto_key_t *cipher_key,
+			 odp_auth_alg_t auth_alg,
+			 const odp_crypto_key_t *auth_key)
+{
+	odp_ipsec_sa_param_init(param);
+	param->dir = in ? ODP_IPSEC_DIR_INBOUND : ODP_IPSEC_DIR_OUTBOUND;
+	param->lookup_mode = in ? ODP_IPSEC_LOOKUP_SPI : ODP_IPSEC_LOOKUP_DISABLED;
+	param->proto = ah ? ODP_IPSEC_AH : ODP_IPSEC_ESP;
+
+	param->mode = /*tun ? ODP_IPSEC_MODE_TUNNEL : */ODP_IPSEC_MODE_TRANSPORT;
+	param->spi = spi;
+	param->seq = 0;
+
+	param->dest_queue = suite_context.queue;
+
+	if (cipher_key) {
+		param->crypto.cipher_alg = cipher_alg;
+		param->crypto.cipher_key = *cipher_key;
+	}
+
+	if (auth_key) {
+		param->crypto.auth_alg = auth_alg;
+		param->crypto.auth_key = *auth_key;
+	}
+}
+
+void ipsec_sa_destroy(odp_ipsec_sa_t sa)
+{
+	odp_event_t event;
+	odp_ipsec_status_t status;
+
+	CU_ASSERT_EQUAL(ODP_IPSEC_OK, odp_ipsec_sa_disable(sa));
+
+	if (ODP_QUEUE_INVALID != suite_context.queue) {
+		do {
+			event = odp_queue_deq(suite_context.queue);
+		} while (event == ODP_EVENT_INVALID);
+
+		CU_ASSERT_EQUAL(ODP_EVENT_IPSEC_STATUS, odp_event_type(event));
+
+		CU_ASSERT_EQUAL(ODP_IPSEC_OK, odp_ipsec_status(&status, event));
+
+		CU_ASSERT_EQUAL(ODP_IPSEC_STATUS_SA_DISABLE, status.id);
+		CU_ASSERT_EQUAL(0, status.ret);
+		CU_ASSERT_EQUAL(sa, status.sa);
+
+		odp_event_free(event);
+	}
+
+	CU_ASSERT_EQUAL(ODP_IPSEC_OK, odp_ipsec_sa_destroy(sa));
+}
+
+#define PACKET_USER_PTR	((void *)0x1212fefe)
+
+odp_packet_t ipsec_packet(const ipsec_test_packet *itp)
+{
+	odp_packet_t pkt = odp_packet_alloc(suite_context.pool, itp->len);
+
+	CU_ASSERT_NOT_EQUAL(ODP_PACKET_INVALID, pkt);
+	if (ODP_PACKET_INVALID == pkt)
+		return pkt;
+
+	CU_ASSERT_EQUAL(0, odp_packet_copy_from_mem(pkt, 0, itp->len, itp->data));
+	if (itp->l2_offset != ODP_PACKET_OFFSET_INVALID)
+		CU_ASSERT_EQUAL(0, odp_packet_l2_offset_set(pkt, itp->l2_offset));
+	if (itp->l3_offset != ODP_PACKET_OFFSET_INVALID)
+		CU_ASSERT_EQUAL(0, odp_packet_l3_offset_set(pkt, itp->l3_offset));
+	if (itp->l4_offset != ODP_PACKET_OFFSET_INVALID)
+		CU_ASSERT_EQUAL(0, odp_packet_l4_offset_set(pkt, itp->l4_offset));
+
+	odp_packet_user_ptr_set(pkt, PACKET_USER_PTR);
+
+	return pkt;
+}
+
+/*
+ * Compare packages ignoring everything before L3 header
+ */
+odp_bool_t ipsec_check_packet(const ipsec_test_packet *itp, odp_packet_t pkt)
+{
+	uint32_t len = (ODP_PACKET_INVALID == pkt) ? 1 : odp_packet_len(pkt);
+	uint32_t l3, l4;
+	uint8_t data[len];
+
+	if (!itp)
+		return true;
+
+	if (ODP_PACKET_INVALID == pkt)
+		return false;
+
+	CU_ASSERT_EQUAL(PACKET_USER_PTR, odp_packet_user_ptr(pkt));
+
+	l3 = odp_packet_l3_offset(pkt);
+	l4 = odp_packet_l4_offset(pkt);
+	odp_packet_copy_to_mem(pkt, 0, len, data);
+
+	if (len - l3 != itp->len - itp->l3_offset)
+		return false;
+
+	if (l4 - l3 != itp->l4_offset - itp->l3_offset)
+		return false;
+
+	return memcmp(data + l3, itp->data + itp->l3_offset, len - l3) ? false : true;
+}
+
+void ipsec_check_in_one(const ipsec_test_part *part, odp_ipsec_sa_t sa, odp_bool_t lookup)
+{
+	odp_ipsec_op_param_t op_param;
+	odp_ipsec_op_result_t op_result;
+	odp_packet_t pkt;
+	odp_packet_t pkto[part->out_pkt];
+	odp_ipsec_packet_result_t result[part->out_pkt];
+	int i;
+
+	pkt = ipsec_packet(part->pkt_in);
+
+	memset(&op_param, 0, sizeof(op_param));
+	op_param.num_pkt = 1;
+	op_param.pkt = &pkt;
+	if (lookup) {
+		op_param.num_sa = 1;
+		op_param.sa = &sa;
+	} else {
+		op_param.num_sa = 0;
+		op_param.sa = NULL;
+	}
+	op_param.num_opt = 0;
+	op_param.opt = NULL;
+
+	op_result.num_pkt = part->out_pkt;
+	op_result.pkt = pkto;
+	op_result.res = result;
+
+	if (ODP_IPSEC_OP_MODE_SYNC == suite_context.pref_mode) {
+		CU_ASSERT_EQUAL(part->out_pkt, odp_ipsec_in(&op_param, &op_result));
+	} else if (ODP_IPSEC_OP_MODE_ASYNC == suite_context.pref_mode) {
+		odp_event_t event;
+
+		CU_ASSERT_EQUAL(1, odp_ipsec_in_enq(&op_param));
+
+		do {
+			event = odp_queue_deq(suite_context.queue);
+		} while (event == ODP_EVENT_INVALID);
+
+		CU_ASSERT_EQUAL(ODP_EVENT_IPSEC_RESULT, odp_event_type(event));
+		CU_ASSERT_EQUAL(part->out_pkt, odp_ipsec_result(&op_result, event));
+	} else {
+		CU_FAIL("INLINE not supported");
+	}
+
+	CU_ASSERT_EQUAL(part->out_pkt, op_result.num_pkt);
+
+	for (i = 0; i < op_result.num_pkt && i < part->out_pkt; i++) {
+		CU_ASSERT_EQUAL(part->out[i].status.all_error, result[i].status.all_error);
+		CU_ASSERT_EQUAL(sa, result[i].sa);
+		if (ODP_PACKET_INVALID == pkto[i]) {
+			CU_FAIL("ODP_PACKET_INVALID received");
+		} else {
+			CU_ASSERT(ipsec_check_packet(part->out[i].pkt_out, pkto[i]));
+			odp_packet_free(pkto[i]);
+		}
+	}
+}
+
+void ipsec_check_out_one(const ipsec_test_part *part, odp_ipsec_sa_t sa)
+{
+	odp_ipsec_op_param_t op_param;
+	odp_ipsec_op_result_t op_result;
+	odp_packet_t pkt;
+	odp_packet_t pkto[part->out_pkt];
+	odp_ipsec_packet_result_t result[part->out_pkt];
+	int i;
+
+	pkt = ipsec_packet(part->pkt_in);
+
+	memset(&op_param, 0, sizeof(op_param));
+	op_param.num_pkt = 1;
+	op_param.pkt = &pkt;
+	op_param.num_sa = 1;
+	op_param.sa = &sa;
+	op_param.num_opt = 0;
+	op_param.opt = NULL;
+
+	op_result.num_pkt = part->out_pkt;
+	op_result.pkt = pkto;
+	op_result.res = result;
+
+	if (ODP_IPSEC_OP_MODE_SYNC == suite_context.pref_mode) {
+		CU_ASSERT_EQUAL(part->out_pkt, odp_ipsec_out(&op_param, &op_result));
+	} else if (ODP_IPSEC_OP_MODE_ASYNC == suite_context.pref_mode) {
+		odp_event_t event;
+
+		CU_ASSERT_EQUAL(1, odp_ipsec_out_enq(&op_param));
+
+		do {
+			event = odp_queue_deq(suite_context.queue);
+		} while (event == ODP_EVENT_INVALID);
+
+		CU_ASSERT_EQUAL(ODP_EVENT_IPSEC_RESULT, odp_event_type(event));
+		CU_ASSERT_EQUAL(part->out_pkt, odp_ipsec_result(&op_result, event));
+	} else {
+		CU_FAIL("INLINE not supported");
+	}
+
+	CU_ASSERT_EQUAL(part->out_pkt, op_result.num_pkt);
+
+	for (i = 0; i < op_result.num_pkt && i < part->out_pkt; i++) {
+		CU_ASSERT_EQUAL(part->out[i].status.all_error, result[i].status.all_error);
+		CU_ASSERT_EQUAL(sa, result[i].sa);
+		if (ODP_PACKET_INVALID == pkto[i]) {
+			CU_FAIL("ODP_PACKET_INVALID received");
+		} else {
+			CU_ASSERT(ipsec_check_packet(part->out[i].pkt_out, pkto[i]));
+			odp_packet_free(pkto[i]);
+		}
+	}
+}
+
+void ipsec_check_out_in_one(const ipsec_test_part *part, odp_ipsec_sa_t sa, odp_ipsec_sa_t sa_in)
+{
+	odp_ipsec_op_param_t op_param;
+	odp_ipsec_op_result_t op_result;
+	odp_packet_t pkt;
+	odp_packet_t pkto[part->out_pkt];
+	odp_ipsec_packet_result_t result[part->out_pkt];
+	int i;
+
+	pkt = ipsec_packet(part->pkt_in);
+
+	memset(&op_param, 0, sizeof(op_param));
+	op_param.num_pkt = 1;
+	op_param.pkt = &pkt;
+	op_param.num_sa = 1;
+	op_param.sa = &sa;
+	op_param.num_opt = 0;
+	op_param.opt = NULL;
+
+	op_result.num_pkt = part->out_pkt;
+	op_result.pkt = pkto;
+	op_result.res = result;
+
+	if (ODP_IPSEC_OP_MODE_SYNC == suite_context.pref_mode) {
+		CU_ASSERT_EQUAL(part->out_pkt, odp_ipsec_out(&op_param, &op_result));
+	} else if (ODP_IPSEC_OP_MODE_ASYNC == suite_context.pref_mode) {
+		odp_event_t event;
+
+		CU_ASSERT_EQUAL(1, odp_ipsec_out_enq(&op_param));
+
+		do {
+			event = odp_queue_deq(suite_context.queue);
+		} while (event == ODP_EVENT_INVALID);
+
+		CU_ASSERT_EQUAL(ODP_EVENT_IPSEC_RESULT, odp_event_type(event));
+		CU_ASSERT_EQUAL(part->out_pkt, odp_ipsec_result(&op_result, event));
+	} else {
+		CU_FAIL("INLINE not supported");
+	}
+
+	CU_ASSERT_EQUAL(part->out_pkt, op_result.num_pkt);
+
+	for (i = 0; i < op_result.num_pkt && i < part->out_pkt; i++) {
+		CU_ASSERT_EQUAL(part->out[i].status.all_error, result[i].status.all_error);
+		CU_ASSERT_EQUAL(sa, result[i].sa);
+		if (ODP_PACKET_INVALID == pkto[i]) {
+			CU_FAIL("ODP_PACKET_INVALID received");
+		} else {
+			ipsec_test_part part_in = *part;
+			ipsec_test_packet pkt_in;
+
+			CU_ASSERT_FATAL(odp_packet_len(pkto[i]) <= sizeof(pkt_in.data));
+
+			pkt_in.len = odp_packet_len(pkto[i]);
+			pkt_in.l2_offset = odp_packet_l2_offset(pkto[i]);
+			pkt_in.l3_offset = odp_packet_l3_offset(pkto[i]);
+			pkt_in.l4_offset = odp_packet_l4_offset(pkto[i]);
+			odp_packet_copy_to_mem(pkto[i], 0, pkt_in.len, pkt_in.data);
+			part_in.pkt_in = &pkt_in;
+			ipsec_check_in_one(&part_in, sa_in, false);
+			odp_packet_free(pkto[i]);
+		}
+	}
+}
+
+static
 void ipsec_test_capability(void)
 {
 	odp_ipsec_capability_t capa;
@@ -22,11 +399,164 @@  odp_testinfo_t ipsec_suite[] = {
 	ODP_TEST_INFO_NULL
 };
 
+static
+int ODP_UNUSED ipsec_sync_init(void)
+{
+	suite_context.pool = odp_pool_lookup("packet_pool");
+	if (suite_context.pool == ODP_POOL_INVALID)
+		return -1;
+
+	suite_context.queue = ODP_QUEUE_INVALID;
+	suite_context.pref_mode = ODP_IPSEC_OP_MODE_SYNC;
+	return 0;
+}
+
+static
+int ODP_UNUSED ipsec_async_init(void)
+{
+	suite_context.pool = odp_pool_lookup("packet_pool");
+	if (suite_context.pool == ODP_POOL_INVALID)
+		return -1;
+	suite_context.queue = odp_queue_lookup("ipsec-out");
+	if (suite_context.queue == ODP_QUEUE_INVALID)
+		return -1;
+
+	suite_context.pref_mode = ODP_IPSEC_OP_MODE_ASYNC;
+	return 0;
+}
+
+static
+int ipsec_suite_term(odp_testinfo_t *suite)
+{
+	int i;
+	int first = 1;
+
+	for (i = 0; suite[i].pName; i++) {
+		if (suite[i].check_active &&
+		    suite[i].check_active() == ODP_TEST_INACTIVE) {
+			if (first) {
+				first = 0;
+				printf("\n\n  Inactive tests:\n");
+			}
+			printf("    %s\n", suite[i].pName);
+		}
+	}
+
+	return 0;
+}
+
+static
+int ipsec_in_term(void)
+{
+	return ipsec_suite_term(ipsec_in_suite);
+}
+
+static
+int ipsec_out_term(void)
+{
+	return ipsec_suite_term(ipsec_out_suite);
+}
+
 odp_suiteinfo_t ipsec_suites[] = {
 	{"IPsec", NULL, NULL, ipsec_suite},
+	{"IPsec-sync-in", ipsec_sync_init, ipsec_in_term, ipsec_in_suite},
+	{"IPsec-async-in", ipsec_async_init, ipsec_in_term, ipsec_in_suite},
+	{"IPsec-sync-out", ipsec_sync_init, ipsec_out_term, ipsec_out_suite},
+	{"IPsec-async-out", ipsec_async_init, ipsec_out_term, ipsec_out_suite},
 	ODP_SUITE_INFO_NULL,
 };
 
+static
+int ipsec_outit(odp_instance_t *inst)
+{
+	odp_pool_param_t params;
+	odp_pool_t pool;
+	odp_queue_t out_queue;
+	odp_pool_capability_t pool_capa;
+
+	if (0 != odp_init_global(inst, NULL, NULL)) {
+		fprintf(stderr, "error: odp_init_global() failed.\n");
+		return -1;
+	}
+
+	if (0 != odp_init_local(*inst, ODP_THREAD_CONTROL)) {
+		fprintf(stderr, "error: odp_init_local() failed.\n");
+		return -1;
+	}
+
+	if (odp_pool_capability(&pool_capa) < 0) {
+		fprintf(stderr, "error: odp_pool_capability() failed.\n");
+		return -1;
+	}
+
+	odp_pool_param_init(&params);
+	params.pkt.seg_len = PKT_POOL_LEN;
+	params.pkt.len     = PKT_POOL_LEN;
+	params.pkt.num     = PKT_POOL_NUM;
+	params.type        = ODP_POOL_PACKET;
+
+	if (pool_capa.pkt.max_seg_len &&
+	    PKT_POOL_LEN > pool_capa.pkt.max_seg_len) {
+		fprintf(stderr, "Warning: small packet segment length\n");
+		params.pkt.seg_len = pool_capa.pkt.max_seg_len;
+	}
+
+	if (pool_capa.pkt.max_len &&
+	    PKT_POOL_LEN > pool_capa.pkt.max_len) {
+		fprintf(stderr, "Pool max packet length too small\n");
+		return -1;
+	}
+
+	pool = odp_pool_create("packet_pool", &params);
+
+	if (ODP_POOL_INVALID == pool) {
+		fprintf(stderr, "Packet pool creation failed.\n");
+		return -1;
+	}
+	out_queue = odp_queue_create("ipsec-out", NULL);
+	if (ODP_QUEUE_INVALID == out_queue) {
+		fprintf(stderr, "Crypto outq creation failed.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static
+int ipsec_term(odp_instance_t inst)
+{
+	odp_pool_t pool;
+	odp_queue_t out_queue;
+
+	out_queue = odp_queue_lookup("ipsec-out");
+	if (ODP_QUEUE_INVALID != out_queue) {
+		if (odp_queue_destroy(out_queue))
+			fprintf(stderr, "Crypto outq destroy failed.\n");
+	} else {
+		fprintf(stderr, "Crypto outq not found.\n");
+	}
+
+	pool = odp_pool_lookup("packet_pool");
+	if (ODP_POOL_INVALID != pool) {
+		if (odp_pool_destroy(pool))
+			fprintf(stderr, "Packet pool destroy failed.\n");
+	} else {
+		fprintf(stderr, "Packet pool not found.\n");
+	}
+
+	if (0 != odp_term_local()) {
+		fprintf(stderr, "error: odp_term_local() failed.\n");
+		return -1;
+	}
+
+	if (0 != odp_term_global(inst)) {
+		fprintf(stderr, "error: odp_term_global() failed.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
 int ipsec_main(int argc, char *argv[])
 {
 	int ret;
@@ -35,8 +565,10 @@  int ipsec_main(int argc, char *argv[])
 	if (odp_cunit_parse_options(argc, argv))
 		return -1;
 
-	ret = odp_cunit_register(ipsec_suites);
+	odp_cunit_register_global_init(ipsec_outit);
+	odp_cunit_register_global_term(ipsec_term);
 
+	ret = odp_cunit_register(ipsec_suites);
 	if (ret == 0)
 		ret = odp_cunit_run();
 
diff --git a/test/common_plat/validation/api/ipsec/ipsec.h b/test/common_plat/validation/api/ipsec/ipsec.h
index 290a186..e0d68c5 100644
--- a/test/common_plat/validation/api/ipsec/ipsec.h
+++ b/test/common_plat/validation/api/ipsec/ipsec.h
@@ -9,16 +9,56 @@ 
 
 #include <odp_cunit_common.h>
 
-/* test functions: */
-void ipsec_test_capability(void);
-
 /* test arrays: */
-extern odp_testinfo_t ipsec_suite[];
-
-/* test registry: */
-extern odp_suiteinfo_t ipsec_suites[];
+extern odp_testinfo_t ipsec_in_suite[];
+extern odp_testinfo_t ipsec_out_suite[];
 
 /* main test program: */
 int ipsec_main(int argc, char *argv[]);
 
+struct suite_context_s {
+	odp_ipsec_op_mode_t pref_mode;
+	odp_pool_t pool;
+	odp_queue_t queue;
+};
+
+extern struct suite_context_s suite_context;
+
+typedef struct {
+	uint32_t len;
+	uint32_t l2_offset;
+	uint32_t l3_offset;
+	uint32_t l4_offset;
+	uint8_t data[256];
+} ipsec_test_packet;
+
+typedef struct {
+	const ipsec_test_packet *pkt_in;
+	int out_pkt;
+	struct {
+		odp_ipsec_op_status_t status;
+		const ipsec_test_packet *pkt_out;
+	} out[1];
+} ipsec_test_part;
+
+void ipsec_sa_param_fill(odp_ipsec_sa_param_t *param,
+			 odp_bool_t in,
+			 odp_bool_t ah,
+			 uint32_t spi,
+			 odp_cipher_alg_t cipher_alg,
+			 const odp_crypto_key_t *cipher_key,
+			 odp_auth_alg_t auth_alg,
+			 const odp_crypto_key_t *auth_key);
+
+void ipsec_sa_destroy(odp_ipsec_sa_t sa);
+odp_packet_t ipsec_packet(const ipsec_test_packet *itp);
+odp_bool_t ipsec_check_packet(const ipsec_test_packet *itp, odp_packet_t pkt);
+void ipsec_check_in_one(const ipsec_test_part *part, odp_ipsec_sa_t sa, odp_bool_t lookup);
+void ipsec_check_out_one(const ipsec_test_part *part, odp_ipsec_sa_t sa);
+void ipsec_check_out_in_one(const ipsec_test_part *part, odp_ipsec_sa_t sa, odp_ipsec_sa_t sa_in);
+
+int ipsec_check(odp_bool_t in, odp_bool_t ah, odp_cipher_alg_t cipher, odp_auth_alg_t auth);
+#define ipsec_check_ah(in, auth) ipsec_check(in, true, ODP_CIPHER_ALG_NULL, auth)
+#define ipsec_check_esp(in, cipher, auth) ipsec_check(in, false, cipher, auth)
+
 #endif
diff --git a/test/common_plat/validation/api/ipsec/ipsec_test_in.c b/test/common_plat/validation/api/ipsec/ipsec_test_in.c
new file mode 100644
index 0000000..c774729
--- /dev/null
+++ b/test/common_plat/validation/api/ipsec/ipsec_test_in.c
@@ -0,0 +1,444 @@ 
+/* Copyright (c) 2017, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include "ipsec.h"
+
+#include "test_vectors.h"
+
+static
+void test_in_ah_sha256(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    true, true, 123,
+			    ODP_CIPHER_ALG_NULL, NULL,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0_ah_sha256_1,
+		.out_pkt = 1,
+		.out = {
+			{ { }, &pkt_icmp_0 },
+		},
+	};
+
+	ipsec_check_in_one(&test, sa, true);
+
+	ipsec_sa_destroy(sa);
+}
+
+static
+void test_in_esp_null_sha256(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    true, false, 123,
+			    ODP_CIPHER_ALG_NULL, NULL,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0_esp_null_sha256_1,
+		.out_pkt = 1,
+		.out = {
+			{ { }, &pkt_icmp_0 },
+		},
+	};
+
+	ipsec_check_in_one(&test, sa, true);
+
+	ipsec_sa_destroy(sa);
+}
+
+static
+void test_in_esp_aes_cbc_null(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    true, false, 123,
+			    ODP_CIPHER_ALG_AES_CBC, &key_a5_128,
+			    ODP_AUTH_ALG_NULL, NULL);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0_esp_aes_cbc_null_1,
+		.out_pkt = 1,
+		.out = {
+			{ { }, &pkt_icmp_0 },
+		},
+	};
+
+	ipsec_check_in_one(&test, sa, true);
+
+	ipsec_sa_destroy(sa);
+}
+
+static
+void test_in_esp_aes_cbc_sha256(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    true, false, 123,
+			    ODP_CIPHER_ALG_AES_CBC, &key_a5_128,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0_esp_aes_cbc_sha256_1,
+		.out_pkt = 1,
+		.out = {
+			{ { }, &pkt_icmp_0 },
+		},
+	};
+
+	ipsec_check_in_one(&test, sa, true);
+
+	ipsec_sa_destroy(sa);
+}
+
+static
+void test_in_lookup_ah_sha256(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    true, true, 123,
+			    ODP_CIPHER_ALG_NULL, NULL,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0_ah_sha256_1,
+		.out_pkt = 1,
+		.out = {
+			{ { }, &pkt_icmp_0 },
+		},
+	};
+
+	ipsec_check_in_one(&test, sa, true);
+
+	ipsec_sa_destroy(sa);
+}
+
+static
+void test_in_lookup_esp_null_sha256(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    true, false, 123,
+			    ODP_CIPHER_ALG_NULL, NULL,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0_esp_null_sha256_1,
+		.out_pkt = 1,
+		.out = {
+			{ { }, &pkt_icmp_0 },
+		},
+	};
+
+	ipsec_check_in_one(&test, sa, true);
+
+	ipsec_sa_destroy(sa);
+}
+
+static
+void test_in_ah_esp_pkt(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    true, true, 123,
+			    ODP_CIPHER_ALG_NULL, NULL,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0_esp_null_sha256_1,
+		.out_pkt = 1,
+		.out = {
+			{ { .all_error = 0, .error.proto = 1 }, NULL },
+		},
+	};
+
+	ipsec_check_in_one(&test, sa, true);
+
+	ipsec_sa_destroy(sa);
+}
+
+static
+void test_in_esp_ah_pkt(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    true, false, 123,
+			    ODP_CIPHER_ALG_NULL, NULL,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0_ah_sha256_1,
+		.out_pkt = 1,
+		.out = {
+			{ { .all_error = 0, .error.proto = 1 }, NULL },
+		},
+	};
+
+	ipsec_check_in_one(&test, sa, true);
+
+	ipsec_sa_destroy(sa);
+}
+
+static
+void test_in_ah_sha256_bad1(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    true, true, 123,
+			    ODP_CIPHER_ALG_NULL, NULL,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0_ah_sha256_1_bad1,
+		.out_pkt = 1,
+		.out = {
+			{ { .all_error = 0, .error.auth = 1 }, NULL },
+		},
+	};
+
+	ipsec_check_in_one(&test, sa, true);
+
+	ipsec_sa_destroy(sa);
+}
+
+static
+void test_in_ah_sha256_bad2(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    true, true, 123,
+			    ODP_CIPHER_ALG_NULL, NULL,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0_ah_sha256_1_bad2,
+		.out_pkt = 1,
+		.out = {
+			{ { .all_error = 0, .error.auth = 1 }, NULL },
+		},
+	};
+
+	ipsec_check_in_one(&test, sa, true);
+
+	ipsec_sa_destroy(sa);
+}
+
+static
+void test_in_esp_null_sha256_bad1(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    true, false, 123,
+			    ODP_CIPHER_ALG_NULL, NULL,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0_esp_null_sha256_1_bad1,
+		.out_pkt = 1,
+		.out = {
+			{ { .all_error = 0, .error.auth = 1 }, NULL },
+		},
+	};
+
+	ipsec_check_in_one(&test, sa, true);
+
+	ipsec_sa_destroy(sa);
+}
+
+static
+int ipsec_check_in_ah_sha256(void)
+{
+	return ipsec_check_ah(true, ODP_AUTH_ALG_SHA256_HMAC);
+}
+
+static
+int ipsec_check_in_esp_null_sha256(void)
+{
+	return ipsec_check_esp(true, ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA256_HMAC);
+}
+
+static
+int ipsec_check_in_esp_aes_cbc_null(void)
+{
+	return ipsec_check_esp(true, ODP_CIPHER_ALG_AES_CBC, ODP_AUTH_ALG_NULL);
+}
+
+static
+int ipsec_check_in_esp_aes_cbc_sha256(void)
+{
+	return ipsec_check_esp(true, ODP_CIPHER_ALG_AES_CBC, ODP_AUTH_ALG_SHA256_HMAC);
+}
+
+odp_testinfo_t ipsec_in_suite[] = {
+	ODP_TEST_INFO_CONDITIONAL(test_in_ah_sha256, ipsec_check_in_ah_sha256),
+	ODP_TEST_INFO_CONDITIONAL(test_in_esp_null_sha256, ipsec_check_in_esp_null_sha256),
+	ODP_TEST_INFO_CONDITIONAL(test_in_esp_aes_cbc_null, ipsec_check_in_esp_aes_cbc_null),
+	ODP_TEST_INFO_CONDITIONAL(test_in_esp_aes_cbc_sha256, ipsec_check_in_esp_aes_cbc_sha256),
+	ODP_TEST_INFO_CONDITIONAL(test_in_lookup_ah_sha256, ipsec_check_in_ah_sha256),
+	ODP_TEST_INFO_CONDITIONAL(test_in_lookup_esp_null_sha256, ipsec_check_in_esp_null_sha256),
+	ODP_TEST_INFO_CONDITIONAL(test_in_ah_esp_pkt, ipsec_check_in_ah_sha256),
+	ODP_TEST_INFO_CONDITIONAL(test_in_esp_ah_pkt, ipsec_check_in_esp_null_sha256),
+	ODP_TEST_INFO_CONDITIONAL(test_in_ah_sha256_bad1, ipsec_check_in_ah_sha256),
+	ODP_TEST_INFO_CONDITIONAL(test_in_ah_sha256_bad2, ipsec_check_in_ah_sha256),
+	ODP_TEST_INFO_CONDITIONAL(test_in_esp_null_sha256_bad1, ipsec_check_in_esp_null_sha256),
+	ODP_TEST_INFO_NULL,
+};
diff --git a/test/common_plat/validation/api/ipsec/ipsec_test_out.c b/test/common_plat/validation/api/ipsec/ipsec_test_out.c
new file mode 100644
index 0000000..d4ecaaf
--- /dev/null
+++ b/test/common_plat/validation/api/ipsec/ipsec_test_out.c
@@ -0,0 +1,154 @@ 
+/* Copyright (c) 2017, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include "ipsec.h"
+
+#include "test_vectors.h"
+
+static
+void test_out_ah_sha256(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    false, true, 123,
+			    ODP_CIPHER_ALG_NULL, NULL,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0,
+		.out_pkt = 1,
+		.out = {
+			{ { }, &pkt_icmp_0_ah_sha256_1 },
+		},
+	};
+
+	ipsec_check_out_one(&test, sa);
+
+	ipsec_sa_destroy(sa);
+}
+
+static
+void test_out_esp_null_sha256(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    false, false, 123,
+			    ODP_CIPHER_ALG_NULL, NULL,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0,
+		.out_pkt = 1,
+		.out = {
+			{ { }, &pkt_icmp_0_esp_null_sha256_1 },
+		},
+	};
+
+	ipsec_check_out_one(&test, sa);
+
+	ipsec_sa_destroy(sa);
+}
+
+static
+void test_out_esp_aes_cbc_sha256(void)
+{
+	odp_ipsec_config_t ipsec_config;
+	odp_ipsec_sa_param_t param;
+	odp_ipsec_sa_t sa;
+	odp_ipsec_sa_t sa2;
+
+	odp_ipsec_config_init(&ipsec_config);
+	ipsec_config.inbound_mode = suite_context.pref_mode;
+	ipsec_config.outbound_mode = suite_context.pref_mode;
+	ipsec_config.inbound.default_queue = suite_context.queue;
+
+	CU_ASSERT_EQUAL_FATAL(ODP_IPSEC_OK, odp_ipsec_config(&ipsec_config));
+
+	ipsec_sa_param_fill(&param,
+			    false, false, 123,
+			    ODP_CIPHER_ALG_AES_CBC, &key_a5_128,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+
+	ipsec_sa_param_fill(&param,
+			    true, false, 123,
+			    ODP_CIPHER_ALG_AES_CBC, &key_a5_128,
+			    ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256);
+
+	sa2 = odp_ipsec_sa_create(&param);
+
+	CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa2);
+
+	ipsec_test_part test = {
+		.pkt_in = &pkt_icmp_0,
+		.out_pkt = 1,
+		.out = {
+			{ { }, &pkt_icmp_0 },
+		},
+	};
+
+	ipsec_check_out_in_one(&test, sa, sa2);
+
+	ipsec_sa_destroy(sa2);
+	ipsec_sa_destroy(sa);
+}
+
+static
+int ipsec_check_out_ah_sha256(void)
+{
+	return ipsec_check_ah(false, ODP_AUTH_ALG_SHA256_HMAC);
+}
+
+static
+int ipsec_check_out_esp_null_sha256(void)
+{
+	return ipsec_check_esp(false, ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA256_HMAC);
+}
+
+static
+int ipsec_check_both_esp_aes_cbc_sha256(void)
+{
+	return ipsec_check_esp(false, ODP_CIPHER_ALG_AES_CBC, ODP_AUTH_ALG_SHA256_HMAC) &&
+	       ipsec_check_esp(true, ODP_CIPHER_ALG_AES_CBC, ODP_AUTH_ALG_SHA256_HMAC);
+}
+
+odp_testinfo_t ipsec_out_suite[] = {
+	ODP_TEST_INFO_CONDITIONAL(test_out_ah_sha256, ipsec_check_out_ah_sha256),
+	ODP_TEST_INFO_CONDITIONAL(test_out_esp_null_sha256, ipsec_check_out_esp_null_sha256),
+	ODP_TEST_INFO_CONDITIONAL(test_out_esp_aes_cbc_sha256, ipsec_check_both_esp_aes_cbc_sha256),
+	ODP_TEST_INFO_NULL,
+};
diff --git a/test/common_plat/validation/api/ipsec/test_vectors.h b/test/common_plat/validation/api/ipsec/test_vectors.h
new file mode 100644
index 0000000..47817bc
--- /dev/null
+++ b/test/common_plat/validation/api/ipsec/test_vectors.h
@@ -0,0 +1,414 @@ 
+/* Copyright (c) 2017, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#ifndef _ODP_TEST_IPSEC_VECTORS_H_
+#define _ODP_TEST_IPSEC_VECTORS_H_
+
+#define KEY(name, ...)					\
+	static uint8_t name ## _data[] = { __VA_ARGS__ };	\
+	static const ODP_UNUSED odp_crypto_key_t name = {			\
+		.data = name ## _data,			\
+		.length = sizeof(name ## _data),	\
+	}
+
+KEY(key_a5_128, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5);
+KEY(key_5a_128, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a);
+KEY(key_a5_256, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+		0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5);
+KEY(key_5a_256, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+		0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a);
+
+static const ODP_UNUSED ipsec_test_packet pkt_icmp_0 = {
+	.len = 142,
+	.l2_offset = 0,
+	.l3_offset = 14,
+	.l4_offset = 34,
+	.data = {
+		/* ETH */
+		0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
+		0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x00, 0x08,
+
+		/* IP */
+		0x45, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+		0x40, 0x01, 0xac, 0x27, 0xc0, 0xa8, 0x6f, 0x02,
+		0xc0, 0xa8, 0xde, 0x02,
+
+		/* ICMP */
+		0x08, 0x00, 0xfb, 0x37,
+
+		/* ICMP echo */
+		0x12, 0x34, 0x00, 0x00,
+
+		/* data */
+		0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe,
+		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+		0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+		0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5a, 0x5b,
+	},
+};
+
+static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_ah_sha256_1 = {
+	.len = 170,
+	.l2_offset = 0,
+	.l3_offset = 14,
+	.l4_offset = 34,
+	.data = {
+		/* ETH */
+		0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
+		0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x00, 0x08,
+
+		/* IP */
+		0x45, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00,
+		0x40, 0x33, 0xab, 0xd9, 0xc0, 0xa8, 0x6f, 0x02,
+		0xc0, 0xa8, 0xde, 0x02,
+
+		/* AH */
+		0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
+		0x00, 0x00, 0x00, 0x01,
+		0x6c, 0x2e, 0xf7, 0x1f, 0x7c, 0x70, 0x39, 0xa3,
+		0x4a, 0x77, 0x01, 0x47, 0x9e, 0x45, 0x73, 0x51,
+
+		/* ICMP */
+		0x08, 0x00, 0xfb, 0x37,
+
+		/* ICMP echo */
+		0x12, 0x34, 0x00, 0x00,
+
+		/* data */
+		0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe,
+		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+		0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+		0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5a, 0x5b,
+	},
+};
+
+static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_ah_sha256_1235 = {
+	.len = 170,
+	.l2_offset = 0,
+	.l3_offset = 14,
+	.l4_offset = 34,
+	.data = {
+		/* ETH */
+		0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
+		0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x00, 0x08,
+
+		/* IP */
+		0x45, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00,
+		0x40, 0x33, 0xab, 0xd9, 0xc0, 0xa8, 0x6f, 0x02,
+		0xc0, 0xa8, 0xde, 0x02,
+
+		/* AH */
+		0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
+		0x00, 0x00, 0x12, 0x35,
+		0x04, 0xef, 0x71, 0x73, 0xa1, 0xd4, 0x71, 0x3f,
+		0xd6, 0x78, 0xfe, 0xa2, 0x59, 0xe9, 0x93, 0x70,
+
+		/* ICMP */
+		0x08, 0x00, 0xfb, 0x37,
+
+		/* ICMP echo */
+		0x12, 0x34, 0x00, 0x00,
+
+		/* data */
+		0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe,
+		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+		0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+		0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5a, 0x5b,
+	},
+};
+
+static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_ah_sha256_1_bad1 = {
+	.len = 168,
+	.l2_offset = 0,
+	.l3_offset = 14,
+	.l4_offset = 34,
+	.data = {
+		/* ETH */
+		0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
+		0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x00, 0x08,
+
+		/* IP */
+		0x45, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00,
+		0x40, 0x33, 0xab, 0xd9, 0xc0, 0xa8, 0x6f, 0x02,
+		0xc0, 0xa8, 0xde, 0x02,
+
+		/* AH */
+		0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
+		0x00, 0x00, 0x00, 0x01,
+		0x6c, 0x2e, 0xf7, 0x1f, 0x7c, 0x70, 0x39, 0xa3,
+		0x4a, 0x77, 0x01, 0x47, 0x9e, 0x45, 0x73, 0x51,
+
+		/* ICMP */
+		0x08, 0x00, 0xfb, 0x37,
+
+		/* ICMP echo */
+		0x12, 0x34, 0x00, 0x00,
+
+		/* data */
+		0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe,
+		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+		0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+		0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59,
+	},
+};
+
+static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_ah_sha256_1_bad2 = {
+	.len = 170,
+	.l2_offset = 0,
+	.l3_offset = 14,
+	.l4_offset = 34,
+	.data = {
+		/* ETH */
+		0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
+		0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x00, 0x08,
+
+		/* IP */
+		0x45, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00,
+		0x40, 0x33, 0xab, 0xd9, 0xc0, 0xa8, 0x6f, 0x02,
+		0xc0, 0xa8, 0xde, 0x02,
+
+		/* AH */
+		0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
+		0x00, 0x00, 0x00, 0x01,
+		0x6c, 0x2e, 0xf7, 0x1f, 0x7c, 0x70, 0x39, 0xa3,
+		0x4a, 0x77, 0x01, 0x47, 0x9e, 0x45, 0x73, 0x51,
+
+		/* ICMP */
+		0x08, 0x00, 0xfb, 0x37,
+
+		/* ICMP echo */
+		0x12, 0x34, 0x00, 0x00,
+
+		/* data */
+		0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe,
+		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+		0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+		0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5a, 0x5d,
+	},
+};
+
+static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_esp_null_sha256_1 = {
+	.len = 168,
+	.l2_offset = 0,
+	.l3_offset = 14,
+	.l4_offset = 34,
+	.data = {
+		/* ETH */
+		0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
+		0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x00, 0x08,
+
+		/* IP */
+		0x45, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00,
+		0x40, 0x32, 0xab, 0xdc, 0xc0, 0xa8, 0x6f, 0x02,
+		0xc0, 0xa8, 0xde, 0x02,
+
+		/* ESP */
+		0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01,
+
+		/* ICMP */
+		0x08, 0x00, 0xfb, 0x37,
+
+		/* ICMP echo */
+		0x12, 0x34, 0x00, 0x00,
+
+		/* data */
+		0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe,
+		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+		0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+		0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5a, 0x5b,
+
+		/* ESP TRL */
+		0x00, 0x01,
+
+		/* ICV */
+		0x18, 0x00, 0x14, 0x3a, 0x54, 0x72, 0x98, 0xe8,
+		0xc7, 0x2d, 0xfa, 0xeb, 0x70, 0xe0, 0x24, 0xdb,
+	},
+};
+
+static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_esp_null_sha256_1_bad1 = {
+	.len = 168,
+	.l2_offset = 0,
+	.l3_offset = 14,
+	.l4_offset = 34,
+	.data = {
+		/* ETH */
+		0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
+		0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x00, 0x08,
+
+		/* IP */
+		0x45, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00,
+		0x40, 0x32, 0xab, 0xdc, 0xc0, 0xa8, 0x6f, 0x02,
+		0xc0, 0xa8, 0xde, 0x02,
+
+		/* ESP */
+		0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01,
+
+		/* ICMP */
+		0x08, 0x00, 0xfb, 0x37,
+
+		/* ICMP echo */
+		0x12, 0x34, 0x00, 0x00,
+
+		/* data */
+		0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe,
+		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+		0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+		0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5a, 0x5b,
+
+		/* ESP TRL */
+		0x00, 0x01,
+
+		/* ICV */
+		0x18, 0x00, 0x14, 0x3a, 0x54, 0x72, 0x98, 0xe8,
+		0xc7, 0x2d, 0xfa, 0xeb, 0x70, 0xe0, 0x24, 0xdf,
+	},
+};
+
+static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_esp_aes_cbc_null_1 = {
+	.len = 170,
+	.l2_offset = 0,
+	.l3_offset = 14,
+	.l4_offset = 34,
+	.data = {
+		/* ETH */
+		0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
+		0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x00, 0x08,
+
+		/* IP */
+		0x45, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00,
+		0x40, 0x32, 0xab, 0xca, 0xc0, 0xa8, 0x6f, 0x02,
+		0xc0, 0xa8, 0xde, 0x02,
+
+		/* ESP */
+		0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01,
+
+		/* IV */
+		0xcc, 0xa6, 0x77, 0xa4, 0xda, 0x3a, 0x8d, 0x8c,
+		0xdb, 0x0b, 0x77, 0xcd, 0x97, 0xa0, 0x90, 0xa6,
+		0x96, 0x23, 0xad, 0x7e, 0x45, 0xe4, 0x32, 0xc3,
+		0x0c, 0x54, 0xa9, 0x5a, 0x7a, 0xc9, 0xb4, 0x9f,
+		0x59, 0x79, 0xe2, 0xfc, 0x5c, 0x7e, 0x27, 0x8b,
+		0xad, 0x4a, 0x1f, 0x78, 0xe0, 0x92, 0x90, 0x70,
+		0x79, 0xa2, 0x55, 0x38, 0x8f, 0x41, 0xe9, 0x07,
+		0xfe, 0xfc, 0x04, 0x06, 0xda, 0xa5, 0xd4, 0xd8,
+		0xcd, 0x02, 0x95, 0x54, 0x01, 0x25, 0xe2, 0x44,
+		0x6f, 0xf7, 0x85, 0xa0, 0x53, 0xb9, 0x2b, 0xa1,
+		0xad, 0x24, 0x62, 0xa3, 0x45, 0x3e, 0x3c, 0x75,
+		0x44, 0x2d, 0x8f, 0x69, 0x8e, 0xa0, 0x64, 0x54,
+		0xe6, 0x84, 0x3f, 0x8e, 0x9f, 0x5e, 0x74, 0x56,
+		0x3c, 0x20, 0x0b, 0x1a, 0x7b, 0x1b, 0xb5, 0xd8,
+		0x7e, 0xb0, 0xc4, 0x4d, 0x6e, 0xd1, 0x53, 0x05,
+		0x28, 0xe9, 0x7d, 0xf9, 0xe5, 0x91, 0x98, 0xed,
+	},
+};
+
+static const ODP_UNUSED ipsec_test_packet pkt_icmp_0_esp_aes_cbc_sha256_1 = {
+	.len = 186,
+	.l2_offset = 0,
+	.l3_offset = 14,
+	.l4_offset = 34,
+	.data = {
+		/* ETH */
+		0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,
+		0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x00, 0x08,
+
+		/* IP */
+		0x45, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x00,
+		0x40, 0x32, 0xab, 0xca, 0xc0, 0xa8, 0x6f, 0x02,
+		0xc0, 0xa8, 0xde, 0x02,
+
+		/* ESP */
+		0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01,
+
+		/* IV */
+		0xcc, 0xa6, 0x77, 0xa4, 0xda, 0x3a, 0x8d, 0x8c,
+		0xdb, 0x0b, 0x77, 0xcd, 0x97, 0xa0, 0x90, 0xa6,
+		0x96, 0x23, 0xad, 0x7e, 0x45, 0xe4, 0x32, 0xc3,
+		0x0c, 0x54, 0xa9, 0x5a, 0x7a, 0xc9, 0xb4, 0x9f,
+		0x59, 0x79, 0xe2, 0xfc, 0x5c, 0x7e, 0x27, 0x8b,
+		0xad, 0x4a, 0x1f, 0x78, 0xe0, 0x92, 0x90, 0x70,
+		0x79, 0xa2, 0x55, 0x38, 0x8f, 0x41, 0xe9, 0x07,
+		0xfe, 0xfc, 0x04, 0x06, 0xda, 0xa5, 0xd4, 0xd8,
+		0xcd, 0x02, 0x95, 0x54, 0x01, 0x25, 0xe2, 0x44,
+		0x6f, 0xf7, 0x85, 0xa0, 0x53, 0xb9, 0x2b, 0xa1,
+		0xad, 0x24, 0x62, 0xa3, 0x45, 0x3e, 0x3c, 0x75,
+		0x44, 0x2d, 0x8f, 0x69, 0x8e, 0xa0, 0x64, 0x54,
+		0xe6, 0x84, 0x3f, 0x8e, 0x9f, 0x5e, 0x74, 0x56,
+		0x3c, 0x20, 0x0b, 0x1a, 0x7b, 0x1b, 0xb5, 0xd8,
+		0x7e, 0xb0, 0xc4, 0x4d, 0x6e, 0xd1, 0x53, 0x05,
+		0x28, 0xe9, 0x7d, 0xf9, 0xe5, 0x91, 0x98, 0xed,
+
+		/* ICV */
+		0xaa, 0x81, 0xa0, 0xd0, 0x2f, 0x92, 0x85, 0x51,
+		0x4e, 0x8d, 0x22, 0x2e, 0x54, 0x80, 0xf0, 0xd9,
+	},
+};
+
+#endif