Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.a...@intel.com>
Signed-off-by: Bernard Iremonger <bernard.iremon...@intel.com>
---
 test/test/Makefile     |    3 +
 test/test/meson.build  |    3 +
 test/test/test_ipsec.c | 1329 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1335 insertions(+)
 create mode 100644 test/test/test_ipsec.c

diff --git a/test/test/Makefile b/test/test/Makefile
index dcea4410d..2be25808c 100644
--- a/test/test/Makefile
+++ b/test/test/Makefile
@@ -204,6 +204,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_KVARGS) += test_kvargs.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_BPF) += test_bpf.c
 
+SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec.c
+LDLIBS += -lrte_ipsec
+
 CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 CFLAGS += -O3
diff --git a/test/test/meson.build b/test/test/meson.build
index bacb5b144..803f2e28d 100644
--- a/test/test/meson.build
+++ b/test/test/meson.build
@@ -47,6 +47,7 @@ test_sources = files('commands.c',
        'test_hash_perf.c',
        'test_hash_scaling.c',
        'test_interrupts.c',
+       'test_ipsec.c',
        'test_kni.c',
        'test_kvargs.c',
        'test_link_bonding.c',
@@ -113,6 +114,7 @@ test_deps = ['acl',
        'eventdev',
        'flow_classify',
        'hash',
+       'ipsec',
        'lpm',
        'member',
        'pipeline',
@@ -172,6 +174,7 @@ test_names = [
        'hash_multiwriter_autotest',
        'hash_perf_autotest',
        'interrupt_autotest',
+       'ipsec_autotest',
        'kni_autotest',
        'kvargs_autotest',
        'link_bonding_autotest',
diff --git a/test/test/test_ipsec.c b/test/test/test_ipsec.c
new file mode 100644
index 000000000..6922cbb7e
--- /dev/null
+++ b/test/test/test_ipsec.c
@@ -0,0 +1,1329 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <time.h>
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+
+#include <rte_common.h>
+#include <rte_hexdump.h>
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_pause.h>
+#include <rte_bus_vdev.h>
+#include <rte_ip.h>
+
+#include <rte_crypto.h>
+#include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
+#include <rte_lcore.h>
+#include <rte_ipsec.h>
+#include <rte_random.h>
+#include <rte_esp.h>
+#include <rte_security_driver.h>
+
+#include "test.h"
+#include "test_cryptodev.h"
+
+#define VDEV_ARGS_SIZE 100
+#define MAX_NB_SESSIONS            8
+
+struct user_params {
+       enum rte_crypto_sym_xform_type auth;
+       enum rte_crypto_sym_xform_type cipher;
+       enum rte_crypto_sym_xform_type aead;
+
+       char auth_algo[128];
+       char cipher_algo[128];
+       char aead_algo[128];
+};
+
+struct crypto_testsuite_params {
+       struct rte_mempool *mbuf_pool;
+       struct rte_mempool *op_mpool;
+       struct rte_mempool *session_mpool;
+       struct rte_cryptodev_config conf;
+       struct rte_cryptodev_qp_conf qp_conf;
+
+       uint8_t valid_devs[RTE_CRYPTO_MAX_DEVS];
+       uint8_t valid_dev_count;
+};
+
+struct crypto_unittest_params {
+       struct rte_crypto_sym_xform cipher_xform;
+       struct rte_crypto_sym_xform auth_xform;
+       struct rte_crypto_sym_xform aead_xform;
+       struct rte_crypto_sym_xform *crypto_xforms;
+
+       struct rte_ipsec_sa_prm sa_prm;
+       struct rte_ipsec_session ss;
+
+       struct rte_crypto_op *op;
+
+       struct rte_mbuf *obuf, *ibuf, *testbuf;
+
+       uint8_t *digest;
+};
+
+static struct crypto_testsuite_params testsuite_params = { NULL };
+static struct crypto_unittest_params unittest_params;
+static struct user_params uparams;
+
+static uint8_t global_key[128] = { 0 };
+
+struct supported_cipher_algo {
+       const char *keyword;
+       enum rte_crypto_cipher_algorithm algo;
+       uint16_t iv_len;
+       uint16_t block_size;
+       uint16_t key_len;
+};
+
+struct supported_auth_algo {
+       const char *keyword;
+       enum rte_crypto_auth_algorithm algo;
+       uint16_t digest_len;
+       uint16_t key_len;
+       uint8_t key_not_req;
+};
+
+const struct supported_cipher_algo cipher_algos[] = {
+       {
+               .keyword = "null",
+               .algo = RTE_CRYPTO_CIPHER_NULL,
+               .iv_len = 0,
+               .block_size = 4,
+               .key_len = 0
+       },
+};
+
+const struct supported_auth_algo auth_algos[] = {
+       {
+               .keyword = "null",
+               .algo = RTE_CRYPTO_AUTH_NULL,
+               .digest_len = 0,
+               .key_len = 0,
+               .key_not_req = 1
+       },
+};
+
+static int
+dummy_sec_create(void *device, struct rte_security_session_conf *conf,
+       struct rte_security_session *sess, struct rte_mempool *mp)
+{
+       RTE_SET_USED(device);
+       RTE_SET_USED(conf);
+       RTE_SET_USED(mp);
+
+       sess->sess_private_data = NULL;
+       return 0;
+}
+
+static int
+dummy_sec_destroy(void *device, struct rte_security_session *sess)
+{
+       RTE_SET_USED(device);
+       RTE_SET_USED(sess);
+       return 0;
+}
+
+static const struct rte_security_ops dummy_sec_ops = {
+       .session_create = dummy_sec_create,
+       .session_destroy = dummy_sec_destroy,
+};
+
+static struct rte_security_ctx dummy_sec_ctx = {
+       .ops = &dummy_sec_ops,
+};
+
+static const struct supported_cipher_algo *
+find_match_cipher_algo(const char *cipher_keyword)
+{
+       size_t i;
+
+       for (i = 0; i < RTE_DIM(cipher_algos); i++) {
+               const struct supported_cipher_algo *algo =
+                       &cipher_algos[i];
+
+               if (strcmp(cipher_keyword, algo->keyword) == 0)
+                       return algo;
+       }
+
+       return NULL;
+}
+
+static const struct supported_auth_algo *
+find_match_auth_algo(const char *auth_keyword)
+{
+       size_t i;
+
+       for (i = 0; i < RTE_DIM(auth_algos); i++) {
+               const struct supported_auth_algo *algo =
+                       &auth_algos[i];
+
+               if (strcmp(auth_keyword, algo->keyword) == 0)
+                       return algo;
+       }
+
+       return NULL;
+}
+
+static int
+testsuite_setup(void)
+{
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+       struct rte_cryptodev_info info;
+       uint32_t nb_devs, dev_id;
+
+       memset(ts_params, 0, sizeof(*ts_params));
+
+       ts_params->mbuf_pool = rte_pktmbuf_pool_create(
+                       "CRYPTO_MBUFPOOL",
+                       NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE,
+                       rte_socket_id());
+       if (ts_params->mbuf_pool == NULL) {
+               RTE_LOG(ERR, USER1, "Can't create CRYPTO_MBUFPOOL\n");
+               return TEST_FAILED;
+       }
+
+       ts_params->op_mpool = rte_crypto_op_pool_create(
+                       "MBUF_CRYPTO_SYM_OP_POOL",
+                       RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+                       NUM_MBUFS, MBUF_CACHE_SIZE,
+                       DEFAULT_NUM_XFORMS *
+                       sizeof(struct rte_crypto_sym_xform) +
+                       MAXIMUM_IV_LENGTH,
+                       rte_socket_id());
+       if (ts_params->op_mpool == NULL) {
+               RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n");
+               return TEST_FAILED;
+       }
+
+       nb_devs = rte_cryptodev_count();
+       if (nb_devs < 1) {
+               RTE_LOG(ERR, USER1, "No crypto devices found?\n");
+               return TEST_FAILED;
+       }
+
+       ts_params->valid_devs[ts_params->valid_dev_count++] = 0;
+
+       /* Set up all the qps on the first of the valid devices found */
+       dev_id = ts_params->valid_devs[0];
+
+       rte_cryptodev_info_get(dev_id, &info);
+
+       ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs;
+       ts_params->conf.socket_id = SOCKET_ID_ANY;
+
+       unsigned int session_size =
+               rte_cryptodev_sym_get_private_session_size(dev_id);
+
+       /*
+        * Create mempool with maximum number of sessions * 2,
+        * to include the session headers
+        */
+       if (info.sym.max_nb_sessions != 0 &&
+                       info.sym.max_nb_sessions < MAX_NB_SESSIONS) {
+               RTE_LOG(ERR, USER1, "Device does not support "
+                               "at least %u sessions\n",
+                               MAX_NB_SESSIONS);
+               return TEST_FAILED;
+       }
+
+       ts_params->session_mpool = rte_mempool_create(
+                               "test_sess_mp",
+                               MAX_NB_SESSIONS * 2,
+                               session_size,
+                               0, 0, NULL, NULL, NULL,
+                               NULL, SOCKET_ID_ANY,
+                               0);
+
+       TEST_ASSERT_NOT_NULL(ts_params->session_mpool,
+                       "session mempool allocation failed");
+
+       TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id,
+                       &ts_params->conf),
+                       "Failed to configure cryptodev %u with %u qps",
+                       dev_id, ts_params->conf.nb_queue_pairs);
+
+       ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
+
+       TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
+               dev_id, 0, &ts_params->qp_conf,
+               rte_cryptodev_socket_id(dev_id),
+               ts_params->session_mpool),
+               "Failed to setup queue pair %u on cryptodev %u",
+               0, dev_id);
+
+       return TEST_SUCCESS;
+}
+
+static void
+testsuite_teardown(void)
+{
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+
+       if (ts_params->mbuf_pool != NULL) {
+               RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n",
+               rte_mempool_avail_count(ts_params->mbuf_pool));
+               rte_mempool_free(ts_params->mbuf_pool);
+               ts_params->mbuf_pool = NULL;
+       }
+
+       if (ts_params->op_mpool != NULL) {
+               RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n",
+               rte_mempool_avail_count(ts_params->op_mpool));
+               rte_mempool_free(ts_params->op_mpool);
+               ts_params->op_mpool = NULL;
+       }
+
+       /* Free session mempools */
+       if (ts_params->session_mpool != NULL) {
+               rte_mempool_free(ts_params->session_mpool);
+               ts_params->session_mpool = NULL;
+       }
+}
+
+static int
+ut_setup(void)
+{
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+       struct crypto_unittest_params *ut_params = &unittest_params;
+
+       /* Clear unit test parameters before running test */
+       memset(ut_params, 0, sizeof(*ut_params));
+
+       /* Reconfigure device to default parameters */
+       ts_params->conf.socket_id = SOCKET_ID_ANY;
+
+       /* Start the device */
+       TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->valid_devs[0]),
+                       "Failed to start cryptodev %u",
+                       ts_params->valid_devs[0]);
+
+       return TEST_SUCCESS;
+}
+
+static void
+ut_teardown(void)
+{
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+       struct crypto_unittest_params *ut_params = &unittest_params;
+
+       /* free crypto operation structure */
+       if (ut_params->op)
+               rte_crypto_op_free(ut_params->op);
+
+       /*
+        * free mbuf - both obuf and ibuf are usually the same,
+        * so check if they point at the same address is necessary,
+        * to avoid freeing the mbuf twice.
+        */
+       if (ut_params->obuf) {
+               rte_pktmbuf_free(ut_params->obuf);
+               if (ut_params->ibuf == ut_params->obuf)
+                       ut_params->ibuf = 0;
+               ut_params->obuf = 0;
+       }
+       if (ut_params->ibuf) {
+               rte_pktmbuf_free(ut_params->ibuf);
+               ut_params->ibuf = 0;
+       }
+
+       if (ut_params->testbuf) {
+               rte_pktmbuf_free(ut_params->testbuf);
+               ut_params->testbuf = 0;
+       }
+
+       if (ts_params->mbuf_pool != NULL)
+               RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n",
+                       rte_mempool_avail_count(ts_params->mbuf_pool));
+
+       /* Stop the device */
+       rte_cryptodev_stop(ts_params->valid_devs[0]);
+}
+
+#define IPSEC_MAX_PAD_SIZE     UINT8_MAX
+
+static const uint8_t esp_pad_bytes[IPSEC_MAX_PAD_SIZE] = {
+       1, 2, 3, 4, 5, 6, 7, 8,
+       9, 10, 11, 12, 13, 14, 15, 16,
+       17, 18, 19, 20, 21, 22, 23, 24,
+       25, 26, 27, 28, 29, 30, 31, 32,
+       33, 34, 35, 36, 37, 38, 39, 40,
+       41, 42, 43, 44, 45, 46, 47, 48,
+       49, 50, 51, 52, 53, 54, 55, 56,
+       57, 58, 59, 60, 61, 62, 63, 64,
+       65, 66, 67, 68, 69, 70, 71, 72,
+       73, 74, 75, 76, 77, 78, 79, 80,
+       81, 82, 83, 84, 85, 86, 87, 88,
+       89, 90, 91, 92, 93, 94, 95, 96,
+       97, 98, 99, 100, 101, 102, 103, 104,
+       105, 106, 107, 108, 109, 110, 111, 112,
+       113, 114, 115, 116, 117, 118, 119, 120,
+       121, 122, 123, 124, 125, 126, 127, 128,
+       129, 130, 131, 132, 133, 134, 135, 136,
+       137, 138, 139, 140, 141, 142, 143, 144,
+       145, 146, 147, 148, 149, 150, 151, 152,
+       153, 154, 155, 156, 157, 158, 159, 160,
+       161, 162, 163, 164, 165, 166, 167, 168,
+       169, 170, 171, 172, 173, 174, 175, 176,
+       177, 178, 179, 180, 181, 182, 183, 184,
+       185, 186, 187, 188, 189, 190, 191, 192,
+       193, 194, 195, 196, 197, 198, 199, 200,
+       201, 202, 203, 204, 205, 206, 207, 208,
+       209, 210, 211, 212, 213, 214, 215, 216,
+       217, 218, 219, 220, 221, 222, 223, 224,
+       225, 226, 227, 228, 229, 230, 231, 232,
+       233, 234, 235, 236, 237, 238, 239, 240,
+       241, 242, 243, 244, 245, 246, 247, 248,
+       249, 250, 251, 252, 253, 254, 255,
+};
+
+/* ***** data for tests ***** */
+
+const char null_plain_data[] =
+       "Network Security People Have A Strange Sense Of Humor unlike Other "
+       "People who have a normal sense of humour";
+const char null_encrypted_data[] =
+       "Network Security People Have A Strange Sense Of Humor unlike Other "
+       "People who have a normal sense of humour";
+
+#define DATA_64_BYTES          (64)
+#define DATA_80_BYTES          (80)
+#define DATA_100_BYTES         (100)
+#define INBOUND_SPI                    (7)
+#define OUTBOUND_SPI           (17)
+
+struct ipv4_hdr ipv4_outer  = {
+       .version_ihl = IPVERSION << 4 |
+               sizeof(ipv4_outer) / IPV4_IHL_MULTIPLIER,
+       .time_to_live = IPDEFTTL,
+       .next_proto_id = IPPROTO_ESP,
+       .src_addr = IPv4(192, 168, 1, 100),
+       .dst_addr = IPv4(192, 168, 2, 100),
+};
+
+static struct rte_mbuf *
+setup_test_string(struct rte_mempool *mpool,
+               const char *string, size_t len, uint8_t blocksize)
+{
+       struct rte_mbuf *m = rte_pktmbuf_alloc(mpool);
+       size_t t_len = len - (blocksize ? (len % blocksize) : 0);
+
+       if (m) {
+               memset(m->buf_addr, 0, m->buf_len);
+               char *dst = rte_pktmbuf_append(m, t_len);
+
+               if (!dst) {
+                       rte_pktmbuf_free(m);
+                       return NULL;
+               }
+               if (string != NULL)
+                       rte_memcpy(dst, string, t_len);
+               else
+                       memset(dst, 0, t_len);
+       }
+
+       return m;
+}
+
+static struct rte_mbuf *
+setup_test_string_tunneled(struct rte_mempool *mpool, const char *string,
+       size_t len, uint32_t spi, uint32_t seq)
+{
+       struct rte_mbuf *m = rte_pktmbuf_alloc(mpool);
+       uint32_t hdrlen = sizeof(struct ipv4_hdr) + sizeof(struct esp_hdr);
+       uint32_t taillen = sizeof(struct esp_tail);
+       uint32_t t_len = len + hdrlen + taillen;
+       uint32_t padlen;
+
+       struct esp_hdr esph  = {
+               .spi = rte_cpu_to_be_32(spi),
+               .seq = rte_cpu_to_be_32(seq)
+       };
+
+       padlen = RTE_ALIGN(t_len, 4) - t_len;
+       t_len += padlen;
+
+       struct esp_tail espt  = {
+               .pad_len = padlen,
+               .next_proto = IPPROTO_IPIP,
+       };
+
+       if (m == NULL)
+               return NULL;
+
+       memset(m->buf_addr, 0, m->buf_len);
+       char *dst = rte_pktmbuf_append(m, t_len);
+
+       if (!dst) {
+               rte_pktmbuf_free(m);
+               return NULL;
+       }
+       /* copy outer IP and ESP header */
+       ipv4_outer.total_length = rte_cpu_to_be_16(t_len);
+       ipv4_outer.packet_id = rte_cpu_to_be_16(1);
+       rte_memcpy(dst, &ipv4_outer, sizeof(ipv4_outer));
+       dst += sizeof(ipv4_outer);
+       m->l3_len = sizeof(ipv4_outer);
+       rte_memcpy(dst, &esph, sizeof(esph));
+       dst += sizeof(esph);
+
+       if (string != NULL) {
+               /* copy payload */
+               rte_memcpy(dst, string, len);
+               dst += len;
+               /* copy pad bytes */
+               rte_memcpy(dst, esp_pad_bytes, padlen);
+               dst += padlen;
+               /* copy ESP tail header */
+               rte_memcpy(dst, &espt, sizeof(espt));
+       } else
+               memset(dst, 0, t_len);
+
+       return m;
+}
+
+static int
+check_cryptodev_capablity(const struct crypto_unittest_params *ut,
+               uint8_t devid)
+{
+       struct rte_cryptodev_sym_capability_idx cap_idx;
+       const struct rte_cryptodev_symmetric_capability *cap;
+       int rc = -1;
+
+       cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+       cap_idx.algo.auth = ut->auth_xform.auth.algo;
+       cap = rte_cryptodev_sym_capability_get(devid, &cap_idx);
+
+       if (cap != NULL) {
+               rc = rte_cryptodev_sym_capability_check_auth(cap,
+                               ut->auth_xform.auth.key.length,
+                               ut->auth_xform.auth.digest_length, 0);
+               if (rc == 0) {
+                       cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+                       cap_idx.algo.cipher = ut->cipher_xform.cipher.algo;
+                       cap = rte_cryptodev_sym_capability_get(devid, &cap_idx);
+                       if (cap != NULL)
+                               rc = rte_cryptodev_sym_capability_check_cipher(
+                                       cap,
+                                       ut->cipher_xform.cipher.key.length,
+                                       ut->cipher_xform.cipher.iv.length);
+               }
+       }
+
+       return rc;
+}
+
+static int
+create_dummy_sec_session(struct crypto_unittest_params *ut,
+       struct rte_mempool *pool)
+{
+       static struct rte_security_session_conf conf;
+
+       ut->ss.security.ses = rte_security_session_create(&dummy_sec_ctx,
+                                       &conf, pool);
+
+       if (ut->ss.security.ses == NULL)
+               return -ENOMEM;
+
+       ut->ss.security.ctx = &dummy_sec_ctx;
+       ut->ss.security.ol_flags = 0;
+       return 0;
+}
+
+static int
+create_crypto_session(struct crypto_unittest_params *ut,
+       struct rte_mempool *pool, const uint8_t crypto_dev[],
+       uint32_t crypto_dev_num)
+{
+       int32_t rc;
+       uint32_t devnum, i;
+       struct rte_cryptodev_sym_session *s;
+       uint8_t devid[RTE_CRYPTO_MAX_DEVS];
+
+       /* check which cryptodevs support SA */
+       devnum = 0;
+       for (i = 0; i < crypto_dev_num; i++) {
+               if (check_cryptodev_capablity(ut, crypto_dev[i]) == 0)
+                       devid[devnum++] = crypto_dev[i];
+       }
+
+       if (devnum == 0)
+               return -ENODEV;
+
+       s = rte_cryptodev_sym_session_create(pool);
+       if (s == NULL)
+               return -ENOMEM;
+
+       /* initiliaze SA crypto session for all supported devices */
+       for (i = 0; i != devnum; i++) {
+               rc = rte_cryptodev_sym_session_init(devid[i], s,
+                       ut->crypto_xforms, pool);
+               if (rc != 0)
+                       break;
+       }
+
+       if (i == devnum) {
+               ut->ss.crypto.ses = s;
+               return 0;
+       }
+
+       /* failure, do cleanup */
+       while (i-- != 0)
+               rte_cryptodev_sym_session_clear(devid[i], s);
+
+       rte_cryptodev_sym_session_free(s);
+       return rc;
+}
+
+static int
+create_session(struct crypto_unittest_params *ut,
+       struct rte_mempool *pool, const uint8_t crypto_dev[],
+       uint32_t crypto_dev_num)
+{
+       if (ut->ss.type == RTE_SECURITY_ACTION_TYPE_NONE)
+               return create_crypto_session(ut, pool, crypto_dev,
+                       crypto_dev_num);
+       else
+               return create_dummy_sec_session(ut, pool);
+}
+
+static void
+fill_crypto_xform(struct crypto_unittest_params *ut_params,
+       const struct supported_auth_algo *auth_algo,
+       const struct supported_cipher_algo *cipher_algo)
+{
+       ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+       ut_params->auth_xform.auth.algo = auth_algo->algo;
+       ut_params->auth_xform.auth.key.data = global_key;
+       ut_params->auth_xform.auth.key.length = auth_algo->key_len;
+       ut_params->auth_xform.auth.digest_length = auth_algo->digest_len;
+
+       ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
+       ut_params->auth_xform.next = &ut_params->cipher_xform;
+
+       ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+       ut_params->cipher_xform.cipher.algo = cipher_algo->algo;
+       ut_params->cipher_xform.cipher.key.data = global_key;
+       ut_params->cipher_xform.cipher.key.length = cipher_algo->key_len;
+       ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT;
+       ut_params->cipher_xform.cipher.iv.offset = IV_OFFSET;
+       ut_params->cipher_xform.cipher.iv.length = cipher_algo->iv_len;
+       ut_params->cipher_xform.next = NULL;
+
+       ut_params->crypto_xforms = &ut_params->auth_xform;
+}
+
+static int
+fill_ipsec_param(uint32_t spi, enum rte_security_ipsec_sa_direction direction,
+               uint32_t replay_win_sz, uint64_t flags)
+{
+       struct crypto_unittest_params *ut_params = &unittest_params;
+       struct rte_ipsec_sa_prm *prm = &ut_params->sa_prm;
+       const struct supported_auth_algo *auth_algo;
+       const struct supported_cipher_algo *cipher_algo;
+
+       memset(prm, 0, sizeof(*prm));
+
+       prm->userdata = 1;
+       prm->flags = flags;
+       prm->replay_win_sz = replay_win_sz;
+
+       /* setup ipsec xform */
+       prm->ipsec_xform.spi = spi;
+       prm->ipsec_xform.salt = (uint32_t)rte_rand();
+       prm->ipsec_xform.direction = direction;
+       prm->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
+       prm->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
+
+       /* setup tunnel related fields */
+       prm->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
+       prm->tun.hdr_len = sizeof(ipv4_outer);
+       prm->tun.next_proto = IPPROTO_IPIP;
+       prm->tun.hdr = &ipv4_outer;
+
+       /* setup crypto section */
+       if (uparams.aead != 0) {
+               /* TODO: will need to fill out with other test cases */
+       } else {
+               if (uparams.auth == 0 && uparams.cipher == 0)
+                       return TEST_FAILED;
+
+               auth_algo = find_match_auth_algo(uparams.auth_algo);
+               cipher_algo = find_match_cipher_algo(uparams.cipher_algo);
+
+               fill_crypto_xform(ut_params, auth_algo, cipher_algo);
+       }
+
+       prm->crypto_xform = ut_params->crypto_xforms;
+       return TEST_SUCCESS;
+}
+
+static int
+create_sa(uint32_t spi, enum rte_security_ipsec_sa_direction direction,
+               enum rte_security_session_action_type action_type,
+               uint32_t replay_win_sz, uint64_t flags)
+{
+       struct crypto_testsuite_params *ts = &testsuite_params;
+       struct crypto_unittest_params *ut = &unittest_params;
+       size_t sz;
+       int rc;
+
+       const struct rte_ipsec_sa_prm prm = {
+               .flags = flags,
+               .ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+               .replay_win_sz = replay_win_sz,
+       };
+
+       memset(&ut->ss, 0, sizeof(ut->ss));
+
+       /* create rte_ipsec_sa*/
+       sz = rte_ipsec_sa_size(&prm);
+       TEST_ASSERT(sz > 0, "rte_ipsec_sa_size() failed\n");
+       ut->ss.sa = rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE);
+       TEST_ASSERT_NOT_NULL(ut->ss.sa,
+               "failed to allocate memory for rte_ipsec_sa\n");
+
+       rc = fill_ipsec_param(spi, direction, replay_win_sz, flags);
+       if (rc != 0)
+               return TEST_FAILED;
+
+       ut->ss.type = action_type;
+       rc = create_session(ut, ts->session_mpool, ts->valid_devs,
+               ts->valid_dev_count);
+       if (rc != 0)
+               return TEST_FAILED;
+
+       rc = rte_ipsec_sa_init(ut->ss.sa, &ut->sa_prm, sz);
+       rc = (rc > 0 && (uint32_t)rc <= sz) ? 0 : -EINVAL;
+
+       return rte_ipsec_session_prepare(&ut->ss);
+}
+
+static int
+crypto_ipsec(void)
+{
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+       struct crypto_unittest_params *ut_params = &unittest_params;
+       uint32_t k, n;
+       struct rte_ipsec_group grp[1];
+
+       /* call crypto prepare */
+       k = rte_ipsec_crypto_prepare(&ut_params->ss, &ut_params->ibuf,
+               &ut_params->op, 1);
+       if (k != 1) {
+               RTE_LOG(ERR, USER1, "rte_ipsec_crypto_prepare fail\n");
+               return TEST_FAILED;
+       }
+       k = rte_cryptodev_enqueue_burst(ts_params->valid_devs[0], 0,
+               &ut_params->op, k);
+       if (k != 1) {
+               RTE_LOG(ERR, USER1, "rte_cryptodev_enqueue_burst fail\n");
+               return TEST_FAILED;
+       }
+
+       n = rte_cryptodev_dequeue_burst(ts_params->valid_devs[0], 0,
+               &ut_params->op, RTE_DIM(&ut_params->op));
+       if (n != 1) {
+               RTE_LOG(ERR, USER1, "rte_cryptodev_dequeue_burst fail\n");
+               return TEST_FAILED;
+       }
+
+       n = rte_ipsec_crypto_group(
+               (const struct rte_crypto_op **)(uintptr_t)&ut_params->op,
+               &ut_params->obuf, grp, n);
+       if (n != 1 || grp[0].m[0] != ut_params->obuf || grp[0].cnt != 1 ||
+                grp[0].id.ptr != &ut_params->ss) {
+               RTE_LOG(ERR, USER1, "rte_ipsec_crypto_group fail\n");
+               return TEST_FAILED;
+       }
+
+       /* call crypto process */
+       n = rte_ipsec_process(grp[0].id.ptr, grp[0].m, grp[0].cnt);
+
+       if (n != 1) {
+               RTE_LOG(ERR, USER1, "rte_ipsec_crypto_process fail\n");
+               return TEST_FAILED;
+       }
+
+       return TEST_SUCCESS;
+}
+
+static int
+test_ipsec_crypto_op_alloc(void)
+{
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+       struct crypto_unittest_params *ut_params = &unittest_params;
+       int rc = 0;
+
+       ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool,
+                               RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+       if (ut_params->op != NULL)
+               ut_params->op->sym[0].m_src = ut_params->ibuf;
+       else {
+               RTE_LOG(ERR, USER1,
+                       "Failed to allocate symmetric crypto operation 
struct\n");
+               rc = TEST_FAILED;
+       }
+       return rc;
+}
+
+static void
+test_ipsec_dump_buffers(struct crypto_unittest_params *ut_params)
+{
+       if (ut_params->ibuf) {
+               printf("ibuf data:\n");
+               rte_pktmbuf_dump(stdout, ut_params->ibuf,
+                       ut_params->ibuf->data_len);
+       }
+       if (ut_params->obuf) {
+               printf("obuf data:\n");
+               rte_pktmbuf_dump(stdout, ut_params->obuf,
+                       ut_params->obuf->data_len);
+       }
+       if (ut_params->testbuf) {
+               printf("testbuf data:\n");
+               rte_pktmbuf_dump(stdout, ut_params->testbuf,
+                       ut_params->testbuf->data_len);
+       }
+}
+
+static int
+crypto_inb_null_null_check(struct crypto_unittest_params *ut_params)
+{
+       /* compare the data buffers */
+       TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data,
+                       rte_pktmbuf_mtod(ut_params->obuf, void *),
+                       DATA_64_BYTES,
+                       "input and output data does not match\n");
+       TEST_ASSERT_EQUAL(ut_params->obuf->data_len, ut_params->obuf->pkt_len,
+               "data_len is not equal to pkt_len");
+       TEST_ASSERT_EQUAL(ut_params->obuf->data_len, DATA_64_BYTES,
+               "data_len is not equal to input data");
+       return 0;
+}
+
+static void
+destroy_sa(void)
+{
+       struct crypto_unittest_params *ut = &unittest_params;
+
+       rte_ipsec_sa_fini(ut->ss.sa);
+       rte_free(ut->ss.sa);
+       rte_cryptodev_sym_session_free(ut->ss.crypto.ses);
+       memset(&ut->ss, 0, sizeof(ut->ss));
+}
+
+static int
+test_ipsec_crypto_inb_null_null(void)
+{
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+       struct crypto_unittest_params *ut_params = &unittest_params;
+       int rc;
+
+       uparams.auth = RTE_CRYPTO_SYM_XFORM_AUTH;
+       uparams.cipher = RTE_CRYPTO_SYM_XFORM_CIPHER;
+       strcpy(uparams.auth_algo, "null");
+       strcpy(uparams.cipher_algo, "null");
+
+       /* create rte_ipsec_sa*/
+       rc = create_sa(INBOUND_SPI, RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+                       RTE_SECURITY_ACTION_TYPE_NONE, 0, 0);
+       if (rc != 0) {
+               RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed\n");
+               return TEST_FAILED;
+       }
+
+       /* Generate test mbuf data */
+       ut_params->ibuf = setup_test_string_tunneled(ts_params->mbuf_pool,
+               null_encrypted_data, DATA_64_BYTES, INBOUND_SPI, 1);
+
+       rc = test_ipsec_crypto_op_alloc();
+       if (rc == 0) {
+               /* call ipsec library api */
+               rc = crypto_ipsec();
+               if (rc == 0)
+                       rc = crypto_inb_null_null_check(ut_params);
+               else {
+                       RTE_LOG(ERR, USER1, "crypto_ipsec failed\n");
+                       rc = TEST_FAILED;
+               }
+       }
+
+       if (rc == TEST_FAILED)
+               test_ipsec_dump_buffers(ut_params);
+
+       destroy_sa();
+       return rc;
+}
+
+static int
+crypto_outb_null_null_check(struct crypto_unittest_params *ut_params)
+{
+       void *obuf_data;
+       void *testbuf_data;
+
+       /* compare the buffer data */
+       testbuf_data = rte_pktmbuf_mtod(ut_params->testbuf, void *);
+       obuf_data = rte_pktmbuf_mtod(ut_params->obuf, void *);
+
+       TEST_ASSERT_BUFFERS_ARE_EQUAL(testbuf_data, obuf_data,
+               ut_params->obuf->pkt_len,
+               "test and output data does not match\n");
+       TEST_ASSERT_EQUAL(ut_params->obuf->data_len,
+               ut_params->testbuf->data_len,
+               "obuf data_len is not equal to testbuf data_len");
+       TEST_ASSERT_EQUAL(ut_params->obuf->pkt_len,
+               ut_params->testbuf->pkt_len,
+               "obuf pkt_len is not equal to testbuf pkt_len");
+
+       return 0;
+}
+
+static int
+test_ipsec_crypto_outb_null_null(void)
+{
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+       struct crypto_unittest_params *ut_params = &unittest_params;
+       int32_t rc;
+
+       uparams.auth = RTE_CRYPTO_SYM_XFORM_AUTH;
+       uparams.cipher = RTE_CRYPTO_SYM_XFORM_CIPHER;
+       strcpy(uparams.auth_algo, "null");
+       strcpy(uparams.cipher_algo, "null");
+
+       /* create rte_ipsec_sa*/
+       rc = create_sa(OUTBOUND_SPI, RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
+                       RTE_SECURITY_ACTION_TYPE_NONE, 0, 0);
+       if (rc != 0) {
+               RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed\n");
+               return TEST_FAILED;
+       }
+
+       /* Generate input mbuf data */
+       ut_params->ibuf = setup_test_string(ts_params->mbuf_pool,
+               null_plain_data, DATA_80_BYTES, 0);
+
+       /* Generate test mbuf data */
+       ut_params->testbuf = setup_test_string_tunneled(ts_params->mbuf_pool,
+               null_plain_data, DATA_80_BYTES, OUTBOUND_SPI, 1);
+
+       rc = test_ipsec_crypto_op_alloc();
+       if (rc == 0) {
+               /* call ipsec library api */
+               rc = crypto_ipsec();
+               if (rc == 0)
+                       rc = crypto_outb_null_null_check(ut_params);
+               else
+                       RTE_LOG(ERR, USER1, "crypto_ipsec failed\n");
+       }
+
+       if (rc == TEST_FAILED)
+               test_ipsec_dump_buffers(ut_params);
+
+       destroy_sa();
+       return rc;
+}
+
+static int
+inline_inb_null_null_check(struct crypto_unittest_params *ut_params)
+{
+       void *ibuf_data;
+       void *obuf_data;
+
+       /* compare the buffer data */
+       ibuf_data = rte_pktmbuf_mtod(ut_params->ibuf, void *);
+       obuf_data = rte_pktmbuf_mtod(ut_params->obuf, void *);
+
+       TEST_ASSERT_BUFFERS_ARE_EQUAL(ibuf_data, obuf_data,
+               ut_params->ibuf->data_len,
+               "input and output data does not match\n");
+       TEST_ASSERT_EQUAL(ut_params->ibuf->data_len, ut_params->obuf->data_len,
+               "ibuf data_len is not equal to obuf data_len");
+       TEST_ASSERT_EQUAL(ut_params->ibuf->pkt_len, ut_params->obuf->pkt_len,
+               "ibuf pkt_len is not equal to obuf pkt_len");
+       TEST_ASSERT_EQUAL(ut_params->ibuf->data_len, DATA_100_BYTES,
+               "data_len is not equal input data");
+
+       return 0;
+}
+
+static int
+test_ipsec_inline_inb_null_null(void)
+{
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+       struct crypto_unittest_params *ut_params = &unittest_params;
+
+       int32_t rc;
+       uint32_t n;
+
+       uparams.auth = RTE_CRYPTO_SYM_XFORM_AUTH;
+       uparams.cipher = RTE_CRYPTO_SYM_XFORM_CIPHER;
+       strcpy(uparams.auth_algo, "null");
+       strcpy(uparams.cipher_algo, "null");
+
+       /* create rte_ipsec_sa*/
+       rc = create_sa(INBOUND_SPI, RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+                       RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, 0, 0);
+       if (rc != 0) {
+               RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed\n");
+               return TEST_FAILED;
+       }
+
+       /* Generate inbound mbuf data */
+       ut_params->ibuf = setup_test_string_tunneled(ts_params->mbuf_pool,
+               null_plain_data, DATA_100_BYTES, INBOUND_SPI, 1);
+
+       /* Generate test mbuf data */
+       ut_params->obuf = setup_test_string(ts_params->mbuf_pool,
+               null_plain_data, DATA_100_BYTES, 0);
+
+       n = rte_ipsec_process(&ut_params->ss, &ut_params->ibuf, 1);
+       if (n == 1)
+               rc = inline_inb_null_null_check(ut_params);
+       else {
+               RTE_LOG(ERR, USER1, "rte_ipsec_process failed\n");
+               rc = TEST_FAILED;
+       }
+
+       if (rc == TEST_FAILED)
+               test_ipsec_dump_buffers(ut_params);
+
+       destroy_sa();
+       return rc;
+}
+
+static int
+inline_outb_null_null_check(struct crypto_unittest_params *ut_params)
+{
+       void *obuf_data;
+       void *ibuf_data;
+
+       /* compare the buffer data */
+       ibuf_data = rte_pktmbuf_mtod(ut_params->ibuf, void *);
+       obuf_data = rte_pktmbuf_mtod(ut_params->obuf, void *);
+       TEST_ASSERT_BUFFERS_ARE_EQUAL(ibuf_data, obuf_data,
+               ut_params->ibuf->data_len,
+               "input and output data does not match\n");
+       TEST_ASSERT_EQUAL(ut_params->ibuf->data_len,
+               ut_params->obuf->data_len,
+               "ibuf data_len is not equal to obuf data_len");
+       TEST_ASSERT_EQUAL(ut_params->ibuf->pkt_len,
+               ut_params->obuf->pkt_len,
+               "ibuf pkt_len is not equal to obuf pkt_len");
+
+       return 0;
+}
+
+static int
+test_ipsec_inline_outb_null_null(void)
+{
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+       struct crypto_unittest_params *ut_params = &unittest_params;
+       int32_t rc;
+       uint32_t n;
+
+       uparams.auth = RTE_CRYPTO_SYM_XFORM_AUTH;
+       uparams.cipher = RTE_CRYPTO_SYM_XFORM_CIPHER;
+       strcpy(uparams.auth_algo, "null");
+       strcpy(uparams.cipher_algo, "null");
+
+       /* create rte_ipsec_sa*/
+       rc = create_sa(OUTBOUND_SPI, RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
+                       RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO, 0, 0);
+       if (rc != 0) {
+               RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed\n");
+               return TEST_FAILED;
+       }
+
+       /* Generate test mbuf data */
+       ut_params->ibuf = setup_test_string(ts_params->mbuf_pool,
+               null_plain_data, DATA_100_BYTES, 0);
+
+       /* Generate test tunneled mbuf data for comparison*/
+       ut_params->obuf = setup_test_string_tunneled(ts_params->mbuf_pool,
+               null_plain_data, DATA_100_BYTES, OUTBOUND_SPI, 1);
+
+       n = rte_ipsec_process(&ut_params->ss, &ut_params->ibuf, 1);
+       if (n == 1)
+               rc = inline_outb_null_null_check(ut_params);
+       else {
+               RTE_LOG(ERR, USER1, "rte_ipsec_process failed\n");
+               rc = TEST_FAILED;
+       }
+
+       if (rc == TEST_FAILED)
+               test_ipsec_dump_buffers(ut_params);
+
+       destroy_sa();
+       return rc;
+}
+
+#define REPLAY_WIN_64  64
+
+static int
+replay_inb_null_null_check(struct crypto_unittest_params *ut_params)
+{
+       /* compare the buffer data */
+       TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data,
+               rte_pktmbuf_mtod(ut_params->obuf, void *),
+               DATA_64_BYTES,
+               "input and output data does not match\n");
+       TEST_ASSERT_EQUAL(ut_params->obuf->data_len, ut_params->obuf->pkt_len,
+               "data_len is not equal to pkt_len");
+
+       return 0;
+}
+
+static int
+test_ipsec_replay_inb_inside_null_null(void)
+{
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+       struct crypto_unittest_params *ut_params = &unittest_params;
+       int rc;
+
+       uparams.auth = RTE_CRYPTO_SYM_XFORM_AUTH;
+       uparams.cipher = RTE_CRYPTO_SYM_XFORM_CIPHER;
+       strcpy(uparams.auth_algo, "null");
+       strcpy(uparams.cipher_algo, "null");
+
+       /* create rte_ipsec_sa*/
+       rc = create_sa(INBOUND_SPI, RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+                       RTE_SECURITY_ACTION_TYPE_NONE, REPLAY_WIN_64, 0);
+       if (rc != 0) {
+               RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed\n");
+               return TEST_FAILED;
+       }
+
+       /* Generate test mbuf data */
+       ut_params->ibuf = setup_test_string_tunneled(ts_params->mbuf_pool,
+               null_encrypted_data, DATA_64_BYTES, INBOUND_SPI, 1);
+
+       rc = test_ipsec_crypto_op_alloc();
+       if (rc == 0) {
+               /* call ipsec library api */
+               rc = crypto_ipsec();
+               if (rc == 0)
+                       rc = replay_inb_null_null_check(ut_params);
+               else {
+                       RTE_LOG(ERR, USER1, "crypto_ipsec failed\n");
+                       rc = TEST_FAILED;
+               }
+       } else {
+               RTE_LOG(ERR, USER1,
+                       "Failed to allocate symmetric crypto operation 
struct\n");
+               rc = TEST_FAILED;
+       }
+
+       if (rc == 0) {
+               /* generate packet with seq number inside the replay window */
+               if (ut_params->ibuf) {
+                       rte_pktmbuf_free(ut_params->ibuf);
+                       ut_params->ibuf = 0;
+               }
+
+               ut_params->ibuf = setup_test_string_tunneled(
+                       ts_params->mbuf_pool, null_encrypted_data,
+                       DATA_64_BYTES, INBOUND_SPI, REPLAY_WIN_64);
+
+               rc = test_ipsec_crypto_op_alloc();
+               if (rc == 0) {
+                       /* call ipsec library api */
+                       rc = crypto_ipsec();
+                       if (rc == 0)
+                               rc = replay_inb_null_null_check(ut_params);
+                       else {
+                               RTE_LOG(ERR, USER1, "crypto_ipsec failed\n");
+                               rc = TEST_FAILED;
+                       }
+               }
+       }
+
+       if (rc == TEST_FAILED)
+               test_ipsec_dump_buffers(ut_params);
+
+       destroy_sa();
+
+       return rc;
+}
+
+static int
+test_ipsec_replay_inb_outside_null_null(void)
+{
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+       struct crypto_unittest_params *ut_params = &unittest_params;
+       int rc;
+
+       uparams.auth = RTE_CRYPTO_SYM_XFORM_AUTH;
+       uparams.cipher = RTE_CRYPTO_SYM_XFORM_CIPHER;
+       strcpy(uparams.auth_algo, "null");
+       strcpy(uparams.cipher_algo, "null");
+
+       /* create rte_ipsec_sa */
+       rc = create_sa(INBOUND_SPI, RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+                       RTE_SECURITY_ACTION_TYPE_NONE, REPLAY_WIN_64, 0);
+       if (rc != 0) {
+               RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed\n");
+               return TEST_FAILED;
+       }
+
+       /* Generate test mbuf data */
+       ut_params->ibuf = setup_test_string_tunneled(ts_params->mbuf_pool,
+               null_encrypted_data, DATA_64_BYTES, INBOUND_SPI,
+               REPLAY_WIN_64 + 2);
+
+       rc = test_ipsec_crypto_op_alloc();
+       if (rc == 0) {
+               /* call ipsec library api */
+               rc = crypto_ipsec();
+               if (rc == 0)
+                       rc = replay_inb_null_null_check(ut_params);
+               else {
+                       RTE_LOG(ERR, USER1, "crypto_ipsec failed\n");
+                       rc = TEST_FAILED;
+               }
+       }
+
+       if (rc == 0) {
+               /* generate packet with seq number outside the replay window */
+               if (ut_params->ibuf) {
+                       rte_pktmbuf_free(ut_params->ibuf);
+                       ut_params->ibuf = 0;
+               }
+               ut_params->ibuf = setup_test_string_tunneled(
+                       ts_params->mbuf_pool, null_encrypted_data,
+                       DATA_64_BYTES, INBOUND_SPI, 1);
+
+               rc = test_ipsec_crypto_op_alloc();
+               if (rc == 0) {
+                       /* call ipsec library api */
+                       rc = crypto_ipsec();
+                       if (rc == 0) {
+                               RTE_LOG(ERR, USER1,
+                                       "packet is not outside the replay 
window\n");
+                               rc = TEST_FAILED;
+                       } else {
+                               RTE_LOG(ERR, USER1,
+                                       "packet is outside the replay 
window\n");
+                               rc = 0;
+                       }
+               }
+       }
+
+       if (rc == TEST_FAILED)
+               test_ipsec_dump_buffers(ut_params);
+
+       destroy_sa();
+
+       return rc;
+}
+
+static int
+test_ipsec_replay_inb_repeat_null_null(void)
+{
+       struct crypto_testsuite_params *ts_params = &testsuite_params;
+       struct crypto_unittest_params *ut_params = &unittest_params;
+       int rc;
+
+       uparams.auth = RTE_CRYPTO_SYM_XFORM_AUTH;
+       uparams.cipher = RTE_CRYPTO_SYM_XFORM_CIPHER;
+       strcpy(uparams.auth_algo, "null");
+       strcpy(uparams.cipher_algo, "null");
+
+       /* create rte_ipsec_sa */
+       rc = create_sa(INBOUND_SPI, RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+                       RTE_SECURITY_ACTION_TYPE_NONE, REPLAY_WIN_64, 0);
+       if (rc != 0) {
+               RTE_LOG(ERR, USER1, "rte_ipsec_sa_init failed\n");
+               return TEST_FAILED;
+       }
+
+       /* Generate test mbuf data */
+       ut_params->ibuf = setup_test_string_tunneled(ts_params->mbuf_pool,
+               null_encrypted_data, DATA_64_BYTES, INBOUND_SPI, 1);
+
+       rc = test_ipsec_crypto_op_alloc();
+       if (rc == 0) {
+               /* call ipsec library api */
+               rc = crypto_ipsec();
+               if (rc == 0)
+                       rc = replay_inb_null_null_check(ut_params);
+               else {
+                       RTE_LOG(ERR, USER1, "crypto_ipsec failed\n");
+                       rc = TEST_FAILED;
+               }
+       }
+
+       if (rc == 0) {
+               /*
+                * generate packet with repeat seq number in the replay
+                * window
+                */
+               if (ut_params->ibuf) {
+                       rte_pktmbuf_free(ut_params->ibuf);
+                       ut_params->ibuf = 0;
+               }
+               ut_params->ibuf = setup_test_string_tunneled(
+                       ts_params->mbuf_pool, null_encrypted_data,
+                       DATA_64_BYTES, INBOUND_SPI, 1);
+
+               rc = test_ipsec_crypto_op_alloc();
+               if (rc == 0) {
+                       /* call ipsec library api */
+                       rc = crypto_ipsec();
+                       if (rc == 0) {
+                               RTE_LOG(ERR, USER1,
+                                       "packet is not repeated in the replay 
window\n");
+                               rc = TEST_FAILED;
+                       } else {
+                               RTE_LOG(ERR, USER1,
+                                       "packet is repeated in the replay 
window\n");
+                               rc = 0;
+                       }
+               }
+       }
+
+       if (rc == TEST_FAILED)
+               test_ipsec_dump_buffers(ut_params);
+
+       destroy_sa();
+
+       return rc;
+}
+
+static struct unit_test_suite ipsec_testsuite  = {
+       .suite_name = "IPsec NULL Unit Test Suite",
+       .setup = testsuite_setup,
+       .teardown = testsuite_teardown,
+       .unit_test_cases = {
+
+               TEST_CASE_ST(ut_setup, ut_teardown,
+                               test_ipsec_crypto_inb_null_null),
+               TEST_CASE_ST(ut_setup, ut_teardown,
+                               test_ipsec_crypto_outb_null_null),
+               TEST_CASE_ST(ut_setup, ut_teardown,
+                               test_ipsec_inline_inb_null_null),
+               TEST_CASE_ST(ut_setup, ut_teardown,
+                               test_ipsec_inline_outb_null_null),
+               TEST_CASE_ST(ut_setup, ut_teardown,
+                               test_ipsec_replay_inb_inside_null_null),
+               TEST_CASE_ST(ut_setup, ut_teardown,
+                               test_ipsec_replay_inb_outside_null_null),
+               TEST_CASE_ST(ut_setup, ut_teardown,
+                               test_ipsec_replay_inb_repeat_null_null),
+               TEST_CASES_END() /**< NULL terminate unit test array */
+       }
+};
+
+static int
+test_ipsec(void)
+{
+       return unit_test_suite_runner(&ipsec_testsuite);
+}
+
+REGISTER_TEST_COMMAND(ipsec_autotest, test_ipsec);
-- 
2.13.6

Reply via email to