diff options
Diffstat (limited to 'test/validation/api/crypto/odp_crypto_test_inp.c')
-rw-r--r-- | test/validation/api/crypto/odp_crypto_test_inp.c | 2428 |
1 files changed, 2428 insertions, 0 deletions
diff --git a/test/validation/api/crypto/odp_crypto_test_inp.c b/test/validation/api/crypto/odp_crypto_test_inp.c new file mode 100644 index 000000000..7ce37a3cd --- /dev/null +++ b/test/validation/api/crypto/odp_crypto_test_inp.c @@ -0,0 +1,2428 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Linaro Limited + * Copyright (c) 2021-2024 Nokia + */ + +#include <string.h> +#include <stdlib.h> +#include <odp_api.h> +#include <odp/helper/odph_api.h> +#include <odp_cunit_common.h> +#include "test_vectors.h" +#include "test_vector_defs.h" +#include "crypto_op_test.h" +#include "util.h" + +/* + * If nonzero, run time consuming tests too. + * Set through FULL_TEST environment variable. + */ +static int full_test; + +#define MAX_FAILURE_PRINTS 20 + +#define PKT_POOL_NUM 64 +#define PKT_POOL_LEN 1200 /* enough for a test packet and some headroom */ +#define UAREA_SIZE 8 + +static void test_defaults(uint8_t fill) +{ + odp_crypto_session_param_t param; + + memset(¶m, fill, sizeof(param)); + odp_crypto_session_param_init(¶m); + + CU_ASSERT(param.op == ODP_CRYPTO_OP_ENCODE); + CU_ASSERT(param.op_type == ODP_CRYPTO_OP_TYPE_LEGACY); + CU_ASSERT(param.cipher_range_in_bits == false); + CU_ASSERT(param.auth_range_in_bits == false); + CU_ASSERT(param.auth_cipher_text == false); + CU_ASSERT(param.null_crypto_enable == false); + CU_ASSERT(param.op_mode == ODP_CRYPTO_SYNC); + CU_ASSERT(param.cipher_alg == ODP_CIPHER_ALG_NULL); + CU_ASSERT(param.cipher_iv_len == 0); + CU_ASSERT(param.auth_alg == ODP_AUTH_ALG_NULL); + CU_ASSERT(param.auth_iv_len == 0); + CU_ASSERT(param.auth_aad_len == 0); +} + +static void test_default_values(void) +{ + test_defaults(0); + test_defaults(0xff); +} + +static void print_alg_test_param(const crypto_op_test_param_t *p) +{ + const char *cipher_mode = p->session.cipher_range_in_bits ? "bit" : "byte"; + const char *auth_mode = p->session.auth_range_in_bits ? "bit" : "byte"; + + switch (p->session.op_type) { + case ODP_CRYPTO_OP_TYPE_LEGACY: + printf("legacy "); + break; + case ODP_CRYPTO_OP_TYPE_BASIC: + printf("basic "); + break; + case ODP_CRYPTO_OP_TYPE_OOP: + printf("out-of-place "); + break; + case ODP_CRYPTO_OP_TYPE_BASIC_AND_OOP: + printf("basic-and-out-of-place (%s)", + p->op_type == ODP_CRYPTO_OP_TYPE_BASIC ? "basic" : "oop"); + break; + default: + printf("unknown (internal error) "); + break; + } + printf("%s\n", p->session.op == ODP_CRYPTO_OP_ENCODE ? "encode" : "decode"); + + printf("cipher: %s, %s mode\n", cipher_alg_name(p->ref->cipher), cipher_mode); + printf(" key length: %d, iv length: %d\n", + p->ref->cipher_key_length, p->ref->cipher_iv_length); + printf(" range: offset %d, length %d\n", + p->cipher_range.offset, p->cipher_range.length); + + printf("auth: %s, %s mode\n", auth_alg_name(p->ref->auth), auth_mode); + printf(" key length: %d, iv length: %d\n", + p->ref->auth_key_length, p->ref->auth_iv_length); + printf(" range: offset %d, length %d; aad length: %d\n", + p->auth_range.offset, p->auth_range.length, p->ref->aad_length); + printf(" digest offset: %d, digest length %d\n", + p->digest_offset, p->ref->digest_length); + + if (p->wrong_digest) + printf("wrong digest test\n"); + printf("header length: %d, trailer length: %d\n", p->header_len, p->trailer_len); + if (p->adjust_segmentation) + printf("segmentation adjusted, first_seg_len: %d\n", p->first_seg_len); + if (p->op_type == ODP_CRYPTO_OP_TYPE_OOP) + printf("oop_shift: %d\n", p->oop_shift); + if (p->session.null_crypto_enable) + printf("null crypto enabled in session\n"); + if (p->null_crypto) + printf("null crypto requested\n"); +} + +static void alg_test_execute_and_print(crypto_op_test_param_t *param) +{ + static int print_limit = MAX_FAILURE_PRINTS; + unsigned int num = CU_get_number_of_failures(); + + test_crypto_op(param); + + if (CU_get_number_of_failures() > num) { + if (print_limit > 0) { + printf("\nTest failed:\n"); + print_alg_test_param(param); + printf("\n"); + print_limit--; + if (print_limit == 0) + printf("Suppressing further failure output\n"); + } + } +} + +static void alg_test_op2(crypto_op_test_param_t *param) +{ + int32_t oop_shifts[] = {0, 3, 130, -10}; + + for (uint32_t n = 0; n < ODPH_ARRAY_SIZE(oop_shifts); n++) { + if (oop_shifts[n] != 0 && + param->op_type != ODP_CRYPTO_OP_TYPE_OOP) + continue; + if ((int32_t)param->header_len + oop_shifts[n] < 0) + continue; + param->oop_shift = oop_shifts[n]; + + param->wrong_digest = false; + alg_test_execute_and_print(param); + + param->null_crypto = true; + alg_test_execute_and_print(param); + param->null_crypto = false; + + if (full_test) + alg_test_execute_and_print(param); /* rerun with the same parameters */ + + if (!full_test && param->session.null_crypto_enable) + break; + if (!full_test && param->session.op_type == ODP_CRYPTO_OP_TYPE_BASIC_AND_OOP) + break; + + param->wrong_digest = true; + alg_test_execute_and_print(param); + } +} + +static void alg_test_op(crypto_op_test_param_t *param) +{ + param->op_type = param->session.op_type; + if (param->op_type == ODP_CRYPTO_OP_TYPE_BASIC_AND_OOP) { + param->op_type = ODP_CRYPTO_OP_TYPE_BASIC; + alg_test_op2(param); + param->op_type = ODP_CRYPTO_OP_TYPE_OOP; + } + alg_test_op2(param); +} + +static int combo_warning_shown; +static int oop_warning_shown; + +typedef enum { + HASH_NO_OVERLAP, + HASH_OVERLAP, +} hash_test_mode_t; + +typedef enum { + AUTH_CIPHERTEXT, + AUTH_PLAINTEXT +} alg_order_t; + +static int session_create(crypto_session_t *session, + alg_order_t order, + crypto_test_reference_t *ref, + hash_test_mode_t hash_mode, + odp_bool_t must_fail) +{ + int rc; + odp_crypto_ses_create_err_t status; + odp_crypto_session_param_t ses_params; + uint8_t cipher_key_data[MAX_KEY_LEN]; + uint8_t auth_key_data[MAX_KEY_LEN]; + odp_crypto_key_t cipher_key = { + .data = cipher_key_data, + .length = ref->cipher_key_length + }; + odp_crypto_key_t auth_key = { + .data = auth_key_data, + .length = ref->auth_key_length + }; + + memcpy(cipher_key_data, ref->cipher_key, ref->cipher_key_length); + memcpy(auth_key_data, ref->auth_key, ref->auth_key_length); + + /* Create a crypto session */ + odp_crypto_session_param_init(&ses_params); + ses_params.op = session->op; + ses_params.op_type = session->op_type; + ses_params.cipher_range_in_bits = session->cipher_range_in_bits; + ses_params.auth_range_in_bits = session->auth_range_in_bits; + ses_params.auth_cipher_text = (order == AUTH_CIPHERTEXT); + ses_params.null_crypto_enable = session->null_crypto_enable; + ses_params.op_mode = suite_context.op_mode; + ses_params.cipher_alg = ref->cipher; + ses_params.auth_alg = ref->auth; + ses_params.compl_queue = suite_context.queue; + ses_params.output_pool = suite_context.pool; + ses_params.cipher_key = cipher_key; + ses_params.cipher_iv_len = ref->cipher_iv_length; + ses_params.auth_iv_len = ref->auth_iv_length; + ses_params.auth_key = auth_key; + ses_params.auth_digest_len = ref->digest_length; + ses_params.auth_aad_len = ref->aad_length; + ses_params.hash_result_in_auth_range = (hash_mode == HASH_OVERLAP); + rc = odp_crypto_session_create(&ses_params, &session->session, &status); + + if (must_fail) { + CU_ASSERT(rc < 0); + if (rc == 0) { + rc = odp_crypto_session_destroy(session->session); + CU_ASSERT(rc == 0); + } + return -1; + } + + if (rc < 0 && status == ODP_CRYPTO_SES_ERR_ALG_COMBO) { + if (!combo_warning_shown) { + combo_warning_shown = 1; + printf("\n Unsupported algorithm combination: %s, %s\n", + cipher_alg_name(ref->cipher), + auth_alg_name(ref->auth)); + } + return -1; + } + + /* + * Allow ODP_CRYPTO_SES_ERR_ALG_ORDER only in async op mode. + * In sync mode an implementation should be able to support both + * orders without much difficulty. + */ + if (rc < 0 && status == ODP_CRYPTO_SES_ERR_ALG_ORDER && + ses_params.op_mode == ODP_CRYPTO_ASYNC) { + printf("\n Unsupported algorithm order: %s, %s, auth_cipher_text: %d\n", + cipher_alg_name(ref->cipher), + auth_alg_name(ref->auth), + ses_params.auth_cipher_text); + return -1; + } + + /* For now, allow out-of-place sessions not to be supported. */ + if (rc < 0 && status == ODP_CRYPTO_SES_ERR_PARAMS && + (ses_params.op_type == ODP_CRYPTO_OP_TYPE_OOP || + ses_params.op_type == ODP_CRYPTO_OP_TYPE_BASIC_AND_OOP)) { + if (!oop_warning_shown) + printf("\n Skipping out-of-place tests\n"); + oop_warning_shown = 1; + return -1; + } + + CU_ASSERT_FATAL(!rc); + CU_ASSERT(status == ODP_CRYPTO_SES_ERR_NONE); + CU_ASSERT(odp_crypto_session_to_u64(session->session) != + odp_crypto_session_to_u64(ODP_CRYPTO_SESSION_INVALID)); + + /* + * Clear session creation parameters so that we might notice if + * the implementation still tried to use them. + */ + memset(cipher_key_data, 0, sizeof(cipher_key_data)); + memset(auth_key_data, 0, sizeof(auth_key_data)); + memset(&ses_params, 0, sizeof(ses_params)); + + return 0; +} + +static void alg_test_ses(odp_crypto_op_t op, + odp_crypto_op_type_t op_type, + alg_order_t order, + crypto_test_reference_t *ref, + odp_packet_data_range_t cipher_range, + odp_packet_data_range_t auth_range, + uint32_t digest_offset, + odp_bool_t cipher_range_in_bits, + odp_bool_t auth_range_in_bits, + odp_bool_t null_crypto_enable, + odp_bool_t session_creation_must_fail) +{ + unsigned int initial_num_failures = CU_get_number_of_failures(); + const uint32_t reflength = ref_length_in_bytes(ref); + const uint32_t auth_scale = auth_range_in_bits ? 8 : 1; + hash_test_mode_t hash_mode = HASH_NO_OVERLAP; + int rc; + uint32_t seg_len; + uint32_t max_shift; + crypto_op_test_param_t test_param; + + if (null_crypto_enable && suite_context.op_mode == ODP_CRYPTO_SYNC) + return; + + if (digest_offset * auth_scale >= auth_range.offset && + digest_offset * auth_scale < auth_range.offset + auth_range.length) + hash_mode = HASH_OVERLAP; + + memset(&test_param, 0, sizeof(test_param)); + test_param.session.op = op; + test_param.session.op_type = op_type; + test_param.session.cipher_range_in_bits = cipher_range_in_bits; + test_param.session.auth_range_in_bits = auth_range_in_bits; + test_param.session.null_crypto_enable = null_crypto_enable; + if (session_create(&test_param.session, order, ref, hash_mode, session_creation_must_fail)) + return; + test_param.ref = ref; + test_param.cipher_range = cipher_range; + test_param.auth_range = auth_range; + test_param.digest_offset = digest_offset; + + alg_test_op(&test_param); + + max_shift = reflength + ref->digest_length; + seg_len = 0; + + if (!full_test) + if ((ref->cipher != ODP_CIPHER_ALG_NULL && + ref->auth != ODP_AUTH_ALG_NULL) || + test_param.session.null_crypto_enable || + test_param.session.op_type == ODP_CRYPTO_OP_TYPE_BASIC_AND_OOP) { + /* run the loop body just once */ + seg_len = max_shift / 2; + max_shift = seg_len; + } + + /* + * Test with segmented packets with all possible segment boundaries + * within the packet data + */ + for (; seg_len <= max_shift; seg_len++) { + /* + * CUnit chokes on too many assertion failures, so bail + * out if this test has already failed. + */ + if (CU_get_number_of_failures() > initial_num_failures) + break; + + test_param.adjust_segmentation = true; + test_param.first_seg_len = seg_len; + test_param.header_len = 0; + test_param.trailer_len = 0; + test_param.digest_offset = digest_offset; + alg_test_op(&test_param); + + /* Test partial packet crypto with odd alignment. */ + test_param.header_len = 13; + test_param.trailer_len = 32; + test_param.digest_offset = test_param.header_len + digest_offset; + alg_test_op(&test_param); + } + + rc = odp_crypto_session_destroy(test_param.session.session); + CU_ASSERT(!rc); +} + +static void alg_test_op_types(odp_crypto_op_t op, + alg_order_t order, + crypto_test_reference_t *ref, + odp_packet_data_range_t cipher_range, + odp_packet_data_range_t auth_range, + uint32_t digest_offset, + odp_bool_t cipher_range_in_bits, + odp_bool_t auth_range_in_bits, + odp_bool_t session_creation_must_fail) +{ + odp_crypto_op_type_t op_types[] = { + ODP_CRYPTO_OP_TYPE_LEGACY, + ODP_CRYPTO_OP_TYPE_BASIC, + ODP_CRYPTO_OP_TYPE_OOP, + ODP_CRYPTO_OP_TYPE_BASIC_AND_OOP, + }; + + for (unsigned int n = 0; n < ODPH_ARRAY_SIZE(op_types); n++) { + for (unsigned int null_crypto = 0 ; null_crypto <= 1; null_crypto++) + alg_test_ses(op, + op_types[n], + order, + ref, + cipher_range, + auth_range, + digest_offset, + cipher_range_in_bits, + auth_range_in_bits, + null_crypto, + session_creation_must_fail); + } +} + +static void alg_test(odp_crypto_op_t op, + alg_order_t order, + crypto_test_reference_t *ref, + odp_packet_data_range_t cipher_bit_range, + odp_packet_data_range_t auth_bit_range, + uint32_t digest_offset, + odp_bool_t is_bit_mode_cipher, + odp_bool_t is_bit_mode_auth) +{ + odp_packet_data_range_t cipher_range; + odp_packet_data_range_t auth_range; + + for (int cr_in_bits = 0; cr_in_bits <= 1; cr_in_bits++) { + if (!cr_in_bits && cipher_bit_range.length % 8 != 0) + continue; + for (int ar_in_bits = 0; ar_in_bits <= 1; ar_in_bits++) { + odp_bool_t session_creation_must_fail; + + if (!ar_in_bits && auth_bit_range.length % 8 != 0) + continue; + + cipher_range = cipher_bit_range; + auth_range = auth_bit_range; + if (!cr_in_bits) { + cipher_range.offset /= 8; + cipher_range.length /= 8; + } + if (!ar_in_bits) { + auth_range.offset /= 8; + auth_range.length /= 8; + } + session_creation_must_fail = ((ar_in_bits && !is_bit_mode_auth) || + (cr_in_bits && !is_bit_mode_cipher)); + alg_test_op_types(op, order, ref, cipher_range, auth_range, + digest_offset, cr_in_bits, ar_in_bits, + session_creation_must_fail); + } + } +} + +static odp_bool_t aad_len_ok(const odp_crypto_auth_capability_t *capa, uint32_t len) +{ + if (len < capa->aad_len.min || len > capa->aad_len.max) + return false; + + if (len == capa->aad_len.min) + return true; + if (capa->aad_len.inc == 0) + return false; + + return ((len - capa->aad_len.min) % capa->aad_len.inc) == 0; +} + +static void check_alg(odp_crypto_op_t op, + crypto_test_reference_t *ref, + size_t count) +{ + int rc, i; + const odp_cipher_alg_t cipher_alg = ref->cipher; + const odp_auth_alg_t auth_alg = ref->auth; + int cipher_num = odp_crypto_cipher_capability(cipher_alg, NULL, 0); + int auth_num = odp_crypto_auth_capability(auth_alg, NULL, 0); + odp_bool_t cipher_ok = false; + odp_bool_t auth_ok = false; + size_t idx; + + CU_ASSERT_FATAL(cipher_num > 0); + CU_ASSERT_FATAL(auth_num > 0); + + init_reference(ref, count); + + odp_crypto_cipher_capability_t cipher_capa[cipher_num]; + odp_crypto_auth_capability_t auth_capa[auth_num]; + odp_bool_t cipher_tested[cipher_num]; + odp_bool_t auth_tested[auth_num]; + + rc = odp_crypto_cipher_capability(cipher_alg, cipher_capa, cipher_num); + CU_ASSERT_FATAL(rc == cipher_num); + + rc = odp_crypto_auth_capability(auth_alg, auth_capa, auth_num); + CU_ASSERT_FATAL(rc == auth_num); + + memset(cipher_tested, 0, sizeof(cipher_tested)); + memset(auth_tested, 0, sizeof(auth_tested)); + + oop_warning_shown = 0; /* allow OOP-unsupported warning again */ + + for (idx = 0; idx < count; idx++) { + int cipher_idx = -1, auth_idx = -1; + odp_bool_t is_bit_mode_cipher = false; + odp_bool_t is_bit_mode_auth = false; + uint32_t digest_offs = ref_length_in_bytes(&ref[idx]); + odp_packet_data_range_t cipher_bit_range = {.offset = 0}; + odp_packet_data_range_t auth_bit_range = {.offset = 0}; + + for (i = 0; i < cipher_num; i++) { + if (cipher_capa[i].key_len == + ref[idx].cipher_key_length && + cipher_capa[i].iv_len == + ref[idx].cipher_iv_length) { + cipher_idx = i; + is_bit_mode_cipher = cipher_capa[i].bit_mode; + break; + } + } + + if (cipher_idx < 0) { + printf("\n Unsupported: alg=%s, key_len=%" PRIu32 + ", iv_len=%" PRIu32 "\n", + cipher_alg_name(cipher_alg), + ref[idx].cipher_key_length, + ref[idx].cipher_iv_length); + continue; + } + + for (i = 0; i < auth_num; i++) { + if (auth_capa[i].digest_len == + ref[idx].digest_length && + auth_capa[i].iv_len == + ref[idx].auth_iv_length && + auth_capa[i].key_len == + ref[idx].auth_key_length && + aad_len_ok(&auth_capa[i], ref[idx].aad_length)) { + auth_idx = i; + is_bit_mode_auth = auth_capa[i].bit_mode; + break; + } + } + + if (auth_idx < 0) { + printf("\n Unsupported: alg=%s, key_len=%" PRIu32 + ", iv_len=%" PRIu32 ", digest_len=%" PRIu32 + "\n", + auth_alg_name(auth_alg), + ref[idx].auth_key_length, + ref[idx].auth_iv_length, + ref[idx].digest_length); + continue; + } + + cipher_bit_range.length = ref_length_in_bits(&ref[idx]); + auth_bit_range.length = ref_length_in_bits(&ref[idx]); + + alg_test(op, AUTH_PLAINTEXT, &ref[idx], + cipher_bit_range, auth_bit_range, digest_offs, + is_bit_mode_cipher, is_bit_mode_auth); + alg_test(op, AUTH_CIPHERTEXT, &ref[idx], + cipher_bit_range, auth_bit_range, digest_offs, + is_bit_mode_cipher, is_bit_mode_auth); + + cipher_tested[cipher_idx] = true; + auth_tested[auth_idx] = true; + } + + for (i = 0; i < cipher_num; i++) { + cipher_ok |= cipher_tested[i]; + if (!cipher_tested[i] && cipher_alg != ODP_CIPHER_ALG_NULL) + printf("\n Untested: alg=%s, key_len=%" PRIu32 ", " + "iv_len=%" PRIu32 "%s\n", + cipher_alg_name(cipher_alg), + cipher_capa[i].key_len, + cipher_capa[i].iv_len, + cipher_capa[i].bit_mode ? ", bit mode" : ""); + } + + for (i = 0; i < auth_num; i++) { + auth_ok |= auth_tested[i]; + if (!auth_tested[i] && auth_alg != ODP_AUTH_ALG_NULL) + printf("\n Untested: alg=%s, key_len=%" PRIu32 ", " + "digest_len=%" PRIu32 "%s\n", + auth_alg_name(auth_alg), + auth_capa[i].key_len, + auth_capa[i].digest_len, + auth_capa[i].bit_mode ? ", bit mode" : ""); + } + + /* Verify that we were able to run at least one test */ + CU_ASSERT(cipher_ok); + CU_ASSERT(auth_ok); +} + +static void test_capability(void) +{ + odp_crypto_capability_t capa = {.max_sessions = 1}; + int rc; + + rc = odp_crypto_capability(&capa); + CU_ASSERT(!rc); + if (capa.max_sessions > 0) + CU_ASSERT(capa.sync_mode || capa.async_mode); + CU_ASSERT((~capa.ciphers.all_bits & capa.hw_ciphers.all_bits) == 0); + CU_ASSERT((~capa.auths.all_bits & capa.hw_auths.all_bits) == 0); +} + +/* + * Create a test reference, which can be used in tests where the hash + * result is within auth_range. + * + * The ciphertext packet and the hash are calculated using an encode + * operation with hash_result_offset outside the auth_range and by + * copying the hash in the ciphertext packet. + */ +static int create_hash_test_reference(odp_auth_alg_t auth, + const odp_crypto_auth_capability_t *capa, + crypto_test_reference_t *ref, + uint32_t digest_offset, + uint8_t digest_fill) +{ + crypto_session_t session; + int rc; + odp_packet_t pkt; + odp_bool_t ok; + const uint32_t auth_bytes = 100; + uint32_t enc_digest_offset = auth_bytes; + + ref->cipher = ODP_CIPHER_ALG_NULL; + ref->auth = auth; + ref->auth_key_length = capa->key_len; + ref->auth_iv_length = capa->iv_len; + ref->digest_length = capa->digest_len; + ref->is_length_in_bits = false; + ref->length = auth_bytes; + + if (ref->auth_key_length > MAX_KEY_LEN || + ref->auth_iv_length > MAX_IV_LEN || + auth_bytes > MAX_DATA_LEN || + digest_offset + ref->digest_length > MAX_DATA_LEN) + CU_FAIL_FATAL("Internal error\n"); + + fill_with_pattern(ref->auth_key, ref->auth_key_length); + fill_with_pattern(ref->auth_iv, ref->auth_iv_length); + fill_with_pattern(ref->plaintext, auth_bytes); + + memset(ref->plaintext + digest_offset, digest_fill, ref->digest_length); + + pkt = odp_packet_alloc(suite_context.pool, auth_bytes + ref->digest_length); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + + rc = odp_packet_copy_from_mem(pkt, 0, auth_bytes, ref->plaintext); + CU_ASSERT(rc == 0); + + session.op = ODP_CRYPTO_OP_ENCODE; + session.op_type = ODP_CRYPTO_OP_TYPE_BASIC; + session.cipher_range_in_bits = false; + session.auth_range_in_bits = false; + session.null_crypto_enable = false; + if (session_create(&session, AUTH_PLAINTEXT, ref, HASH_NO_OVERLAP, false)) + return -1; + + odp_crypto_packet_op_param_t op_params = { + .session = session.session, + .cipher_iv_ptr = ref->cipher_iv, + .auth_iv_ptr = ref->auth_iv, + .hash_result_offset = enc_digest_offset, + .aad_ptr = ref->aad, + .cipher_range = {.offset = 0, .length = 0}, + .auth_range = { .offset = 0, .length = auth_bytes }, + .dst_offset_shift = 0, + }; + rc = crypto_op(pkt, &pkt, &ok, &op_params, + ODP_CRYPTO_OP_TYPE_BASIC, ODP_CRYPTO_OP_TYPE_BASIC); + + CU_ASSERT(rc == 0); + if (rc) { + (void)odp_crypto_session_destroy(session.session); + return -1; + } + CU_ASSERT(ok); + + rc = odp_crypto_session_destroy(session.session); + CU_ASSERT(rc == 0); + + /* copy the processed packet to the ciphertext packet in ref */ + rc = odp_packet_copy_to_mem(pkt, 0, auth_bytes, ref->ciphertext); + CU_ASSERT(rc == 0); + + /* copy the calculated digest in the ciphertext packet in ref */ + rc = odp_packet_copy_to_mem(pkt, enc_digest_offset, ref->digest_length, + &ref->ciphertext[digest_offset]); + CU_ASSERT(rc == 0); + + /* copy the calculated digest the digest field in ref */ + rc = odp_packet_copy_to_mem(pkt, enc_digest_offset, ref->digest_length, + &ref->digest); + CU_ASSERT(rc == 0); + + odp_packet_free(pkt); + + return 0; +} + +static void test_auth_hash_in_auth_range(odp_auth_alg_t auth, + const odp_crypto_auth_capability_t *capa, + odp_bool_t is_bit_mode_cipher, + alg_order_t order) +{ + static crypto_test_reference_t ref = {.length = 0}; + uint32_t digest_offset = 13; + const odp_packet_data_range_t cipher_bit_range = {.offset = 0, .length = 0}; + odp_packet_data_range_t auth_bit_range; + + if (!full_test && capa->digest_len % 4 != 0) + return; + + /* + * Create test packets with auth hash in the authenticated range and + * zeroes in the hash location in the plaintext packet. + */ + if (create_hash_test_reference(auth, capa, &ref, digest_offset, 0)) + return; + + auth_bit_range.offset = 0; + auth_bit_range.length = ref_length_in_bits(&ref); + + /* + * Decode the ciphertext packet. + * + * Check that auth hash verification works even if hash_result_offset + * is within the auth range. The ODP implementation must clear the + * hash bytes in the ciphertext packet before calculating the hash. + */ + alg_test(ODP_CRYPTO_OP_DECODE, + order, + &ref, + cipher_bit_range, auth_bit_range, + digest_offset, + is_bit_mode_cipher, + capa->bit_mode); + + /* + * Create test packets with auth hash in the authenticated range and + * ones in the hash location in the plaintext packet. + */ + if (create_hash_test_reference(auth, capa, &ref, digest_offset, 1)) + return; + + auth_bit_range.offset = 0; + auth_bit_range.length = ref_length_in_bits(&ref); + + /* + * Encode the plaintext packet. + * + * Check that auth hash generation works even if hash_result_offset + * is within the auth range. The ODP implementation must not clear + * the hash bytes in the plaintext packet before calculating the hash. + */ + alg_test(ODP_CRYPTO_OP_ENCODE, + order, + &ref, + cipher_bit_range, auth_bit_range, + digest_offset, + is_bit_mode_cipher, + capa->bit_mode); +} + +/* + * Cipher algorithms that are not AEAD algorithms + */ +static odp_cipher_alg_t cipher_algs[] = { + ODP_CIPHER_ALG_NULL, + ODP_CIPHER_ALG_DES, + ODP_CIPHER_ALG_3DES_CBC, + ODP_CIPHER_ALG_3DES_ECB, + ODP_CIPHER_ALG_AES_CBC, + ODP_CIPHER_ALG_AES_CTR, + ODP_CIPHER_ALG_AES_ECB, + ODP_CIPHER_ALG_AES_CFB128, + ODP_CIPHER_ALG_AES_XTS, + ODP_CIPHER_ALG_KASUMI_F8, + ODP_CIPHER_ALG_SNOW3G_UEA2, + ODP_CIPHER_ALG_AES_EEA2, + ODP_CIPHER_ALG_ZUC_EEA3, + ODP_CIPHER_ALG_SNOW_V, + ODP_CIPHER_ALG_SM4_ECB, + ODP_CIPHER_ALG_SM4_CBC, + ODP_CIPHER_ALG_SM4_CTR, +}; + +/* + * Authentication algorithms and hashes that may use auth_range + * parameter. AEAD algorithms are excluded. + */ +static odp_auth_alg_t auth_algs[] = { + ODP_AUTH_ALG_NULL, + ODP_AUTH_ALG_MD5_HMAC, + ODP_AUTH_ALG_SHA1_HMAC, + ODP_AUTH_ALG_SHA224_HMAC, + ODP_AUTH_ALG_SHA256_HMAC, + ODP_AUTH_ALG_SHA384_HMAC, + ODP_AUTH_ALG_SHA512_HMAC, + ODP_AUTH_ALG_SHA3_224_HMAC, + ODP_AUTH_ALG_SHA3_256_HMAC, + ODP_AUTH_ALG_SHA3_384_HMAC, + ODP_AUTH_ALG_SHA3_512_HMAC, + ODP_AUTH_ALG_AES_GMAC, + ODP_AUTH_ALG_AES_CMAC, + ODP_AUTH_ALG_AES_XCBC_MAC, + ODP_AUTH_ALG_KASUMI_F9, + ODP_AUTH_ALG_SNOW3G_UIA2, + ODP_AUTH_ALG_AES_EIA2, + ODP_AUTH_ALG_ZUC_EIA3, + ODP_AUTH_ALG_SNOW_V_GMAC, + ODP_AUTH_ALG_SM3_HMAC, + ODP_AUTH_ALG_SM4_GMAC, + ODP_AUTH_ALG_MD5, + ODP_AUTH_ALG_SHA1, + ODP_AUTH_ALG_SHA224, + ODP_AUTH_ALG_SHA256, + ODP_AUTH_ALG_SHA384, + ODP_AUTH_ALG_SHA512, + ODP_AUTH_ALG_SHA3_224, + ODP_AUTH_ALG_SHA3_256, + ODP_AUTH_ALG_SHA3_384, + ODP_AUTH_ALG_SHA3_512, + ODP_AUTH_ALG_SM3, +}; + +static void test_auth_hashes_in_auth_range(void) +{ + for (size_t n = 0; n < ODPH_ARRAY_SIZE(auth_algs); n++) { + odp_auth_alg_t auth = auth_algs[n]; + odp_crypto_cipher_capability_t c_capa; + int num; + + if (check_alg_support(ODP_CIPHER_ALG_NULL, auth) == ODP_TEST_INACTIVE) + continue; + + num = odp_crypto_cipher_capability(ODP_CIPHER_ALG_NULL, &c_capa, 1); + CU_ASSERT_FATAL(num == 1); + + num = odp_crypto_auth_capability(auth, NULL, 0); + CU_ASSERT_FATAL(num > 0); + + odp_crypto_auth_capability_t capa[num]; + + num = odp_crypto_auth_capability(auth, capa, num); + + for (int i = 0; i < num; i++) { + test_auth_hash_in_auth_range(auth, &capa[i], c_capa.bit_mode, + AUTH_PLAINTEXT); + test_auth_hash_in_auth_range(auth, &capa[i], c_capa.bit_mode, + AUTH_CIPHERTEXT); + } + } +} + +/* + * Encode ref->plaintext and save result in ref->ciphertext. + */ +static int crypto_encode_ref(crypto_test_reference_t *ref, + odp_packet_data_range_t cipher_range, + odp_packet_data_range_t auth_range, + uint32_t hash_result_offset) +{ + odp_packet_data_range_t zero_range = {.offset = 0, .length = 0}; + odp_packet_t pkt; + int rc; + crypto_session_t session; + odp_bool_t ok; + + pkt = odp_packet_alloc(suite_context.pool, ref->length); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + + rc = odp_packet_copy_from_mem(pkt, 0, ref->length, ref->plaintext); + CU_ASSERT(rc == 0); + + session.op = ODP_CRYPTO_OP_ENCODE; + session.op_type = ODP_CRYPTO_OP_TYPE_BASIC; + session.cipher_range_in_bits = false; + session.auth_range_in_bits = false; + session.null_crypto_enable = false; + if (session_create(&session, AUTH_PLAINTEXT, ref, HASH_OVERLAP, false)) { + odp_packet_free(pkt); + return 1; + } + + if (ref->cipher == ODP_CIPHER_ALG_NULL) + cipher_range = zero_range; + if (ref->auth == ODP_AUTH_ALG_NULL) { + auth_range = zero_range; + hash_result_offset = 0; + } + + CU_ASSERT_FATAL(hash_result_offset + ref->digest_length <= ref->length); + + odp_crypto_packet_op_param_t op_params = { + .session = session.session, + .cipher_iv_ptr = ref->cipher_iv, + .auth_iv_ptr = ref->auth_iv, + .hash_result_offset = hash_result_offset, + .aad_ptr = ref->aad, + .cipher_range = cipher_range, + .auth_range = auth_range, + .dst_offset_shift = 0, + }; + rc = crypto_op(pkt, &pkt, &ok, &op_params, + ODP_CRYPTO_OP_TYPE_BASIC, ODP_CRYPTO_OP_TYPE_BASIC); + CU_ASSERT(rc == 0); + if (rc) { + (void)odp_crypto_session_destroy(session.session); + return -1; + } + CU_ASSERT(ok); + + rc = odp_crypto_session_destroy(session.session); + CU_ASSERT(rc == 0); + + rc = odp_packet_copy_to_mem(pkt, 0, ref->length, ref->ciphertext); + CU_ASSERT(rc == 0); + + odp_packet_free(pkt); + return 0; +} + +typedef struct crypto_suite_t { + odp_cipher_alg_t cipher; + odp_auth_alg_t auth; + alg_order_t order; + const odp_crypto_cipher_capability_t *cipher_capa; + const odp_crypto_auth_capability_t *auth_capa; +} crypto_suite_t; + +/* + * Create test reference for combined auth & cipher by doing authentication + * and ciphering through separate ODP crypto operations. + */ +static int create_combined_ref(const crypto_suite_t *suite, + crypto_test_reference_t *ref, + const odp_packet_data_range_t *cipher_range, + const odp_packet_data_range_t *auth_range, + uint32_t digest_offset) +{ + uint32_t total_len; + int rc; + crypto_test_reference_t ref_cipher_only; + crypto_test_reference_t ref_auth_only; + crypto_test_reference_t *first_ref, *second_ref; + + total_len = cipher_range->offset + cipher_range->length; + if (auth_range->offset + auth_range->length > total_len) + total_len = auth_range->offset + auth_range->length; + if (digest_offset + suite->auth_capa->digest_len > total_len) + total_len = digest_offset + suite->auth_capa->digest_len; + + ref->cipher = suite->cipher; + ref->auth = suite->auth; + ref->cipher_key_length = suite->cipher_capa->key_len; + ref->cipher_iv_length = suite->cipher_capa->iv_len; + ref->auth_key_length = suite->auth_capa->key_len; + ref->auth_iv_length = suite->auth_capa->iv_len; + ref->digest_length = suite->auth_capa->digest_len; + ref->aad_length = 0; + ref->is_length_in_bits = false; + ref->length = total_len; + + if (ref->auth_key_length > MAX_KEY_LEN || + ref->auth_iv_length > MAX_IV_LEN || + total_len > MAX_DATA_LEN || + digest_offset + ref->digest_length > MAX_DATA_LEN) + CU_FAIL_FATAL("Internal error\n"); + + fill_with_pattern(ref->cipher_key, ref->cipher_key_length); + fill_with_pattern(ref->cipher_iv, ref->cipher_iv_length); + fill_with_pattern(ref->auth_key, ref->auth_key_length); + fill_with_pattern(ref->auth_iv, ref->auth_iv_length); + fill_with_pattern(ref->plaintext, ref->length); + memset(ref->plaintext + digest_offset, 0, ref->digest_length); + + ref_cipher_only = *ref; + ref_cipher_only.auth = ODP_AUTH_ALG_NULL; + ref_cipher_only.auth_key_length = 0; + ref_cipher_only.auth_iv_length = 0; + ref_cipher_only.aad_length = 0; + ref_cipher_only.digest_length = 0; + + ref_auth_only = *ref; + ref_auth_only.cipher = ODP_CIPHER_ALG_NULL; + ref_auth_only.cipher_key_length = 0; + ref_auth_only.cipher_iv_length = 0; + + if (suite->order == AUTH_CIPHERTEXT) { + first_ref = &ref_cipher_only; + second_ref = &ref_auth_only; + } else { + first_ref = &ref_auth_only; + second_ref = &ref_cipher_only; + } + rc = crypto_encode_ref(first_ref, + *cipher_range, *auth_range, + digest_offset); + if (rc) + return 1; + memcpy(second_ref->plaintext, first_ref->ciphertext, ref->length); + rc = crypto_encode_ref(second_ref, + *cipher_range, *auth_range, + digest_offset); + if (rc) + return 1; + memcpy(ref->ciphertext, second_ref->ciphertext, ref->length); + /* + * These may be encrypted bytes, but that is what alg_test wants if + * the digest is encrypted in the input packet. + */ + memcpy(ref->digest, second_ref->ciphertext + digest_offset, ref->digest_length); + + return 0; +} + +/* + * Return cipher range that is at least min_len bytes long, multiple of the + * block size and at least 3 blocks. + */ +static uint32_t get_cipher_range_len(uint32_t min_len) +{ +#define MAX_BLOCK_SIZE 16 + uint32_t bs = MAX_BLOCK_SIZE; + uint32_t len = 3 * bs; + + if (min_len > len) + len = ((min_len + bs - 1) / bs) * bs; + return len; +} + +typedef enum range_overlap_t { + SEPARATE_AUTH_AND_CIPHER_RANGES, + SAME_AUTH_AND_CIPHER_RANGE, + RANGES_PARTIALLY_OVERLAP, + AUTH_RANGE_IN_CIPHER_RANGE, + CIPHER_RANGE_IN_AUTH_RANGE, +} range_overlap_t; +#define NUM_RANGE_OVERLAPS 5 + +typedef enum hash_location_t { + HASH_SEPARATE, + HASH_IN_AUTH_RANGE_ONLY, + HASH_IN_CIPHER_RANGE_ONLY, + HASH_IN_AUTH_AND_CIPHER_RANGE, +} hash_location_t; +#define NUM_HASH_LOCATIONS 4 + +static int make_byte_ranges(range_overlap_t overlap, + hash_location_t hash_location, + uint32_t hash_len, + odp_packet_data_range_t *cipher_range, + odp_packet_data_range_t *auth_range, + uint32_t *digest_offset) +{ + const uint32_t padding = 5; /* padding between parts, could also be zero */ + const uint32_t nonzero_len = 3; + uint32_t c_offs = 0, c_len = 0, a_offs = 0, a_len = 0, digest_offs = 0; + + switch (overlap) { + case SEPARATE_AUTH_AND_CIPHER_RANGES: + switch (hash_location) { + case HASH_SEPARATE: + /* |cccc_aaaa_dd| */ + c_offs = 0; + c_len = get_cipher_range_len(nonzero_len); + a_offs = c_offs + c_len + padding; + a_len = nonzero_len; + digest_offs = a_offs + a_len + padding; + break; + case HASH_IN_AUTH_RANGE_ONLY: + /* + * |cccc_aaaa| + * | _dd_| + */ + c_offs = 0; + c_len = get_cipher_range_len(nonzero_len); + a_offs = c_offs + c_len + padding; + a_len = hash_len + 2 * padding; + digest_offs = a_offs + padding; + break; + case HASH_IN_CIPHER_RANGE_ONLY: + /* + * |cccc_aaaa| + * |_dd_ | + */ + c_offs = 0; + c_len = get_cipher_range_len(hash_len + 2 * padding); + a_offs = c_offs + c_len + padding; + a_len = nonzero_len; + digest_offs = c_offs + padding; + break; + case HASH_IN_AUTH_AND_CIPHER_RANGE: + /* not possible when ranges are separate */ + return 1; + } + break; + case SAME_AUTH_AND_CIPHER_RANGE: + c_offs = 0; + a_offs = 0; + switch (hash_location) { + case HASH_SEPARATE: + /* + * |cccc_dd| + * |aaaa | + */ + c_len = get_cipher_range_len(nonzero_len); + a_len = c_len; + digest_offs = c_len + padding; + break; + case HASH_IN_AUTH_RANGE_ONLY: + case HASH_IN_CIPHER_RANGE_ONLY: + /* not possible when ranges are the same */ + return 1; + case HASH_IN_AUTH_AND_CIPHER_RANGE: + /* + * |cccc| + * |aaaa| + * |_dd_| + */ + c_len = get_cipher_range_len(hash_len + 2 * padding); + a_len = c_len; + digest_offs = padding; + break; + } + break; + case RANGES_PARTIALLY_OVERLAP: + a_offs = 0; + switch (hash_location) { + case HASH_SEPARATE: + /* + * |aaaa | + * | cccc_dd| + */ + a_len = 2 * nonzero_len; + c_offs = nonzero_len; + c_len = get_cipher_range_len(a_len); + digest_offs = c_offs + c_len + padding; + break; + case HASH_IN_AUTH_RANGE_ONLY: + /* + * |aaaaa | + * |_dd_ccc| + */ + digest_offs = padding; + a_len = hash_len + 2 * padding + nonzero_len; + c_offs = hash_len + 2 * padding; + c_len = get_cipher_range_len(2 * nonzero_len); + break; + case HASH_IN_CIPHER_RANGE_ONLY: + /* PDCP case when AUTH_PLAINTEXT */ + /* + * |aaaadd| + * | ccccc| + */ + c_offs = nonzero_len; + c_len = get_cipher_range_len(nonzero_len + hash_len); + a_len = nonzero_len + c_len - hash_len; + digest_offs = c_offs + c_len - hash_len; + break; + case HASH_IN_AUTH_AND_CIPHER_RANGE: + /* + * |aaaaaa | + * | cccccc| + * |¨_dd_ | + */ + c_offs = nonzero_len; + c_len = get_cipher_range_len(hash_len + 2 * padding + nonzero_len); + a_len = c_offs + hash_len + 2 * padding; + digest_offs = c_offs + padding; + break; + } + break; + case AUTH_RANGE_IN_CIPHER_RANGE: + c_offs = 0; + a_offs = nonzero_len; + switch (hash_location) { + case HASH_SEPARATE: + /* + * |cccc_dd| + * | aa_ | + */ + a_len = nonzero_len; + c_len = get_cipher_range_len(a_offs + a_len + padding); + digest_offs = c_len + padding; + break; + case HASH_IN_AUTH_RANGE_ONLY: + /* not possible since auth range is in cipher range */ + return 1; + case HASH_IN_CIPHER_RANGE_ONLY: + /* + * |ccccccc| + * | aa_dd_| + */ + a_len = nonzero_len; + digest_offs = a_offs + a_len + padding; + c_len = get_cipher_range_len(digest_offs + hash_len + padding); + break; + case HASH_IN_AUTH_AND_CIPHER_RANGE: + /* + * |cccccc| + * | aaaa_| + * | _dd_ | + */ + a_len = /**/ hash_len + 2 * padding; + c_len = get_cipher_range_len(a_offs + a_len + padding); + digest_offs = a_offs + /**/ padding; + break; + } + break; + case CIPHER_RANGE_IN_AUTH_RANGE: + a_offs = 0; + c_offs = nonzero_len; + switch (hash_location) { + case HASH_SEPARATE: + /* + * |aaaa_dd| + * | cc_ | + */ + c_len = get_cipher_range_len(nonzero_len); + a_len = c_offs + c_len + padding; + digest_offs = a_len + padding; + break; + case HASH_IN_AUTH_RANGE_ONLY: + /* + * |aaaaaaa| + * | cc_dd_| + */ + c_len = get_cipher_range_len(nonzero_len); + digest_offs = c_offs + c_len + padding; + a_len = digest_offs + hash_len + padding; + break; + case HASH_IN_CIPHER_RANGE_ONLY: + /* not possible since cipher range is in auth range */ + return 1; + case HASH_IN_AUTH_AND_CIPHER_RANGE: + /* + * |aaaaaa| + * | cccc_| + * | _dd_ | + */ + c_len = get_cipher_range_len(hash_len + 2 * padding); + a_len = c_offs + c_len + padding; + digest_offs = c_offs + padding; + break; + } + break; + } + cipher_range->offset = c_offs; + cipher_range->length = c_len; + auth_range->offset = a_offs; + auth_range->length = a_len; + *digest_offset = digest_offs; + return 0; +} + +static void test_combo(const crypto_suite_t *suite, + range_overlap_t overlap, + hash_location_t location) +{ + int rc; + + odp_packet_data_range_t cipher_range = {0, 0}; + odp_packet_data_range_t auth_range = {0, 0}; + uint32_t digest_offset = 0; + crypto_test_reference_t ref; + + rc = make_byte_ranges(overlap, + location, + suite->auth_capa->digest_len, + &cipher_range, + &auth_range, + &digest_offset); + if (rc) + return; + + rc = create_combined_ref(suite, &ref, + &cipher_range, &auth_range, + digest_offset); + if (rc) + return; + + cipher_range.offset *= 8; + cipher_range.length *= 8; + auth_range.offset *= 8; + auth_range.length *= 8; + + alg_test(ODP_CRYPTO_OP_ENCODE, + suite->order, + &ref, + cipher_range, auth_range, + digest_offset, + suite->cipher_capa->bit_mode, + suite->auth_capa->bit_mode); + + alg_test(ODP_CRYPTO_OP_DECODE, + suite->order, + &ref, + cipher_range, auth_range, + digest_offset, + suite->cipher_capa->bit_mode, + suite->auth_capa->bit_mode); +} + +/* Iterate and test different cipher/auth range and hash locations */ +static void test_combo_ranges(const crypto_suite_t *suite) +{ + if (!full_test && suite->auth_capa->digest_len % 4 != 0) + return; + + for (int overlap = 0; overlap < NUM_RANGE_OVERLAPS; overlap++) + for (int location = 0; location < NUM_HASH_LOCATIONS; location++) { + if (suite->order == AUTH_CIPHERTEXT && + (location == HASH_IN_CIPHER_RANGE_ONLY || + location == HASH_IN_AUTH_AND_CIPHER_RANGE)) { + /* + * This combination ís not valid since + * the generated hash would overwrite some + * ciphertext, preventing decryption. + */ + continue; + } + test_combo(suite, overlap, location); + } +} + +/* Iterate and test all variants (key sizes etc) of an alg combo */ +static void test_combo_variants(odp_cipher_alg_t cipher, odp_auth_alg_t auth) +{ + int num, num_ciphers, num_auths; + + /* ODP API says AES-GMAC can be combined with the null cipher only */ + if (auth == ODP_AUTH_ALG_AES_GMAC && + cipher != ODP_CIPHER_ALG_NULL) + return; + + if (check_alg_support(cipher, auth) == ODP_TEST_INACTIVE) + return; + + printf(" %s, %s\n", + cipher_alg_name(cipher), + auth_alg_name(auth)); + + num_ciphers = odp_crypto_cipher_capability(cipher, NULL, 0); + num_auths = odp_crypto_auth_capability(auth, NULL, 0); + CU_ASSERT_FATAL(num_ciphers > 0); + CU_ASSERT_FATAL(num_auths > 0); + + odp_crypto_cipher_capability_t cipher_capa[num_ciphers]; + odp_crypto_auth_capability_t auth_capa[num_auths]; + + num = odp_crypto_cipher_capability(cipher, cipher_capa, num_ciphers); + CU_ASSERT(num == num_ciphers); + num = odp_crypto_auth_capability(auth, auth_capa, num_auths); + CU_ASSERT(num == num_auths); + + combo_warning_shown = 0; + + for (int n = 0; n < num_ciphers; n++) + for (int i = 0; i < num_auths; i++) { + crypto_suite_t suite = {.cipher = cipher, + .auth = auth, + .cipher_capa = &cipher_capa[n], + .auth_capa = &auth_capa[i]}; + suite.order = AUTH_PLAINTEXT; + test_combo_ranges(&suite); + suite.order = AUTH_CIPHERTEXT; + test_combo_ranges(&suite); + } +} + +static void test_all_combinations(void) +{ + if (suite_context.partial_test) { + printf("skipped "); + return; + } + + printf("\n"); + for (size_t n = 0; n < ODPH_ARRAY_SIZE(cipher_algs); n++) + for (size_t i = 0; i < ODPH_ARRAY_SIZE(auth_algs); i++) + test_combo_variants(cipher_algs[n], auth_algs[i]); +} + +static int check_alg_null(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_NULL); +} + +static void crypto_test_enc_alg_null(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + null_reference, + ODPH_ARRAY_SIZE(null_reference)); +} + +static void crypto_test_dec_alg_null(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + null_reference, + ODPH_ARRAY_SIZE(null_reference)); +} + +static int check_alg_3des_cbc(void) +{ + return check_alg_support(ODP_CIPHER_ALG_3DES_CBC, ODP_AUTH_ALG_NULL); +} + +static void crypto_test_enc_alg_3des_cbc(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + tdes_cbc_reference, + ODPH_ARRAY_SIZE(tdes_cbc_reference)); +} + +static void crypto_test_dec_alg_3des_cbc(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + tdes_cbc_reference, + ODPH_ARRAY_SIZE(tdes_cbc_reference)); +} + +static int check_alg_3des_ecb(void) +{ + return check_alg_support(ODP_CIPHER_ALG_3DES_ECB, ODP_AUTH_ALG_NULL); +} + +static void crypto_test_enc_alg_3des_ecb(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + tdes_ecb_reference, + ODPH_ARRAY_SIZE(tdes_ecb_reference)); +} + +static void crypto_test_dec_alg_3des_ecb(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + tdes_ecb_reference, + ODPH_ARRAY_SIZE(tdes_ecb_reference)); +} + +static int check_alg_chacha20_poly1305(void) +{ + return check_alg_support(ODP_CIPHER_ALG_CHACHA20_POLY1305, + ODP_AUTH_ALG_CHACHA20_POLY1305); +} + +static void crypto_test_enc_alg_chacha20_poly1305(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + chacha20_poly1305_reference, + ODPH_ARRAY_SIZE(chacha20_poly1305_reference)); +} + +static void crypto_test_dec_alg_chacha20_poly1305(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + chacha20_poly1305_reference, + ODPH_ARRAY_SIZE(chacha20_poly1305_reference)); +} + +static int check_alg_aes_gcm(void) +{ + return check_alg_support(ODP_CIPHER_ALG_AES_GCM, ODP_AUTH_ALG_AES_GCM); +} + +static void crypto_test_enc_alg_aes_gcm(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + aes_gcm_reference, + ODPH_ARRAY_SIZE(aes_gcm_reference)); +} + +static void crypto_test_dec_alg_aes_gcm(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + aes_gcm_reference, + ODPH_ARRAY_SIZE(aes_gcm_reference)); +} + +static int check_alg_aes_ccm(void) +{ + return check_alg_support(ODP_CIPHER_ALG_AES_CCM, ODP_AUTH_ALG_AES_CCM); +} + +static void crypto_test_enc_alg_aes_ccm(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + aes_ccm_reference, + ODPH_ARRAY_SIZE(aes_ccm_reference)); +} + +static void crypto_test_dec_alg_aes_ccm(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + aes_ccm_reference, + ODPH_ARRAY_SIZE(aes_ccm_reference)); +} + +static int check_alg_aes_cbc(void) +{ + return check_alg_support(ODP_CIPHER_ALG_AES_CBC, ODP_AUTH_ALG_NULL); +} + +static void crypto_test_enc_alg_aes_cbc(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + aes_cbc_reference, + ODPH_ARRAY_SIZE(aes_cbc_reference)); +} + +static void crypto_test_dec_alg_aes_cbc(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + aes_cbc_reference, + ODPH_ARRAY_SIZE(aes_cbc_reference)); +} + +static int check_alg_aes_ctr(void) +{ + return check_alg_support(ODP_CIPHER_ALG_AES_CTR, ODP_AUTH_ALG_NULL); +} + +static void crypto_test_enc_alg_aes_ctr(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + aes_ctr_reference, + ODPH_ARRAY_SIZE(aes_ctr_reference)); +} + +static void crypto_test_dec_alg_aes_ctr(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + aes_ctr_reference, + ODPH_ARRAY_SIZE(aes_ctr_reference)); +} + +static int check_alg_aes_ecb(void) +{ + return check_alg_support(ODP_CIPHER_ALG_AES_ECB, ODP_AUTH_ALG_NULL); +} + +static void crypto_test_enc_alg_aes_ecb(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + aes_ecb_reference, + ODPH_ARRAY_SIZE(aes_ecb_reference)); +} + +static void crypto_test_dec_alg_aes_ecb(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + aes_ecb_reference, + ODPH_ARRAY_SIZE(aes_ecb_reference)); +} + +static int check_alg_aes_cfb128(void) +{ + return check_alg_support(ODP_CIPHER_ALG_AES_CFB128, ODP_AUTH_ALG_NULL); +} + +static void crypto_test_enc_alg_aes_cfb128(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + aes_cfb128_reference, + ODPH_ARRAY_SIZE(aes_cfb128_reference)); +} + +static void crypto_test_dec_alg_aes_cfb128(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + aes_cfb128_reference, + ODPH_ARRAY_SIZE(aes_cfb128_reference)); +} + +static int check_alg_aes_xts(void) +{ + return check_alg_support(ODP_CIPHER_ALG_AES_XTS, ODP_AUTH_ALG_NULL); +} + +static void crypto_test_enc_alg_aes_xts(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + aes_xts_reference, + ODPH_ARRAY_SIZE(aes_xts_reference)); +} + +static void crypto_test_dec_alg_aes_xts(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + aes_xts_reference, + ODPH_ARRAY_SIZE(aes_xts_reference)); +} + +static int check_alg_kasumi_f8(void) +{ + return check_alg_support(ODP_CIPHER_ALG_KASUMI_F8, ODP_AUTH_ALG_NULL); +} + +static void crypto_test_enc_alg_kasumi_f8(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + kasumi_f8_reference, + ODPH_ARRAY_SIZE(kasumi_f8_reference)); +} + +static void crypto_test_dec_alg_kasumi_f8(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + kasumi_f8_reference, + ODPH_ARRAY_SIZE(kasumi_f8_reference)); +} + +static int check_alg_snow3g_uea2(void) +{ + return check_alg_support(ODP_CIPHER_ALG_SNOW3G_UEA2, ODP_AUTH_ALG_NULL); +} + +static void crypto_test_enc_alg_snow3g_uea2(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + snow3g_uea2_reference, + ODPH_ARRAY_SIZE(snow3g_uea2_reference)); +} + +static void crypto_test_dec_alg_snow3g_uea2(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + snow3g_uea2_reference, + ODPH_ARRAY_SIZE(snow3g_uea2_reference)); +} + +static int check_alg_aes_eea2(void) +{ + return check_alg_support(ODP_CIPHER_ALG_AES_EEA2, + ODP_AUTH_ALG_NULL); +} + +static void crypto_test_enc_alg_aes_eea2(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + aes_eea2_reference, + ODPH_ARRAY_SIZE(aes_eea2_reference)); +} + +static void crypto_test_dec_alg_aes_eea2(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + aes_eea2_reference, + ODPH_ARRAY_SIZE(aes_eea2_reference)); +} + +static int check_alg_zuc_eea3(void) +{ + return check_alg_support(ODP_CIPHER_ALG_ZUC_EEA3, ODP_AUTH_ALG_NULL); +} + +static void crypto_test_enc_alg_zuc_eea3(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + zuc_eea3_reference, + ODPH_ARRAY_SIZE(zuc_eea3_reference)); +} + +static void crypto_test_dec_alg_zuc_eea3(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + zuc_eea3_reference, + ODPH_ARRAY_SIZE(zuc_eea3_reference)); +} + +static int check_alg_hmac_md5(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_MD5_HMAC); +} + +static void crypto_test_gen_alg_hmac_md5(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + hmac_md5_reference, + ODPH_ARRAY_SIZE(hmac_md5_reference)); +} + +static void crypto_test_check_alg_hmac_md5(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + hmac_md5_reference, + ODPH_ARRAY_SIZE(hmac_md5_reference)); +} + +static int check_alg_hmac_sha1(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA1_HMAC); +} + +static void crypto_test_gen_alg_hmac_sha1(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + hmac_sha1_reference, + ODPH_ARRAY_SIZE(hmac_sha1_reference)); +} + +static void crypto_test_check_alg_hmac_sha1(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + hmac_sha1_reference, + ODPH_ARRAY_SIZE(hmac_sha1_reference)); +} + +static int check_alg_hmac_sha224(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA224_HMAC); +} + +static void crypto_test_gen_alg_hmac_sha224(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + hmac_sha224_reference, + ODPH_ARRAY_SIZE(hmac_sha224_reference)); +} + +static void crypto_test_check_alg_hmac_sha224(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + hmac_sha224_reference, + ODPH_ARRAY_SIZE(hmac_sha224_reference)); +} + +static int check_alg_hmac_sha256(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA256_HMAC); +} + +static void crypto_test_gen_alg_hmac_sha256(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + hmac_sha256_reference, + ODPH_ARRAY_SIZE(hmac_sha256_reference)); +} + +static void crypto_test_check_alg_hmac_sha256(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + hmac_sha256_reference, + ODPH_ARRAY_SIZE(hmac_sha256_reference)); +} + +static int check_alg_hmac_sha384(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA384_HMAC); +} + +static void crypto_test_gen_alg_hmac_sha384(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + hmac_sha384_reference, + ODPH_ARRAY_SIZE(hmac_sha384_reference)); +} + +static void crypto_test_check_alg_hmac_sha384(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + hmac_sha384_reference, + ODPH_ARRAY_SIZE(hmac_sha384_reference)); +} + +static int check_alg_hmac_sha512(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA512_HMAC); +} + +static void crypto_test_gen_alg_hmac_sha512(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + hmac_sha512_reference, + ODPH_ARRAY_SIZE(hmac_sha512_reference)); +} + +static void crypto_test_check_alg_hmac_sha512(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + hmac_sha512_reference, + ODPH_ARRAY_SIZE(hmac_sha512_reference)); +} + +static int check_alg_aes_xcbc(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_AES_XCBC_MAC); +} + +static void crypto_test_gen_alg_aes_xcbc(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + aes_xcbc_reference, + ODPH_ARRAY_SIZE(aes_xcbc_reference)); +} + +static void crypto_test_check_alg_aes_xcbc(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + aes_xcbc_reference, + ODPH_ARRAY_SIZE(aes_xcbc_reference)); +} + +static int check_alg_aes_gmac(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_AES_GMAC); +} + +static void crypto_test_gen_alg_aes_gmac(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + aes_gmac_reference, + ODPH_ARRAY_SIZE(aes_gmac_reference)); +} + +static void crypto_test_check_alg_aes_gmac(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + aes_gmac_reference, + ODPH_ARRAY_SIZE(aes_gmac_reference)); +} + +static int check_alg_aes_cmac(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_AES_CMAC); +} + +static void crypto_test_gen_alg_aes_cmac(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + aes_cmac_reference, + ODPH_ARRAY_SIZE(aes_cmac_reference)); +} + +static void crypto_test_check_alg_aes_cmac(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + aes_cmac_reference, + ODPH_ARRAY_SIZE(aes_cmac_reference)); +} + +static int check_alg_kasumi_f9(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_KASUMI_F9); +} + +static void crypto_test_gen_alg_kasumi_f9(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + kasumi_f9_reference, + ODPH_ARRAY_SIZE(kasumi_f9_reference)); +} + +static void crypto_test_check_alg_kasumi_f9(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + kasumi_f9_reference, + ODPH_ARRAY_SIZE(kasumi_f9_reference)); +} + +static int check_alg_snow3g_uia2(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SNOW3G_UIA2); +} + +static void crypto_test_gen_alg_snow3g_uia2(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + snow3g_uia2_reference, + ODPH_ARRAY_SIZE(snow3g_uia2_reference)); +} + +static void crypto_test_check_alg_snow3g_uia2(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + snow3g_uia2_reference, + ODPH_ARRAY_SIZE(snow3g_uia2_reference)); +} + +static int check_alg_aes_eia2(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_AES_EIA2); +} + +static void crypto_test_gen_alg_aes_eia2(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + aes_eia2_reference, + ODPH_ARRAY_SIZE(aes_eia2_reference)); +} + +static void crypto_test_check_alg_aes_eia2(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + aes_eia2_reference, + ODPH_ARRAY_SIZE(aes_eia2_reference)); +} + +static int check_alg_zuc_eia3(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_ZUC_EIA3); +} + +static void crypto_test_gen_alg_zuc_eia3(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + zuc_eia3_reference, + ODPH_ARRAY_SIZE(zuc_eia3_reference)); +} + +static void crypto_test_check_alg_zuc_eia3(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + zuc_eia3_reference, + ODPH_ARRAY_SIZE(zuc_eia3_reference)); +} + +static int check_alg_md5(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_MD5); +} + +static void crypto_test_gen_alg_md5(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + md5_reference, + ODPH_ARRAY_SIZE(md5_reference)); +} + +static void crypto_test_check_alg_md5(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + md5_reference, + ODPH_ARRAY_SIZE(md5_reference)); +} + +static int check_alg_sha1(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA1); +} + +static void crypto_test_gen_alg_sha1(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + sha1_reference, + ODPH_ARRAY_SIZE(sha1_reference)); +} + +static void crypto_test_check_alg_sha1(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + sha1_reference, + ODPH_ARRAY_SIZE(sha1_reference)); +} + +static int check_alg_sha224(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA224); +} + +static void crypto_test_gen_alg_sha224(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + sha224_reference, + ODPH_ARRAY_SIZE(sha224_reference)); +} + +static void crypto_test_check_alg_sha224(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + sha224_reference, + ODPH_ARRAY_SIZE(sha224_reference)); +} + +static int check_alg_sha256(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA256); +} + +static void crypto_test_gen_alg_sha256(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + sha256_reference, + ODPH_ARRAY_SIZE(sha256_reference)); +} + +static void crypto_test_check_alg_sha256(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + sha256_reference, + ODPH_ARRAY_SIZE(sha256_reference)); +} + +static int check_alg_sha384(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA384); +} + +static void crypto_test_gen_alg_sha384(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + sha384_reference, + ODPH_ARRAY_SIZE(sha384_reference)); +} + +static void crypto_test_check_alg_sha384(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + sha384_reference, + ODPH_ARRAY_SIZE(sha384_reference)); +} + +static int check_alg_sha512(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA512); +} + +static void crypto_test_gen_alg_sha512(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + sha512_reference, + ODPH_ARRAY_SIZE(sha512_reference)); +} + +static void crypto_test_check_alg_sha512(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + sha512_reference, + ODPH_ARRAY_SIZE(sha512_reference)); +} + +static odp_queue_t sched_compl_queue_create(void) +{ + odp_queue_param_t qparam; + + odp_queue_param_init(&qparam); + qparam.type = ODP_QUEUE_TYPE_SCHED; + qparam.sched.prio = odp_schedule_default_prio(); + qparam.sched.sync = ODP_SCHED_SYNC_PARALLEL; + qparam.sched.group = ODP_SCHED_GROUP_ALL; + + return odp_queue_create("crypto-out", &qparam); +} + +static odp_queue_t plain_compl_queue_create(void) +{ + return odp_queue_create("crypto-out", NULL); +} + +static odp_event_t sched_compl_queue_deq(void) +{ + return odp_schedule(NULL, ODP_SCHED_NO_WAIT); +} + +static odp_event_t plain_compl_queue_deq(void) +{ + return odp_queue_deq(suite_context.queue); +} + +static int partial_test_only(odp_crypto_op_mode_t op_mode, odp_queue_type_t q_type) +{ + odp_crypto_capability_t capa; + + if (full_test || odp_crypto_capability(&capa)) + return 0; + + if (!capa.async_mode) + return 0; + + if (op_mode == ODP_CRYPTO_SYNC) + return 1; + else if (q_type == ODP_QUEUE_TYPE_PLAIN && capa.queue_type_sched) + return 1; + + return 0; +} + +static int crypto_suite_packet_sync_init(void) +{ + suite_context.op_mode = ODP_CRYPTO_SYNC; + + suite_context.pool = odp_pool_lookup("packet_pool"); + if (suite_context.pool == ODP_POOL_INVALID) + return -1; + + suite_context.queue = ODP_QUEUE_INVALID; + suite_context.partial_test = partial_test_only(suite_context.op_mode, + ODP_QUEUE_TYPE_PLAIN); + return 0; +} + +static int crypto_suite_packet_async_plain_init(void) +{ + odp_queue_t out_queue; + + suite_context.op_mode = ODP_CRYPTO_ASYNC; + + suite_context.pool = odp_pool_lookup("packet_pool"); + if (suite_context.pool == ODP_POOL_INVALID) + return -1; + + out_queue = plain_compl_queue_create(); + if (ODP_QUEUE_INVALID == out_queue) { + ODPH_ERR("Crypto outq creation failed\n"); + return -1; + } + suite_context.queue = out_queue; + suite_context.q_type = ODP_QUEUE_TYPE_PLAIN; + suite_context.compl_queue_deq = plain_compl_queue_deq; + suite_context.partial_test = partial_test_only(suite_context.op_mode, + suite_context.q_type); + + return 0; +} + +static int crypto_suite_packet_async_sched_init(void) +{ + odp_queue_t out_queue; + + suite_context.op_mode = ODP_CRYPTO_ASYNC; + + suite_context.pool = odp_pool_lookup("packet_pool"); + if (suite_context.pool == ODP_POOL_INVALID) + return -1; + + out_queue = sched_compl_queue_create(); + if (ODP_QUEUE_INVALID == out_queue) { + ODPH_ERR("Crypto outq creation failed\n"); + return -1; + } + suite_context.queue = out_queue; + suite_context.q_type = ODP_QUEUE_TYPE_SCHED; + suite_context.compl_queue_deq = sched_compl_queue_deq; + suite_context.partial_test = partial_test_only(suite_context.op_mode, + suite_context.q_type); + + return 0; +} + +static int crypto_suite_term(void) +{ + if (ODP_QUEUE_INVALID != suite_context.queue) { + if (odp_queue_destroy(suite_context.queue)) + ODPH_ERR("Crypto outq destroy failed\n"); + } else { + ODPH_ERR("Crypto outq not found\n"); + } + + return odp_cunit_print_inactive(); +} + +odp_testinfo_t crypto_suite[] = { + ODP_TEST_INFO(test_capability), + ODP_TEST_INFO(test_default_values), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_null, + check_alg_null), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_null, + check_alg_null), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_3des_cbc, + check_alg_3des_cbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_3des_cbc, + check_alg_3des_cbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_3des_ecb, + check_alg_3des_ecb), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_3des_ecb, + check_alg_3des_ecb), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_cbc, + check_alg_aes_cbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_cbc, + check_alg_aes_cbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_ctr, + check_alg_aes_ctr), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_ctr, + check_alg_aes_ctr), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_ecb, + check_alg_aes_ecb), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_ecb, + check_alg_aes_ecb), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_cfb128, + check_alg_aes_cfb128), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_cfb128, + check_alg_aes_cfb128), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_xts, + check_alg_aes_xts), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_xts, + check_alg_aes_xts), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_kasumi_f8, + check_alg_kasumi_f8), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_kasumi_f8, + check_alg_kasumi_f8), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_snow3g_uea2, + check_alg_snow3g_uea2), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_snow3g_uea2, + check_alg_snow3g_uea2), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_eea2, + check_alg_aes_eea2), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_eea2, + check_alg_aes_eea2), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_zuc_eea3, + check_alg_zuc_eea3), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_zuc_eea3, + check_alg_zuc_eea3), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_gcm, + check_alg_aes_gcm), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_gcm, + check_alg_aes_gcm), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_ccm, + check_alg_aes_ccm), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_ccm, + check_alg_aes_ccm), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_chacha20_poly1305, + check_alg_chacha20_poly1305), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_chacha20_poly1305, + check_alg_chacha20_poly1305), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_md5, + check_alg_hmac_md5), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_md5, + check_alg_hmac_md5), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha1, + check_alg_hmac_sha1), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha1, + check_alg_hmac_sha1), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha224, + check_alg_hmac_sha224), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha224, + check_alg_hmac_sha224), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha256, + check_alg_hmac_sha256), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha256, + check_alg_hmac_sha256), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha384, + check_alg_hmac_sha384), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha384, + check_alg_hmac_sha384), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha512, + check_alg_hmac_sha512), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha512, + check_alg_hmac_sha512), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_aes_xcbc, + check_alg_aes_xcbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_aes_xcbc, + check_alg_aes_xcbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_aes_gmac, + check_alg_aes_gmac), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_aes_gmac, + check_alg_aes_gmac), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_aes_cmac, + check_alg_aes_cmac), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_aes_cmac, + check_alg_aes_cmac), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_kasumi_f9, + check_alg_kasumi_f9), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_kasumi_f9, + check_alg_kasumi_f9), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_snow3g_uia2, + check_alg_snow3g_uia2), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_snow3g_uia2, + check_alg_snow3g_uia2), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_aes_eia2, + check_alg_aes_eia2), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_aes_eia2, + check_alg_aes_eia2), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_zuc_eia3, + check_alg_zuc_eia3), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_zuc_eia3, + check_alg_zuc_eia3), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_md5, + check_alg_md5), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_md5, + check_alg_md5), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_sha1, + check_alg_sha1), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_sha1, + check_alg_sha1), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_sha224, + check_alg_sha224), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_sha224, + check_alg_sha224), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_sha256, + check_alg_sha256), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_sha256, + check_alg_sha256), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_sha384, + check_alg_sha384), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_sha384, + check_alg_sha384), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_sha512, + check_alg_sha512), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_sha512, + check_alg_sha512), + ODP_TEST_INFO(test_auth_hashes_in_auth_range), + ODP_TEST_INFO(test_all_combinations), + ODP_TEST_INFO_NULL, +}; + +odp_suiteinfo_t crypto_suites[] = { + {"odp_crypto_packet_sync_inp", crypto_suite_packet_sync_init, + NULL, crypto_suite}, + {"odp_crypto_packet_async_plain_inp", + crypto_suite_packet_async_plain_init, + crypto_suite_term, crypto_suite}, + {"odp_crypto_packet_async_sched_inp", + crypto_suite_packet_async_sched_init, + crypto_suite_term, crypto_suite}, + ODP_SUITE_INFO_NULL, +}; + +static int crypto_init(odp_instance_t *inst) +{ + odp_pool_param_t params; + odp_pool_t pool; + odp_pool_capability_t pool_capa; + odp_init_t init_param; + odph_helper_options_t helper_options; + + if (odph_options(&helper_options)) { + ODPH_ERR("odph_options() failed\n"); + return -1; + } + + odp_init_param_init(&init_param); + init_param.mem_model = helper_options.mem_model; + + if (0 != odp_init_global(inst, &init_param, NULL)) { + ODPH_ERR("odp_init_global() failed\n"); + return -1; + } + + if (0 != odp_init_local(*inst, ODP_THREAD_CONTROL)) { + ODPH_ERR("odp_init_local() failed\n"); + return -1; + } + + /* Configure the scheduler. */ + if (odp_schedule_config(NULL)) { + ODPH_ERR("odp_schedule_config() failed\n"); + return -1; + } + + if (odp_pool_capability(&pool_capa) < 0) { + ODPH_ERR("odp_pool_capability() failed\n"); + return -1; + } + + odp_pool_param_init(¶ms); + params.pkt.seg_len = PKT_POOL_LEN; + params.pkt.len = PKT_POOL_LEN; + params.pkt.num = PKT_POOL_NUM; + params.type = ODP_POOL_PACKET; + + /* + * Let's have a user area so that we can check that its + * content gets copied along with other metadata when needed. + */ + if (pool_capa.pkt.max_uarea_size >= UAREA_SIZE) + params.pkt.uarea_size = UAREA_SIZE; + else + printf("Warning: could not request packet user area\n"); + + if (pool_capa.pkt.max_seg_len && + PKT_POOL_LEN > pool_capa.pkt.max_seg_len) { + ODPH_ERR("Warning: small packet segment length\n"); + params.pkt.seg_len = pool_capa.pkt.max_seg_len; + } + + if (pool_capa.pkt.max_len && + PKT_POOL_LEN > pool_capa.pkt.max_len) { + ODPH_ERR("Pool max packet length too small\n"); + return -1; + } + + pool = odp_pool_create("packet_pool", ¶ms); + + if (ODP_POOL_INVALID == pool) { + ODPH_ERR("Packet pool creation failed\n"); + return -1; + } + + return 0; +} + +static int crypto_term(odp_instance_t inst) +{ + odp_pool_t pool; + + pool = odp_pool_lookup("packet_pool"); + if (ODP_POOL_INVALID != pool) { + if (odp_pool_destroy(pool)) + ODPH_ERR("Packet pool destroy failed\n"); + } else { + ODPH_ERR("Packet pool not found\n"); + } + + if (0 != odp_term_local()) { + ODPH_ERR("odp_term_local() failed\n"); + return -1; + } + + if (0 != odp_term_global(inst)) { + ODPH_ERR("odp_term_global() failed\n"); + return -1; + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret; + char *env = getenv("FULL_TEST"); + + if (env && strcmp(env, "0")) + full_test = 1; + printf("Test mode: %s\n", full_test ? "full" : "partial"); + + /* parse common options: */ + if (odp_cunit_parse_options(&argc, argv)) + return -1; + + odp_cunit_register_global_init(crypto_init); + odp_cunit_register_global_term(crypto_term); + + ret = odp_cunit_register(crypto_suites); + + if (ret == 0) + ret = odp_cunit_run(); + + return ret; +} |