diff mbox

[v2,1/1] cunit : add tests for crypto APIs

Message ID 1414757327-32308-1-git-send-email-alexandru.badicioiu@linaro.org
State New
Headers show

Commit Message

Alexandru Badicioiu Oct. 31, 2014, 12:08 p.m. UTC
From: Alexandru Badicioiu <alexandru.badicioiu@linaro.org>

This patch adds a suite for async inplace mode of crypto APIs.
Correctness of crypto operations output is verified with known
test vectors  as well as various options and functionalities:
use session IV or operation IV for ciphering, use input packet
buffer or a separate buffer as the completion event, set and
retrieve the context associated with an operation.

Signed-off-by: Alexandru Badicioiu <alexandru.badicioiu@linaro.org>
---
 configure.ac                                  |    1 +
 test/cunit/Makefile.am                        |    2 +
 test/cunit/crypto/Makefile.am                 |    9 +
 test/cunit/crypto/odp_crypto_test.c           |   26 ++
 test/cunit/crypto/odp_crypto_test_async_inp.c |  459 +++++++++++++++++++++++++
 test/cunit/crypto/odp_crypto_test_async_inp.h |   13 +
 test/cunit/crypto/test_vectors.h              |   94 +++++
 7 files changed, 604 insertions(+), 0 deletions(-)
 create mode 100644 test/cunit/crypto/Makefile.am
 create mode 100644 test/cunit/crypto/odp_crypto_test.c
 create mode 100644 test/cunit/crypto/odp_crypto_test_async_inp.c
 create mode 100644 test/cunit/crypto/odp_crypto_test_async_inp.h
 create mode 100644 test/cunit/crypto/test_vectors.h

Comments

Jerin Jacob Oct. 31, 2014, 2:28 p.m. UTC | #1
On Fri, Oct 31, 2014 at 02:08:47PM +0200, alexandru.badicioiu@linaro.org wrote:
> From: Alexandru Badicioiu <alexandru.badicioiu@linaro.org>
> 
> This patch adds a suite for async inplace mode of crypto APIs.
> Correctness of crypto operations output is verified with known
> test vectors  as well as various options and functionalities:
> use session IV or operation IV for ciphering, use input packet
> buffer or a separate buffer as the completion event, set and
> retrieve the context associated with an operation.

IMO crypto functionality unit tests should be capable of running on both sync and async modes.
Platform like octeon supports only sync crypto mode.
We can introduce a command-line option to select the mode for functional testcases.
We can have separate  dedicated test to verify async/sync operation but crypto functional tests
should cater both.

Jerin

> 
> Signed-off-by: Alexandru Badicioiu <alexandru.badicioiu@linaro.org>
> ---
>  configure.ac                                  |    1 +
>  test/cunit/Makefile.am                        |    2 +
>  test/cunit/crypto/Makefile.am                 |    9 +
>  test/cunit/crypto/odp_crypto_test.c           |   26 ++
>  test/cunit/crypto/odp_crypto_test_async_inp.c |  459 +++++++++++++++++++++++++
>  test/cunit/crypto/odp_crypto_test_async_inp.h |   13 +
>  test/cunit/crypto/test_vectors.h              |   94 +++++
>  7 files changed, 604 insertions(+), 0 deletions(-)
>  create mode 100644 test/cunit/crypto/Makefile.am
>  create mode 100644 test/cunit/crypto/odp_crypto_test.c
>  create mode 100644 test/cunit/crypto/odp_crypto_test_async_inp.c
>  create mode 100644 test/cunit/crypto/odp_crypto_test_async_inp.h
>  create mode 100644 test/cunit/crypto/test_vectors.h
> 
> diff --git a/configure.ac b/configure.ac
> index fd69e85..b1785e9 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -166,6 +166,7 @@ AC_CONFIG_FILES([Makefile
>  		 test/Makefile
>  		 test/api_test/Makefile
>                   test/cunit/Makefile
> +		 test/cunit/crypto/Makefile
>  		 pkgconfig/libodp.pc])
>  
>  AC_SEARCH_LIBS([timer_create],[rt posix4])
> diff --git a/test/cunit/Makefile.am b/test/cunit/Makefile.am
> index 927a5a5..7611145 100644
> --- a/test/cunit/Makefile.am
> +++ b/test/cunit/Makefile.am
> @@ -3,6 +3,8 @@ include $(top_srcdir)/test/Makefile.inc
>  AM_CFLAGS += -I$(CUNIT_PATH)/include
>  AM_LDFLAGS += -L$(CUNIT_PATH)/lib
>  
> +SUBDIRS = crypto
> +
>  if ODP_CUNIT_ENABLED
>  TESTS = ${bin_PROGRAMS}
>  check_PROGRAMS = ${bin_PROGRAMS}
> diff --git a/test/cunit/crypto/Makefile.am b/test/cunit/crypto/Makefile.am
> new file mode 100644
> index 0000000..b984eaa
> --- /dev/null
> +++ b/test/cunit/crypto/Makefile.am
> @@ -0,0 +1,9 @@
> +include $(top_srcdir)/test/Makefile.inc
> +
> +if ODP_CUNIT_ENABLED
> +bin_PROGRAMS = odp_crypto
> +odp_crypto_LDFLAGS = $(AM_LDFLAGS) -static -lcunit
> +endif
> +
> +dist_odp_crypto_SOURCES = odp_crypto_test_async_inp.c \
> +			  odp_crypto_test.c
> diff --git a/test/cunit/crypto/odp_crypto_test.c b/test/cunit/crypto/odp_crypto_test.c
> new file mode 100644
> index 0000000..b5d0dea
> --- /dev/null
> +++ b/test/cunit/crypto/odp_crypto_test.c
> @@ -0,0 +1,26 @@
> +/* Copyright (c) 2014, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:     BSD-3-Clause
> + */
> +
> +#include <odp.h>
> +#include "CUnit/Headers/Basic.h"
> +#include "CUnit/Headers/TestDB.h"
> +#include "odp_crypto_test_async_inp.h"
> +
> +int main(void)
> +{
> +	/* initialize the CUnit test registry */
> +	if (CUE_SUCCESS != CU_initialize_registry())
> +		return CU_get_error();
> +
> +	/* register suites */
> +	CU_register_suites(suites);
> +	/* Run all tests using the CUnit Basic interface */
> +	CU_basic_set_mode(CU_BRM_VERBOSE);
> +	CU_basic_run_tests();
> +	CU_cleanup_registry();
> +
> +	return CU_get_error();
> +}
> diff --git a/test/cunit/crypto/odp_crypto_test_async_inp.c b/test/cunit/crypto/odp_crypto_test_async_inp.c
> new file mode 100644
> index 0000000..dd5fb5f
> --- /dev/null
> +++ b/test/cunit/crypto/odp_crypto_test_async_inp.c
> @@ -0,0 +1,458 @@
> +/* Copyright (c) 2014, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:	BSD-3-Clause
> + */
> +
> +#include <odp.h>
> +#include <odp_crypto.h>
> +#include "CUnit/Headers/Basic.h"
> +#include "CUnit/Headers/TestDB.h"
> +#include "test_vectors.h"
> +
> +/* Suite name */
> +#define ODP_CRYPTO_ASYNC_INP	"odp_crypto_async_inp"
> +
> +/* Suite init/finalize funcs */
> +/* ODP global/local initialization
> + * Packet pool creation
> + * Crypto output queue creation */
> +
> +#define SHM_PKT_POOL_SIZE      (512*2048*2)
> +#define SHM_PKT_POOL_BUF_SIZE  (1024 * 32)
> +
> +#define SHM_COMPL_POOL_SIZE	(128*1024)
> +#define SHM_COMPL_POOL_BUF_SIZE 128
> +
> +static int init(void)
> +{
> +	odp_shm_t shm;
> +	void *pool_base = NULL;
> +	odp_buffer_pool_t pool;
> +	odp_queue_t out_queue;
> +
> +	if (odp_init_global(NULL, NULL)) {
> +		ODP_ERR("ODP global init failed.\n");
> +		return -1;
> +	}
> +	odp_init_local();
> +
> +	shm = odp_shm_reserve("shm_packet_pool",
> +			      SHM_PKT_POOL_SIZE,
> +			      ODP_CACHE_LINE_SIZE, 0);
> +
> +	pool_base = odp_shm_addr(shm);
> +	if (!pool_base) {
> +		ODP_ERR("Packet pool allocation failed.\n");
> +		return -1;
> +	}
> +
> +	pool = odp_buffer_pool_create("packet_pool", pool_base,
> +				      SHM_PKT_POOL_SIZE,
> +				      SHM_PKT_POOL_BUF_SIZE,
> +				      ODP_CACHE_LINE_SIZE,
> +				      ODP_BUFFER_TYPE_PACKET);
> +	if (pool == ODP_BUFFER_POOL_INVALID) {
> +		ODP_ERR("Packet pool creation failed.\n");
> +		return -1;
> +	}
> +	out_queue = odp_queue_create("crypto-out",
> +				     ODP_QUEUE_TYPE_POLL, NULL);
> +	if (out_queue == ODP_QUEUE_INVALID) {
> +		ODP_ERR("Crypto outq creation failed.\n");
> +		return -1;
> +	}
> +	shm = odp_shm_reserve("shm_compl_pool",
> +			     SHM_COMPL_POOL_SIZE,
> +			     ODP_CACHE_LINE_SIZE,
> +			     ODP_SHM_SW_ONLY);
> +	pool_base = odp_shm_addr(shm);
> +	if (!pool_base) {
> +		ODP_ERR("Completion pool allocation failed.\n");
> +		return -1;
> +	}
> +	pool = odp_buffer_pool_create("compl_pool", pool_base,
> +				      SHM_COMPL_POOL_SIZE,
> +				      SHM_COMPL_POOL_BUF_SIZE,
> +				      ODP_CACHE_LINE_SIZE,
> +				      ODP_BUFFER_TYPE_RAW);
> +	if (pool == ODP_BUFFER_POOL_INVALID) {
> +		ODP_ERR("Completion pool creation failed.\n");
> +		return -1;
> +	}
> +
> +	printf("\tODP version: %s\n", odp_version_api_str());
> +	return 0;
> +}
> +
> +/* ODP cleanup */
> +static int finalize(void)
> +{
> +	odp_term_local();
> +	odp_term_global();
> +	return 0;
> +}
> +
> +
> +/* Basic algorithm run function.
> + * Creates a session from input parameters and runs one operation
> + * on input_vec. Checks the output of the crypto operation against
> + * output_vec. Operation completion event is dequeued polling the
> + * session output queue. Completion context pointer is retrieved
> + * and checked against the one set before the operation.
> + * */
> +static void alg_test(enum odp_crypto_op op,
> +		     enum odp_cipher_alg cipher_alg,
> +		     odp_crypto_iv_t ses_iv,
> +		     uint8_t *op_iv_ptr,
> +		     odp_crypto_key_t cipher_key,
> +		     enum odp_auth_alg auth_alg,
> +		     odp_crypto_key_t auth_key,
> +		     odp_buffer_t compl_new,
> +		     uint8_t *input_vec,
> +		     unsigned int input_vec_len,
> +		     uint8_t *output_vec,
> +		     unsigned int output_vec_len)
> +{
> +	odp_crypto_session_t session;
> +	int rc;
> +	enum odp_crypto_ses_create_err status;
> +	bool posted;
> +	odp_buffer_t compl_event;
> +
> +	odp_queue_t compl_queue = odp_queue_lookup("crypto-out");
> +	CU_ASSERT(compl_queue != ODP_QUEUE_INVALID);
> +	odp_buffer_pool_t pool = odp_buffer_pool_lookup("packet_pool");
> +	CU_ASSERT(pool != ODP_BUFFER_POOL_INVALID);
> +
> +	/* Create a crypto session */
> +	odp_crypto_session_params_t ses_params;
> +	memset(&ses_params, 0, sizeof(ses_params));
> +	ses_params.op = op;
> +	ses_params.auth_cipher_text = false;
> +	ses_params.pref_mode = ODP_CRYPTO_ASYNC;
> +	ses_params.cipher_alg = cipher_alg;
> +	ses_params.auth_alg = auth_alg;
> +	ses_params.compl_queue = compl_queue;
> +	ses_params.output_pool = pool;
> +	ses_params.cipher_key = cipher_key;
> +	ses_params.iv = ses_iv;
> +	ses_params.auth_key = auth_key;
> +
> +	/* TEST : odp_crypto_session_create */
> +	rc = odp_crypto_session_create(&ses_params, &session, &status);
> +	CU_ASSERT(!rc);
> +	CU_ASSERT(status == ODP_CRYPTO_SES_CREATE_ERR_NONE);
> +
> +	/* Prepare input data */
> +	odp_buffer_t buf = odp_buffer_alloc(pool);
> +	CU_ASSERT(buf != ODP_BUFFER_INVALID);
> +	odp_packet_t pkt = odp_packet_from_buffer(buf);
> +	CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +	uint8_t *data_addr = odp_packet_data(pkt);
> +	memcpy(data_addr, input_vec, input_vec_len);
> +	/* offsets are relative to buffer address (not packet data)
> +	until https://bugs.linaro.org/show_bug.cgi?id=387 is fixed */
> +	int data_off = data_addr - (uint8_t *)odp_buffer_addr(buf);
> +
> +	/* Prepare input/output params */
> +	odp_crypto_op_params_t op_params;
> +	memset(&op_params, 0, sizeof(op_params));
> +	op_params.session = session;
> +	op_params.pkt = pkt;
> +	op_params.out_pkt = pkt;
> +	if (cipher_alg != ODP_CIPHER_ALG_NULL &&
> +	    auth_alg == ODP_AUTH_ALG_NULL) {
> +		op_params.cipher_range.offset = data_off;
> +		op_params.cipher_range.length = input_vec_len;
> +		if (op_iv_ptr)
> +			op_params.override_iv_ptr = op_iv_ptr;
> +	} else if (cipher_alg == ODP_CIPHER_ALG_NULL &&
> +		 auth_alg != ODP_AUTH_ALG_NULL) {
> +		op_params.auth_range.offset = data_off;
> +		op_params.auth_range.length = input_vec_len;
> +		op_params.hash_result_offset = data_off;
> +	} else {
> +		CU_FAIL("%s : not implemented for combined alg mode\n");
> +	}
> +
> +	/* TEST : odp_crypto_set_operation_compl_ctx */
> +	/* TEST : odp_crypto_operation */
> +	if (compl_new == ODP_BUFFER_INVALID) {
> +		odp_crypto_set_operation_compl_ctx(buf, (void *)0xdeadbeef);
> +		rc = odp_crypto_operation(&op_params, &posted, buf);
> +	} else {
> +		odp_crypto_set_operation_compl_ctx(compl_new,
> +						   (void *)0xdeadbeef);
> +		rc = odp_crypto_operation(&op_params, &posted, compl_new);
> +	}
> +	CU_ASSERT(posted);
> +
> +	/* Poll completion queue for results */
> +	do {
> +		compl_event = odp_queue_deq(compl_queue);
> +	} while (compl_event == ODP_BUFFER_INVALID);
> +
> +	if (compl_new == ODP_BUFFER_INVALID) {
> +		CU_ASSERT(compl_event == buf);
> +	} else {
> +		CU_ASSERT(compl_event == compl_new);
> +	}
> +
> +	/* TEST : odp_crypto_get_operation_compl_status */
> +	struct odp_crypto_compl_status auth_status, cipher_status;
> +	odp_crypto_get_operation_compl_status(compl_event,
> +					      &auth_status, &cipher_status);
> +	CU_ASSERT(auth_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE);
> +	CU_ASSERT(auth_status.hw_err == ODP_CRYPTO_HW_ERR_NONE);
> +	CU_ASSERT(cipher_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE);
> +	CU_ASSERT(cipher_status.hw_err == ODP_CRYPTO_HW_ERR_NONE);
> +
> +	/* TEST : odp_crypto_get_operation_compl_packet */
> +	odp_packet_t out_pkt;
> +	out_pkt = odp_crypto_get_operation_compl_packet(compl_event);
> +	CU_ASSERT(out_pkt == pkt);
> +
> +	/* TEST : operation output was correct */
> +	CU_ASSERT(!memcmp(data_addr, output_vec, output_vec_len));
> +
> +	/* TEST : we got back the context pointer */
> +	void *ctx = odp_crypto_get_operation_compl_ctx(compl_event);
> +	CU_ASSERT(ctx == (void *)0xdeadbeef);
> +
> +	odp_buffer_free(buf);
> +}
> +
> +/* This test verifies the correctness of encode (plaintext -> ciphertext)
> + * operation for 3DES_CBC algorithm. IV for the operation is the session IV.
> + * In addition the test verifies if the implementation can use the
> + * packet buffer as completion event buffer.*/
> +#define ASYNC_INP_ENC_ALG_3DES_CBC	"ENC_ALG_3DES_CBC"
> +static void test_enc_alg_3des_cbc(void)
> +{
> +	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> +			 auth_key   = { .data = NULL, .length = 0 };
> +	odp_crypto_iv_t iv;
> +	unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> +				     sizeof(tdes_cbc_reference_length[0]));
> +
> +	unsigned int i;
> +	for (i = 0; i < test_vec_num; i++) {
> +		cipher_key.data = tdes_cbc_reference_key[i];
> +		cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> +		iv.data = tdes_cbc_reference_iv[i];
> +		iv.length = sizeof(tdes_cbc_reference_iv[i]);
> +
> +		alg_test(ODP_CRYPTO_OP_ENCODE,
> +			 ODP_CIPHER_ALG_3DES_CBC,
> +			 iv,
> +			 NULL,
> +			 cipher_key,
> +			 ODP_AUTH_ALG_NULL,
> +			 auth_key,
> +			 ODP_BUFFER_INVALID,
> +			 tdes_cbc_reference_plaintext[i],
> +			 tdes_cbc_reference_length[i],
> +			 tdes_cbc_reference_ciphertext[i],
> +			 tdes_cbc_reference_length[i]);
> +	}
> +}
> +
> +/* This test verifies the correctness of encode (plaintext -> ciphertext)
> + * operation for 3DES_CBC algorithm. IV for the operation is the operation IV.
> + * */
> +#define ASYNC_INP_ENC_ALG_3DES_CBC_OVR_IV	"ENC_ALG_3DES_CBC_OVR_IV"
> +static void test_enc_alg_3des_cbc_ovr_iv(void)
> +{
> +	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> +			 auth_key   = { .data = NULL, .length = 0 };
> +	odp_crypto_iv_t iv = { .data = NULL, .length = TDES_CBC_IV_LEN };
> +	unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> +				     sizeof(tdes_cbc_reference_length[0]));
> +
> +	unsigned int i;
> +	for (i = 0; i < test_vec_num; i++) {
> +		cipher_key.data = tdes_cbc_reference_key[i];
> +		cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> +
> +		alg_test(ODP_CRYPTO_OP_ENCODE,
> +			 ODP_CIPHER_ALG_3DES_CBC,
> +			 iv,
> +			 tdes_cbc_reference_iv[i],
> +			 cipher_key,
> +			 ODP_AUTH_ALG_NULL,
> +			 auth_key,
> +			 ODP_BUFFER_INVALID,
> +			 tdes_cbc_reference_plaintext[i],
> +			 tdes_cbc_reference_length[i],
> +			 tdes_cbc_reference_ciphertext[i],
> +			 tdes_cbc_reference_length[i]);
> +	}
> +}
> +
> +
> +/* This test verifies the correctness of decode (ciphertext -> plaintext)
> + * operation for 3DES_CBC algorithm. IV for the operation is the session IV
> + * In addition the test verifies if the implementation can use the
> + * packet buffer as completion event buffer.
> + * */
> +#define ASYNC_INP_DEC_ALG_3DES_CBC	 "DEC_ALG_3DES_CBC"
> +static void test_dec_alg_3des_cbc(void)
> +{
> +	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> +			 auth_key   = { .data = NULL, .length = 0 };
> +	odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
> +	unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> +				     sizeof(tdes_cbc_reference_length[0]));
> +
> +	unsigned int i;
> +	for (i = 0; i < test_vec_num; i++) {
> +		cipher_key.data = tdes_cbc_reference_key[i];
> +		cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> +		iv.data = tdes_cbc_reference_iv[i];
> +		iv.length = sizeof(tdes_cbc_reference_iv[i]);
> +
> +		alg_test(ODP_CRYPTO_OP_DECODE,
> +			 ODP_CIPHER_ALG_3DES_CBC,
> +			 iv,
> +			 NULL,
> +			 cipher_key,
> +			 ODP_AUTH_ALG_NULL,
> +			 auth_key,
> +			 ODP_BUFFER_INVALID,
> +			 tdes_cbc_reference_ciphertext[i],
> +			 tdes_cbc_reference_length[i],
> +			 tdes_cbc_reference_plaintext[i],
> +			 tdes_cbc_reference_length[i]);
> +	}
> +}
> +
> +/* This test verifies the correctness of decode (ciphertext -> plaintext)
> + * operation for 3DES_CBC algorithm. IV for the operation is the session IV
> + * In addition the test verifies if the implementation can use the
> + * packet buffer as completion event buffer.
> + * */
> +#define ASYNC_INP_DEC_ALG_3DES_CBC_OVR_IV	 "DEC_ALG_3DES_CBC_OVR_IV"
> +static void test_dec_alg_3des_cbc_ovr_iv(void)
> +{
> +	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> +			 auth_key   = { .data = NULL, .length = 0 };
> +	odp_crypto_iv_t iv = { .data = NULL, .length = TDES_CBC_IV_LEN };
> +	unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> +				     sizeof(tdes_cbc_reference_length[0]));
> +
> +	unsigned int i;
> +	for (i = 0; i < test_vec_num; i++) {
> +		cipher_key.data = tdes_cbc_reference_key[i];
> +		cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> +
> +		alg_test(ODP_CRYPTO_OP_DECODE,
> +			 ODP_CIPHER_ALG_3DES_CBC,
> +			 iv,
> +			 tdes_cbc_reference_iv[i],
> +			 cipher_key,
> +			 ODP_AUTH_ALG_NULL,
> +			 auth_key,
> +			 ODP_BUFFER_INVALID,
> +			 tdes_cbc_reference_ciphertext[i],
> +			 tdes_cbc_reference_length[i],
> +			 tdes_cbc_reference_plaintext[i],
> +			 tdes_cbc_reference_length[i]);
> +	}
> +}
> +
> +
> +/* This test verifies the correctness of HMAC_MD5 digest operation.
> + * The output check length is truncated to 12 bytes (96 bits) as
> + * returned by the crypto operation API call.
> + * Note that hash digest is a one-way operation.
> + * In addition the test verifies if the implementation can use the
> + * packet buffer as completion event buffer.
> + * */
> +#define ASYNC_INP_ALG_HMAC_MD5	      "ALG_HMAC_MD5"
> +static void test_alg_hmac_md5(void)
> +{
> +	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> +			 auth_key   = { .data = NULL, .length = 0 };
> +	odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
> +
> +	unsigned int test_vec_num = (sizeof(hmac_md5_reference_length)/
> +				     sizeof(hmac_md5_reference_length[0]));
> +
> +	unsigned int i;
> +	for (i = 0; i < test_vec_num; i++) {
> +		auth_key.data = hmac_md5_reference_key[i];
> +		auth_key.length = sizeof(hmac_md5_reference_key[i]);
> +
> +		alg_test(ODP_CRYPTO_OP_ENCODE,
> +			 ODP_CIPHER_ALG_NULL,
> +			 iv,
> +			 iv.data,
> +			 cipher_key,
> +			 ODP_AUTH_ALG_MD5_96,
> +			 auth_key,
> +			 ODP_BUFFER_INVALID,
> +			 hmac_md5_reference_plaintext[i],
> +			 hmac_md5_reference_length[i],
> +			 hmac_md5_reference_digest[i],
> +			 HMAC_MD5_96_CHECK_LEN);
> +	}
> +}
> +
> +/* This test verifies the correctness of encode (plaintext -> ciphertext)
> + * operation for 3DES_CBC algorithm. IV for the operation is the session IV.
> + * Uses a separate buffer for completion event
> + * */
> +#define ASYNC_INP_ENC_ALG_3DES_CBC_COMPL_NEW	   "ENC_ALG_3DES_CBC_COMPL_NEW"
> +static void test_enc_alg_3des_cbc_compl_new(void)
> +{
> +	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> +			 auth_key   = { .data = NULL, .length = 0 };
> +	odp_crypto_iv_t iv;
> +	unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> +				     sizeof(tdes_cbc_reference_length[0]));
> +
> +	odp_buffer_pool_t pool = odp_buffer_pool_lookup("compl_pool");
> +	CU_ASSERT(pool != ODP_BUFFER_POOL_INVALID);
> +
> +	unsigned int i;
> +	odp_buffer_t compl_new;
> +	for (i = 0; i < test_vec_num; i++) {
> +		compl_new = odp_buffer_alloc(pool);
> +		CU_ASSERT(compl_new != ODP_BUFFER_INVALID);
> +
> +		cipher_key.data = tdes_cbc_reference_key[i];
> +		cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> +		iv.data = tdes_cbc_reference_iv[i];
> +		iv.length = sizeof(tdes_cbc_reference_iv[i]);
> +
> +		alg_test(ODP_CRYPTO_OP_ENCODE,
> +			 ODP_CIPHER_ALG_3DES_CBC,
> +			 iv,
> +			 NULL,
> +			 cipher_key,
> +			 ODP_AUTH_ALG_NULL,
> +			 auth_key,
> +			 compl_new,
> +			 tdes_cbc_reference_plaintext[i],
> +			 tdes_cbc_reference_length[i],
> +			 tdes_cbc_reference_ciphertext[i],
> +			 tdes_cbc_reference_length[i]);
> +		odp_buffer_free(compl_new);
> +	}
> +}
> +
> +static CU_TestInfo test_array[] = {
> +	{ASYNC_INP_ENC_ALG_3DES_CBC, test_enc_alg_3des_cbc },
> +	{ASYNC_INP_DEC_ALG_3DES_CBC, test_dec_alg_3des_cbc },
> +	{ASYNC_INP_ENC_ALG_3DES_CBC_OVR_IV, test_enc_alg_3des_cbc_ovr_iv },
> +	{ASYNC_INP_DEC_ALG_3DES_CBC_OVR_IV, test_dec_alg_3des_cbc_ovr_iv },
> +	{ASYNC_INP_ALG_HMAC_MD5, test_alg_hmac_md5 },
> +	{ASYNC_INP_ENC_ALG_3DES_CBC_COMPL_NEW, test_enc_alg_3des_cbc_compl_new },
> +	CU_TEST_INFO_NULL,
> +};
> +
> +CU_SuiteInfo suites[] = {
> +	{ ODP_CRYPTO_ASYNC_INP , init, finalize, NULL, NULL, test_array },
> +	CU_SUITE_INFO_NULL,
> +};
> diff --git a/test/cunit/crypto/odp_crypto_test_async_inp.h b/test/cunit/crypto/odp_crypto_test_async_inp.h
> new file mode 100644
> index 0000000..818f7e7
> --- /dev/null
> +++ b/test/cunit/crypto/odp_crypto_test_async_inp.h
> @@ -0,0 +1,13 @@
> +/* Copyright (c) 2014, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:     BSD-3-Clause
> + */
> +#ifndef ODP_CRYPTO_TEST_ASYNC_INP_
> +#define ODP_CRYPTO_TEST_ASYNC_INP_
> +
> +#include "CUnit/Headers/TestDB.h"
> +
> +CU_SuiteInfo suites[1];
> +
> +#endif
> diff --git a/test/cunit/crypto/test_vectors.h b/test/cunit/crypto/test_vectors.h
> new file mode 100644
> index 0000000..c151952
> --- /dev/null
> +++ b/test/cunit/crypto/test_vectors.h
> @@ -0,0 +1,94 @@
> +/* Copyright (c) 2014, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:	BSD-3-Clause
> + */
> +
> +
> +/* TDES-CBC reference vectors, according to
> + * "http://csrc.nist.gov/groups/STM/cavp/documents/des/DESMMT.pdf"
> + */
> +
> +#define TDES_CBC_KEY_LEN	24	/* key length(in bytes) for tdes-cbc */
> +#define TDES_CBC_IV_LEN		8	/* IV length(in bytes) for tdes-cbc */
> +#define TDES_CBC_MAX_DATA_LEN	16	/* max. plain text length(in bytes) */
> +
> +static uint8_t tdes_cbc_reference_key[][TDES_CBC_KEY_LEN] = {
> +	{0x62, 0x7f, 0x46, 0x0e, 0x08, 0x10, 0x4a, 0x10, 0x43, 0xcd, 0x26, 0x5d,
> +	 0x58, 0x40, 0xea, 0xf1, 0x31, 0x3e, 0xdf, 0x97, 0xdf, 0x2a, 0x8a, 0x8c,
> +	 },
> +
> +	{0x37, 0xae, 0x5e, 0xbf, 0x46, 0xdf, 0xf2, 0xdc, 0x07, 0x54, 0xb9, 0x4f,
> +	 0x31, 0xcb, 0xb3, 0x85, 0x5e, 0x7f, 0xd3, 0x6d, 0xc8, 0x70, 0xbf, 0xae}
> +};
> +
> +static uint8_t tdes_cbc_reference_iv[][TDES_CBC_IV_LEN] = {
> +	{0x8e, 0x29, 0xf7, 0x5e, 0xa7, 0x7e, 0x54, 0x75},
> +
> +	{0x3d, 0x1d, 0xe3, 0xcc, 0x13, 0x2e, 0x3b, 0x65}
> +};
> +
> +/** length in bytes */
> +static uint32_t tdes_cbc_reference_length[] = { 8, 16 };
> +
> +static uint8_t tdes_cbc_reference_plaintext[][TDES_CBC_MAX_DATA_LEN] = {
> +	{0x32, 0x6a, 0x49, 0x4c, 0xd3, 0x3f, 0xe7, 0x56},
> +
> +	{0x84, 0x40, 0x1f, 0x78, 0xfe, 0x6c, 0x10, 0x87, 0x6d, 0x8e, 0xa2, 0x30,
> +	 0x94, 0xea, 0x53, 0x09}
> +};
> +
> +static uint8_t tdes_cbc_reference_ciphertext[][TDES_CBC_MAX_DATA_LEN] = {
> +	{0xb2, 0x2b, 0x8d, 0x66, 0xde, 0x97, 0x06, 0x92},
> +
> +	{0x7b, 0x1f, 0x7c, 0x7e, 0x3b, 0x1c, 0x94, 0x8e, 0xbd, 0x04, 0xa7, 0x5f,
> +	 0xfb, 0xa7, 0xd2, 0xf5}
> +};
> +
> +
> +/* HMAC-MD5 test vectors  - RFC2104 */
> +#define HMAC_MD5_KEY_LEN	16
> +#define HMAC_MD5_MAX_DATA_LEN	128
> +#define HMAC_MD5_DIGEST_LEN	16
> +#define HMAC_MD5_96_CHECK_LEN	12
> +
> +static uint8_t hmac_md5_reference_key[][HMAC_MD5_KEY_LEN] = {
> +	{ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
> +	  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b } ,
> +
> +	/* "Jefe" */
> +	{ 0x4a, 0x65, 0x66, 0x65 },
> +
> +	{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
> +	  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }
> +};
> +
> +static uint32_t hmac_md5_reference_length[] = { 8, 28, 50 };
> +
> +static uint8_t hmac_md5_reference_plaintext[][HMAC_MD5_MAX_DATA_LEN] = {
> +	/* "Hi There" */
> +	{ 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65},
> +
> +	/* what do ya want for nothing?*/
> +	{ 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
> +	  0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
> +	  0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
> +	  0x69, 0x6e, 0x67, 0x3f },
> +
> +	{ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> +	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> +	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> +	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> +	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd }
> +};
> +
> +static uint8_t hmac_md5_reference_digest[][HMAC_MD5_DIGEST_LEN] = {
> +	{ 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
> +	  0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d },
> +
> +	{ 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
> +	  0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 },
> +
> +	{ 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
> +	  0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }
> +};
> -- 
> 1.7.3.4
> 
> 
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
Alexandru Badicioiu Oct. 31, 2014, 2:35 p.m. UTC | #2
This suite is only for async inplace mode.The tests can be reused, with
some modifications, for other modes too (sync/inplace/outplace/). Command
line argument to select the the suite(s) or separate test programs could
work too.

On 31 October 2014 16:28, Jerin Jacob <jerin.jacob@caviumnetworks.com>
wrote:

> On Fri, Oct 31, 2014 at 02:08:47PM +0200, alexandru.badicioiu@linaro.org
> wrote:
> > From: Alexandru Badicioiu <alexandru.badicioiu@linaro.org>
> >
> > This patch adds a suite for async inplace mode of crypto APIs.
> > Correctness of crypto operations output is verified with known
> > test vectors  as well as various options and functionalities:
> > use session IV or operation IV for ciphering, use input packet
> > buffer or a separate buffer as the completion event, set and
> > retrieve the context associated with an operation.
>
> IMO crypto functionality unit tests should be capable of running on both
> sync and async modes.
> Platform like octeon supports only sync crypto mode.
> We can introduce a command-line option to select the mode for functional
> testcases.
> We can have separate  dedicated test to verify async/sync operation but
> crypto functional tests
> should cater both.
>
> Jerin
>
> >
> > Signed-off-by: Alexandru Badicioiu <alexandru.badicioiu@linaro.org>
> > ---
> >  configure.ac                                  |    1 +
> >  test/cunit/Makefile.am                        |    2 +
> >  test/cunit/crypto/Makefile.am                 |    9 +
> >  test/cunit/crypto/odp_crypto_test.c           |   26 ++
> >  test/cunit/crypto/odp_crypto_test_async_inp.c |  459
> +++++++++++++++++++++++++
> >  test/cunit/crypto/odp_crypto_test_async_inp.h |   13 +
> >  test/cunit/crypto/test_vectors.h              |   94 +++++
> >  7 files changed, 604 insertions(+), 0 deletions(-)
> >  create mode 100644 test/cunit/crypto/Makefile.am
> >  create mode 100644 test/cunit/crypto/odp_crypto_test.c
> >  create mode 100644 test/cunit/crypto/odp_crypto_test_async_inp.c
> >  create mode 100644 test/cunit/crypto/odp_crypto_test_async_inp.h
> >  create mode 100644 test/cunit/crypto/test_vectors.h
> >
> > diff --git a/configure.ac b/configure.ac
> > index fd69e85..b1785e9 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -166,6 +166,7 @@ AC_CONFIG_FILES([Makefile
> >                test/Makefile
> >                test/api_test/Makefile
> >                   test/cunit/Makefile
> > +              test/cunit/crypto/Makefile
> >                pkgconfig/libodp.pc])
> >
> >  AC_SEARCH_LIBS([timer_create],[rt posix4])
> > diff --git a/test/cunit/Makefile.am b/test/cunit/Makefile.am
> > index 927a5a5..7611145 100644
> > --- a/test/cunit/Makefile.am
> > +++ b/test/cunit/Makefile.am
> > @@ -3,6 +3,8 @@ include $(top_srcdir)/test/Makefile.inc
> >  AM_CFLAGS += -I$(CUNIT_PATH)/include
> >  AM_LDFLAGS += -L$(CUNIT_PATH)/lib
> >
> > +SUBDIRS = crypto
> > +
> >  if ODP_CUNIT_ENABLED
> >  TESTS = ${bin_PROGRAMS}
> >  check_PROGRAMS = ${bin_PROGRAMS}
> > diff --git a/test/cunit/crypto/Makefile.am
> b/test/cunit/crypto/Makefile.am
> > new file mode 100644
> > index 0000000..b984eaa
> > --- /dev/null
> > +++ b/test/cunit/crypto/Makefile.am
> > @@ -0,0 +1,9 @@
> > +include $(top_srcdir)/test/Makefile.inc
> > +
> > +if ODP_CUNIT_ENABLED
> > +bin_PROGRAMS = odp_crypto
> > +odp_crypto_LDFLAGS = $(AM_LDFLAGS) -static -lcunit
> > +endif
> > +
> > +dist_odp_crypto_SOURCES = odp_crypto_test_async_inp.c \
> > +                       odp_crypto_test.c
> > diff --git a/test/cunit/crypto/odp_crypto_test.c
> b/test/cunit/crypto/odp_crypto_test.c
> > new file mode 100644
> > index 0000000..b5d0dea
> > --- /dev/null
> > +++ b/test/cunit/crypto/odp_crypto_test.c
> > @@ -0,0 +1,26 @@
> > +/* Copyright (c) 2014, Linaro Limited
> > + * All rights reserved.
> > + *
> > + * SPDX-License-Identifier:     BSD-3-Clause
> > + */
> > +
> > +#include <odp.h>
> > +#include "CUnit/Headers/Basic.h"
> > +#include "CUnit/Headers/TestDB.h"
> > +#include "odp_crypto_test_async_inp.h"
> > +
> > +int main(void)
> > +{
> > +     /* initialize the CUnit test registry */
> > +     if (CUE_SUCCESS != CU_initialize_registry())
> > +             return CU_get_error();
> > +
> > +     /* register suites */
> > +     CU_register_suites(suites);
> > +     /* Run all tests using the CUnit Basic interface */
> > +     CU_basic_set_mode(CU_BRM_VERBOSE);
> > +     CU_basic_run_tests();
> > +     CU_cleanup_registry();
> > +
> > +     return CU_get_error();
> > +}
> > diff --git a/test/cunit/crypto/odp_crypto_test_async_inp.c
> b/test/cunit/crypto/odp_crypto_test_async_inp.c
> > new file mode 100644
> > index 0000000..dd5fb5f
> > --- /dev/null
> > +++ b/test/cunit/crypto/odp_crypto_test_async_inp.c
> > @@ -0,0 +1,458 @@
> > +/* Copyright (c) 2014, Linaro Limited
> > + * All rights reserved.
> > + *
> > + * SPDX-License-Identifier:  BSD-3-Clause
> > + */
> > +
> > +#include <odp.h>
> > +#include <odp_crypto.h>
> > +#include "CUnit/Headers/Basic.h"
> > +#include "CUnit/Headers/TestDB.h"
> > +#include "test_vectors.h"
> > +
> > +/* Suite name */
> > +#define ODP_CRYPTO_ASYNC_INP "odp_crypto_async_inp"
> > +
> > +/* Suite init/finalize funcs */
> > +/* ODP global/local initialization
> > + * Packet pool creation
> > + * Crypto output queue creation */
> > +
> > +#define SHM_PKT_POOL_SIZE      (512*2048*2)
> > +#define SHM_PKT_POOL_BUF_SIZE  (1024 * 32)
> > +
> > +#define SHM_COMPL_POOL_SIZE  (128*1024)
> > +#define SHM_COMPL_POOL_BUF_SIZE 128
> > +
> > +static int init(void)
> > +{
> > +     odp_shm_t shm;
> > +     void *pool_base = NULL;
> > +     odp_buffer_pool_t pool;
> > +     odp_queue_t out_queue;
> > +
> > +     if (odp_init_global(NULL, NULL)) {
> > +             ODP_ERR("ODP global init failed.\n");
> > +             return -1;
> > +     }
> > +     odp_init_local();
> > +
> > +     shm = odp_shm_reserve("shm_packet_pool",
> > +                           SHM_PKT_POOL_SIZE,
> > +                           ODP_CACHE_LINE_SIZE, 0);
> > +
> > +     pool_base = odp_shm_addr(shm);
> > +     if (!pool_base) {
> > +             ODP_ERR("Packet pool allocation failed.\n");
> > +             return -1;
> > +     }
> > +
> > +     pool = odp_buffer_pool_create("packet_pool", pool_base,
> > +                                   SHM_PKT_POOL_SIZE,
> > +                                   SHM_PKT_POOL_BUF_SIZE,
> > +                                   ODP_CACHE_LINE_SIZE,
> > +                                   ODP_BUFFER_TYPE_PACKET);
> > +     if (pool == ODP_BUFFER_POOL_INVALID) {
> > +             ODP_ERR("Packet pool creation failed.\n");
> > +             return -1;
> > +     }
> > +     out_queue = odp_queue_create("crypto-out",
> > +                                  ODP_QUEUE_TYPE_POLL, NULL);
> > +     if (out_queue == ODP_QUEUE_INVALID) {
> > +             ODP_ERR("Crypto outq creation failed.\n");
> > +             return -1;
> > +     }
> > +     shm = odp_shm_reserve("shm_compl_pool",
> > +                          SHM_COMPL_POOL_SIZE,
> > +                          ODP_CACHE_LINE_SIZE,
> > +                          ODP_SHM_SW_ONLY);
> > +     pool_base = odp_shm_addr(shm);
> > +     if (!pool_base) {
> > +             ODP_ERR("Completion pool allocation failed.\n");
> > +             return -1;
> > +     }
> > +     pool = odp_buffer_pool_create("compl_pool", pool_base,
> > +                                   SHM_COMPL_POOL_SIZE,
> > +                                   SHM_COMPL_POOL_BUF_SIZE,
> > +                                   ODP_CACHE_LINE_SIZE,
> > +                                   ODP_BUFFER_TYPE_RAW);
> > +     if (pool == ODP_BUFFER_POOL_INVALID) {
> > +             ODP_ERR("Completion pool creation failed.\n");
> > +             return -1;
> > +     }
> > +
> > +     printf("\tODP version: %s\n", odp_version_api_str());
> > +     return 0;
> > +}
> > +
> > +/* ODP cleanup */
> > +static int finalize(void)
> > +{
> > +     odp_term_local();
> > +     odp_term_global();
> > +     return 0;
> > +}
> > +
> > +
> > +/* Basic algorithm run function.
> > + * Creates a session from input parameters and runs one operation
> > + * on input_vec. Checks the output of the crypto operation against
> > + * output_vec. Operation completion event is dequeued polling the
> > + * session output queue. Completion context pointer is retrieved
> > + * and checked against the one set before the operation.
> > + * */
> > +static void alg_test(enum odp_crypto_op op,
> > +                  enum odp_cipher_alg cipher_alg,
> > +                  odp_crypto_iv_t ses_iv,
> > +                  uint8_t *op_iv_ptr,
> > +                  odp_crypto_key_t cipher_key,
> > +                  enum odp_auth_alg auth_alg,
> > +                  odp_crypto_key_t auth_key,
> > +                  odp_buffer_t compl_new,
> > +                  uint8_t *input_vec,
> > +                  unsigned int input_vec_len,
> > +                  uint8_t *output_vec,
> > +                  unsigned int output_vec_len)
> > +{
> > +     odp_crypto_session_t session;
> > +     int rc;
> > +     enum odp_crypto_ses_create_err status;
> > +     bool posted;
> > +     odp_buffer_t compl_event;
> > +
> > +     odp_queue_t compl_queue = odp_queue_lookup("crypto-out");
> > +     CU_ASSERT(compl_queue != ODP_QUEUE_INVALID);
> > +     odp_buffer_pool_t pool = odp_buffer_pool_lookup("packet_pool");
> > +     CU_ASSERT(pool != ODP_BUFFER_POOL_INVALID);
> > +
> > +     /* Create a crypto session */
> > +     odp_crypto_session_params_t ses_params;
> > +     memset(&ses_params, 0, sizeof(ses_params));
> > +     ses_params.op = op;
> > +     ses_params.auth_cipher_text = false;
> > +     ses_params.pref_mode = ODP_CRYPTO_ASYNC;
> > +     ses_params.cipher_alg = cipher_alg;
> > +     ses_params.auth_alg = auth_alg;
> > +     ses_params.compl_queue = compl_queue;
> > +     ses_params.output_pool = pool;
> > +     ses_params.cipher_key = cipher_key;
> > +     ses_params.iv = ses_iv;
> > +     ses_params.auth_key = auth_key;
> > +
> > +     /* TEST : odp_crypto_session_create */
> > +     rc = odp_crypto_session_create(&ses_params, &session, &status);
> > +     CU_ASSERT(!rc);
> > +     CU_ASSERT(status == ODP_CRYPTO_SES_CREATE_ERR_NONE);
> > +
> > +     /* Prepare input data */
> > +     odp_buffer_t buf = odp_buffer_alloc(pool);
> > +     CU_ASSERT(buf != ODP_BUFFER_INVALID);
> > +     odp_packet_t pkt = odp_packet_from_buffer(buf);
> > +     CU_ASSERT(pkt != ODP_PACKET_INVALID);
> > +     uint8_t *data_addr = odp_packet_data(pkt);
> > +     memcpy(data_addr, input_vec, input_vec_len);
> > +     /* offsets are relative to buffer address (not packet data)
> > +     until https://bugs.linaro.org/show_bug.cgi?id=387 is fixed */
> > +     int data_off = data_addr - (uint8_t *)odp_buffer_addr(buf);
> > +
> > +     /* Prepare input/output params */
> > +     odp_crypto_op_params_t op_params;
> > +     memset(&op_params, 0, sizeof(op_params));
> > +     op_params.session = session;
> > +     op_params.pkt = pkt;
> > +     op_params.out_pkt = pkt;
> > +     if (cipher_alg != ODP_CIPHER_ALG_NULL &&
> > +         auth_alg == ODP_AUTH_ALG_NULL) {
> > +             op_params.cipher_range.offset = data_off;
> > +             op_params.cipher_range.length = input_vec_len;
> > +             if (op_iv_ptr)
> > +                     op_params.override_iv_ptr = op_iv_ptr;
> > +     } else if (cipher_alg == ODP_CIPHER_ALG_NULL &&
> > +              auth_alg != ODP_AUTH_ALG_NULL) {
> > +             op_params.auth_range.offset = data_off;
> > +             op_params.auth_range.length = input_vec_len;
> > +             op_params.hash_result_offset = data_off;
> > +     } else {
> > +             CU_FAIL("%s : not implemented for combined alg mode\n");
> > +     }
> > +
> > +     /* TEST : odp_crypto_set_operation_compl_ctx */
> > +     /* TEST : odp_crypto_operation */
> > +     if (compl_new == ODP_BUFFER_INVALID) {
> > +             odp_crypto_set_operation_compl_ctx(buf, (void
> *)0xdeadbeef);
> > +             rc = odp_crypto_operation(&op_params, &posted, buf);
> > +     } else {
> > +             odp_crypto_set_operation_compl_ctx(compl_new,
> > +                                                (void *)0xdeadbeef);
> > +             rc = odp_crypto_operation(&op_params, &posted, compl_new);
> > +     }
> > +     CU_ASSERT(posted);
> > +
> > +     /* Poll completion queue for results */
> > +     do {
> > +             compl_event = odp_queue_deq(compl_queue);
> > +     } while (compl_event == ODP_BUFFER_INVALID);
> > +
> > +     if (compl_new == ODP_BUFFER_INVALID) {
> > +             CU_ASSERT(compl_event == buf);
> > +     } else {
> > +             CU_ASSERT(compl_event == compl_new);
> > +     }
> > +
> > +     /* TEST : odp_crypto_get_operation_compl_status */
> > +     struct odp_crypto_compl_status auth_status, cipher_status;
> > +     odp_crypto_get_operation_compl_status(compl_event,
> > +                                           &auth_status,
> &cipher_status);
> > +     CU_ASSERT(auth_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE);
> > +     CU_ASSERT(auth_status.hw_err == ODP_CRYPTO_HW_ERR_NONE);
> > +     CU_ASSERT(cipher_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE);
> > +     CU_ASSERT(cipher_status.hw_err == ODP_CRYPTO_HW_ERR_NONE);
> > +
> > +     /* TEST : odp_crypto_get_operation_compl_packet */
> > +     odp_packet_t out_pkt;
> > +     out_pkt = odp_crypto_get_operation_compl_packet(compl_event);
> > +     CU_ASSERT(out_pkt == pkt);
> > +
> > +     /* TEST : operation output was correct */
> > +     CU_ASSERT(!memcmp(data_addr, output_vec, output_vec_len));
> > +
> > +     /* TEST : we got back the context pointer */
> > +     void *ctx = odp_crypto_get_operation_compl_ctx(compl_event);
> > +     CU_ASSERT(ctx == (void *)0xdeadbeef);
> > +
> > +     odp_buffer_free(buf);
> > +}
> > +
> > +/* This test verifies the correctness of encode (plaintext ->
> ciphertext)
> > + * operation for 3DES_CBC algorithm. IV for the operation is the
> session IV.
> > + * In addition the test verifies if the implementation can use the
> > + * packet buffer as completion event buffer.*/
> > +#define ASYNC_INP_ENC_ALG_3DES_CBC   "ENC_ALG_3DES_CBC"
> > +static void test_enc_alg_3des_cbc(void)
> > +{
> > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > +                      auth_key   = { .data = NULL, .length = 0 };
> > +     odp_crypto_iv_t iv;
> > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > +                                  sizeof(tdes_cbc_reference_length[0]));
> > +
> > +     unsigned int i;
> > +     for (i = 0; i < test_vec_num; i++) {
> > +             cipher_key.data = tdes_cbc_reference_key[i];
> > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > +             iv.data = tdes_cbc_reference_iv[i];
> > +             iv.length = sizeof(tdes_cbc_reference_iv[i]);
> > +
> > +             alg_test(ODP_CRYPTO_OP_ENCODE,
> > +                      ODP_CIPHER_ALG_3DES_CBC,
> > +                      iv,
> > +                      NULL,
> > +                      cipher_key,
> > +                      ODP_AUTH_ALG_NULL,
> > +                      auth_key,
> > +                      ODP_BUFFER_INVALID,
> > +                      tdes_cbc_reference_plaintext[i],
> > +                      tdes_cbc_reference_length[i],
> > +                      tdes_cbc_reference_ciphertext[i],
> > +                      tdes_cbc_reference_length[i]);
> > +     }
> > +}
> > +
> > +/* This test verifies the correctness of encode (plaintext ->
> ciphertext)
> > + * operation for 3DES_CBC algorithm. IV for the operation is the
> operation IV.
> > + * */
> > +#define ASYNC_INP_ENC_ALG_3DES_CBC_OVR_IV    "ENC_ALG_3DES_CBC_OVR_IV"
> > +static void test_enc_alg_3des_cbc_ovr_iv(void)
> > +{
> > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > +                      auth_key   = { .data = NULL, .length = 0 };
> > +     odp_crypto_iv_t iv = { .data = NULL, .length = TDES_CBC_IV_LEN };
> > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > +                                  sizeof(tdes_cbc_reference_length[0]));
> > +
> > +     unsigned int i;
> > +     for (i = 0; i < test_vec_num; i++) {
> > +             cipher_key.data = tdes_cbc_reference_key[i];
> > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > +
> > +             alg_test(ODP_CRYPTO_OP_ENCODE,
> > +                      ODP_CIPHER_ALG_3DES_CBC,
> > +                      iv,
> > +                      tdes_cbc_reference_iv[i],
> > +                      cipher_key,
> > +                      ODP_AUTH_ALG_NULL,
> > +                      auth_key,
> > +                      ODP_BUFFER_INVALID,
> > +                      tdes_cbc_reference_plaintext[i],
> > +                      tdes_cbc_reference_length[i],
> > +                      tdes_cbc_reference_ciphertext[i],
> > +                      tdes_cbc_reference_length[i]);
> > +     }
> > +}
> > +
> > +
> > +/* This test verifies the correctness of decode (ciphertext ->
> plaintext)
> > + * operation for 3DES_CBC algorithm. IV for the operation is the
> session IV
> > + * In addition the test verifies if the implementation can use the
> > + * packet buffer as completion event buffer.
> > + * */
> > +#define ASYNC_INP_DEC_ALG_3DES_CBC    "DEC_ALG_3DES_CBC"
> > +static void test_dec_alg_3des_cbc(void)
> > +{
> > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > +                      auth_key   = { .data = NULL, .length = 0 };
> > +     odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
> > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > +                                  sizeof(tdes_cbc_reference_length[0]));
> > +
> > +     unsigned int i;
> > +     for (i = 0; i < test_vec_num; i++) {
> > +             cipher_key.data = tdes_cbc_reference_key[i];
> > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > +             iv.data = tdes_cbc_reference_iv[i];
> > +             iv.length = sizeof(tdes_cbc_reference_iv[i]);
> > +
> > +             alg_test(ODP_CRYPTO_OP_DECODE,
> > +                      ODP_CIPHER_ALG_3DES_CBC,
> > +                      iv,
> > +                      NULL,
> > +                      cipher_key,
> > +                      ODP_AUTH_ALG_NULL,
> > +                      auth_key,
> > +                      ODP_BUFFER_INVALID,
> > +                      tdes_cbc_reference_ciphertext[i],
> > +                      tdes_cbc_reference_length[i],
> > +                      tdes_cbc_reference_plaintext[i],
> > +                      tdes_cbc_reference_length[i]);
> > +     }
> > +}
> > +
> > +/* This test verifies the correctness of decode (ciphertext ->
> plaintext)
> > + * operation for 3DES_CBC algorithm. IV for the operation is the
> session IV
> > + * In addition the test verifies if the implementation can use the
> > + * packet buffer as completion event buffer.
> > + * */
> > +#define ASYNC_INP_DEC_ALG_3DES_CBC_OVR_IV     "DEC_ALG_3DES_CBC_OVR_IV"
> > +static void test_dec_alg_3des_cbc_ovr_iv(void)
> > +{
> > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > +                      auth_key   = { .data = NULL, .length = 0 };
> > +     odp_crypto_iv_t iv = { .data = NULL, .length = TDES_CBC_IV_LEN };
> > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > +                                  sizeof(tdes_cbc_reference_length[0]));
> > +
> > +     unsigned int i;
> > +     for (i = 0; i < test_vec_num; i++) {
> > +             cipher_key.data = tdes_cbc_reference_key[i];
> > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > +
> > +             alg_test(ODP_CRYPTO_OP_DECODE,
> > +                      ODP_CIPHER_ALG_3DES_CBC,
> > +                      iv,
> > +                      tdes_cbc_reference_iv[i],
> > +                      cipher_key,
> > +                      ODP_AUTH_ALG_NULL,
> > +                      auth_key,
> > +                      ODP_BUFFER_INVALID,
> > +                      tdes_cbc_reference_ciphertext[i],
> > +                      tdes_cbc_reference_length[i],
> > +                      tdes_cbc_reference_plaintext[i],
> > +                      tdes_cbc_reference_length[i]);
> > +     }
> > +}
> > +
> > +
> > +/* This test verifies the correctness of HMAC_MD5 digest operation.
> > + * The output check length is truncated to 12 bytes (96 bits) as
> > + * returned by the crypto operation API call.
> > + * Note that hash digest is a one-way operation.
> > + * In addition the test verifies if the implementation can use the
> > + * packet buffer as completion event buffer.
> > + * */
> > +#define ASYNC_INP_ALG_HMAC_MD5             "ALG_HMAC_MD5"
> > +static void test_alg_hmac_md5(void)
> > +{
> > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > +                      auth_key   = { .data = NULL, .length = 0 };
> > +     odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
> > +
> > +     unsigned int test_vec_num = (sizeof(hmac_md5_reference_length)/
> > +                                  sizeof(hmac_md5_reference_length[0]));
> > +
> > +     unsigned int i;
> > +     for (i = 0; i < test_vec_num; i++) {
> > +             auth_key.data = hmac_md5_reference_key[i];
> > +             auth_key.length = sizeof(hmac_md5_reference_key[i]);
> > +
> > +             alg_test(ODP_CRYPTO_OP_ENCODE,
> > +                      ODP_CIPHER_ALG_NULL,
> > +                      iv,
> > +                      iv.data,
> > +                      cipher_key,
> > +                      ODP_AUTH_ALG_MD5_96,
> > +                      auth_key,
> > +                      ODP_BUFFER_INVALID,
> > +                      hmac_md5_reference_plaintext[i],
> > +                      hmac_md5_reference_length[i],
> > +                      hmac_md5_reference_digest[i],
> > +                      HMAC_MD5_96_CHECK_LEN);
> > +     }
> > +}
> > +
> > +/* This test verifies the correctness of encode (plaintext ->
> ciphertext)
> > + * operation for 3DES_CBC algorithm. IV for the operation is the
> session IV.
> > + * Uses a separate buffer for completion event
> > + * */
> > +#define ASYNC_INP_ENC_ALG_3DES_CBC_COMPL_NEW
> "ENC_ALG_3DES_CBC_COMPL_NEW"
> > +static void test_enc_alg_3des_cbc_compl_new(void)
> > +{
> > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > +                      auth_key   = { .data = NULL, .length = 0 };
> > +     odp_crypto_iv_t iv;
> > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > +                                  sizeof(tdes_cbc_reference_length[0]));
> > +
> > +     odp_buffer_pool_t pool = odp_buffer_pool_lookup("compl_pool");
> > +     CU_ASSERT(pool != ODP_BUFFER_POOL_INVALID);
> > +
> > +     unsigned int i;
> > +     odp_buffer_t compl_new;
> > +     for (i = 0; i < test_vec_num; i++) {
> > +             compl_new = odp_buffer_alloc(pool);
> > +             CU_ASSERT(compl_new != ODP_BUFFER_INVALID);
> > +
> > +             cipher_key.data = tdes_cbc_reference_key[i];
> > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > +             iv.data = tdes_cbc_reference_iv[i];
> > +             iv.length = sizeof(tdes_cbc_reference_iv[i]);
> > +
> > +             alg_test(ODP_CRYPTO_OP_ENCODE,
> > +                      ODP_CIPHER_ALG_3DES_CBC,
> > +                      iv,
> > +                      NULL,
> > +                      cipher_key,
> > +                      ODP_AUTH_ALG_NULL,
> > +                      auth_key,
> > +                      compl_new,
> > +                      tdes_cbc_reference_plaintext[i],
> > +                      tdes_cbc_reference_length[i],
> > +                      tdes_cbc_reference_ciphertext[i],
> > +                      tdes_cbc_reference_length[i]);
> > +             odp_buffer_free(compl_new);
> > +     }
> > +}
> > +
> > +static CU_TestInfo test_array[] = {
> > +     {ASYNC_INP_ENC_ALG_3DES_CBC, test_enc_alg_3des_cbc },
> > +     {ASYNC_INP_DEC_ALG_3DES_CBC, test_dec_alg_3des_cbc },
> > +     {ASYNC_INP_ENC_ALG_3DES_CBC_OVR_IV, test_enc_alg_3des_cbc_ovr_iv },
> > +     {ASYNC_INP_DEC_ALG_3DES_CBC_OVR_IV, test_dec_alg_3des_cbc_ovr_iv },
> > +     {ASYNC_INP_ALG_HMAC_MD5, test_alg_hmac_md5 },
> > +     {ASYNC_INP_ENC_ALG_3DES_CBC_COMPL_NEW,
> test_enc_alg_3des_cbc_compl_new },
> > +     CU_TEST_INFO_NULL,
> > +};
> > +
> > +CU_SuiteInfo suites[] = {
> > +     { ODP_CRYPTO_ASYNC_INP , init, finalize, NULL, NULL, test_array },
> > +     CU_SUITE_INFO_NULL,
> > +};
> > diff --git a/test/cunit/crypto/odp_crypto_test_async_inp.h
> b/test/cunit/crypto/odp_crypto_test_async_inp.h
> > new file mode 100644
> > index 0000000..818f7e7
> > --- /dev/null
> > +++ b/test/cunit/crypto/odp_crypto_test_async_inp.h
> > @@ -0,0 +1,13 @@
> > +/* Copyright (c) 2014, Linaro Limited
> > + * All rights reserved.
> > + *
> > + * SPDX-License-Identifier:     BSD-3-Clause
> > + */
> > +#ifndef ODP_CRYPTO_TEST_ASYNC_INP_
> > +#define ODP_CRYPTO_TEST_ASYNC_INP_
> > +
> > +#include "CUnit/Headers/TestDB.h"
> > +
> > +CU_SuiteInfo suites[1];
> > +
> > +#endif
> > diff --git a/test/cunit/crypto/test_vectors.h
> b/test/cunit/crypto/test_vectors.h
> > new file mode 100644
> > index 0000000..c151952
> > --- /dev/null
> > +++ b/test/cunit/crypto/test_vectors.h
> > @@ -0,0 +1,94 @@
> > +/* Copyright (c) 2014, Linaro Limited
> > + * All rights reserved.
> > + *
> > + * SPDX-License-Identifier:  BSD-3-Clause
> > + */
> > +
> > +
> > +/* TDES-CBC reference vectors, according to
> > + * "http://csrc.nist.gov/groups/STM/cavp/documents/des/DESMMT.pdf"
> > + */
> > +
> > +#define TDES_CBC_KEY_LEN     24      /* key length(in bytes) for
> tdes-cbc */
> > +#define TDES_CBC_IV_LEN              8       /* IV length(in bytes) for
> tdes-cbc */
> > +#define TDES_CBC_MAX_DATA_LEN        16      /* max. plain text
> length(in bytes) */
> > +
> > +static uint8_t tdes_cbc_reference_key[][TDES_CBC_KEY_LEN] = {
> > +     {0x62, 0x7f, 0x46, 0x0e, 0x08, 0x10, 0x4a, 0x10, 0x43, 0xcd, 0x26,
> 0x5d,
> > +      0x58, 0x40, 0xea, 0xf1, 0x31, 0x3e, 0xdf, 0x97, 0xdf, 0x2a, 0x8a,
> 0x8c,
> > +      },
> > +
> > +     {0x37, 0xae, 0x5e, 0xbf, 0x46, 0xdf, 0xf2, 0xdc, 0x07, 0x54, 0xb9,
> 0x4f,
> > +      0x31, 0xcb, 0xb3, 0x85, 0x5e, 0x7f, 0xd3, 0x6d, 0xc8, 0x70, 0xbf,
> 0xae}
> > +};
> > +
> > +static uint8_t tdes_cbc_reference_iv[][TDES_CBC_IV_LEN] = {
> > +     {0x8e, 0x29, 0xf7, 0x5e, 0xa7, 0x7e, 0x54, 0x75},
> > +
> > +     {0x3d, 0x1d, 0xe3, 0xcc, 0x13, 0x2e, 0x3b, 0x65}
> > +};
> > +
> > +/** length in bytes */
> > +static uint32_t tdes_cbc_reference_length[] = { 8, 16 };
> > +
> > +static uint8_t tdes_cbc_reference_plaintext[][TDES_CBC_MAX_DATA_LEN] = {
> > +     {0x32, 0x6a, 0x49, 0x4c, 0xd3, 0x3f, 0xe7, 0x56},
> > +
> > +     {0x84, 0x40, 0x1f, 0x78, 0xfe, 0x6c, 0x10, 0x87, 0x6d, 0x8e, 0xa2,
> 0x30,
> > +      0x94, 0xea, 0x53, 0x09}
> > +};
> > +
> > +static uint8_t tdes_cbc_reference_ciphertext[][TDES_CBC_MAX_DATA_LEN] =
> {
> > +     {0xb2, 0x2b, 0x8d, 0x66, 0xde, 0x97, 0x06, 0x92},
> > +
> > +     {0x7b, 0x1f, 0x7c, 0x7e, 0x3b, 0x1c, 0x94, 0x8e, 0xbd, 0x04, 0xa7,
> 0x5f,
> > +      0xfb, 0xa7, 0xd2, 0xf5}
> > +};
> > +
> > +
> > +/* HMAC-MD5 test vectors  - RFC2104 */
> > +#define HMAC_MD5_KEY_LEN     16
> > +#define HMAC_MD5_MAX_DATA_LEN        128
> > +#define HMAC_MD5_DIGEST_LEN  16
> > +#define HMAC_MD5_96_CHECK_LEN        12
> > +
> > +static uint8_t hmac_md5_reference_key[][HMAC_MD5_KEY_LEN] = {
> > +     { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
> > +       0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b } ,
> > +
> > +     /* "Jefe" */
> > +     { 0x4a, 0x65, 0x66, 0x65 },
> > +
> > +     { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
> > +       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }
> > +};
> > +
> > +static uint32_t hmac_md5_reference_length[] = { 8, 28, 50 };
> > +
> > +static uint8_t hmac_md5_reference_plaintext[][HMAC_MD5_MAX_DATA_LEN] = {
> > +     /* "Hi There" */
> > +     { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65},
> > +
> > +     /* what do ya want for nothing?*/
> > +     { 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
> > +       0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
> > +       0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
> > +       0x69, 0x6e, 0x67, 0x3f },
> > +
> > +     { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd }
> > +};
> > +
> > +static uint8_t hmac_md5_reference_digest[][HMAC_MD5_DIGEST_LEN] = {
> > +     { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
> > +       0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d },
> > +
> > +     { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
> > +       0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 },
> > +
> > +     { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
> > +       0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }
> > +};
> > --
> > 1.7.3.4
> >
> >
> > _______________________________________________
> > lng-odp mailing list
> > lng-odp@lists.linaro.org
> > http://lists.linaro.org/mailman/listinfo/lng-odp
>
Jerin Jacob Oct. 31, 2014, 3:10 p.m. UTC | #3
On Fri, Oct 31, 2014 at 04:35:21PM +0200, Alexandru Badicioiu wrote:
> This suite is only for async inplace mode.The tests can be reused, with
> some modifications, for other modes too (sync/inplace/outplace/). Command
> line argument to select the the suite(s) or separate test programs could
> work too.

Introducing an abstraction for sync/async mode for functional test-case is very straight forward.
Most of the platforms don't support both async and sync together.
and its very difficult to maintain parallel tests suites for the same functionality which can be abstracted.
If you need any help in defining/reviewing the abstraction and/or testing the sync mode then I can help you with that.
I would like avoid the duplicate effort of writing parallel ODP crypto Cunit testcases.

Let me know your views on the proposal.

> 
> On 31 October 2014 16:28, Jerin Jacob <jerin.jacob@caviumnetworks.com>
> wrote:
> 
> > On Fri, Oct 31, 2014 at 02:08:47PM +0200, alexandru.badicioiu@linaro.org
> > wrote:
> > > From: Alexandru Badicioiu <alexandru.badicioiu@linaro.org>
> > >
> > > This patch adds a suite for async inplace mode of crypto APIs.
> > > Correctness of crypto operations output is verified with known
> > > test vectors  as well as various options and functionalities:
> > > use session IV or operation IV for ciphering, use input packet
> > > buffer or a separate buffer as the completion event, set and
> > > retrieve the context associated with an operation.
> >
> > IMO crypto functionality unit tests should be capable of running on both
> > sync and async modes.
> > Platform like octeon supports only sync crypto mode.
> > We can introduce a command-line option to select the mode for functional
> > testcases.
> > We can have separate  dedicated test to verify async/sync operation but
> > crypto functional tests
> > should cater both.
> >
> > Jerin
> >
> > >
> > > Signed-off-by: Alexandru Badicioiu <alexandru.badicioiu@linaro.org>
> > > ---
> > >  configure.ac                                  |    1 +
> > >  test/cunit/Makefile.am                        |    2 +
> > >  test/cunit/crypto/Makefile.am                 |    9 +
> > >  test/cunit/crypto/odp_crypto_test.c           |   26 ++
> > >  test/cunit/crypto/odp_crypto_test_async_inp.c |  459
> > +++++++++++++++++++++++++
> > >  test/cunit/crypto/odp_crypto_test_async_inp.h |   13 +
> > >  test/cunit/crypto/test_vectors.h              |   94 +++++
> > >  7 files changed, 604 insertions(+), 0 deletions(-)
> > >  create mode 100644 test/cunit/crypto/Makefile.am
> > >  create mode 100644 test/cunit/crypto/odp_crypto_test.c
> > >  create mode 100644 test/cunit/crypto/odp_crypto_test_async_inp.c
> > >  create mode 100644 test/cunit/crypto/odp_crypto_test_async_inp.h
> > >  create mode 100644 test/cunit/crypto/test_vectors.h
> > >
> > > diff --git a/configure.ac b/configure.ac
> > > index fd69e85..b1785e9 100644
> > > --- a/configure.ac
> > > +++ b/configure.ac
> > > @@ -166,6 +166,7 @@ AC_CONFIG_FILES([Makefile
> > >                test/Makefile
> > >                test/api_test/Makefile
> > >                   test/cunit/Makefile
> > > +              test/cunit/crypto/Makefile
> > >                pkgconfig/libodp.pc])
> > >
> > >  AC_SEARCH_LIBS([timer_create],[rt posix4])
> > > diff --git a/test/cunit/Makefile.am b/test/cunit/Makefile.am
> > > index 927a5a5..7611145 100644
> > > --- a/test/cunit/Makefile.am
> > > +++ b/test/cunit/Makefile.am
> > > @@ -3,6 +3,8 @@ include $(top_srcdir)/test/Makefile.inc
> > >  AM_CFLAGS += -I$(CUNIT_PATH)/include
> > >  AM_LDFLAGS += -L$(CUNIT_PATH)/lib
> > >
> > > +SUBDIRS = crypto
> > > +
> > >  if ODP_CUNIT_ENABLED
> > >  TESTS = ${bin_PROGRAMS}
> > >  check_PROGRAMS = ${bin_PROGRAMS}
> > > diff --git a/test/cunit/crypto/Makefile.am
> > b/test/cunit/crypto/Makefile.am
> > > new file mode 100644
> > > index 0000000..b984eaa
> > > --- /dev/null
> > > +++ b/test/cunit/crypto/Makefile.am
> > > @@ -0,0 +1,9 @@
> > > +include $(top_srcdir)/test/Makefile.inc
> > > +
> > > +if ODP_CUNIT_ENABLED
> > > +bin_PROGRAMS = odp_crypto
> > > +odp_crypto_LDFLAGS = $(AM_LDFLAGS) -static -lcunit
> > > +endif
> > > +
> > > +dist_odp_crypto_SOURCES = odp_crypto_test_async_inp.c \
> > > +                       odp_crypto_test.c
> > > diff --git a/test/cunit/crypto/odp_crypto_test.c
> > b/test/cunit/crypto/odp_crypto_test.c
> > > new file mode 100644
> > > index 0000000..b5d0dea
> > > --- /dev/null
> > > +++ b/test/cunit/crypto/odp_crypto_test.c
> > > @@ -0,0 +1,26 @@
> > > +/* Copyright (c) 2014, Linaro Limited
> > > + * All rights reserved.
> > > + *
> > > + * SPDX-License-Identifier:     BSD-3-Clause
> > > + */
> > > +
> > > +#include <odp.h>
> > > +#include "CUnit/Headers/Basic.h"
> > > +#include "CUnit/Headers/TestDB.h"
> > > +#include "odp_crypto_test_async_inp.h"
> > > +
> > > +int main(void)
> > > +{
> > > +     /* initialize the CUnit test registry */
> > > +     if (CUE_SUCCESS != CU_initialize_registry())
> > > +             return CU_get_error();
> > > +
> > > +     /* register suites */
> > > +     CU_register_suites(suites);
> > > +     /* Run all tests using the CUnit Basic interface */
> > > +     CU_basic_set_mode(CU_BRM_VERBOSE);
> > > +     CU_basic_run_tests();
> > > +     CU_cleanup_registry();
> > > +
> > > +     return CU_get_error();
> > > +}
> > > diff --git a/test/cunit/crypto/odp_crypto_test_async_inp.c
> > b/test/cunit/crypto/odp_crypto_test_async_inp.c
> > > new file mode 100644
> > > index 0000000..dd5fb5f
> > > --- /dev/null
> > > +++ b/test/cunit/crypto/odp_crypto_test_async_inp.c
> > > @@ -0,0 +1,458 @@
> > > +/* Copyright (c) 2014, Linaro Limited
> > > + * All rights reserved.
> > > + *
> > > + * SPDX-License-Identifier:  BSD-3-Clause
> > > + */
> > > +
> > > +#include <odp.h>
> > > +#include <odp_crypto.h>
> > > +#include "CUnit/Headers/Basic.h"
> > > +#include "CUnit/Headers/TestDB.h"
> > > +#include "test_vectors.h"
> > > +
> > > +/* Suite name */
> > > +#define ODP_CRYPTO_ASYNC_INP "odp_crypto_async_inp"
> > > +
> > > +/* Suite init/finalize funcs */
> > > +/* ODP global/local initialization
> > > + * Packet pool creation
> > > + * Crypto output queue creation */
> > > +
> > > +#define SHM_PKT_POOL_SIZE      (512*2048*2)
> > > +#define SHM_PKT_POOL_BUF_SIZE  (1024 * 32)
> > > +
> > > +#define SHM_COMPL_POOL_SIZE  (128*1024)
> > > +#define SHM_COMPL_POOL_BUF_SIZE 128
> > > +
> > > +static int init(void)
> > > +{
> > > +     odp_shm_t shm;
> > > +     void *pool_base = NULL;
> > > +     odp_buffer_pool_t pool;
> > > +     odp_queue_t out_queue;
> > > +
> > > +     if (odp_init_global(NULL, NULL)) {
> > > +             ODP_ERR("ODP global init failed.\n");
> > > +             return -1;
> > > +     }
> > > +     odp_init_local();
> > > +
> > > +     shm = odp_shm_reserve("shm_packet_pool",
> > > +                           SHM_PKT_POOL_SIZE,
> > > +                           ODP_CACHE_LINE_SIZE, 0);
> > > +
> > > +     pool_base = odp_shm_addr(shm);
> > > +     if (!pool_base) {
> > > +             ODP_ERR("Packet pool allocation failed.\n");
> > > +             return -1;
> > > +     }
> > > +
> > > +     pool = odp_buffer_pool_create("packet_pool", pool_base,
> > > +                                   SHM_PKT_POOL_SIZE,
> > > +                                   SHM_PKT_POOL_BUF_SIZE,
> > > +                                   ODP_CACHE_LINE_SIZE,
> > > +                                   ODP_BUFFER_TYPE_PACKET);
> > > +     if (pool == ODP_BUFFER_POOL_INVALID) {
> > > +             ODP_ERR("Packet pool creation failed.\n");
> > > +             return -1;
> > > +     }
> > > +     out_queue = odp_queue_create("crypto-out",
> > > +                                  ODP_QUEUE_TYPE_POLL, NULL);
> > > +     if (out_queue == ODP_QUEUE_INVALID) {
> > > +             ODP_ERR("Crypto outq creation failed.\n");
> > > +             return -1;
> > > +     }
> > > +     shm = odp_shm_reserve("shm_compl_pool",
> > > +                          SHM_COMPL_POOL_SIZE,
> > > +                          ODP_CACHE_LINE_SIZE,
> > > +                          ODP_SHM_SW_ONLY);
> > > +     pool_base = odp_shm_addr(shm);
> > > +     if (!pool_base) {
> > > +             ODP_ERR("Completion pool allocation failed.\n");
> > > +             return -1;
> > > +     }
> > > +     pool = odp_buffer_pool_create("compl_pool", pool_base,
> > > +                                   SHM_COMPL_POOL_SIZE,
> > > +                                   SHM_COMPL_POOL_BUF_SIZE,
> > > +                                   ODP_CACHE_LINE_SIZE,
> > > +                                   ODP_BUFFER_TYPE_RAW);
> > > +     if (pool == ODP_BUFFER_POOL_INVALID) {
> > > +             ODP_ERR("Completion pool creation failed.\n");
> > > +             return -1;
> > > +     }
> > > +
> > > +     printf("\tODP version: %s\n", odp_version_api_str());
> > > +     return 0;
> > > +}
> > > +
> > > +/* ODP cleanup */
> > > +static int finalize(void)
> > > +{
> > > +     odp_term_local();
> > > +     odp_term_global();
> > > +     return 0;
> > > +}
> > > +
> > > +
> > > +/* Basic algorithm run function.
> > > + * Creates a session from input parameters and runs one operation
> > > + * on input_vec. Checks the output of the crypto operation against
> > > + * output_vec. Operation completion event is dequeued polling the
> > > + * session output queue. Completion context pointer is retrieved
> > > + * and checked against the one set before the operation.
> > > + * */
> > > +static void alg_test(enum odp_crypto_op op,
> > > +                  enum odp_cipher_alg cipher_alg,
> > > +                  odp_crypto_iv_t ses_iv,
> > > +                  uint8_t *op_iv_ptr,
> > > +                  odp_crypto_key_t cipher_key,
> > > +                  enum odp_auth_alg auth_alg,
> > > +                  odp_crypto_key_t auth_key,
> > > +                  odp_buffer_t compl_new,
> > > +                  uint8_t *input_vec,
> > > +                  unsigned int input_vec_len,
> > > +                  uint8_t *output_vec,
> > > +                  unsigned int output_vec_len)
> > > +{
> > > +     odp_crypto_session_t session;
> > > +     int rc;
> > > +     enum odp_crypto_ses_create_err status;
> > > +     bool posted;
> > > +     odp_buffer_t compl_event;
> > > +
> > > +     odp_queue_t compl_queue = odp_queue_lookup("crypto-out");
> > > +     CU_ASSERT(compl_queue != ODP_QUEUE_INVALID);
> > > +     odp_buffer_pool_t pool = odp_buffer_pool_lookup("packet_pool");
> > > +     CU_ASSERT(pool != ODP_BUFFER_POOL_INVALID);
> > > +
> > > +     /* Create a crypto session */
> > > +     odp_crypto_session_params_t ses_params;
> > > +     memset(&ses_params, 0, sizeof(ses_params));
> > > +     ses_params.op = op;
> > > +     ses_params.auth_cipher_text = false;
> > > +     ses_params.pref_mode = ODP_CRYPTO_ASYNC;
> > > +     ses_params.cipher_alg = cipher_alg;
> > > +     ses_params.auth_alg = auth_alg;
> > > +     ses_params.compl_queue = compl_queue;
> > > +     ses_params.output_pool = pool;
> > > +     ses_params.cipher_key = cipher_key;
> > > +     ses_params.iv = ses_iv;
> > > +     ses_params.auth_key = auth_key;
> > > +
> > > +     /* TEST : odp_crypto_session_create */
> > > +     rc = odp_crypto_session_create(&ses_params, &session, &status);
> > > +     CU_ASSERT(!rc);
> > > +     CU_ASSERT(status == ODP_CRYPTO_SES_CREATE_ERR_NONE);
> > > +
> > > +     /* Prepare input data */
> > > +     odp_buffer_t buf = odp_buffer_alloc(pool);
> > > +     CU_ASSERT(buf != ODP_BUFFER_INVALID);
> > > +     odp_packet_t pkt = odp_packet_from_buffer(buf);
> > > +     CU_ASSERT(pkt != ODP_PACKET_INVALID);
> > > +     uint8_t *data_addr = odp_packet_data(pkt);
> > > +     memcpy(data_addr, input_vec, input_vec_len);
> > > +     /* offsets are relative to buffer address (not packet data)
> > > +     until https://bugs.linaro.org/show_bug.cgi?id=387 is fixed */
> > > +     int data_off = data_addr - (uint8_t *)odp_buffer_addr(buf);
> > > +
> > > +     /* Prepare input/output params */
> > > +     odp_crypto_op_params_t op_params;
> > > +     memset(&op_params, 0, sizeof(op_params));
> > > +     op_params.session = session;
> > > +     op_params.pkt = pkt;
> > > +     op_params.out_pkt = pkt;
> > > +     if (cipher_alg != ODP_CIPHER_ALG_NULL &&
> > > +         auth_alg == ODP_AUTH_ALG_NULL) {
> > > +             op_params.cipher_range.offset = data_off;
> > > +             op_params.cipher_range.length = input_vec_len;
> > > +             if (op_iv_ptr)
> > > +                     op_params.override_iv_ptr = op_iv_ptr;
> > > +     } else if (cipher_alg == ODP_CIPHER_ALG_NULL &&
> > > +              auth_alg != ODP_AUTH_ALG_NULL) {
> > > +             op_params.auth_range.offset = data_off;
> > > +             op_params.auth_range.length = input_vec_len;
> > > +             op_params.hash_result_offset = data_off;
> > > +     } else {
> > > +             CU_FAIL("%s : not implemented for combined alg mode\n");
> > > +     }
> > > +
> > > +     /* TEST : odp_crypto_set_operation_compl_ctx */
> > > +     /* TEST : odp_crypto_operation */
> > > +     if (compl_new == ODP_BUFFER_INVALID) {
> > > +             odp_crypto_set_operation_compl_ctx(buf, (void
> > *)0xdeadbeef);
> > > +             rc = odp_crypto_operation(&op_params, &posted, buf);
> > > +     } else {
> > > +             odp_crypto_set_operation_compl_ctx(compl_new,
> > > +                                                (void *)0xdeadbeef);
> > > +             rc = odp_crypto_operation(&op_params, &posted, compl_new);
> > > +     }
> > > +     CU_ASSERT(posted);
> > > +
> > > +     /* Poll completion queue for results */
> > > +     do {
> > > +             compl_event = odp_queue_deq(compl_queue);
> > > +     } while (compl_event == ODP_BUFFER_INVALID);
> > > +
> > > +     if (compl_new == ODP_BUFFER_INVALID) {
> > > +             CU_ASSERT(compl_event == buf);
> > > +     } else {
> > > +             CU_ASSERT(compl_event == compl_new);
> > > +     }
> > > +
> > > +     /* TEST : odp_crypto_get_operation_compl_status */
> > > +     struct odp_crypto_compl_status auth_status, cipher_status;
> > > +     odp_crypto_get_operation_compl_status(compl_event,
> > > +                                           &auth_status,
> > &cipher_status);
> > > +     CU_ASSERT(auth_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE);
> > > +     CU_ASSERT(auth_status.hw_err == ODP_CRYPTO_HW_ERR_NONE);
> > > +     CU_ASSERT(cipher_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE);
> > > +     CU_ASSERT(cipher_status.hw_err == ODP_CRYPTO_HW_ERR_NONE);
> > > +
> > > +     /* TEST : odp_crypto_get_operation_compl_packet */
> > > +     odp_packet_t out_pkt;
> > > +     out_pkt = odp_crypto_get_operation_compl_packet(compl_event);
> > > +     CU_ASSERT(out_pkt == pkt);
> > > +
> > > +     /* TEST : operation output was correct */
> > > +     CU_ASSERT(!memcmp(data_addr, output_vec, output_vec_len));
> > > +
> > > +     /* TEST : we got back the context pointer */
> > > +     void *ctx = odp_crypto_get_operation_compl_ctx(compl_event);
> > > +     CU_ASSERT(ctx == (void *)0xdeadbeef);
> > > +
> > > +     odp_buffer_free(buf);
> > > +}
> > > +
> > > +/* This test verifies the correctness of encode (plaintext ->
> > ciphertext)
> > > + * operation for 3DES_CBC algorithm. IV for the operation is the
> > session IV.
> > > + * In addition the test verifies if the implementation can use the
> > > + * packet buffer as completion event buffer.*/
> > > +#define ASYNC_INP_ENC_ALG_3DES_CBC   "ENC_ALG_3DES_CBC"
> > > +static void test_enc_alg_3des_cbc(void)
> > > +{
> > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > > +                      auth_key   = { .data = NULL, .length = 0 };
> > > +     odp_crypto_iv_t iv;
> > > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > > +                                  sizeof(tdes_cbc_reference_length[0]));
> > > +
> > > +     unsigned int i;
> > > +     for (i = 0; i < test_vec_num; i++) {
> > > +             cipher_key.data = tdes_cbc_reference_key[i];
> > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > > +             iv.data = tdes_cbc_reference_iv[i];
> > > +             iv.length = sizeof(tdes_cbc_reference_iv[i]);
> > > +
> > > +             alg_test(ODP_CRYPTO_OP_ENCODE,
> > > +                      ODP_CIPHER_ALG_3DES_CBC,
> > > +                      iv,
> > > +                      NULL,
> > > +                      cipher_key,
> > > +                      ODP_AUTH_ALG_NULL,
> > > +                      auth_key,
> > > +                      ODP_BUFFER_INVALID,
> > > +                      tdes_cbc_reference_plaintext[i],
> > > +                      tdes_cbc_reference_length[i],
> > > +                      tdes_cbc_reference_ciphertext[i],
> > > +                      tdes_cbc_reference_length[i]);
> > > +     }
> > > +}
> > > +
> > > +/* This test verifies the correctness of encode (plaintext ->
> > ciphertext)
> > > + * operation for 3DES_CBC algorithm. IV for the operation is the
> > operation IV.
> > > + * */
> > > +#define ASYNC_INP_ENC_ALG_3DES_CBC_OVR_IV    "ENC_ALG_3DES_CBC_OVR_IV"
> > > +static void test_enc_alg_3des_cbc_ovr_iv(void)
> > > +{
> > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > > +                      auth_key   = { .data = NULL, .length = 0 };
> > > +     odp_crypto_iv_t iv = { .data = NULL, .length = TDES_CBC_IV_LEN };
> > > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > > +                                  sizeof(tdes_cbc_reference_length[0]));
> > > +
> > > +     unsigned int i;
> > > +     for (i = 0; i < test_vec_num; i++) {
> > > +             cipher_key.data = tdes_cbc_reference_key[i];
> > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > > +
> > > +             alg_test(ODP_CRYPTO_OP_ENCODE,
> > > +                      ODP_CIPHER_ALG_3DES_CBC,
> > > +                      iv,
> > > +                      tdes_cbc_reference_iv[i],
> > > +                      cipher_key,
> > > +                      ODP_AUTH_ALG_NULL,
> > > +                      auth_key,
> > > +                      ODP_BUFFER_INVALID,
> > > +                      tdes_cbc_reference_plaintext[i],
> > > +                      tdes_cbc_reference_length[i],
> > > +                      tdes_cbc_reference_ciphertext[i],
> > > +                      tdes_cbc_reference_length[i]);
> > > +     }
> > > +}
> > > +
> > > +
> > > +/* This test verifies the correctness of decode (ciphertext ->
> > plaintext)
> > > + * operation for 3DES_CBC algorithm. IV for the operation is the
> > session IV
> > > + * In addition the test verifies if the implementation can use the
> > > + * packet buffer as completion event buffer.
> > > + * */
> > > +#define ASYNC_INP_DEC_ALG_3DES_CBC    "DEC_ALG_3DES_CBC"
> > > +static void test_dec_alg_3des_cbc(void)
> > > +{
> > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > > +                      auth_key   = { .data = NULL, .length = 0 };
> > > +     odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
> > > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > > +                                  sizeof(tdes_cbc_reference_length[0]));
> > > +
> > > +     unsigned int i;
> > > +     for (i = 0; i < test_vec_num; i++) {
> > > +             cipher_key.data = tdes_cbc_reference_key[i];
> > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > > +             iv.data = tdes_cbc_reference_iv[i];
> > > +             iv.length = sizeof(tdes_cbc_reference_iv[i]);
> > > +
> > > +             alg_test(ODP_CRYPTO_OP_DECODE,
> > > +                      ODP_CIPHER_ALG_3DES_CBC,
> > > +                      iv,
> > > +                      NULL,
> > > +                      cipher_key,
> > > +                      ODP_AUTH_ALG_NULL,
> > > +                      auth_key,
> > > +                      ODP_BUFFER_INVALID,
> > > +                      tdes_cbc_reference_ciphertext[i],
> > > +                      tdes_cbc_reference_length[i],
> > > +                      tdes_cbc_reference_plaintext[i],
> > > +                      tdes_cbc_reference_length[i]);
> > > +     }
> > > +}
> > > +
> > > +/* This test verifies the correctness of decode (ciphertext ->
> > plaintext)
> > > + * operation for 3DES_CBC algorithm. IV for the operation is the
> > session IV
> > > + * In addition the test verifies if the implementation can use the
> > > + * packet buffer as completion event buffer.
> > > + * */
> > > +#define ASYNC_INP_DEC_ALG_3DES_CBC_OVR_IV     "DEC_ALG_3DES_CBC_OVR_IV"
> > > +static void test_dec_alg_3des_cbc_ovr_iv(void)
> > > +{
> > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > > +                      auth_key   = { .data = NULL, .length = 0 };
> > > +     odp_crypto_iv_t iv = { .data = NULL, .length = TDES_CBC_IV_LEN };
> > > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > > +                                  sizeof(tdes_cbc_reference_length[0]));
> > > +
> > > +     unsigned int i;
> > > +     for (i = 0; i < test_vec_num; i++) {
> > > +             cipher_key.data = tdes_cbc_reference_key[i];
> > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > > +
> > > +             alg_test(ODP_CRYPTO_OP_DECODE,
> > > +                      ODP_CIPHER_ALG_3DES_CBC,
> > > +                      iv,
> > > +                      tdes_cbc_reference_iv[i],
> > > +                      cipher_key,
> > > +                      ODP_AUTH_ALG_NULL,
> > > +                      auth_key,
> > > +                      ODP_BUFFER_INVALID,
> > > +                      tdes_cbc_reference_ciphertext[i],
> > > +                      tdes_cbc_reference_length[i],
> > > +                      tdes_cbc_reference_plaintext[i],
> > > +                      tdes_cbc_reference_length[i]);
> > > +     }
> > > +}
> > > +
> > > +
> > > +/* This test verifies the correctness of HMAC_MD5 digest operation.
> > > + * The output check length is truncated to 12 bytes (96 bits) as
> > > + * returned by the crypto operation API call.
> > > + * Note that hash digest is a one-way operation.
> > > + * In addition the test verifies if the implementation can use the
> > > + * packet buffer as completion event buffer.
> > > + * */
> > > +#define ASYNC_INP_ALG_HMAC_MD5             "ALG_HMAC_MD5"
> > > +static void test_alg_hmac_md5(void)
> > > +{
> > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > > +                      auth_key   = { .data = NULL, .length = 0 };
> > > +     odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
> > > +
> > > +     unsigned int test_vec_num = (sizeof(hmac_md5_reference_length)/
> > > +                                  sizeof(hmac_md5_reference_length[0]));
> > > +
> > > +     unsigned int i;
> > > +     for (i = 0; i < test_vec_num; i++) {
> > > +             auth_key.data = hmac_md5_reference_key[i];
> > > +             auth_key.length = sizeof(hmac_md5_reference_key[i]);
> > > +
> > > +             alg_test(ODP_CRYPTO_OP_ENCODE,
> > > +                      ODP_CIPHER_ALG_NULL,
> > > +                      iv,
> > > +                      iv.data,
> > > +                      cipher_key,
> > > +                      ODP_AUTH_ALG_MD5_96,
> > > +                      auth_key,
> > > +                      ODP_BUFFER_INVALID,
> > > +                      hmac_md5_reference_plaintext[i],
> > > +                      hmac_md5_reference_length[i],
> > > +                      hmac_md5_reference_digest[i],
> > > +                      HMAC_MD5_96_CHECK_LEN);
> > > +     }
> > > +}
> > > +
> > > +/* This test verifies the correctness of encode (plaintext ->
> > ciphertext)
> > > + * operation for 3DES_CBC algorithm. IV for the operation is the
> > session IV.
> > > + * Uses a separate buffer for completion event
> > > + * */
> > > +#define ASYNC_INP_ENC_ALG_3DES_CBC_COMPL_NEW
> > "ENC_ALG_3DES_CBC_COMPL_NEW"
> > > +static void test_enc_alg_3des_cbc_compl_new(void)
> > > +{
> > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > > +                      auth_key   = { .data = NULL, .length = 0 };
> > > +     odp_crypto_iv_t iv;
> > > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > > +                                  sizeof(tdes_cbc_reference_length[0]));
> > > +
> > > +     odp_buffer_pool_t pool = odp_buffer_pool_lookup("compl_pool");
> > > +     CU_ASSERT(pool != ODP_BUFFER_POOL_INVALID);
> > > +
> > > +     unsigned int i;
> > > +     odp_buffer_t compl_new;
> > > +     for (i = 0; i < test_vec_num; i++) {
> > > +             compl_new = odp_buffer_alloc(pool);
> > > +             CU_ASSERT(compl_new != ODP_BUFFER_INVALID);
> > > +
> > > +             cipher_key.data = tdes_cbc_reference_key[i];
> > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > > +             iv.data = tdes_cbc_reference_iv[i];
> > > +             iv.length = sizeof(tdes_cbc_reference_iv[i]);
> > > +
> > > +             alg_test(ODP_CRYPTO_OP_ENCODE,
> > > +                      ODP_CIPHER_ALG_3DES_CBC,
> > > +                      iv,
> > > +                      NULL,
> > > +                      cipher_key,
> > > +                      ODP_AUTH_ALG_NULL,
> > > +                      auth_key,
> > > +                      compl_new,
> > > +                      tdes_cbc_reference_plaintext[i],
> > > +                      tdes_cbc_reference_length[i],
> > > +                      tdes_cbc_reference_ciphertext[i],
> > > +                      tdes_cbc_reference_length[i]);
> > > +             odp_buffer_free(compl_new);
> > > +     }
> > > +}
> > > +
> > > +static CU_TestInfo test_array[] = {
> > > +     {ASYNC_INP_ENC_ALG_3DES_CBC, test_enc_alg_3des_cbc },
> > > +     {ASYNC_INP_DEC_ALG_3DES_CBC, test_dec_alg_3des_cbc },
> > > +     {ASYNC_INP_ENC_ALG_3DES_CBC_OVR_IV, test_enc_alg_3des_cbc_ovr_iv },
> > > +     {ASYNC_INP_DEC_ALG_3DES_CBC_OVR_IV, test_dec_alg_3des_cbc_ovr_iv },
> > > +     {ASYNC_INP_ALG_HMAC_MD5, test_alg_hmac_md5 },
> > > +     {ASYNC_INP_ENC_ALG_3DES_CBC_COMPL_NEW,
> > test_enc_alg_3des_cbc_compl_new },
> > > +     CU_TEST_INFO_NULL,
> > > +};
> > > +
> > > +CU_SuiteInfo suites[] = {
> > > +     { ODP_CRYPTO_ASYNC_INP , init, finalize, NULL, NULL, test_array },
> > > +     CU_SUITE_INFO_NULL,
> > > +};
> > > diff --git a/test/cunit/crypto/odp_crypto_test_async_inp.h
> > b/test/cunit/crypto/odp_crypto_test_async_inp.h
> > > new file mode 100644
> > > index 0000000..818f7e7
> > > --- /dev/null
> > > +++ b/test/cunit/crypto/odp_crypto_test_async_inp.h
> > > @@ -0,0 +1,13 @@
> > > +/* Copyright (c) 2014, Linaro Limited
> > > + * All rights reserved.
> > > + *
> > > + * SPDX-License-Identifier:     BSD-3-Clause
> > > + */
> > > +#ifndef ODP_CRYPTO_TEST_ASYNC_INP_
> > > +#define ODP_CRYPTO_TEST_ASYNC_INP_
> > > +
> > > +#include "CUnit/Headers/TestDB.h"
> > > +
> > > +CU_SuiteInfo suites[1];
> > > +
> > > +#endif
> > > diff --git a/test/cunit/crypto/test_vectors.h
> > b/test/cunit/crypto/test_vectors.h
> > > new file mode 100644
> > > index 0000000..c151952
> > > --- /dev/null
> > > +++ b/test/cunit/crypto/test_vectors.h
> > > @@ -0,0 +1,94 @@
> > > +/* Copyright (c) 2014, Linaro Limited
> > > + * All rights reserved.
> > > + *
> > > + * SPDX-License-Identifier:  BSD-3-Clause
> > > + */
> > > +
> > > +
> > > +/* TDES-CBC reference vectors, according to
> > > + * "http://csrc.nist.gov/groups/STM/cavp/documents/des/DESMMT.pdf"
> > > + */
> > > +
> > > +#define TDES_CBC_KEY_LEN     24      /* key length(in bytes) for
> > tdes-cbc */
> > > +#define TDES_CBC_IV_LEN              8       /* IV length(in bytes) for
> > tdes-cbc */
> > > +#define TDES_CBC_MAX_DATA_LEN        16      /* max. plain text
> > length(in bytes) */
> > > +
> > > +static uint8_t tdes_cbc_reference_key[][TDES_CBC_KEY_LEN] = {
> > > +     {0x62, 0x7f, 0x46, 0x0e, 0x08, 0x10, 0x4a, 0x10, 0x43, 0xcd, 0x26,
> > 0x5d,
> > > +      0x58, 0x40, 0xea, 0xf1, 0x31, 0x3e, 0xdf, 0x97, 0xdf, 0x2a, 0x8a,
> > 0x8c,
> > > +      },
> > > +
> > > +     {0x37, 0xae, 0x5e, 0xbf, 0x46, 0xdf, 0xf2, 0xdc, 0x07, 0x54, 0xb9,
> > 0x4f,
> > > +      0x31, 0xcb, 0xb3, 0x85, 0x5e, 0x7f, 0xd3, 0x6d, 0xc8, 0x70, 0xbf,
> > 0xae}
> > > +};
> > > +
> > > +static uint8_t tdes_cbc_reference_iv[][TDES_CBC_IV_LEN] = {
> > > +     {0x8e, 0x29, 0xf7, 0x5e, 0xa7, 0x7e, 0x54, 0x75},
> > > +
> > > +     {0x3d, 0x1d, 0xe3, 0xcc, 0x13, 0x2e, 0x3b, 0x65}
> > > +};
> > > +
> > > +/** length in bytes */
> > > +static uint32_t tdes_cbc_reference_length[] = { 8, 16 };
> > > +
> > > +static uint8_t tdes_cbc_reference_plaintext[][TDES_CBC_MAX_DATA_LEN] = {
> > > +     {0x32, 0x6a, 0x49, 0x4c, 0xd3, 0x3f, 0xe7, 0x56},
> > > +
> > > +     {0x84, 0x40, 0x1f, 0x78, 0xfe, 0x6c, 0x10, 0x87, 0x6d, 0x8e, 0xa2,
> > 0x30,
> > > +      0x94, 0xea, 0x53, 0x09}
> > > +};
> > > +
> > > +static uint8_t tdes_cbc_reference_ciphertext[][TDES_CBC_MAX_DATA_LEN] =
> > {
> > > +     {0xb2, 0x2b, 0x8d, 0x66, 0xde, 0x97, 0x06, 0x92},
> > > +
> > > +     {0x7b, 0x1f, 0x7c, 0x7e, 0x3b, 0x1c, 0x94, 0x8e, 0xbd, 0x04, 0xa7,
> > 0x5f,
> > > +      0xfb, 0xa7, 0xd2, 0xf5}
> > > +};
> > > +
> > > +
> > > +/* HMAC-MD5 test vectors  - RFC2104 */
> > > +#define HMAC_MD5_KEY_LEN     16
> > > +#define HMAC_MD5_MAX_DATA_LEN        128
> > > +#define HMAC_MD5_DIGEST_LEN  16
> > > +#define HMAC_MD5_96_CHECK_LEN        12
> > > +
> > > +static uint8_t hmac_md5_reference_key[][HMAC_MD5_KEY_LEN] = {
> > > +     { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
> > > +       0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b } ,
> > > +
> > > +     /* "Jefe" */
> > > +     { 0x4a, 0x65, 0x66, 0x65 },
> > > +
> > > +     { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
> > > +       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }
> > > +};
> > > +
> > > +static uint32_t hmac_md5_reference_length[] = { 8, 28, 50 };
> > > +
> > > +static uint8_t hmac_md5_reference_plaintext[][HMAC_MD5_MAX_DATA_LEN] = {
> > > +     /* "Hi There" */
> > > +     { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65},
> > > +
> > > +     /* what do ya want for nothing?*/
> > > +     { 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
> > > +       0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
> > > +       0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
> > > +       0x69, 0x6e, 0x67, 0x3f },
> > > +
> > > +     { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> > > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> > > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> > > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> > > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd }
> > > +};
> > > +
> > > +static uint8_t hmac_md5_reference_digest[][HMAC_MD5_DIGEST_LEN] = {
> > > +     { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
> > > +       0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d },
> > > +
> > > +     { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
> > > +       0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 },
> > > +
> > > +     { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
> > > +       0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }
> > > +};
> > > --
> > > 1.7.3.4
> > >
> > >
> > > _______________________________________________
> > > lng-odp mailing list
> > > lng-odp@lists.linaro.org
> > > http://lists.linaro.org/mailman/listinfo/lng-odp
> >
Mike Holmes Oct. 31, 2014, 6:14 p.m. UTC | #4
I had thought that in this case it might be something like below using the
cunit ability to organise tests into different suites.
The code can then be organized and reused as needed, but it is all built
together as a suite that can be run for async only, sync only or both, with
the main entry point just taking an commandline argument as to which suites
to run.

                        crypto
                            |
             ------------------------------
             |                            |
          async      . . . .             sync
             |                            |
       ---------------             ---------------
       |             |             |             |
    Test '11' ... Test '1M'     Test 'N1' ... Test 'NM'


On 31 October 2014 11:10, Jerin Jacob <jerin.jacob@caviumnetworks.com>
wrote:

> On Fri, Oct 31, 2014 at 04:35:21PM +0200, Alexandru Badicioiu wrote:
> > This suite is only for async inplace mode.The tests can be reused, with
> > some modifications, for other modes too (sync/inplace/outplace/). Command
> > line argument to select the the suite(s) or separate test programs could
> > work too.
>
> Introducing an abstraction for sync/async mode for functional test-case is
> very straight forward.
> Most of the platforms don't support both async and sync together.
> and its very difficult to maintain parallel tests suites for the same
> functionality which can be abstracted.
> If you need any help in defining/reviewing the abstraction and/or testing
> the sync mode then I can help you with that.
> I would like avoid the duplicate effort of writing parallel ODP crypto
> Cunit testcases.
>
> Let me know your views on the proposal.
>
> >
> > On 31 October 2014 16:28, Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > wrote:
> >
> > > On Fri, Oct 31, 2014 at 02:08:47PM +0200,
> alexandru.badicioiu@linaro.org
> > > wrote:
> > > > From: Alexandru Badicioiu <alexandru.badicioiu@linaro.org>
> > > >
> > > > This patch adds a suite for async inplace mode of crypto APIs.
> > > > Correctness of crypto operations output is verified with known
> > > > test vectors  as well as various options and functionalities:
> > > > use session IV or operation IV for ciphering, use input packet
> > > > buffer or a separate buffer as the completion event, set and
> > > > retrieve the context associated with an operation.
> > >
> > > IMO crypto functionality unit tests should be capable of running on
> both
> > > sync and async modes.
> > > Platform like octeon supports only sync crypto mode.
> > > We can introduce a command-line option to select the mode for
> functional
> > > testcases.
> > > We can have separate  dedicated test to verify async/sync operation but
> > > crypto functional tests
> > > should cater both.
> > >
> > > Jerin
> > >
> > > >
> > > > Signed-off-by: Alexandru Badicioiu <alexandru.badicioiu@linaro.org>
> > > > ---
> > > >  configure.ac                                  |    1 +
> > > >  test/cunit/Makefile.am                        |    2 +
> > > >  test/cunit/crypto/Makefile.am                 |    9 +
> > > >  test/cunit/crypto/odp_crypto_test.c           |   26 ++
> > > >  test/cunit/crypto/odp_crypto_test_async_inp.c |  459
> > > +++++++++++++++++++++++++
> > > >  test/cunit/crypto/odp_crypto_test_async_inp.h |   13 +
> > > >  test/cunit/crypto/test_vectors.h              |   94 +++++
> > > >  7 files changed, 604 insertions(+), 0 deletions(-)
> > > >  create mode 100644 test/cunit/crypto/Makefile.am
> > > >  create mode 100644 test/cunit/crypto/odp_crypto_test.c
> > > >  create mode 100644 test/cunit/crypto/odp_crypto_test_async_inp.c
> > > >  create mode 100644 test/cunit/crypto/odp_crypto_test_async_inp.h
> > > >  create mode 100644 test/cunit/crypto/test_vectors.h
> > > >
> > > > diff --git a/configure.ac b/configure.ac
> > > > index fd69e85..b1785e9 100644
> > > > --- a/configure.ac
> > > > +++ b/configure.ac
> > > > @@ -166,6 +166,7 @@ AC_CONFIG_FILES([Makefile
> > > >                test/Makefile
> > > >                test/api_test/Makefile
> > > >                   test/cunit/Makefile
> > > > +              test/cunit/crypto/Makefile
> > > >                pkgconfig/libodp.pc])
> > > >
> > > >  AC_SEARCH_LIBS([timer_create],[rt posix4])
> > > > diff --git a/test/cunit/Makefile.am b/test/cunit/Makefile.am
> > > > index 927a5a5..7611145 100644
> > > > --- a/test/cunit/Makefile.am
> > > > +++ b/test/cunit/Makefile.am
> > > > @@ -3,6 +3,8 @@ include $(top_srcdir)/test/Makefile.inc
> > > >  AM_CFLAGS += -I$(CUNIT_PATH)/include
> > > >  AM_LDFLAGS += -L$(CUNIT_PATH)/lib
> > > >
> > > > +SUBDIRS = crypto
> > > > +
> > > >  if ODP_CUNIT_ENABLED
> > > >  TESTS = ${bin_PROGRAMS}
> > > >  check_PROGRAMS = ${bin_PROGRAMS}
> > > > diff --git a/test/cunit/crypto/Makefile.am
> > > b/test/cunit/crypto/Makefile.am
> > > > new file mode 100644
> > > > index 0000000..b984eaa
> > > > --- /dev/null
> > > > +++ b/test/cunit/crypto/Makefile.am
> > > > @@ -0,0 +1,9 @@
> > > > +include $(top_srcdir)/test/Makefile.inc
> > > > +
> > > > +if ODP_CUNIT_ENABLED
> > > > +bin_PROGRAMS = odp_crypto
> > > > +odp_crypto_LDFLAGS = $(AM_LDFLAGS) -static -lcunit
> > > > +endif
> > > > +
> > > > +dist_odp_crypto_SOURCES = odp_crypto_test_async_inp.c \
> > > > +                       odp_crypto_test.c
> > > > diff --git a/test/cunit/crypto/odp_crypto_test.c
> > > b/test/cunit/crypto/odp_crypto_test.c
> > > > new file mode 100644
> > > > index 0000000..b5d0dea
> > > > --- /dev/null
> > > > +++ b/test/cunit/crypto/odp_crypto_test.c
> > > > @@ -0,0 +1,26 @@
> > > > +/* Copyright (c) 2014, Linaro Limited
> > > > + * All rights reserved.
> > > > + *
> > > > + * SPDX-License-Identifier:     BSD-3-Clause
> > > > + */
> > > > +
> > > > +#include <odp.h>
> > > > +#include "CUnit/Headers/Basic.h"
> > > > +#include "CUnit/Headers/TestDB.h"
> > > > +#include "odp_crypto_test_async_inp.h"
> > > > +
> > > > +int main(void)
> > > > +{
> > > > +     /* initialize the CUnit test registry */
> > > > +     if (CUE_SUCCESS != CU_initialize_registry())
> > > > +             return CU_get_error();
> > > > +
> > > > +     /* register suites */
> > > > +     CU_register_suites(suites);
> > > > +     /* Run all tests using the CUnit Basic interface */
> > > > +     CU_basic_set_mode(CU_BRM_VERBOSE);
> > > > +     CU_basic_run_tests();
> > > > +     CU_cleanup_registry();
> > > > +
> > > > +     return CU_get_error();
> > > > +}
> > > > diff --git a/test/cunit/crypto/odp_crypto_test_async_inp.c
> > > b/test/cunit/crypto/odp_crypto_test_async_inp.c
> > > > new file mode 100644
> > > > index 0000000..dd5fb5f
> > > > --- /dev/null
> > > > +++ b/test/cunit/crypto/odp_crypto_test_async_inp.c
> > > > @@ -0,0 +1,458 @@
> > > > +/* Copyright (c) 2014, Linaro Limited
> > > > + * All rights reserved.
> > > > + *
> > > > + * SPDX-License-Identifier:  BSD-3-Clause
> > > > + */
> > > > +
> > > > +#include <odp.h>
> > > > +#include <odp_crypto.h>
> > > > +#include "CUnit/Headers/Basic.h"
> > > > +#include "CUnit/Headers/TestDB.h"
> > > > +#include "test_vectors.h"
> > > > +
> > > > +/* Suite name */
> > > > +#define ODP_CRYPTO_ASYNC_INP "odp_crypto_async_inp"
> > > > +
> > > > +/* Suite init/finalize funcs */
> > > > +/* ODP global/local initialization
> > > > + * Packet pool creation
> > > > + * Crypto output queue creation */
> > > > +
> > > > +#define SHM_PKT_POOL_SIZE      (512*2048*2)
> > > > +#define SHM_PKT_POOL_BUF_SIZE  (1024 * 32)
> > > > +
> > > > +#define SHM_COMPL_POOL_SIZE  (128*1024)
> > > > +#define SHM_COMPL_POOL_BUF_SIZE 128
> > > > +
> > > > +static int init(void)
> > > > +{
> > > > +     odp_shm_t shm;
> > > > +     void *pool_base = NULL;
> > > > +     odp_buffer_pool_t pool;
> > > > +     odp_queue_t out_queue;
> > > > +
> > > > +     if (odp_init_global(NULL, NULL)) {
> > > > +             ODP_ERR("ODP global init failed.\n");
> > > > +             return -1;
> > > > +     }
> > > > +     odp_init_local();
> > > > +
> > > > +     shm = odp_shm_reserve("shm_packet_pool",
> > > > +                           SHM_PKT_POOL_SIZE,
> > > > +                           ODP_CACHE_LINE_SIZE, 0);
> > > > +
> > > > +     pool_base = odp_shm_addr(shm);
> > > > +     if (!pool_base) {
> > > > +             ODP_ERR("Packet pool allocation failed.\n");
> > > > +             return -1;
> > > > +     }
> > > > +
> > > > +     pool = odp_buffer_pool_create("packet_pool", pool_base,
> > > > +                                   SHM_PKT_POOL_SIZE,
> > > > +                                   SHM_PKT_POOL_BUF_SIZE,
> > > > +                                   ODP_CACHE_LINE_SIZE,
> > > > +                                   ODP_BUFFER_TYPE_PACKET);
> > > > +     if (pool == ODP_BUFFER_POOL_INVALID) {
> > > > +             ODP_ERR("Packet pool creation failed.\n");
> > > > +             return -1;
> > > > +     }
> > > > +     out_queue = odp_queue_create("crypto-out",
> > > > +                                  ODP_QUEUE_TYPE_POLL, NULL);
> > > > +     if (out_queue == ODP_QUEUE_INVALID) {
> > > > +             ODP_ERR("Crypto outq creation failed.\n");
> > > > +             return -1;
> > > > +     }
> > > > +     shm = odp_shm_reserve("shm_compl_pool",
> > > > +                          SHM_COMPL_POOL_SIZE,
> > > > +                          ODP_CACHE_LINE_SIZE,
> > > > +                          ODP_SHM_SW_ONLY);
> > > > +     pool_base = odp_shm_addr(shm);
> > > > +     if (!pool_base) {
> > > > +             ODP_ERR("Completion pool allocation failed.\n");
> > > > +             return -1;
> > > > +     }
> > > > +     pool = odp_buffer_pool_create("compl_pool", pool_base,
> > > > +                                   SHM_COMPL_POOL_SIZE,
> > > > +                                   SHM_COMPL_POOL_BUF_SIZE,
> > > > +                                   ODP_CACHE_LINE_SIZE,
> > > > +                                   ODP_BUFFER_TYPE_RAW);
> > > > +     if (pool == ODP_BUFFER_POOL_INVALID) {
> > > > +             ODP_ERR("Completion pool creation failed.\n");
> > > > +             return -1;
> > > > +     }
> > > > +
> > > > +     printf("\tODP version: %s\n", odp_version_api_str());
> > > > +     return 0;
> > > > +}
> > > > +
> > > > +/* ODP cleanup */
> > > > +static int finalize(void)
> > > > +{
> > > > +     odp_term_local();
> > > > +     odp_term_global();
> > > > +     return 0;
> > > > +}
> > > > +
> > > > +
> > > > +/* Basic algorithm run function.
> > > > + * Creates a session from input parameters and runs one operation
> > > > + * on input_vec. Checks the output of the crypto operation against
> > > > + * output_vec. Operation completion event is dequeued polling the
> > > > + * session output queue. Completion context pointer is retrieved
> > > > + * and checked against the one set before the operation.
> > > > + * */
> > > > +static void alg_test(enum odp_crypto_op op,
> > > > +                  enum odp_cipher_alg cipher_alg,
> > > > +                  odp_crypto_iv_t ses_iv,
> > > > +                  uint8_t *op_iv_ptr,
> > > > +                  odp_crypto_key_t cipher_key,
> > > > +                  enum odp_auth_alg auth_alg,
> > > > +                  odp_crypto_key_t auth_key,
> > > > +                  odp_buffer_t compl_new,
> > > > +                  uint8_t *input_vec,
> > > > +                  unsigned int input_vec_len,
> > > > +                  uint8_t *output_vec,
> > > > +                  unsigned int output_vec_len)
> > > > +{
> > > > +     odp_crypto_session_t session;
> > > > +     int rc;
> > > > +     enum odp_crypto_ses_create_err status;
> > > > +     bool posted;
> > > > +     odp_buffer_t compl_event;
> > > > +
> > > > +     odp_queue_t compl_queue = odp_queue_lookup("crypto-out");
> > > > +     CU_ASSERT(compl_queue != ODP_QUEUE_INVALID);
> > > > +     odp_buffer_pool_t pool = odp_buffer_pool_lookup("packet_pool");
> > > > +     CU_ASSERT(pool != ODP_BUFFER_POOL_INVALID);
> > > > +
> > > > +     /* Create a crypto session */
> > > > +     odp_crypto_session_params_t ses_params;
> > > > +     memset(&ses_params, 0, sizeof(ses_params));
> > > > +     ses_params.op = op;
> > > > +     ses_params.auth_cipher_text = false;
> > > > +     ses_params.pref_mode = ODP_CRYPTO_ASYNC;
> > > > +     ses_params.cipher_alg = cipher_alg;
> > > > +     ses_params.auth_alg = auth_alg;
> > > > +     ses_params.compl_queue = compl_queue;
> > > > +     ses_params.output_pool = pool;
> > > > +     ses_params.cipher_key = cipher_key;
> > > > +     ses_params.iv = ses_iv;
> > > > +     ses_params.auth_key = auth_key;
> > > > +
> > > > +     /* TEST : odp_crypto_session_create */
> > > > +     rc = odp_crypto_session_create(&ses_params, &session, &status);
> > > > +     CU_ASSERT(!rc);
> > > > +     CU_ASSERT(status == ODP_CRYPTO_SES_CREATE_ERR_NONE);
> > > > +
> > > > +     /* Prepare input data */
> > > > +     odp_buffer_t buf = odp_buffer_alloc(pool);
> > > > +     CU_ASSERT(buf != ODP_BUFFER_INVALID);
> > > > +     odp_packet_t pkt = odp_packet_from_buffer(buf);
> > > > +     CU_ASSERT(pkt != ODP_PACKET_INVALID);
> > > > +     uint8_t *data_addr = odp_packet_data(pkt);
> > > > +     memcpy(data_addr, input_vec, input_vec_len);
> > > > +     /* offsets are relative to buffer address (not packet data)
> > > > +     until https://bugs.linaro.org/show_bug.cgi?id=387 is fixed */
> > > > +     int data_off = data_addr - (uint8_t *)odp_buffer_addr(buf);
> > > > +
> > > > +     /* Prepare input/output params */
> > > > +     odp_crypto_op_params_t op_params;
> > > > +     memset(&op_params, 0, sizeof(op_params));
> > > > +     op_params.session = session;
> > > > +     op_params.pkt = pkt;
> > > > +     op_params.out_pkt = pkt;
> > > > +     if (cipher_alg != ODP_CIPHER_ALG_NULL &&
> > > > +         auth_alg == ODP_AUTH_ALG_NULL) {
> > > > +             op_params.cipher_range.offset = data_off;
> > > > +             op_params.cipher_range.length = input_vec_len;
> > > > +             if (op_iv_ptr)
> > > > +                     op_params.override_iv_ptr = op_iv_ptr;
> > > > +     } else if (cipher_alg == ODP_CIPHER_ALG_NULL &&
> > > > +              auth_alg != ODP_AUTH_ALG_NULL) {
> > > > +             op_params.auth_range.offset = data_off;
> > > > +             op_params.auth_range.length = input_vec_len;
> > > > +             op_params.hash_result_offset = data_off;
> > > > +     } else {
> > > > +             CU_FAIL("%s : not implemented for combined alg
> mode\n");
> > > > +     }
> > > > +
> > > > +     /* TEST : odp_crypto_set_operation_compl_ctx */
> > > > +     /* TEST : odp_crypto_operation */
> > > > +     if (compl_new == ODP_BUFFER_INVALID) {
> > > > +             odp_crypto_set_operation_compl_ctx(buf, (void
> > > *)0xdeadbeef);
> > > > +             rc = odp_crypto_operation(&op_params, &posted, buf);
> > > > +     } else {
> > > > +             odp_crypto_set_operation_compl_ctx(compl_new,
> > > > +                                                (void *)0xdeadbeef);
> > > > +             rc = odp_crypto_operation(&op_params, &posted,
> compl_new);
> > > > +     }
> > > > +     CU_ASSERT(posted);
> > > > +
> > > > +     /* Poll completion queue for results */
> > > > +     do {
> > > > +             compl_event = odp_queue_deq(compl_queue);
> > > > +     } while (compl_event == ODP_BUFFER_INVALID);
> > > > +
> > > > +     if (compl_new == ODP_BUFFER_INVALID) {
> > > > +             CU_ASSERT(compl_event == buf);
> > > > +     } else {
> > > > +             CU_ASSERT(compl_event == compl_new);
> > > > +     }
> > > > +
> > > > +     /* TEST : odp_crypto_get_operation_compl_status */
> > > > +     struct odp_crypto_compl_status auth_status, cipher_status;
> > > > +     odp_crypto_get_operation_compl_status(compl_event,
> > > > +                                           &auth_status,
> > > &cipher_status);
> > > > +     CU_ASSERT(auth_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE);
> > > > +     CU_ASSERT(auth_status.hw_err == ODP_CRYPTO_HW_ERR_NONE);
> > > > +     CU_ASSERT(cipher_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE);
> > > > +     CU_ASSERT(cipher_status.hw_err == ODP_CRYPTO_HW_ERR_NONE);
> > > > +
> > > > +     /* TEST : odp_crypto_get_operation_compl_packet */
> > > > +     odp_packet_t out_pkt;
> > > > +     out_pkt = odp_crypto_get_operation_compl_packet(compl_event);
> > > > +     CU_ASSERT(out_pkt == pkt);
> > > > +
> > > > +     /* TEST : operation output was correct */
> > > > +     CU_ASSERT(!memcmp(data_addr, output_vec, output_vec_len));
> > > > +
> > > > +     /* TEST : we got back the context pointer */
> > > > +     void *ctx = odp_crypto_get_operation_compl_ctx(compl_event);
> > > > +     CU_ASSERT(ctx == (void *)0xdeadbeef);
> > > > +
> > > > +     odp_buffer_free(buf);
> > > > +}
> > > > +
> > > > +/* This test verifies the correctness of encode (plaintext ->
> > > ciphertext)
> > > > + * operation for 3DES_CBC algorithm. IV for the operation is the
> > > session IV.
> > > > + * In addition the test verifies if the implementation can use the
> > > > + * packet buffer as completion event buffer.*/
> > > > +#define ASYNC_INP_ENC_ALG_3DES_CBC   "ENC_ALG_3DES_CBC"
> > > > +static void test_enc_alg_3des_cbc(void)
> > > > +{
> > > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > > > +                      auth_key   = { .data = NULL, .length = 0 };
> > > > +     odp_crypto_iv_t iv;
> > > > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > > > +
> sizeof(tdes_cbc_reference_length[0]));
> > > > +
> > > > +     unsigned int i;
> > > > +     for (i = 0; i < test_vec_num; i++) {
> > > > +             cipher_key.data = tdes_cbc_reference_key[i];
> > > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > > > +             iv.data = tdes_cbc_reference_iv[i];
> > > > +             iv.length = sizeof(tdes_cbc_reference_iv[i]);
> > > > +
> > > > +             alg_test(ODP_CRYPTO_OP_ENCODE,
> > > > +                      ODP_CIPHER_ALG_3DES_CBC,
> > > > +                      iv,
> > > > +                      NULL,
> > > > +                      cipher_key,
> > > > +                      ODP_AUTH_ALG_NULL,
> > > > +                      auth_key,
> > > > +                      ODP_BUFFER_INVALID,
> > > > +                      tdes_cbc_reference_plaintext[i],
> > > > +                      tdes_cbc_reference_length[i],
> > > > +                      tdes_cbc_reference_ciphertext[i],
> > > > +                      tdes_cbc_reference_length[i]);
> > > > +     }
> > > > +}
> > > > +
> > > > +/* This test verifies the correctness of encode (plaintext ->
> > > ciphertext)
> > > > + * operation for 3DES_CBC algorithm. IV for the operation is the
> > > operation IV.
> > > > + * */
> > > > +#define ASYNC_INP_ENC_ALG_3DES_CBC_OVR_IV
> "ENC_ALG_3DES_CBC_OVR_IV"
> > > > +static void test_enc_alg_3des_cbc_ovr_iv(void)
> > > > +{
> > > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > > > +                      auth_key   = { .data = NULL, .length = 0 };
> > > > +     odp_crypto_iv_t iv = { .data = NULL, .length = TDES_CBC_IV_LEN
> };
> > > > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > > > +
> sizeof(tdes_cbc_reference_length[0]));
> > > > +
> > > > +     unsigned int i;
> > > > +     for (i = 0; i < test_vec_num; i++) {
> > > > +             cipher_key.data = tdes_cbc_reference_key[i];
> > > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > > > +
> > > > +             alg_test(ODP_CRYPTO_OP_ENCODE,
> > > > +                      ODP_CIPHER_ALG_3DES_CBC,
> > > > +                      iv,
> > > > +                      tdes_cbc_reference_iv[i],
> > > > +                      cipher_key,
> > > > +                      ODP_AUTH_ALG_NULL,
> > > > +                      auth_key,
> > > > +                      ODP_BUFFER_INVALID,
> > > > +                      tdes_cbc_reference_plaintext[i],
> > > > +                      tdes_cbc_reference_length[i],
> > > > +                      tdes_cbc_reference_ciphertext[i],
> > > > +                      tdes_cbc_reference_length[i]);
> > > > +     }
> > > > +}
> > > > +
> > > > +
> > > > +/* This test verifies the correctness of decode (ciphertext ->
> > > plaintext)
> > > > + * operation for 3DES_CBC algorithm. IV for the operation is the
> > > session IV
> > > > + * In addition the test verifies if the implementation can use the
> > > > + * packet buffer as completion event buffer.
> > > > + * */
> > > > +#define ASYNC_INP_DEC_ALG_3DES_CBC    "DEC_ALG_3DES_CBC"
> > > > +static void test_dec_alg_3des_cbc(void)
> > > > +{
> > > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > > > +                      auth_key   = { .data = NULL, .length = 0 };
> > > > +     odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
> > > > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > > > +
> sizeof(tdes_cbc_reference_length[0]));
> > > > +
> > > > +     unsigned int i;
> > > > +     for (i = 0; i < test_vec_num; i++) {
> > > > +             cipher_key.data = tdes_cbc_reference_key[i];
> > > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > > > +             iv.data = tdes_cbc_reference_iv[i];
> > > > +             iv.length = sizeof(tdes_cbc_reference_iv[i]);
> > > > +
> > > > +             alg_test(ODP_CRYPTO_OP_DECODE,
> > > > +                      ODP_CIPHER_ALG_3DES_CBC,
> > > > +                      iv,
> > > > +                      NULL,
> > > > +                      cipher_key,
> > > > +                      ODP_AUTH_ALG_NULL,
> > > > +                      auth_key,
> > > > +                      ODP_BUFFER_INVALID,
> > > > +                      tdes_cbc_reference_ciphertext[i],
> > > > +                      tdes_cbc_reference_length[i],
> > > > +                      tdes_cbc_reference_plaintext[i],
> > > > +                      tdes_cbc_reference_length[i]);
> > > > +     }
> > > > +}
> > > > +
> > > > +/* This test verifies the correctness of decode (ciphertext ->
> > > plaintext)
> > > > + * operation for 3DES_CBC algorithm. IV for the operation is the
> > > session IV
> > > > + * In addition the test verifies if the implementation can use the
> > > > + * packet buffer as completion event buffer.
> > > > + * */
> > > > +#define ASYNC_INP_DEC_ALG_3DES_CBC_OVR_IV
>  "DEC_ALG_3DES_CBC_OVR_IV"
> > > > +static void test_dec_alg_3des_cbc_ovr_iv(void)
> > > > +{
> > > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > > > +                      auth_key   = { .data = NULL, .length = 0 };
> > > > +     odp_crypto_iv_t iv = { .data = NULL, .length = TDES_CBC_IV_LEN
> };
> > > > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > > > +
> sizeof(tdes_cbc_reference_length[0]));
> > > > +
> > > > +     unsigned int i;
> > > > +     for (i = 0; i < test_vec_num; i++) {
> > > > +             cipher_key.data = tdes_cbc_reference_key[i];
> > > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > > > +
> > > > +             alg_test(ODP_CRYPTO_OP_DECODE,
> > > > +                      ODP_CIPHER_ALG_3DES_CBC,
> > > > +                      iv,
> > > > +                      tdes_cbc_reference_iv[i],
> > > > +                      cipher_key,
> > > > +                      ODP_AUTH_ALG_NULL,
> > > > +                      auth_key,
> > > > +                      ODP_BUFFER_INVALID,
> > > > +                      tdes_cbc_reference_ciphertext[i],
> > > > +                      tdes_cbc_reference_length[i],
> > > > +                      tdes_cbc_reference_plaintext[i],
> > > > +                      tdes_cbc_reference_length[i]);
> > > > +     }
> > > > +}
> > > > +
> > > > +
> > > > +/* This test verifies the correctness of HMAC_MD5 digest operation.
> > > > + * The output check length is truncated to 12 bytes (96 bits) as
> > > > + * returned by the crypto operation API call.
> > > > + * Note that hash digest is a one-way operation.
> > > > + * In addition the test verifies if the implementation can use the
> > > > + * packet buffer as completion event buffer.
> > > > + * */
> > > > +#define ASYNC_INP_ALG_HMAC_MD5             "ALG_HMAC_MD5"
> > > > +static void test_alg_hmac_md5(void)
> > > > +{
> > > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > > > +                      auth_key   = { .data = NULL, .length = 0 };
> > > > +     odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
> > > > +
> > > > +     unsigned int test_vec_num = (sizeof(hmac_md5_reference_length)/
> > > > +
> sizeof(hmac_md5_reference_length[0]));
> > > > +
> > > > +     unsigned int i;
> > > > +     for (i = 0; i < test_vec_num; i++) {
> > > > +             auth_key.data = hmac_md5_reference_key[i];
> > > > +             auth_key.length = sizeof(hmac_md5_reference_key[i]);
> > > > +
> > > > +             alg_test(ODP_CRYPTO_OP_ENCODE,
> > > > +                      ODP_CIPHER_ALG_NULL,
> > > > +                      iv,
> > > > +                      iv.data,
> > > > +                      cipher_key,
> > > > +                      ODP_AUTH_ALG_MD5_96,
> > > > +                      auth_key,
> > > > +                      ODP_BUFFER_INVALID,
> > > > +                      hmac_md5_reference_plaintext[i],
> > > > +                      hmac_md5_reference_length[i],
> > > > +                      hmac_md5_reference_digest[i],
> > > > +                      HMAC_MD5_96_CHECK_LEN);
> > > > +     }
> > > > +}
> > > > +
> > > > +/* This test verifies the correctness of encode (plaintext ->
> > > ciphertext)
> > > > + * operation for 3DES_CBC algorithm. IV for the operation is the
> > > session IV.
> > > > + * Uses a separate buffer for completion event
> > > > + * */
> > > > +#define ASYNC_INP_ENC_ALG_3DES_CBC_COMPL_NEW
> > > "ENC_ALG_3DES_CBC_COMPL_NEW"
> > > > +static void test_enc_alg_3des_cbc_compl_new(void)
> > > > +{
> > > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
> > > > +                      auth_key   = { .data = NULL, .length = 0 };
> > > > +     odp_crypto_iv_t iv;
> > > > +     unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
> > > > +
> sizeof(tdes_cbc_reference_length[0]));
> > > > +
> > > > +     odp_buffer_pool_t pool = odp_buffer_pool_lookup("compl_pool");
> > > > +     CU_ASSERT(pool != ODP_BUFFER_POOL_INVALID);
> > > > +
> > > > +     unsigned int i;
> > > > +     odp_buffer_t compl_new;
> > > > +     for (i = 0; i < test_vec_num; i++) {
> > > > +             compl_new = odp_buffer_alloc(pool);
> > > > +             CU_ASSERT(compl_new != ODP_BUFFER_INVALID);
> > > > +
> > > > +             cipher_key.data = tdes_cbc_reference_key[i];
> > > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
> > > > +             iv.data = tdes_cbc_reference_iv[i];
> > > > +             iv.length = sizeof(tdes_cbc_reference_iv[i]);
> > > > +
> > > > +             alg_test(ODP_CRYPTO_OP_ENCODE,
> > > > +                      ODP_CIPHER_ALG_3DES_CBC,
> > > > +                      iv,
> > > > +                      NULL,
> > > > +                      cipher_key,
> > > > +                      ODP_AUTH_ALG_NULL,
> > > > +                      auth_key,
> > > > +                      compl_new,
> > > > +                      tdes_cbc_reference_plaintext[i],
> > > > +                      tdes_cbc_reference_length[i],
> > > > +                      tdes_cbc_reference_ciphertext[i],
> > > > +                      tdes_cbc_reference_length[i]);
> > > > +             odp_buffer_free(compl_new);
> > > > +     }
> > > > +}
> > > > +
> > > > +static CU_TestInfo test_array[] = {
> > > > +     {ASYNC_INP_ENC_ALG_3DES_CBC, test_enc_alg_3des_cbc },
> > > > +     {ASYNC_INP_DEC_ALG_3DES_CBC, test_dec_alg_3des_cbc },
> > > > +     {ASYNC_INP_ENC_ALG_3DES_CBC_OVR_IV,
> test_enc_alg_3des_cbc_ovr_iv },
> > > > +     {ASYNC_INP_DEC_ALG_3DES_CBC_OVR_IV,
> test_dec_alg_3des_cbc_ovr_iv },
> > > > +     {ASYNC_INP_ALG_HMAC_MD5, test_alg_hmac_md5 },
> > > > +     {ASYNC_INP_ENC_ALG_3DES_CBC_COMPL_NEW,
> > > test_enc_alg_3des_cbc_compl_new },
> > > > +     CU_TEST_INFO_NULL,
> > > > +};
> > > > +
> > > > +CU_SuiteInfo suites[] = {
> > > > +     { ODP_CRYPTO_ASYNC_INP , init, finalize, NULL, NULL,
> test_array },
> > > > +     CU_SUITE_INFO_NULL,
> > > > +};
> > > > diff --git a/test/cunit/crypto/odp_crypto_test_async_inp.h
> > > b/test/cunit/crypto/odp_crypto_test_async_inp.h
> > > > new file mode 100644
> > > > index 0000000..818f7e7
> > > > --- /dev/null
> > > > +++ b/test/cunit/crypto/odp_crypto_test_async_inp.h
> > > > @@ -0,0 +1,13 @@
> > > > +/* Copyright (c) 2014, Linaro Limited
> > > > + * All rights reserved.
> > > > + *
> > > > + * SPDX-License-Identifier:     BSD-3-Clause
> > > > + */
> > > > +#ifndef ODP_CRYPTO_TEST_ASYNC_INP_
> > > > +#define ODP_CRYPTO_TEST_ASYNC_INP_
> > > > +
> > > > +#include "CUnit/Headers/TestDB.h"
> > > > +
> > > > +CU_SuiteInfo suites[1];
> > > > +
> > > > +#endif
> > > > diff --git a/test/cunit/crypto/test_vectors.h
> > > b/test/cunit/crypto/test_vectors.h
> > > > new file mode 100644
> > > > index 0000000..c151952
> > > > --- /dev/null
> > > > +++ b/test/cunit/crypto/test_vectors.h
> > > > @@ -0,0 +1,94 @@
> > > > +/* Copyright (c) 2014, Linaro Limited
> > > > + * All rights reserved.
> > > > + *
> > > > + * SPDX-License-Identifier:  BSD-3-Clause
> > > > + */
> > > > +
> > > > +
> > > > +/* TDES-CBC reference vectors, according to
> > > > + * "http://csrc.nist.gov/groups/STM/cavp/documents/des/DESMMT.pdf"
> > > > + */
> > > > +
> > > > +#define TDES_CBC_KEY_LEN     24      /* key length(in bytes) for
> > > tdes-cbc */
> > > > +#define TDES_CBC_IV_LEN              8       /* IV length(in bytes)
> for
> > > tdes-cbc */
> > > > +#define TDES_CBC_MAX_DATA_LEN        16      /* max. plain text
> > > length(in bytes) */
> > > > +
> > > > +static uint8_t tdes_cbc_reference_key[][TDES_CBC_KEY_LEN] = {
> > > > +     {0x62, 0x7f, 0x46, 0x0e, 0x08, 0x10, 0x4a, 0x10, 0x43, 0xcd,
> 0x26,
> > > 0x5d,
> > > > +      0x58, 0x40, 0xea, 0xf1, 0x31, 0x3e, 0xdf, 0x97, 0xdf, 0x2a,
> 0x8a,
> > > 0x8c,
> > > > +      },
> > > > +
> > > > +     {0x37, 0xae, 0x5e, 0xbf, 0x46, 0xdf, 0xf2, 0xdc, 0x07, 0x54,
> 0xb9,
> > > 0x4f,
> > > > +      0x31, 0xcb, 0xb3, 0x85, 0x5e, 0x7f, 0xd3, 0x6d, 0xc8, 0x70,
> 0xbf,
> > > 0xae}
> > > > +};
> > > > +
> > > > +static uint8_t tdes_cbc_reference_iv[][TDES_CBC_IV_LEN] = {
> > > > +     {0x8e, 0x29, 0xf7, 0x5e, 0xa7, 0x7e, 0x54, 0x75},
> > > > +
> > > > +     {0x3d, 0x1d, 0xe3, 0xcc, 0x13, 0x2e, 0x3b, 0x65}
> > > > +};
> > > > +
> > > > +/** length in bytes */
> > > > +static uint32_t tdes_cbc_reference_length[] = { 8, 16 };
> > > > +
> > > > +static uint8_t
> tdes_cbc_reference_plaintext[][TDES_CBC_MAX_DATA_LEN] = {
> > > > +     {0x32, 0x6a, 0x49, 0x4c, 0xd3, 0x3f, 0xe7, 0x56},
> > > > +
> > > > +     {0x84, 0x40, 0x1f, 0x78, 0xfe, 0x6c, 0x10, 0x87, 0x6d, 0x8e,
> 0xa2,
> > > 0x30,
> > > > +      0x94, 0xea, 0x53, 0x09}
> > > > +};
> > > > +
> > > > +static uint8_t
> tdes_cbc_reference_ciphertext[][TDES_CBC_MAX_DATA_LEN] =
> > > {
> > > > +     {0xb2, 0x2b, 0x8d, 0x66, 0xde, 0x97, 0x06, 0x92},
> > > > +
> > > > +     {0x7b, 0x1f, 0x7c, 0x7e, 0x3b, 0x1c, 0x94, 0x8e, 0xbd, 0x04,
> 0xa7,
> > > 0x5f,
> > > > +      0xfb, 0xa7, 0xd2, 0xf5}
> > > > +};
> > > > +
> > > > +
> > > > +/* HMAC-MD5 test vectors  - RFC2104 */
> > > > +#define HMAC_MD5_KEY_LEN     16
> > > > +#define HMAC_MD5_MAX_DATA_LEN        128
> > > > +#define HMAC_MD5_DIGEST_LEN  16
> > > > +#define HMAC_MD5_96_CHECK_LEN        12
> > > > +
> > > > +static uint8_t hmac_md5_reference_key[][HMAC_MD5_KEY_LEN] = {
> > > > +     { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
> > > > +       0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b } ,
> > > > +
> > > > +     /* "Jefe" */
> > > > +     { 0x4a, 0x65, 0x66, 0x65 },
> > > > +
> > > > +     { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
> > > > +       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }
> > > > +};
> > > > +
> > > > +static uint32_t hmac_md5_reference_length[] = { 8, 28, 50 };
> > > > +
> > > > +static uint8_t
> hmac_md5_reference_plaintext[][HMAC_MD5_MAX_DATA_LEN] = {
> > > > +     /* "Hi There" */
> > > > +     { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65},
> > > > +
> > > > +     /* what do ya want for nothing?*/
> > > > +     { 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
> > > > +       0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
> > > > +       0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
> > > > +       0x69, 0x6e, 0x67, 0x3f },
> > > > +
> > > > +     { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> > > > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> > > > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> > > > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
> > > > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd }
> > > > +};
> > > > +
> > > > +static uint8_t hmac_md5_reference_digest[][HMAC_MD5_DIGEST_LEN] = {
> > > > +     { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
> > > > +       0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d },
> > > > +
> > > > +     { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
> > > > +       0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 },
> > > > +
> > > > +     { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
> > > > +       0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }
> > > > +};
> > > > --
> > > > 1.7.3.4
> > > >
> > > >
> > > > _______________________________________________
> > > > lng-odp mailing list
> > > > lng-odp@lists.linaro.org
> > > > http://lists.linaro.org/mailman/listinfo/lng-odp
> > >
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
>
Balasubramanian Manoharan Nov. 1, 2014, 7:55 a.m. UTC | #5
We should be able to modify the suite once we define the additional API in
crypto to read the supported crypto operations in the underlying platform.
The test suite  could be written in such a way to run only the sync or
async test cases for the specified platform based on the return from the
query function.
So that we can run a single suite which validates the crypto function based
on different methods supported by different platforms.

Regards,
Bala

On 31 October 2014 23:44, Mike Holmes <mike.holmes@linaro.org> wrote:

> I had thought that in this case it might be something like below using the
> cunit ability to organise tests into different suites.
> The code can then be organized and reused as needed, but it is all built
> together as a suite that can be run for async only, sync only or both, with
> the main entry point just taking an commandline argument as to which suites
> to run.
>
>                         crypto
>                             |
>              ------------------------------
>              |                            |
>           async      . . . .             sync
>              |                            |
>        ---------------             ---------------
>        |             |             |             |
>     Test '11' ... Test '1M'     Test 'N1' ... Test 'NM'
>
>
> On 31 October 2014 11:10, Jerin Jacob <jerin.jacob@caviumnetworks.com>
> wrote:
>
>> On Fri, Oct 31, 2014 at 04:35:21PM +0200, Alexandru Badicioiu wrote:
>> > This suite is only for async inplace mode.The tests can be reused, with
>> > some modifications, for other modes too (sync/inplace/outplace/).
>> Command
>> > line argument to select the the suite(s) or separate test programs could
>> > work too.
>>
>> Introducing an abstraction for sync/async mode for functional test-case
>> is very straight forward.
>> Most of the platforms don't support both async and sync together.
>> and its very difficult to maintain parallel tests suites for the same
>> functionality which can be abstracted.
>> If you need any help in defining/reviewing the abstraction and/or testing
>> the sync mode then I can help you with that.
>> I would like avoid the duplicate effort of writing parallel ODP crypto
>> Cunit testcases.
>>
>> Let me know your views on the proposal.
>>
>> >
>> > On 31 October 2014 16:28, Jerin Jacob <jerin.jacob@caviumnetworks.com>
>> > wrote:
>> >
>> > > On Fri, Oct 31, 2014 at 02:08:47PM +0200,
>> alexandru.badicioiu@linaro.org
>> > > wrote:
>> > > > From: Alexandru Badicioiu <alexandru.badicioiu@linaro.org>
>> > > >
>> > > > This patch adds a suite for async inplace mode of crypto APIs.
>> > > > Correctness of crypto operations output is verified with known
>> > > > test vectors  as well as various options and functionalities:
>> > > > use session IV or operation IV for ciphering, use input packet
>> > > > buffer or a separate buffer as the completion event, set and
>> > > > retrieve the context associated with an operation.
>> > >
>> > > IMO crypto functionality unit tests should be capable of running on
>> both
>> > > sync and async modes.
>> > > Platform like octeon supports only sync crypto mode.
>> > > We can introduce a command-line option to select the mode for
>> functional
>> > > testcases.
>> > > We can have separate  dedicated test to verify async/sync operation
>> but
>> > > crypto functional tests
>> > > should cater both.
>> > >
>> > > Jerin
>> > >
>> > > >
>> > > > Signed-off-by: Alexandru Badicioiu <alexandru.badicioiu@linaro.org>
>> > > > ---
>> > > >  configure.ac                                  |    1 +
>> > > >  test/cunit/Makefile.am                        |    2 +
>> > > >  test/cunit/crypto/Makefile.am                 |    9 +
>> > > >  test/cunit/crypto/odp_crypto_test.c           |   26 ++
>> > > >  test/cunit/crypto/odp_crypto_test_async_inp.c |  459
>> > > +++++++++++++++++++++++++
>> > > >  test/cunit/crypto/odp_crypto_test_async_inp.h |   13 +
>> > > >  test/cunit/crypto/test_vectors.h              |   94 +++++
>> > > >  7 files changed, 604 insertions(+), 0 deletions(-)
>> > > >  create mode 100644 test/cunit/crypto/Makefile.am
>> > > >  create mode 100644 test/cunit/crypto/odp_crypto_test.c
>> > > >  create mode 100644 test/cunit/crypto/odp_crypto_test_async_inp.c
>> > > >  create mode 100644 test/cunit/crypto/odp_crypto_test_async_inp.h
>> > > >  create mode 100644 test/cunit/crypto/test_vectors.h
>> > > >
>> > > > diff --git a/configure.ac b/configure.ac
>> > > > index fd69e85..b1785e9 100644
>> > > > --- a/configure.ac
>> > > > +++ b/configure.ac
>> > > > @@ -166,6 +166,7 @@ AC_CONFIG_FILES([Makefile
>> > > >                test/Makefile
>> > > >                test/api_test/Makefile
>> > > >                   test/cunit/Makefile
>> > > > +              test/cunit/crypto/Makefile
>> > > >                pkgconfig/libodp.pc])
>> > > >
>> > > >  AC_SEARCH_LIBS([timer_create],[rt posix4])
>> > > > diff --git a/test/cunit/Makefile.am b/test/cunit/Makefile.am
>> > > > index 927a5a5..7611145 100644
>> > > > --- a/test/cunit/Makefile.am
>> > > > +++ b/test/cunit/Makefile.am
>> > > > @@ -3,6 +3,8 @@ include $(top_srcdir)/test/Makefile.inc
>> > > >  AM_CFLAGS += -I$(CUNIT_PATH)/include
>> > > >  AM_LDFLAGS += -L$(CUNIT_PATH)/lib
>> > > >
>> > > > +SUBDIRS = crypto
>> > > > +
>> > > >  if ODP_CUNIT_ENABLED
>> > > >  TESTS = ${bin_PROGRAMS}
>> > > >  check_PROGRAMS = ${bin_PROGRAMS}
>> > > > diff --git a/test/cunit/crypto/Makefile.am
>> > > b/test/cunit/crypto/Makefile.am
>> > > > new file mode 100644
>> > > > index 0000000..b984eaa
>> > > > --- /dev/null
>> > > > +++ b/test/cunit/crypto/Makefile.am
>> > > > @@ -0,0 +1,9 @@
>> > > > +include $(top_srcdir)/test/Makefile.inc
>> > > > +
>> > > > +if ODP_CUNIT_ENABLED
>> > > > +bin_PROGRAMS = odp_crypto
>> > > > +odp_crypto_LDFLAGS = $(AM_LDFLAGS) -static -lcunit
>> > > > +endif
>> > > > +
>> > > > +dist_odp_crypto_SOURCES = odp_crypto_test_async_inp.c \
>> > > > +                       odp_crypto_test.c
>> > > > diff --git a/test/cunit/crypto/odp_crypto_test.c
>> > > b/test/cunit/crypto/odp_crypto_test.c
>> > > > new file mode 100644
>> > > > index 0000000..b5d0dea
>> > > > --- /dev/null
>> > > > +++ b/test/cunit/crypto/odp_crypto_test.c
>> > > > @@ -0,0 +1,26 @@
>> > > > +/* Copyright (c) 2014, Linaro Limited
>> > > > + * All rights reserved.
>> > > > + *
>> > > > + * SPDX-License-Identifier:     BSD-3-Clause
>> > > > + */
>> > > > +
>> > > > +#include <odp.h>
>> > > > +#include "CUnit/Headers/Basic.h"
>> > > > +#include "CUnit/Headers/TestDB.h"
>> > > > +#include "odp_crypto_test_async_inp.h"
>> > > > +
>> > > > +int main(void)
>> > > > +{
>> > > > +     /* initialize the CUnit test registry */
>> > > > +     if (CUE_SUCCESS != CU_initialize_registry())
>> > > > +             return CU_get_error();
>> > > > +
>> > > > +     /* register suites */
>> > > > +     CU_register_suites(suites);
>> > > > +     /* Run all tests using the CUnit Basic interface */
>> > > > +     CU_basic_set_mode(CU_BRM_VERBOSE);
>> > > > +     CU_basic_run_tests();
>> > > > +     CU_cleanup_registry();
>> > > > +
>> > > > +     return CU_get_error();
>> > > > +}
>> > > > diff --git a/test/cunit/crypto/odp_crypto_test_async_inp.c
>> > > b/test/cunit/crypto/odp_crypto_test_async_inp.c
>> > > > new file mode 100644
>> > > > index 0000000..dd5fb5f
>> > > > --- /dev/null
>> > > > +++ b/test/cunit/crypto/odp_crypto_test_async_inp.c
>> > > > @@ -0,0 +1,458 @@
>> > > > +/* Copyright (c) 2014, Linaro Limited
>> > > > + * All rights reserved.
>> > > > + *
>> > > > + * SPDX-License-Identifier:  BSD-3-Clause
>> > > > + */
>> > > > +
>> > > > +#include <odp.h>
>> > > > +#include <odp_crypto.h>
>> > > > +#include "CUnit/Headers/Basic.h"
>> > > > +#include "CUnit/Headers/TestDB.h"
>> > > > +#include "test_vectors.h"
>> > > > +
>> > > > +/* Suite name */
>> > > > +#define ODP_CRYPTO_ASYNC_INP "odp_crypto_async_inp"
>> > > > +
>> > > > +/* Suite init/finalize funcs */
>> > > > +/* ODP global/local initialization
>> > > > + * Packet pool creation
>> > > > + * Crypto output queue creation */
>> > > > +
>> > > > +#define SHM_PKT_POOL_SIZE      (512*2048*2)
>> > > > +#define SHM_PKT_POOL_BUF_SIZE  (1024 * 32)
>> > > > +
>> > > > +#define SHM_COMPL_POOL_SIZE  (128*1024)
>> > > > +#define SHM_COMPL_POOL_BUF_SIZE 128
>> > > > +
>> > > > +static int init(void)
>> > > > +{
>> > > > +     odp_shm_t shm;
>> > > > +     void *pool_base = NULL;
>> > > > +     odp_buffer_pool_t pool;
>> > > > +     odp_queue_t out_queue;
>> > > > +
>> > > > +     if (odp_init_global(NULL, NULL)) {
>> > > > +             ODP_ERR("ODP global init failed.\n");
>> > > > +             return -1;
>> > > > +     }
>> > > > +     odp_init_local();
>> > > > +
>> > > > +     shm = odp_shm_reserve("shm_packet_pool",
>> > > > +                           SHM_PKT_POOL_SIZE,
>> > > > +                           ODP_CACHE_LINE_SIZE, 0);
>> > > > +
>> > > > +     pool_base = odp_shm_addr(shm);
>> > > > +     if (!pool_base) {
>> > > > +             ODP_ERR("Packet pool allocation failed.\n");
>> > > > +             return -1;
>> > > > +     }
>> > > > +
>> > > > +     pool = odp_buffer_pool_create("packet_pool", pool_base,
>> > > > +                                   SHM_PKT_POOL_SIZE,
>> > > > +                                   SHM_PKT_POOL_BUF_SIZE,
>> > > > +                                   ODP_CACHE_LINE_SIZE,
>> > > > +                                   ODP_BUFFER_TYPE_PACKET);
>> > > > +     if (pool == ODP_BUFFER_POOL_INVALID) {
>> > > > +             ODP_ERR("Packet pool creation failed.\n");
>> > > > +             return -1;
>> > > > +     }
>> > > > +     out_queue = odp_queue_create("crypto-out",
>> > > > +                                  ODP_QUEUE_TYPE_POLL, NULL);
>> > > > +     if (out_queue == ODP_QUEUE_INVALID) {
>> > > > +             ODP_ERR("Crypto outq creation failed.\n");
>> > > > +             return -1;
>> > > > +     }
>> > > > +     shm = odp_shm_reserve("shm_compl_pool",
>> > > > +                          SHM_COMPL_POOL_SIZE,
>> > > > +                          ODP_CACHE_LINE_SIZE,
>> > > > +                          ODP_SHM_SW_ONLY);
>> > > > +     pool_base = odp_shm_addr(shm);
>> > > > +     if (!pool_base) {
>> > > > +             ODP_ERR("Completion pool allocation failed.\n");
>> > > > +             return -1;
>> > > > +     }
>> > > > +     pool = odp_buffer_pool_create("compl_pool", pool_base,
>> > > > +                                   SHM_COMPL_POOL_SIZE,
>> > > > +                                   SHM_COMPL_POOL_BUF_SIZE,
>> > > > +                                   ODP_CACHE_LINE_SIZE,
>> > > > +                                   ODP_BUFFER_TYPE_RAW);
>> > > > +     if (pool == ODP_BUFFER_POOL_INVALID) {
>> > > > +             ODP_ERR("Completion pool creation failed.\n");
>> > > > +             return -1;
>> > > > +     }
>> > > > +
>> > > > +     printf("\tODP version: %s\n", odp_version_api_str());
>> > > > +     return 0;
>> > > > +}
>> > > > +
>> > > > +/* ODP cleanup */
>> > > > +static int finalize(void)
>> > > > +{
>> > > > +     odp_term_local();
>> > > > +     odp_term_global();
>> > > > +     return 0;
>> > > > +}
>> > > > +
>> > > > +
>> > > > +/* Basic algorithm run function.
>> > > > + * Creates a session from input parameters and runs one operation
>> > > > + * on input_vec. Checks the output of the crypto operation against
>> > > > + * output_vec. Operation completion event is dequeued polling the
>> > > > + * session output queue. Completion context pointer is retrieved
>> > > > + * and checked against the one set before the operation.
>> > > > + * */
>> > > > +static void alg_test(enum odp_crypto_op op,
>> > > > +                  enum odp_cipher_alg cipher_alg,
>> > > > +                  odp_crypto_iv_t ses_iv,
>> > > > +                  uint8_t *op_iv_ptr,
>> > > > +                  odp_crypto_key_t cipher_key,
>> > > > +                  enum odp_auth_alg auth_alg,
>> > > > +                  odp_crypto_key_t auth_key,
>> > > > +                  odp_buffer_t compl_new,
>> > > > +                  uint8_t *input_vec,
>> > > > +                  unsigned int input_vec_len,
>> > > > +                  uint8_t *output_vec,
>> > > > +                  unsigned int output_vec_len)
>> > > > +{
>> > > > +     odp_crypto_session_t session;
>> > > > +     int rc;
>> > > > +     enum odp_crypto_ses_create_err status;
>> > > > +     bool posted;
>> > > > +     odp_buffer_t compl_event;
>> > > > +
>> > > > +     odp_queue_t compl_queue = odp_queue_lookup("crypto-out");
>> > > > +     CU_ASSERT(compl_queue != ODP_QUEUE_INVALID);
>> > > > +     odp_buffer_pool_t pool =
>> odp_buffer_pool_lookup("packet_pool");
>> > > > +     CU_ASSERT(pool != ODP_BUFFER_POOL_INVALID);
>> > > > +
>> > > > +     /* Create a crypto session */
>> > > > +     odp_crypto_session_params_t ses_params;
>> > > > +     memset(&ses_params, 0, sizeof(ses_params));
>> > > > +     ses_params.op = op;
>> > > > +     ses_params.auth_cipher_text = false;
>> > > > +     ses_params.pref_mode = ODP_CRYPTO_ASYNC;
>> > > > +     ses_params.cipher_alg = cipher_alg;
>> > > > +     ses_params.auth_alg = auth_alg;
>> > > > +     ses_params.compl_queue = compl_queue;
>> > > > +     ses_params.output_pool = pool;
>> > > > +     ses_params.cipher_key = cipher_key;
>> > > > +     ses_params.iv = ses_iv;
>> > > > +     ses_params.auth_key = auth_key;
>> > > > +
>> > > > +     /* TEST : odp_crypto_session_create */
>> > > > +     rc = odp_crypto_session_create(&ses_params, &session,
>> &status);
>> > > > +     CU_ASSERT(!rc);
>> > > > +     CU_ASSERT(status == ODP_CRYPTO_SES_CREATE_ERR_NONE);
>> > > > +
>> > > > +     /* Prepare input data */
>> > > > +     odp_buffer_t buf = odp_buffer_alloc(pool);
>> > > > +     CU_ASSERT(buf != ODP_BUFFER_INVALID);
>> > > > +     odp_packet_t pkt = odp_packet_from_buffer(buf);
>> > > > +     CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> > > > +     uint8_t *data_addr = odp_packet_data(pkt);
>> > > > +     memcpy(data_addr, input_vec, input_vec_len);
>> > > > +     /* offsets are relative to buffer address (not packet data)
>> > > > +     until https://bugs.linaro.org/show_bug.cgi?id=387 is fixed */
>> > > > +     int data_off = data_addr - (uint8_t *)odp_buffer_addr(buf);
>> > > > +
>> > > > +     /* Prepare input/output params */
>> > > > +     odp_crypto_op_params_t op_params;
>> > > > +     memset(&op_params, 0, sizeof(op_params));
>> > > > +     op_params.session = session;
>> > > > +     op_params.pkt = pkt;
>> > > > +     op_params.out_pkt = pkt;
>> > > > +     if (cipher_alg != ODP_CIPHER_ALG_NULL &&
>> > > > +         auth_alg == ODP_AUTH_ALG_NULL) {
>> > > > +             op_params.cipher_range.offset = data_off;
>> > > > +             op_params.cipher_range.length = input_vec_len;
>> > > > +             if (op_iv_ptr)
>> > > > +                     op_params.override_iv_ptr = op_iv_ptr;
>> > > > +     } else if (cipher_alg == ODP_CIPHER_ALG_NULL &&
>> > > > +              auth_alg != ODP_AUTH_ALG_NULL) {
>> > > > +             op_params.auth_range.offset = data_off;
>> > > > +             op_params.auth_range.length = input_vec_len;
>> > > > +             op_params.hash_result_offset = data_off;
>> > > > +     } else {
>> > > > +             CU_FAIL("%s : not implemented for combined alg
>> mode\n");
>> > > > +     }
>> > > > +
>> > > > +     /* TEST : odp_crypto_set_operation_compl_ctx */
>> > > > +     /* TEST : odp_crypto_operation */
>> > > > +     if (compl_new == ODP_BUFFER_INVALID) {
>> > > > +             odp_crypto_set_operation_compl_ctx(buf, (void
>> > > *)0xdeadbeef);
>> > > > +             rc = odp_crypto_operation(&op_params, &posted, buf);
>> > > > +     } else {
>> > > > +             odp_crypto_set_operation_compl_ctx(compl_new,
>> > > > +                                                (void
>> *)0xdeadbeef);
>> > > > +             rc = odp_crypto_operation(&op_params, &posted,
>> compl_new);
>> > > > +     }
>> > > > +     CU_ASSERT(posted);
>> > > > +
>> > > > +     /* Poll completion queue for results */
>> > > > +     do {
>> > > > +             compl_event = odp_queue_deq(compl_queue);
>> > > > +     } while (compl_event == ODP_BUFFER_INVALID);
>> > > > +
>> > > > +     if (compl_new == ODP_BUFFER_INVALID) {
>> > > > +             CU_ASSERT(compl_event == buf);
>> > > > +     } else {
>> > > > +             CU_ASSERT(compl_event == compl_new);
>> > > > +     }
>> > > > +
>> > > > +     /* TEST : odp_crypto_get_operation_compl_status */
>> > > > +     struct odp_crypto_compl_status auth_status, cipher_status;
>> > > > +     odp_crypto_get_operation_compl_status(compl_event,
>> > > > +                                           &auth_status,
>> > > &cipher_status);
>> > > > +     CU_ASSERT(auth_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE);
>> > > > +     CU_ASSERT(auth_status.hw_err == ODP_CRYPTO_HW_ERR_NONE);
>> > > > +     CU_ASSERT(cipher_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE);
>> > > > +     CU_ASSERT(cipher_status.hw_err == ODP_CRYPTO_HW_ERR_NONE);
>> > > > +
>> > > > +     /* TEST : odp_crypto_get_operation_compl_packet */
>> > > > +     odp_packet_t out_pkt;
>> > > > +     out_pkt = odp_crypto_get_operation_compl_packet(compl_event);
>> > > > +     CU_ASSERT(out_pkt == pkt);
>> > > > +
>> > > > +     /* TEST : operation output was correct */
>> > > > +     CU_ASSERT(!memcmp(data_addr, output_vec, output_vec_len));
>> > > > +
>> > > > +     /* TEST : we got back the context pointer */
>> > > > +     void *ctx = odp_crypto_get_operation_compl_ctx(compl_event);
>> > > > +     CU_ASSERT(ctx == (void *)0xdeadbeef);
>> > > > +
>> > > > +     odp_buffer_free(buf);
>> > > > +}
>> > > > +
>> > > > +/* This test verifies the correctness of encode (plaintext ->
>> > > ciphertext)
>> > > > + * operation for 3DES_CBC algorithm. IV for the operation is the
>> > > session IV.
>> > > > + * In addition the test verifies if the implementation can use the
>> > > > + * packet buffer as completion event buffer.*/
>> > > > +#define ASYNC_INP_ENC_ALG_3DES_CBC   "ENC_ALG_3DES_CBC"
>> > > > +static void test_enc_alg_3des_cbc(void)
>> > > > +{
>> > > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
>> > > > +                      auth_key   = { .data = NULL, .length = 0 };
>> > > > +     odp_crypto_iv_t iv;
>> > > > +     unsigned int test_vec_num =
>> (sizeof(tdes_cbc_reference_length)/
>> > > > +
>> sizeof(tdes_cbc_reference_length[0]));
>> > > > +
>> > > > +     unsigned int i;
>> > > > +     for (i = 0; i < test_vec_num; i++) {
>> > > > +             cipher_key.data = tdes_cbc_reference_key[i];
>> > > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
>> > > > +             iv.data = tdes_cbc_reference_iv[i];
>> > > > +             iv.length = sizeof(tdes_cbc_reference_iv[i]);
>> > > > +
>> > > > +             alg_test(ODP_CRYPTO_OP_ENCODE,
>> > > > +                      ODP_CIPHER_ALG_3DES_CBC,
>> > > > +                      iv,
>> > > > +                      NULL,
>> > > > +                      cipher_key,
>> > > > +                      ODP_AUTH_ALG_NULL,
>> > > > +                      auth_key,
>> > > > +                      ODP_BUFFER_INVALID,
>> > > > +                      tdes_cbc_reference_plaintext[i],
>> > > > +                      tdes_cbc_reference_length[i],
>> > > > +                      tdes_cbc_reference_ciphertext[i],
>> > > > +                      tdes_cbc_reference_length[i]);
>> > > > +     }
>> > > > +}
>> > > > +
>> > > > +/* This test verifies the correctness of encode (plaintext ->
>> > > ciphertext)
>> > > > + * operation for 3DES_CBC algorithm. IV for the operation is the
>> > > operation IV.
>> > > > + * */
>> > > > +#define ASYNC_INP_ENC_ALG_3DES_CBC_OVR_IV
>> "ENC_ALG_3DES_CBC_OVR_IV"
>> > > > +static void test_enc_alg_3des_cbc_ovr_iv(void)
>> > > > +{
>> > > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
>> > > > +                      auth_key   = { .data = NULL, .length = 0 };
>> > > > +     odp_crypto_iv_t iv = { .data = NULL, .length =
>> TDES_CBC_IV_LEN };
>> > > > +     unsigned int test_vec_num =
>> (sizeof(tdes_cbc_reference_length)/
>> > > > +
>> sizeof(tdes_cbc_reference_length[0]));
>> > > > +
>> > > > +     unsigned int i;
>> > > > +     for (i = 0; i < test_vec_num; i++) {
>> > > > +             cipher_key.data = tdes_cbc_reference_key[i];
>> > > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
>> > > > +
>> > > > +             alg_test(ODP_CRYPTO_OP_ENCODE,
>> > > > +                      ODP_CIPHER_ALG_3DES_CBC,
>> > > > +                      iv,
>> > > > +                      tdes_cbc_reference_iv[i],
>> > > > +                      cipher_key,
>> > > > +                      ODP_AUTH_ALG_NULL,
>> > > > +                      auth_key,
>> > > > +                      ODP_BUFFER_INVALID,
>> > > > +                      tdes_cbc_reference_plaintext[i],
>> > > > +                      tdes_cbc_reference_length[i],
>> > > > +                      tdes_cbc_reference_ciphertext[i],
>> > > > +                      tdes_cbc_reference_length[i]);
>> > > > +     }
>> > > > +}
>> > > > +
>> > > > +
>> > > > +/* This test verifies the correctness of decode (ciphertext ->
>> > > plaintext)
>> > > > + * operation for 3DES_CBC algorithm. IV for the operation is the
>> > > session IV
>> > > > + * In addition the test verifies if the implementation can use the
>> > > > + * packet buffer as completion event buffer.
>> > > > + * */
>> > > > +#define ASYNC_INP_DEC_ALG_3DES_CBC    "DEC_ALG_3DES_CBC"
>> > > > +static void test_dec_alg_3des_cbc(void)
>> > > > +{
>> > > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
>> > > > +                      auth_key   = { .data = NULL, .length = 0 };
>> > > > +     odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
>> > > > +     unsigned int test_vec_num =
>> (sizeof(tdes_cbc_reference_length)/
>> > > > +
>> sizeof(tdes_cbc_reference_length[0]));
>> > > > +
>> > > > +     unsigned int i;
>> > > > +     for (i = 0; i < test_vec_num; i++) {
>> > > > +             cipher_key.data = tdes_cbc_reference_key[i];
>> > > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
>> > > > +             iv.data = tdes_cbc_reference_iv[i];
>> > > > +             iv.length = sizeof(tdes_cbc_reference_iv[i]);
>> > > > +
>> > > > +             alg_test(ODP_CRYPTO_OP_DECODE,
>> > > > +                      ODP_CIPHER_ALG_3DES_CBC,
>> > > > +                      iv,
>> > > > +                      NULL,
>> > > > +                      cipher_key,
>> > > > +                      ODP_AUTH_ALG_NULL,
>> > > > +                      auth_key,
>> > > > +                      ODP_BUFFER_INVALID,
>> > > > +                      tdes_cbc_reference_ciphertext[i],
>> > > > +                      tdes_cbc_reference_length[i],
>> > > > +                      tdes_cbc_reference_plaintext[i],
>> > > > +                      tdes_cbc_reference_length[i]);
>> > > > +     }
>> > > > +}
>> > > > +
>> > > > +/* This test verifies the correctness of decode (ciphertext ->
>> > > plaintext)
>> > > > + * operation for 3DES_CBC algorithm. IV for the operation is the
>> > > session IV
>> > > > + * In addition the test verifies if the implementation can use the
>> > > > + * packet buffer as completion event buffer.
>> > > > + * */
>> > > > +#define ASYNC_INP_DEC_ALG_3DES_CBC_OVR_IV
>>  "DEC_ALG_3DES_CBC_OVR_IV"
>> > > > +static void test_dec_alg_3des_cbc_ovr_iv(void)
>> > > > +{
>> > > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
>> > > > +                      auth_key   = { .data = NULL, .length = 0 };
>> > > > +     odp_crypto_iv_t iv = { .data = NULL, .length =
>> TDES_CBC_IV_LEN };
>> > > > +     unsigned int test_vec_num =
>> (sizeof(tdes_cbc_reference_length)/
>> > > > +
>> sizeof(tdes_cbc_reference_length[0]));
>> > > > +
>> > > > +     unsigned int i;
>> > > > +     for (i = 0; i < test_vec_num; i++) {
>> > > > +             cipher_key.data = tdes_cbc_reference_key[i];
>> > > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
>> > > > +
>> > > > +             alg_test(ODP_CRYPTO_OP_DECODE,
>> > > > +                      ODP_CIPHER_ALG_3DES_CBC,
>> > > > +                      iv,
>> > > > +                      tdes_cbc_reference_iv[i],
>> > > > +                      cipher_key,
>> > > > +                      ODP_AUTH_ALG_NULL,
>> > > > +                      auth_key,
>> > > > +                      ODP_BUFFER_INVALID,
>> > > > +                      tdes_cbc_reference_ciphertext[i],
>> > > > +                      tdes_cbc_reference_length[i],
>> > > > +                      tdes_cbc_reference_plaintext[i],
>> > > > +                      tdes_cbc_reference_length[i]);
>> > > > +     }
>> > > > +}
>> > > > +
>> > > > +
>> > > > +/* This test verifies the correctness of HMAC_MD5 digest operation.
>> > > > + * The output check length is truncated to 12 bytes (96 bits) as
>> > > > + * returned by the crypto operation API call.
>> > > > + * Note that hash digest is a one-way operation.
>> > > > + * In addition the test verifies if the implementation can use the
>> > > > + * packet buffer as completion event buffer.
>> > > > + * */
>> > > > +#define ASYNC_INP_ALG_HMAC_MD5             "ALG_HMAC_MD5"
>> > > > +static void test_alg_hmac_md5(void)
>> > > > +{
>> > > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
>> > > > +                      auth_key   = { .data = NULL, .length = 0 };
>> > > > +     odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
>> > > > +
>> > > > +     unsigned int test_vec_num =
>> (sizeof(hmac_md5_reference_length)/
>> > > > +
>> sizeof(hmac_md5_reference_length[0]));
>> > > > +
>> > > > +     unsigned int i;
>> > > > +     for (i = 0; i < test_vec_num; i++) {
>> > > > +             auth_key.data = hmac_md5_reference_key[i];
>> > > > +             auth_key.length = sizeof(hmac_md5_reference_key[i]);
>> > > > +
>> > > > +             alg_test(ODP_CRYPTO_OP_ENCODE,
>> > > > +                      ODP_CIPHER_ALG_NULL,
>> > > > +                      iv,
>> > > > +                      iv.data,
>> > > > +                      cipher_key,
>> > > > +                      ODP_AUTH_ALG_MD5_96,
>> > > > +                      auth_key,
>> > > > +                      ODP_BUFFER_INVALID,
>> > > > +                      hmac_md5_reference_plaintext[i],
>> > > > +                      hmac_md5_reference_length[i],
>> > > > +                      hmac_md5_reference_digest[i],
>> > > > +                      HMAC_MD5_96_CHECK_LEN);
>> > > > +     }
>> > > > +}
>> > > > +
>> > > > +/* This test verifies the correctness of encode (plaintext ->
>> > > ciphertext)
>> > > > + * operation for 3DES_CBC algorithm. IV for the operation is the
>> > > session IV.
>> > > > + * Uses a separate buffer for completion event
>> > > > + * */
>> > > > +#define ASYNC_INP_ENC_ALG_3DES_CBC_COMPL_NEW
>> > > "ENC_ALG_3DES_CBC_COMPL_NEW"
>> > > > +static void test_enc_alg_3des_cbc_compl_new(void)
>> > > > +{
>> > > > +     odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
>> > > > +                      auth_key   = { .data = NULL, .length = 0 };
>> > > > +     odp_crypto_iv_t iv;
>> > > > +     unsigned int test_vec_num =
>> (sizeof(tdes_cbc_reference_length)/
>> > > > +
>> sizeof(tdes_cbc_reference_length[0]));
>> > > > +
>> > > > +     odp_buffer_pool_t pool = odp_buffer_pool_lookup("compl_pool");
>> > > > +     CU_ASSERT(pool != ODP_BUFFER_POOL_INVALID);
>> > > > +
>> > > > +     unsigned int i;
>> > > > +     odp_buffer_t compl_new;
>> > > > +     for (i = 0; i < test_vec_num; i++) {
>> > > > +             compl_new = odp_buffer_alloc(pool);
>> > > > +             CU_ASSERT(compl_new != ODP_BUFFER_INVALID);
>> > > > +
>> > > > +             cipher_key.data = tdes_cbc_reference_key[i];
>> > > > +             cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
>> > > > +             iv.data = tdes_cbc_reference_iv[i];
>> > > > +             iv.length = sizeof(tdes_cbc_reference_iv[i]);
>> > > > +
>> > > > +             alg_test(ODP_CRYPTO_OP_ENCODE,
>> > > > +                      ODP_CIPHER_ALG_3DES_CBC,
>> > > > +                      iv,
>> > > > +                      NULL,
>> > > > +                      cipher_key,
>> > > > +                      ODP_AUTH_ALG_NULL,
>> > > > +                      auth_key,
>> > > > +                      compl_new,
>> > > > +                      tdes_cbc_reference_plaintext[i],
>> > > > +                      tdes_cbc_reference_length[i],
>> > > > +                      tdes_cbc_reference_ciphertext[i],
>> > > > +                      tdes_cbc_reference_length[i]);
>> > > > +             odp_buffer_free(compl_new);
>> > > > +     }
>> > > > +}
>> > > > +
>> > > > +static CU_TestInfo test_array[] = {
>> > > > +     {ASYNC_INP_ENC_ALG_3DES_CBC, test_enc_alg_3des_cbc },
>> > > > +     {ASYNC_INP_DEC_ALG_3DES_CBC, test_dec_alg_3des_cbc },
>> > > > +     {ASYNC_INP_ENC_ALG_3DES_CBC_OVR_IV,
>> test_enc_alg_3des_cbc_ovr_iv },
>> > > > +     {ASYNC_INP_DEC_ALG_3DES_CBC_OVR_IV,
>> test_dec_alg_3des_cbc_ovr_iv },
>> > > > +     {ASYNC_INP_ALG_HMAC_MD5, test_alg_hmac_md5 },
>> > > > +     {ASYNC_INP_ENC_ALG_3DES_CBC_COMPL_NEW,
>> > > test_enc_alg_3des_cbc_compl_new },
>> > > > +     CU_TEST_INFO_NULL,
>> > > > +};
>> > > > +
>> > > > +CU_SuiteInfo suites[] = {
>> > > > +     { ODP_CRYPTO_ASYNC_INP , init, finalize, NULL, NULL,
>> test_array },
>> > > > +     CU_SUITE_INFO_NULL,
>> > > > +};
>> > > > diff --git a/test/cunit/crypto/odp_crypto_test_async_inp.h
>> > > b/test/cunit/crypto/odp_crypto_test_async_inp.h
>> > > > new file mode 100644
>> > > > index 0000000..818f7e7
>> > > > --- /dev/null
>> > > > +++ b/test/cunit/crypto/odp_crypto_test_async_inp.h
>> > > > @@ -0,0 +1,13 @@
>> > > > +/* Copyright (c) 2014, Linaro Limited
>> > > > + * All rights reserved.
>> > > > + *
>> > > > + * SPDX-License-Identifier:     BSD-3-Clause
>> > > > + */
>> > > > +#ifndef ODP_CRYPTO_TEST_ASYNC_INP_
>> > > > +#define ODP_CRYPTO_TEST_ASYNC_INP_
>> > > > +
>> > > > +#include "CUnit/Headers/TestDB.h"
>> > > > +
>> > > > +CU_SuiteInfo suites[1];
>> > > > +
>> > > > +#endif
>> > > > diff --git a/test/cunit/crypto/test_vectors.h
>> > > b/test/cunit/crypto/test_vectors.h
>> > > > new file mode 100644
>> > > > index 0000000..c151952
>> > > > --- /dev/null
>> > > > +++ b/test/cunit/crypto/test_vectors.h
>> > > > @@ -0,0 +1,94 @@
>> > > > +/* Copyright (c) 2014, Linaro Limited
>> > > > + * All rights reserved.
>> > > > + *
>> > > > + * SPDX-License-Identifier:  BSD-3-Clause
>> > > > + */
>> > > > +
>> > > > +
>> > > > +/* TDES-CBC reference vectors, according to
>> > > > + * "http://csrc.nist.gov/groups/STM/cavp/documents/des/DESMMT.pdf"
>> > > > + */
>> > > > +
>> > > > +#define TDES_CBC_KEY_LEN     24      /* key length(in bytes) for
>> > > tdes-cbc */
>> > > > +#define TDES_CBC_IV_LEN              8       /* IV length(in
>> bytes) for
>> > > tdes-cbc */
>> > > > +#define TDES_CBC_MAX_DATA_LEN        16      /* max. plain text
>> > > length(in bytes) */
>> > > > +
>> > > > +static uint8_t tdes_cbc_reference_key[][TDES_CBC_KEY_LEN] = {
>> > > > +     {0x62, 0x7f, 0x46, 0x0e, 0x08, 0x10, 0x4a, 0x10, 0x43, 0xcd,
>> 0x26,
>> > > 0x5d,
>> > > > +      0x58, 0x40, 0xea, 0xf1, 0x31, 0x3e, 0xdf, 0x97, 0xdf, 0x2a,
>> 0x8a,
>> > > 0x8c,
>> > > > +      },
>> > > > +
>> > > > +     {0x37, 0xae, 0x5e, 0xbf, 0x46, 0xdf, 0xf2, 0xdc, 0x07, 0x54,
>> 0xb9,
>> > > 0x4f,
>> > > > +      0x31, 0xcb, 0xb3, 0x85, 0x5e, 0x7f, 0xd3, 0x6d, 0xc8, 0x70,
>> 0xbf,
>> > > 0xae}
>> > > > +};
>> > > > +
>> > > > +static uint8_t tdes_cbc_reference_iv[][TDES_CBC_IV_LEN] = {
>> > > > +     {0x8e, 0x29, 0xf7, 0x5e, 0xa7, 0x7e, 0x54, 0x75},
>> > > > +
>> > > > +     {0x3d, 0x1d, 0xe3, 0xcc, 0x13, 0x2e, 0x3b, 0x65}
>> > > > +};
>> > > > +
>> > > > +/** length in bytes */
>> > > > +static uint32_t tdes_cbc_reference_length[] = { 8, 16 };
>> > > > +
>> > > > +static uint8_t
>> tdes_cbc_reference_plaintext[][TDES_CBC_MAX_DATA_LEN] = {
>> > > > +     {0x32, 0x6a, 0x49, 0x4c, 0xd3, 0x3f, 0xe7, 0x56},
>> > > > +
>> > > > +     {0x84, 0x40, 0x1f, 0x78, 0xfe, 0x6c, 0x10, 0x87, 0x6d, 0x8e,
>> 0xa2,
>> > > 0x30,
>> > > > +      0x94, 0xea, 0x53, 0x09}
>> > > > +};
>> > > > +
>> > > > +static uint8_t
>> tdes_cbc_reference_ciphertext[][TDES_CBC_MAX_DATA_LEN] =
>> > > {
>> > > > +     {0xb2, 0x2b, 0x8d, 0x66, 0xde, 0x97, 0x06, 0x92},
>> > > > +
>> > > > +     {0x7b, 0x1f, 0x7c, 0x7e, 0x3b, 0x1c, 0x94, 0x8e, 0xbd, 0x04,
>> 0xa7,
>> > > 0x5f,
>> > > > +      0xfb, 0xa7, 0xd2, 0xf5}
>> > > > +};
>> > > > +
>> > > > +
>> > > > +/* HMAC-MD5 test vectors  - RFC2104 */
>> > > > +#define HMAC_MD5_KEY_LEN     16
>> > > > +#define HMAC_MD5_MAX_DATA_LEN        128
>> > > > +#define HMAC_MD5_DIGEST_LEN  16
>> > > > +#define HMAC_MD5_96_CHECK_LEN        12
>> > > > +
>> > > > +static uint8_t hmac_md5_reference_key[][HMAC_MD5_KEY_LEN] = {
>> > > > +     { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
>> > > > +       0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b } ,
>> > > > +
>> > > > +     /* "Jefe" */
>> > > > +     { 0x4a, 0x65, 0x66, 0x65 },
>> > > > +
>> > > > +     { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
>> > > > +       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }
>> > > > +};
>> > > > +
>> > > > +static uint32_t hmac_md5_reference_length[] = { 8, 28, 50 };
>> > > > +
>> > > > +static uint8_t
>> hmac_md5_reference_plaintext[][HMAC_MD5_MAX_DATA_LEN] = {
>> > > > +     /* "Hi There" */
>> > > > +     { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65},
>> > > > +
>> > > > +     /* what do ya want for nothing?*/
>> > > > +     { 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
>> > > > +       0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
>> > > > +       0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
>> > > > +       0x69, 0x6e, 0x67, 0x3f },
>> > > > +
>> > > > +     { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
>> > > > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
>> > > > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
>> > > > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
>> > > > +       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd }
>> > > > +};
>> > > > +
>> > > > +static uint8_t hmac_md5_reference_digest[][HMAC_MD5_DIGEST_LEN] = {
>> > > > +     { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
>> > > > +       0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d },
>> > > > +
>> > > > +     { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
>> > > > +       0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 },
>> > > > +
>> > > > +     { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
>> > > > +       0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }
>> > > > +};
>> > > > --
>> > > > 1.7.3.4
>> > > >
>> > > >
>> > > > _______________________________________________
>> > > > lng-odp mailing list
>> > > > lng-odp@lists.linaro.org
>> > > > http://lists.linaro.org/mailman/listinfo/lng-odp
>> > >
>>
>> _______________________________________________
>> lng-odp mailing list
>> lng-odp@lists.linaro.org
>> http://lists.linaro.org/mailman/listinfo/lng-odp
>>
>
>
>
> --
> *Mike Holmes*
> Linaro  Sr Technical Manager
> LNG - ODP
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
>
>
diff mbox

Patch

diff --git a/configure.ac b/configure.ac
index fd69e85..b1785e9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -166,6 +166,7 @@  AC_CONFIG_FILES([Makefile
 		 test/Makefile
 		 test/api_test/Makefile
                  test/cunit/Makefile
+		 test/cunit/crypto/Makefile
 		 pkgconfig/libodp.pc])
 
 AC_SEARCH_LIBS([timer_create],[rt posix4])
diff --git a/test/cunit/Makefile.am b/test/cunit/Makefile.am
index 927a5a5..7611145 100644
--- a/test/cunit/Makefile.am
+++ b/test/cunit/Makefile.am
@@ -3,6 +3,8 @@  include $(top_srcdir)/test/Makefile.inc
 AM_CFLAGS += -I$(CUNIT_PATH)/include
 AM_LDFLAGS += -L$(CUNIT_PATH)/lib
 
+SUBDIRS = crypto
+
 if ODP_CUNIT_ENABLED
 TESTS = ${bin_PROGRAMS}
 check_PROGRAMS = ${bin_PROGRAMS}
diff --git a/test/cunit/crypto/Makefile.am b/test/cunit/crypto/Makefile.am
new file mode 100644
index 0000000..b984eaa
--- /dev/null
+++ b/test/cunit/crypto/Makefile.am
@@ -0,0 +1,9 @@ 
+include $(top_srcdir)/test/Makefile.inc
+
+if ODP_CUNIT_ENABLED
+bin_PROGRAMS = odp_crypto
+odp_crypto_LDFLAGS = $(AM_LDFLAGS) -static -lcunit
+endif
+
+dist_odp_crypto_SOURCES = odp_crypto_test_async_inp.c \
+			  odp_crypto_test.c
diff --git a/test/cunit/crypto/odp_crypto_test.c b/test/cunit/crypto/odp_crypto_test.c
new file mode 100644
index 0000000..b5d0dea
--- /dev/null
+++ b/test/cunit/crypto/odp_crypto_test.c
@@ -0,0 +1,26 @@ 
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include <odp.h>
+#include "CUnit/Headers/Basic.h"
+#include "CUnit/Headers/TestDB.h"
+#include "odp_crypto_test_async_inp.h"
+
+int main(void)
+{
+	/* initialize the CUnit test registry */
+	if (CUE_SUCCESS != CU_initialize_registry())
+		return CU_get_error();
+
+	/* register suites */
+	CU_register_suites(suites);
+	/* Run all tests using the CUnit Basic interface */
+	CU_basic_set_mode(CU_BRM_VERBOSE);
+	CU_basic_run_tests();
+	CU_cleanup_registry();
+
+	return CU_get_error();
+}
diff --git a/test/cunit/crypto/odp_crypto_test_async_inp.c b/test/cunit/crypto/odp_crypto_test_async_inp.c
new file mode 100644
index 0000000..dd5fb5f
--- /dev/null
+++ b/test/cunit/crypto/odp_crypto_test_async_inp.c
@@ -0,0 +1,458 @@ 
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+#include <odp.h>
+#include <odp_crypto.h>
+#include "CUnit/Headers/Basic.h"
+#include "CUnit/Headers/TestDB.h"
+#include "test_vectors.h"
+
+/* Suite name */
+#define ODP_CRYPTO_ASYNC_INP	"odp_crypto_async_inp"
+
+/* Suite init/finalize funcs */
+/* ODP global/local initialization
+ * Packet pool creation
+ * Crypto output queue creation */
+
+#define SHM_PKT_POOL_SIZE      (512*2048*2)
+#define SHM_PKT_POOL_BUF_SIZE  (1024 * 32)
+
+#define SHM_COMPL_POOL_SIZE	(128*1024)
+#define SHM_COMPL_POOL_BUF_SIZE 128
+
+static int init(void)
+{
+	odp_shm_t shm;
+	void *pool_base = NULL;
+	odp_buffer_pool_t pool;
+	odp_queue_t out_queue;
+
+	if (odp_init_global(NULL, NULL)) {
+		ODP_ERR("ODP global init failed.\n");
+		return -1;
+	}
+	odp_init_local();
+
+	shm = odp_shm_reserve("shm_packet_pool",
+			      SHM_PKT_POOL_SIZE,
+			      ODP_CACHE_LINE_SIZE, 0);
+
+	pool_base = odp_shm_addr(shm);
+	if (!pool_base) {
+		ODP_ERR("Packet pool allocation failed.\n");
+		return -1;
+	}
+
+	pool = odp_buffer_pool_create("packet_pool", pool_base,
+				      SHM_PKT_POOL_SIZE,
+				      SHM_PKT_POOL_BUF_SIZE,
+				      ODP_CACHE_LINE_SIZE,
+				      ODP_BUFFER_TYPE_PACKET);
+	if (pool == ODP_BUFFER_POOL_INVALID) {
+		ODP_ERR("Packet pool creation failed.\n");
+		return -1;
+	}
+	out_queue = odp_queue_create("crypto-out",
+				     ODP_QUEUE_TYPE_POLL, NULL);
+	if (out_queue == ODP_QUEUE_INVALID) {
+		ODP_ERR("Crypto outq creation failed.\n");
+		return -1;
+	}
+	shm = odp_shm_reserve("shm_compl_pool",
+			     SHM_COMPL_POOL_SIZE,
+			     ODP_CACHE_LINE_SIZE,
+			     ODP_SHM_SW_ONLY);
+	pool_base = odp_shm_addr(shm);
+	if (!pool_base) {
+		ODP_ERR("Completion pool allocation failed.\n");
+		return -1;
+	}
+	pool = odp_buffer_pool_create("compl_pool", pool_base,
+				      SHM_COMPL_POOL_SIZE,
+				      SHM_COMPL_POOL_BUF_SIZE,
+				      ODP_CACHE_LINE_SIZE,
+				      ODP_BUFFER_TYPE_RAW);
+	if (pool == ODP_BUFFER_POOL_INVALID) {
+		ODP_ERR("Completion pool creation failed.\n");
+		return -1;
+	}
+
+	printf("\tODP version: %s\n", odp_version_api_str());
+	return 0;
+}
+
+/* ODP cleanup */
+static int finalize(void)
+{
+	odp_term_local();
+	odp_term_global();
+	return 0;
+}
+
+
+/* Basic algorithm run function.
+ * Creates a session from input parameters and runs one operation
+ * on input_vec. Checks the output of the crypto operation against
+ * output_vec. Operation completion event is dequeued polling the
+ * session output queue. Completion context pointer is retrieved
+ * and checked against the one set before the operation.
+ * */
+static void alg_test(enum odp_crypto_op op,
+		     enum odp_cipher_alg cipher_alg,
+		     odp_crypto_iv_t ses_iv,
+		     uint8_t *op_iv_ptr,
+		     odp_crypto_key_t cipher_key,
+		     enum odp_auth_alg auth_alg,
+		     odp_crypto_key_t auth_key,
+		     odp_buffer_t compl_new,
+		     uint8_t *input_vec,
+		     unsigned int input_vec_len,
+		     uint8_t *output_vec,
+		     unsigned int output_vec_len)
+{
+	odp_crypto_session_t session;
+	int rc;
+	enum odp_crypto_ses_create_err status;
+	bool posted;
+	odp_buffer_t compl_event;
+
+	odp_queue_t compl_queue = odp_queue_lookup("crypto-out");
+	CU_ASSERT(compl_queue != ODP_QUEUE_INVALID);
+	odp_buffer_pool_t pool = odp_buffer_pool_lookup("packet_pool");
+	CU_ASSERT(pool != ODP_BUFFER_POOL_INVALID);
+
+	/* Create a crypto session */
+	odp_crypto_session_params_t ses_params;
+	memset(&ses_params, 0, sizeof(ses_params));
+	ses_params.op = op;
+	ses_params.auth_cipher_text = false;
+	ses_params.pref_mode = ODP_CRYPTO_ASYNC;
+	ses_params.cipher_alg = cipher_alg;
+	ses_params.auth_alg = auth_alg;
+	ses_params.compl_queue = compl_queue;
+	ses_params.output_pool = pool;
+	ses_params.cipher_key = cipher_key;
+	ses_params.iv = ses_iv;
+	ses_params.auth_key = auth_key;
+
+	/* TEST : odp_crypto_session_create */
+	rc = odp_crypto_session_create(&ses_params, &session, &status);
+	CU_ASSERT(!rc);
+	CU_ASSERT(status == ODP_CRYPTO_SES_CREATE_ERR_NONE);
+
+	/* Prepare input data */
+	odp_buffer_t buf = odp_buffer_alloc(pool);
+	CU_ASSERT(buf != ODP_BUFFER_INVALID);
+	odp_packet_t pkt = odp_packet_from_buffer(buf);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
+	uint8_t *data_addr = odp_packet_data(pkt);
+	memcpy(data_addr, input_vec, input_vec_len);
+	/* offsets are relative to buffer address (not packet data)
+	until https://bugs.linaro.org/show_bug.cgi?id=387 is fixed */
+	int data_off = data_addr - (uint8_t *)odp_buffer_addr(buf);
+
+	/* Prepare input/output params */
+	odp_crypto_op_params_t op_params;
+	memset(&op_params, 0, sizeof(op_params));
+	op_params.session = session;
+	op_params.pkt = pkt;
+	op_params.out_pkt = pkt;
+	if (cipher_alg != ODP_CIPHER_ALG_NULL &&
+	    auth_alg == ODP_AUTH_ALG_NULL) {
+		op_params.cipher_range.offset = data_off;
+		op_params.cipher_range.length = input_vec_len;
+		if (op_iv_ptr)
+			op_params.override_iv_ptr = op_iv_ptr;
+	} else if (cipher_alg == ODP_CIPHER_ALG_NULL &&
+		 auth_alg != ODP_AUTH_ALG_NULL) {
+		op_params.auth_range.offset = data_off;
+		op_params.auth_range.length = input_vec_len;
+		op_params.hash_result_offset = data_off;
+	} else {
+		CU_FAIL("%s : not implemented for combined alg mode\n");
+	}
+
+	/* TEST : odp_crypto_set_operation_compl_ctx */
+	/* TEST : odp_crypto_operation */
+	if (compl_new == ODP_BUFFER_INVALID) {
+		odp_crypto_set_operation_compl_ctx(buf, (void *)0xdeadbeef);
+		rc = odp_crypto_operation(&op_params, &posted, buf);
+	} else {
+		odp_crypto_set_operation_compl_ctx(compl_new,
+						   (void *)0xdeadbeef);
+		rc = odp_crypto_operation(&op_params, &posted, compl_new);
+	}
+	CU_ASSERT(posted);
+
+	/* Poll completion queue for results */
+	do {
+		compl_event = odp_queue_deq(compl_queue);
+	} while (compl_event == ODP_BUFFER_INVALID);
+
+	if (compl_new == ODP_BUFFER_INVALID) {
+		CU_ASSERT(compl_event == buf);
+	} else {
+		CU_ASSERT(compl_event == compl_new);
+	}
+
+	/* TEST : odp_crypto_get_operation_compl_status */
+	struct odp_crypto_compl_status auth_status, cipher_status;
+	odp_crypto_get_operation_compl_status(compl_event,
+					      &auth_status, &cipher_status);
+	CU_ASSERT(auth_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE);
+	CU_ASSERT(auth_status.hw_err == ODP_CRYPTO_HW_ERR_NONE);
+	CU_ASSERT(cipher_status.alg_err == ODP_CRYPTO_ALG_ERR_NONE);
+	CU_ASSERT(cipher_status.hw_err == ODP_CRYPTO_HW_ERR_NONE);
+
+	/* TEST : odp_crypto_get_operation_compl_packet */
+	odp_packet_t out_pkt;
+	out_pkt = odp_crypto_get_operation_compl_packet(compl_event);
+	CU_ASSERT(out_pkt == pkt);
+
+	/* TEST : operation output was correct */
+	CU_ASSERT(!memcmp(data_addr, output_vec, output_vec_len));
+
+	/* TEST : we got back the context pointer */
+	void *ctx = odp_crypto_get_operation_compl_ctx(compl_event);
+	CU_ASSERT(ctx == (void *)0xdeadbeef);
+
+	odp_buffer_free(buf);
+}
+
+/* This test verifies the correctness of encode (plaintext -> ciphertext)
+ * operation for 3DES_CBC algorithm. IV for the operation is the session IV.
+ * In addition the test verifies if the implementation can use the
+ * packet buffer as completion event buffer.*/
+#define ASYNC_INP_ENC_ALG_3DES_CBC	"ENC_ALG_3DES_CBC"
+static void test_enc_alg_3des_cbc(void)
+{
+	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
+			 auth_key   = { .data = NULL, .length = 0 };
+	odp_crypto_iv_t iv;
+	unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
+				     sizeof(tdes_cbc_reference_length[0]));
+
+	unsigned int i;
+	for (i = 0; i < test_vec_num; i++) {
+		cipher_key.data = tdes_cbc_reference_key[i];
+		cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
+		iv.data = tdes_cbc_reference_iv[i];
+		iv.length = sizeof(tdes_cbc_reference_iv[i]);
+
+		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 ODP_CIPHER_ALG_3DES_CBC,
+			 iv,
+			 NULL,
+			 cipher_key,
+			 ODP_AUTH_ALG_NULL,
+			 auth_key,
+			 ODP_BUFFER_INVALID,
+			 tdes_cbc_reference_plaintext[i],
+			 tdes_cbc_reference_length[i],
+			 tdes_cbc_reference_ciphertext[i],
+			 tdes_cbc_reference_length[i]);
+	}
+}
+
+/* This test verifies the correctness of encode (plaintext -> ciphertext)
+ * operation for 3DES_CBC algorithm. IV for the operation is the operation IV.
+ * */
+#define ASYNC_INP_ENC_ALG_3DES_CBC_OVR_IV	"ENC_ALG_3DES_CBC_OVR_IV"
+static void test_enc_alg_3des_cbc_ovr_iv(void)
+{
+	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
+			 auth_key   = { .data = NULL, .length = 0 };
+	odp_crypto_iv_t iv = { .data = NULL, .length = TDES_CBC_IV_LEN };
+	unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
+				     sizeof(tdes_cbc_reference_length[0]));
+
+	unsigned int i;
+	for (i = 0; i < test_vec_num; i++) {
+		cipher_key.data = tdes_cbc_reference_key[i];
+		cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
+
+		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 ODP_CIPHER_ALG_3DES_CBC,
+			 iv,
+			 tdes_cbc_reference_iv[i],
+			 cipher_key,
+			 ODP_AUTH_ALG_NULL,
+			 auth_key,
+			 ODP_BUFFER_INVALID,
+			 tdes_cbc_reference_plaintext[i],
+			 tdes_cbc_reference_length[i],
+			 tdes_cbc_reference_ciphertext[i],
+			 tdes_cbc_reference_length[i]);
+	}
+}
+
+
+/* This test verifies the correctness of decode (ciphertext -> plaintext)
+ * operation for 3DES_CBC algorithm. IV for the operation is the session IV
+ * In addition the test verifies if the implementation can use the
+ * packet buffer as completion event buffer.
+ * */
+#define ASYNC_INP_DEC_ALG_3DES_CBC	 "DEC_ALG_3DES_CBC"
+static void test_dec_alg_3des_cbc(void)
+{
+	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
+			 auth_key   = { .data = NULL, .length = 0 };
+	odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
+	unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
+				     sizeof(tdes_cbc_reference_length[0]));
+
+	unsigned int i;
+	for (i = 0; i < test_vec_num; i++) {
+		cipher_key.data = tdes_cbc_reference_key[i];
+		cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
+		iv.data = tdes_cbc_reference_iv[i];
+		iv.length = sizeof(tdes_cbc_reference_iv[i]);
+
+		alg_test(ODP_CRYPTO_OP_DECODE,
+			 ODP_CIPHER_ALG_3DES_CBC,
+			 iv,
+			 NULL,
+			 cipher_key,
+			 ODP_AUTH_ALG_NULL,
+			 auth_key,
+			 ODP_BUFFER_INVALID,
+			 tdes_cbc_reference_ciphertext[i],
+			 tdes_cbc_reference_length[i],
+			 tdes_cbc_reference_plaintext[i],
+			 tdes_cbc_reference_length[i]);
+	}
+}
+
+/* This test verifies the correctness of decode (ciphertext -> plaintext)
+ * operation for 3DES_CBC algorithm. IV for the operation is the session IV
+ * In addition the test verifies if the implementation can use the
+ * packet buffer as completion event buffer.
+ * */
+#define ASYNC_INP_DEC_ALG_3DES_CBC_OVR_IV	 "DEC_ALG_3DES_CBC_OVR_IV"
+static void test_dec_alg_3des_cbc_ovr_iv(void)
+{
+	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
+			 auth_key   = { .data = NULL, .length = 0 };
+	odp_crypto_iv_t iv = { .data = NULL, .length = TDES_CBC_IV_LEN };
+	unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
+				     sizeof(tdes_cbc_reference_length[0]));
+
+	unsigned int i;
+	for (i = 0; i < test_vec_num; i++) {
+		cipher_key.data = tdes_cbc_reference_key[i];
+		cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
+
+		alg_test(ODP_CRYPTO_OP_DECODE,
+			 ODP_CIPHER_ALG_3DES_CBC,
+			 iv,
+			 tdes_cbc_reference_iv[i],
+			 cipher_key,
+			 ODP_AUTH_ALG_NULL,
+			 auth_key,
+			 ODP_BUFFER_INVALID,
+			 tdes_cbc_reference_ciphertext[i],
+			 tdes_cbc_reference_length[i],
+			 tdes_cbc_reference_plaintext[i],
+			 tdes_cbc_reference_length[i]);
+	}
+}
+
+
+/* This test verifies the correctness of HMAC_MD5 digest operation.
+ * The output check length is truncated to 12 bytes (96 bits) as
+ * returned by the crypto operation API call.
+ * Note that hash digest is a one-way operation.
+ * In addition the test verifies if the implementation can use the
+ * packet buffer as completion event buffer.
+ * */
+#define ASYNC_INP_ALG_HMAC_MD5	      "ALG_HMAC_MD5"
+static void test_alg_hmac_md5(void)
+{
+	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
+			 auth_key   = { .data = NULL, .length = 0 };
+	odp_crypto_iv_t iv = { .data = NULL, .length = 0 };
+
+	unsigned int test_vec_num = (sizeof(hmac_md5_reference_length)/
+				     sizeof(hmac_md5_reference_length[0]));
+
+	unsigned int i;
+	for (i = 0; i < test_vec_num; i++) {
+		auth_key.data = hmac_md5_reference_key[i];
+		auth_key.length = sizeof(hmac_md5_reference_key[i]);
+
+		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 ODP_CIPHER_ALG_NULL,
+			 iv,
+			 iv.data,
+			 cipher_key,
+			 ODP_AUTH_ALG_MD5_96,
+			 auth_key,
+			 ODP_BUFFER_INVALID,
+			 hmac_md5_reference_plaintext[i],
+			 hmac_md5_reference_length[i],
+			 hmac_md5_reference_digest[i],
+			 HMAC_MD5_96_CHECK_LEN);
+	}
+}
+
+/* This test verifies the correctness of encode (plaintext -> ciphertext)
+ * operation for 3DES_CBC algorithm. IV for the operation is the session IV.
+ * Uses a separate buffer for completion event
+ * */
+#define ASYNC_INP_ENC_ALG_3DES_CBC_COMPL_NEW	   "ENC_ALG_3DES_CBC_COMPL_NEW"
+static void test_enc_alg_3des_cbc_compl_new(void)
+{
+	odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 },
+			 auth_key   = { .data = NULL, .length = 0 };
+	odp_crypto_iv_t iv;
+	unsigned int test_vec_num = (sizeof(tdes_cbc_reference_length)/
+				     sizeof(tdes_cbc_reference_length[0]));
+
+	odp_buffer_pool_t pool = odp_buffer_pool_lookup("compl_pool");
+	CU_ASSERT(pool != ODP_BUFFER_POOL_INVALID);
+
+	unsigned int i;
+	odp_buffer_t compl_new;
+	for (i = 0; i < test_vec_num; i++) {
+		compl_new = odp_buffer_alloc(pool);
+		CU_ASSERT(compl_new != ODP_BUFFER_INVALID);
+
+		cipher_key.data = tdes_cbc_reference_key[i];
+		cipher_key.length = sizeof(tdes_cbc_reference_key[i]);
+		iv.data = tdes_cbc_reference_iv[i];
+		iv.length = sizeof(tdes_cbc_reference_iv[i]);
+
+		alg_test(ODP_CRYPTO_OP_ENCODE,
+			 ODP_CIPHER_ALG_3DES_CBC,
+			 iv,
+			 NULL,
+			 cipher_key,
+			 ODP_AUTH_ALG_NULL,
+			 auth_key,
+			 compl_new,
+			 tdes_cbc_reference_plaintext[i],
+			 tdes_cbc_reference_length[i],
+			 tdes_cbc_reference_ciphertext[i],
+			 tdes_cbc_reference_length[i]);
+		odp_buffer_free(compl_new);
+	}
+}
+
+static CU_TestInfo test_array[] = {
+	{ASYNC_INP_ENC_ALG_3DES_CBC, test_enc_alg_3des_cbc },
+	{ASYNC_INP_DEC_ALG_3DES_CBC, test_dec_alg_3des_cbc },
+	{ASYNC_INP_ENC_ALG_3DES_CBC_OVR_IV, test_enc_alg_3des_cbc_ovr_iv },
+	{ASYNC_INP_DEC_ALG_3DES_CBC_OVR_IV, test_dec_alg_3des_cbc_ovr_iv },
+	{ASYNC_INP_ALG_HMAC_MD5, test_alg_hmac_md5 },
+	{ASYNC_INP_ENC_ALG_3DES_CBC_COMPL_NEW, test_enc_alg_3des_cbc_compl_new },
+	CU_TEST_INFO_NULL,
+};
+
+CU_SuiteInfo suites[] = {
+	{ ODP_CRYPTO_ASYNC_INP , init, finalize, NULL, NULL, test_array },
+	CU_SUITE_INFO_NULL,
+};
diff --git a/test/cunit/crypto/odp_crypto_test_async_inp.h b/test/cunit/crypto/odp_crypto_test_async_inp.h
new file mode 100644
index 0000000..818f7e7
--- /dev/null
+++ b/test/cunit/crypto/odp_crypto_test_async_inp.h
@@ -0,0 +1,13 @@ 
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+#ifndef ODP_CRYPTO_TEST_ASYNC_INP_
+#define ODP_CRYPTO_TEST_ASYNC_INP_
+
+#include "CUnit/Headers/TestDB.h"
+
+CU_SuiteInfo suites[1];
+
+#endif
diff --git a/test/cunit/crypto/test_vectors.h b/test/cunit/crypto/test_vectors.h
new file mode 100644
index 0000000..c151952
--- /dev/null
+++ b/test/cunit/crypto/test_vectors.h
@@ -0,0 +1,94 @@ 
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+
+/* TDES-CBC reference vectors, according to
+ * "http://csrc.nist.gov/groups/STM/cavp/documents/des/DESMMT.pdf"
+ */
+
+#define TDES_CBC_KEY_LEN	24	/* key length(in bytes) for tdes-cbc */
+#define TDES_CBC_IV_LEN		8	/* IV length(in bytes) for tdes-cbc */
+#define TDES_CBC_MAX_DATA_LEN	16	/* max. plain text length(in bytes) */
+
+static uint8_t tdes_cbc_reference_key[][TDES_CBC_KEY_LEN] = {
+	{0x62, 0x7f, 0x46, 0x0e, 0x08, 0x10, 0x4a, 0x10, 0x43, 0xcd, 0x26, 0x5d,
+	 0x58, 0x40, 0xea, 0xf1, 0x31, 0x3e, 0xdf, 0x97, 0xdf, 0x2a, 0x8a, 0x8c,
+	 },
+
+	{0x37, 0xae, 0x5e, 0xbf, 0x46, 0xdf, 0xf2, 0xdc, 0x07, 0x54, 0xb9, 0x4f,
+	 0x31, 0xcb, 0xb3, 0x85, 0x5e, 0x7f, 0xd3, 0x6d, 0xc8, 0x70, 0xbf, 0xae}
+};
+
+static uint8_t tdes_cbc_reference_iv[][TDES_CBC_IV_LEN] = {
+	{0x8e, 0x29, 0xf7, 0x5e, 0xa7, 0x7e, 0x54, 0x75},
+
+	{0x3d, 0x1d, 0xe3, 0xcc, 0x13, 0x2e, 0x3b, 0x65}
+};
+
+/** length in bytes */
+static uint32_t tdes_cbc_reference_length[] = { 8, 16 };
+
+static uint8_t tdes_cbc_reference_plaintext[][TDES_CBC_MAX_DATA_LEN] = {
+	{0x32, 0x6a, 0x49, 0x4c, 0xd3, 0x3f, 0xe7, 0x56},
+
+	{0x84, 0x40, 0x1f, 0x78, 0xfe, 0x6c, 0x10, 0x87, 0x6d, 0x8e, 0xa2, 0x30,
+	 0x94, 0xea, 0x53, 0x09}
+};
+
+static uint8_t tdes_cbc_reference_ciphertext[][TDES_CBC_MAX_DATA_LEN] = {
+	{0xb2, 0x2b, 0x8d, 0x66, 0xde, 0x97, 0x06, 0x92},
+
+	{0x7b, 0x1f, 0x7c, 0x7e, 0x3b, 0x1c, 0x94, 0x8e, 0xbd, 0x04, 0xa7, 0x5f,
+	 0xfb, 0xa7, 0xd2, 0xf5}
+};
+
+
+/* HMAC-MD5 test vectors  - RFC2104 */
+#define HMAC_MD5_KEY_LEN	16
+#define HMAC_MD5_MAX_DATA_LEN	128
+#define HMAC_MD5_DIGEST_LEN	16
+#define HMAC_MD5_96_CHECK_LEN	12
+
+static uint8_t hmac_md5_reference_key[][HMAC_MD5_KEY_LEN] = {
+	{ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b } ,
+
+	/* "Jefe" */
+	{ 0x4a, 0x65, 0x66, 0x65 },
+
+	{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+	  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }
+};
+
+static uint32_t hmac_md5_reference_length[] = { 8, 28, 50 };
+
+static uint8_t hmac_md5_reference_plaintext[][HMAC_MD5_MAX_DATA_LEN] = {
+	/* "Hi There" */
+	{ 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65},
+
+	/* what do ya want for nothing?*/
+	{ 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
+	  0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
+	  0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
+	  0x69, 0x6e, 0x67, 0x3f },
+
+	{ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+	  0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd }
+};
+
+static uint8_t hmac_md5_reference_digest[][HMAC_MD5_DIGEST_LEN] = {
+	{ 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
+	  0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d },
+
+	{ 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
+	  0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 },
+
+	{ 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
+	  0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }
+};