@@ -173,6 +173,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])
@@ -3,6 +3,8 @@ include $(top_srcdir)/test/Makefile.inc
AM_CFLAGS += -I$(CUNIT_PATH)/include
AM_LDFLAGS += -L$(CUNIT_PATH)/lib -static -lcunit
+SUBDIRS = crypto
+
if ODP_CUNIT_ENABLED
TESTS = ${bin_PROGRAMS}
check_PROGRAMS = ${bin_PROGRAMS}
new file mode 100644
@@ -0,0 +1,14 @@
+include $(top_srcdir)/test/Makefile.inc
+
+AM_CFLAGS += -I$(CUNIT_PATH)/include
+AM_LDFLAGS += -L$(CUNIT_PATH)/lib -static -lcunit
+
+if ODP_CUNIT_ENABLED
+bin_PROGRAMS = odp_crypto
+odp_crypto_CFLAGS = $(AM_CFLAGS)
+odp_crypto_LDFLAGS = $(AM_LDFLAGS)
+endif
+
+dist_odp_crypto_SOURCES = odp_crypto_test_async_inp.c \
+ odp_crypto_test_sync_inp.c \
+ odp_crypto_test.c
new file mode 100644
@@ -0,0 +1,102 @@
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp.h>
+#include "CUnit/Basic.h"
+#include "CUnit/TestDB.h"
+#include "odp_crypto_test_async_inp.h"
+#include "odp_crypto_test_sync_inp.h"
+
+#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
+
+CU_SuiteInfo suites[] = {
+ { ODP_CRYPTO_SYNC_INP , NULL, NULL, NULL, NULL, test_array_sync },
+ { ODP_CRYPTO_ASYNC_INP , NULL, NULL, NULL, NULL, test_array_async },
+ CU_SUITE_INFO_NULL,
+};
+
+int main(void)
+{
+ odp_shm_t shm;
+ void *pool_base = NULL;
+ odp_buffer_pool_t pool;
+ odp_queue_t out_queue;
+
+ 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");
+ /* TODO - cleanup */
+ 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");
+ /* TODO - cleanup */
+ 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());
+
+
+ if (odp_init_global(NULL, NULL)) {
+ ODP_ERR("ODP global init failed.\n");
+ return -1;
+ }
+ odp_init_local();
+
+ /* 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();
+
+ odp_term_local();
+ odp_term_global();
+
+ return CU_get_error();
+}
new file mode 100644
@@ -0,0 +1,371 @@
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp.h>
+#include <odp_crypto.h>
+#include "CUnit/Basic.h"
+#include "CUnit/TestDB.h"
+#include "test_vectors.h"
+
+/* Basic algorithm run function for async inplace mode.
+ * 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.
+ * Completion event can be a separate buffer or the input packet
+ * buffer can be used.
+ * */
+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_async_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_async_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_async_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_async_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_async_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_async_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);
+ }
+}
+
+CU_TestInfo test_array_async[] = {
+ {ASYNC_INP_ENC_ALG_3DES_CBC, test_async_enc_alg_3des_cbc },
+ {ASYNC_INP_DEC_ALG_3DES_CBC, test_async_dec_alg_3des_cbc },
+ {ASYNC_INP_ENC_ALG_3DES_CBC_OVR_IV, test_async_enc_alg_3des_cbc_ovr_iv },
+ {ASYNC_INP_DEC_ALG_3DES_CBC_OVR_IV, test_async_dec_alg_3des_cbc_ovr_iv },
+ {ASYNC_INP_ALG_HMAC_MD5, test_async_alg_hmac_md5 },
+ {ASYNC_INP_ENC_ALG_3DES_CBC_COMPL_NEW, test_async_enc_alg_3des_cbc_compl_new },
+ CU_TEST_INFO_NULL,
+};
new file mode 100644
@@ -0,0 +1,17 @@
+/* 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/TestDB.h"
+
+/* Suite name */
+#define ODP_CRYPTO_ASYNC_INP "odp_crypto_async_inp"
+
+/* Suite test array */
+CU_TestInfo test_array_async[1];
+
+#endif
new file mode 100644
@@ -0,0 +1,260 @@
+#include <odp.h>
+#include <odp_crypto.h>
+#include "CUnit/Basic.h"
+#include "CUnit/TestDB.h"
+#include "test_vectors.h"
+
+/* Basic algorithm run function for sync inplace.
+ * Creates a session from input parameters and runs one operation
+ * on input_vec. Checks the output of the crypto operation against
+ * output_vec.
+ */
+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,
+ 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_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_SYNC;
+ ses_params.cipher_alg = cipher_alg;
+ ses_params.auth_alg = auth_alg;
+ ses_params.compl_queue = ODP_QUEUE_INVALID;
+ 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_operation */
+ rc = odp_crypto_operation(&op_params, &posted, buf);
+ CU_ASSERT(!rc);
+ /* indication that the operation completed */
+ CU_ASSERT(!posted);
+
+ /* TEST : operation output was correct */
+ CU_ASSERT(!memcmp(data_addr, output_vec, output_vec_len));
+}
+
+#define SYNC_INP_ENC_ALG_3DES_CBC "ENC_ALG_3DES_CBC"
+static void test_sync_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,
+ 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
+ * */
+#define SYNC_INP_DEC_ALG_3DES_CBC "DEC_ALG_3DES_CBC"
+static void test_sync_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,
+ 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.
+ * */
+#define SYNC_INP_ALG_HMAC_MD5 "ALG_HMAC_MD5"
+static void test_sync_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,
+ 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 operation IV.
+ * */
+#define SYNC_INP_ENC_ALG_3DES_CBC_OVR_IV "ENC_ALG_3DES_CBC_OVR_IV"
+static void test_sync_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,
+ 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.
+ * */
+#define SYNC_INP_DEC_ALG_3DES_CBC_OVR_IV "DEC_ALG_3DES_CBC_OVR_IV"
+static void test_sync_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,
+ tdes_cbc_reference_ciphertext[i],
+ tdes_cbc_reference_length[i],
+ tdes_cbc_reference_plaintext[i],
+ tdes_cbc_reference_length[i]);
+ }
+}
+
+CU_TestInfo test_array_sync[] = {
+ {SYNC_INP_ENC_ALG_3DES_CBC, test_sync_enc_alg_3des_cbc },
+ {SYNC_INP_DEC_ALG_3DES_CBC, test_sync_dec_alg_3des_cbc },
+ {SYNC_INP_ENC_ALG_3DES_CBC_OVR_IV, test_sync_enc_alg_3des_cbc_ovr_iv },
+ {SYNC_INP_DEC_ALG_3DES_CBC_OVR_IV, test_sync_dec_alg_3des_cbc_ovr_iv },
+ {SYNC_INP_ALG_HMAC_MD5, test_sync_alg_hmac_md5 },
+ CU_TEST_INFO_NULL,
+};
new file mode 100644
@@ -0,0 +1,17 @@
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef ODP_CRYPTO_TEST_SYNC_INP_
+#define ODP_CRYPTO_TEST_SYNC_INP_
+
+#include "CUnit/TestDB.h"
+
+/* Suite name */
+#define ODP_CRYPTO_SYNC_INP "odp_crypto_sync_inp"
+
+/* Suite test array */
+CU_TestInfo test_array_sync[1];
+
+#endif
new file mode 100644
@@ -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 }
+};