diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
commit | e6918187568dbd01842d8d1d2c808ce16a894239 (patch) | |
tree | 64f88b554b444a49f656b6c656111a145cbbaa28 /src/spdk/intel-ipsec-mb/LibTestApp/api_test.c | |
parent | Initial commit. (diff) | |
download | ceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip |
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/spdk/intel-ipsec-mb/LibTestApp/api_test.c')
-rw-r--r-- | src/spdk/intel-ipsec-mb/LibTestApp/api_test.c | 612 |
1 files changed, 612 insertions, 0 deletions
diff --git a/src/spdk/intel-ipsec-mb/LibTestApp/api_test.c b/src/spdk/intel-ipsec-mb/LibTestApp/api_test.c new file mode 100644 index 000000000..ce5c20d23 --- /dev/null +++ b/src/spdk/intel-ipsec-mb/LibTestApp/api_test.c @@ -0,0 +1,612 @@ +/***************************************************************************** + Copyright (c) 2018-2019, Intel Corporation + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <intel-ipsec-mb.h> +#include "gcm_ctr_vectors_test.h" + +int api_test(const enum arch_type arch, struct MB_MGR *mb_mgr); + +/* + * @brief Performs JOB API behavior tests + */ +static int +test_job_api(struct MB_MGR *mb_mgr) +{ + struct JOB_AES_HMAC *job, *job_next; + + printf("JOB API behavior test:\n"); + + /* ======== test 1 */ + job = IMB_GET_NEXT_JOB(mb_mgr); + if (job == NULL) { + printf("%s: test 1, unexpected job = NULL\n", __func__); + return 1; + } + printf("."); + + /* ======== test 2 : invalid cipher and mac */ + memset(job, 0, sizeof(*job)); + job_next = IMB_SUBMIT_JOB(mb_mgr); + if (job != job_next) { + /* Invalid job should be returned straight away */ + printf("%s: test 2, unexpected job != job_next\n", __func__); + return 1; + } + printf("."); + if (job_next->status != STS_INVALID_ARGS) { + /* Invalid job is returned, and status should be INVALID_ARGS */ + printf("%s: test 2, unexpected job->status != " + "STS_INVALID_ARGS\n", __func__); + return 1; + } + printf("."); + + job_next = IMB_GET_NEXT_JOB(mb_mgr); + if (job == job_next) { + /* get next job should point to a new job slot */ + printf("%s: test 2, unexpected job == get_next_job()\n", + __func__); + return 1; + } + printf("."); + + job = IMB_GET_COMPLETED_JOB(mb_mgr); + if (job) { + /* there should not be any completed jobs left */ + printf("%s: test 2, unexpected completed job\n", + __func__); + return 1; + } + printf("."); + + /* clean up */ + while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL) + ; + + printf("\n"); + return 0; +} + +/* + * @brief Dummy function for custom hash and cipher modes + */ +static int dummy_cipher_hash_func(struct JOB_AES_HMAC *job) +{ + (void) job; + return 0; +} + +/* + * @brief Fills in job structure with valid settings + */ +static void +fill_in_job(struct JOB_AES_HMAC *job, + const JOB_CIPHER_MODE cipher_mode, + const JOB_CIPHER_DIRECTION cipher_direction, + const JOB_HASH_ALG hash_alg, + const JOB_CHAIN_ORDER chain_order) +{ + const uint64_t tag_len_tab[] = { + 0, /* INVALID selection */ + 12, /* SHA1 */ + 14, /* SHA_224 */ + 16, /* SHA_256 */ + 24, /* SHA_384 */ + 32, /* SHA_512 */ + 12, /* AES_XCBC */ + 12, /* MD5 */ + 0, /* NULL_HASH */ + 16, /* AES_GMAC */ + 0, /* CUSTOM HASH */ + 16, /* AES_CCM */ + 16, /* AES_CMAC */ + 20, /* PLAIN_SHA1 */ + 28, /* PLAIN_SHA_224 */ + 32, /* PLAIN_SHA_256 */ + 48, /* PLAIN_SHA_384 */ + 64, /* PLAIN_SHA_512 */ + }; + static DECLARE_ALIGNED(uint8_t dust_bin[2048], 64); + static void *dust_keys[3] = {dust_bin, dust_bin, dust_bin}; + const uint64_t msg_len_to_cipher = 32; + const uint64_t msg_len_to_hash = 48; + + if (job == NULL) + return; + + memset(job, 0, sizeof(*job)); + job->chain_order = chain_order; + job->hash_alg = hash_alg; + job->cipher_mode = cipher_mode; + job->cipher_direction = cipher_direction; + + switch (job->cipher_mode) { + case CBC: + if (job->cipher_direction == ENCRYPT) + job->aes_enc_key_expanded = dust_bin; + else + job->aes_dec_key_expanded = dust_bin; + job->aes_key_len_in_bytes = UINT64_C(16); + job->msg_len_to_cipher_in_bytes = msg_len_to_cipher; + job->iv = dust_bin; + job->iv_len_in_bytes = UINT64_C(16); + break; + case CNTR: + job->aes_enc_key_expanded = dust_bin; + job->aes_key_len_in_bytes = UINT64_C(16); + job->msg_len_to_cipher_in_bytes = msg_len_to_cipher; + job->iv = dust_bin; + job->iv_len_in_bytes = UINT64_C(16); + break; + case NULL_CIPHER: + break; + case DOCSIS_SEC_BPI: + /* it has to be set regardless of direction (AES-CFB) */ + job->aes_enc_key_expanded = dust_bin; + if (job->cipher_direction == DECRYPT) + job->aes_dec_key_expanded = dust_bin; + job->aes_key_len_in_bytes = UINT64_C(16); + job->msg_len_to_cipher_in_bytes = msg_len_to_cipher; + job->iv = dust_bin; + job->iv_len_in_bytes = UINT64_C(16); + break; + case GCM: + if (job->cipher_direction == ENCRYPT) + job->aes_enc_key_expanded = dust_bin; + else + job->aes_dec_key_expanded = dust_bin; + job->aes_key_len_in_bytes = UINT64_C(16); + job->msg_len_to_cipher_in_bytes = msg_len_to_cipher; + job->iv = dust_bin; + job->iv_len_in_bytes = UINT64_C(12); + break; + case CUSTOM_CIPHER: + job->cipher_func = dummy_cipher_hash_func; + break; + case DES: + if (job->cipher_direction == ENCRYPT) + job->aes_enc_key_expanded = dust_bin; + else + job->aes_dec_key_expanded = dust_bin; + job->aes_key_len_in_bytes = UINT64_C(8); + job->msg_len_to_cipher_in_bytes = msg_len_to_cipher; + job->iv = dust_bin; + job->iv_len_in_bytes = UINT64_C(8); + break; + case DOCSIS_DES: + if (job->cipher_direction == ENCRYPT) + job->aes_enc_key_expanded = dust_bin; + else + job->aes_dec_key_expanded = dust_bin; + job->aes_key_len_in_bytes = UINT64_C(8); + job->msg_len_to_cipher_in_bytes = msg_len_to_cipher; + job->iv = dust_bin; + job->iv_len_in_bytes = UINT64_C(8); + break; + case CCM: + /* AES-CTR and CBC-MAC use only encryption keys */ + job->aes_enc_key_expanded = dust_bin; + job->aes_key_len_in_bytes = UINT64_C(16); + job->iv = dust_bin; + job->iv_len_in_bytes = UINT64_C(13); + job->msg_len_to_cipher_in_bytes = msg_len_to_cipher; + break; + case DES3: + if (job->cipher_direction == ENCRYPT) + job->aes_enc_key_expanded = dust_keys; + else + job->aes_dec_key_expanded = dust_keys; + job->aes_key_len_in_bytes = UINT64_C(24); + job->msg_len_to_cipher_in_bytes = msg_len_to_cipher; + job->iv = dust_bin; + job->iv_len_in_bytes = UINT64_C(8); + break; + default: + break; + } + + switch (job->hash_alg) { + case SHA1: + case AES_XCBC: + case MD5: + case SHA_224: + case SHA_256: + case SHA_384: + case SHA_512: + case PLAIN_SHA1: + case PLAIN_SHA_224: + case PLAIN_SHA_256: + case PLAIN_SHA_384: + case PLAIN_SHA_512: + job->msg_len_to_hash_in_bytes = msg_len_to_hash; + job->auth_tag_output = dust_bin; + job->auth_tag_output_len_in_bytes = tag_len_tab[job->hash_alg]; + break; + case NULL_HASH: + break; + case CUSTOM_HASH: + job->hash_func = dummy_cipher_hash_func; + break; + case AES_GMAC: + job->msg_len_to_hash_in_bytes = msg_len_to_hash; + job->auth_tag_output = dust_bin; + job->auth_tag_output_len_in_bytes = tag_len_tab[job->hash_alg]; + job->u.GCM.aad = dust_bin; + job->u.GCM.aad_len_in_bytes = 16; + break; + case AES_CCM: + job->u.CCM.aad = dust_bin; + job->u.CCM.aad_len_in_bytes = 16; + job->msg_len_to_hash_in_bytes = job->msg_len_to_cipher_in_bytes; + job->hash_start_src_offset_in_bytes = + job->cipher_start_src_offset_in_bytes; + job->auth_tag_output = dust_bin; + job->auth_tag_output_len_in_bytes = tag_len_tab[job->hash_alg]; + break; + case AES_CMAC: + job->u.CMAC._key_expanded = dust_bin; + job->u.CMAC._skey1 = dust_bin; + job->u.CMAC._skey2 = dust_bin; + job->msg_len_to_hash_in_bytes = msg_len_to_hash; + job->auth_tag_output = dust_bin; + job->auth_tag_output_len_in_bytes = tag_len_tab[job->hash_alg]; + break; + default: + break; + } +} + +/* + * @brief Submits \a job to \a mb_mgr and verifies it failed with + * invalid arguments status. + */ +static int +is_submit_invalid(struct MB_MGR *mb_mgr, const struct JOB_AES_HMAC *job, + const int test_num) +{ + struct JOB_AES_HMAC *mb_job = NULL, *job_ret = NULL; + + /* get next available job slot */ + mb_job = IMB_GET_NEXT_JOB(mb_mgr); + if (mb_job == NULL) { + printf("%s : test %d, hash_alg %d, chain_order %d, " + "cipher_dir %d, cipher_mode %d : " + "unexpected get_next_job() == NULL\n", + __func__, test_num, (int) job->hash_alg, + (int) job->chain_order, (int) job->cipher_direction, + (int) job->cipher_mode); + return 0; + } + + /* copy template job into available slot */ + *mb_job = *job; + + /* submit the job for processing */ + job_ret = IMB_SUBMIT_JOB(mb_mgr); + + /* + * Returned job can be a previously submitted job or NULL + * (if MB_MGR was empty). + * Let's keep asking for completed jobs until we get the submitted job. + */ + while (job_ret != mb_job) { + job_ret = IMB_GET_COMPLETED_JOB(mb_mgr); + if (job_ret == NULL) { + printf("%s : test %d, hash_alg %d, chain_order %d, " + "cipher_dir %d, cipher_mode %d : " + "unexpected job_ret == NULL " + "(most likely job passed checks and got " + "submitted)\n", + __func__, test_num, (int) job->hash_alg, + (int) job->chain_order, + (int) job->cipher_direction, + (int) job->cipher_mode); + return 0; + } + } + + if (job_ret->status != STS_INVALID_ARGS) { + printf("%s : test %d, hash_alg %d, chain_order %d, " + "cipher_dir %d, cipher_mode %d : " + "unexpected job->status %d != STS_INVALID_ARGS\n", + __func__, test_num, (int) job_ret->hash_alg, + (int) job_ret->chain_order, + (int) job_ret->cipher_direction, + (int) job_ret->cipher_mode, (int) job_ret->status); + return 0; + } + + return 1; +} + +/* + * @brief Tests invalid settings for MAC modes + */ +static int +test_job_invalid_mac_args(struct MB_MGR *mb_mgr) +{ + JOB_HASH_ALG hash; + JOB_CIPHER_DIRECTION dir; + const JOB_CIPHER_MODE cipher = NULL_CIPHER; + JOB_CHAIN_ORDER order; + struct JOB_AES_HMAC template_job; + struct JOB_AES_HMAC *job; + + printf("Invalid JOB MAC arguments test:\n"); + + /* prep */ + while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL) + ; + + /* ======== test 100 + * SRC = NULL + */ + for (order = CIPHER_HASH; order <= HASH_CIPHER; order++) + for (dir = ENCRYPT; dir <= DECRYPT; dir++) + for (hash = SHA1; hash <= PLAIN_SHA_512; hash++) { + if (hash == NULL_HASH || + hash == CUSTOM_HASH) + continue; + + fill_in_job(&template_job, cipher, dir, + hash, order); + template_job.src = NULL; + if (!is_submit_invalid(mb_mgr, &template_job, + 100)) + return 1; + printf("."); + } + + /* ======== test 101 + * AUTH_TAG_OUTPUT = NULL + */ + for (order = CIPHER_HASH; order <= HASH_CIPHER; order++) + for (dir = ENCRYPT; dir <= DECRYPT; dir++) + for (hash = SHA1; hash <= PLAIN_SHA_512; hash++) { + if (hash == NULL_HASH || + hash == CUSTOM_HASH) + continue; + + fill_in_job(&template_job, cipher, dir, + hash, order); + template_job.auth_tag_output = NULL; + if (!is_submit_invalid(mb_mgr, &template_job, + 101)) + return 1; + printf("."); + } + + /* ======== test 102 + * AUTH_TAG_OUTPUT_LEN = 0 + */ + for (order = CIPHER_HASH; order <= HASH_CIPHER; order++) + for (dir = ENCRYPT; dir <= DECRYPT; dir++) + for (hash = SHA1; hash <= PLAIN_SHA_512; hash++) { + if (hash == NULL_HASH || + hash == CUSTOM_HASH) + continue; + + fill_in_job(&template_job, cipher, dir, + hash, order); + template_job.auth_tag_output_len_in_bytes = 0; + if (!is_submit_invalid(mb_mgr, &template_job, + 102)) + return 1; + printf("."); + } + + /* clean up */ + while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL) + ; + + printf("\n"); + return 0; +} + +/* + * @brief Tests invalid settings for CIPHER modes + */ +static int +test_job_invalid_cipher_args(struct MB_MGR *mb_mgr) +{ + const JOB_HASH_ALG hash = NULL_HASH; + JOB_CIPHER_DIRECTION dir; + JOB_CIPHER_MODE cipher; + JOB_CHAIN_ORDER order; + struct JOB_AES_HMAC template_job; + struct JOB_AES_HMAC *job; + + printf("Invalid JOB CIPHER arguments test:\n"); + + /* prep */ + while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL) + ; + + /* ======== test 200 + * SRC = NULL + */ + for (order = CIPHER_HASH; order <= HASH_CIPHER; order++) + for (dir = ENCRYPT; dir <= DECRYPT; dir++) + for (cipher = CBC; cipher <= DES3; cipher++) { + if (cipher == NULL_CIPHER || + cipher == CUSTOM_CIPHER) + continue; + + fill_in_job(&template_job, cipher, dir, + hash, order); + template_job.src = NULL; + if (!is_submit_invalid(mb_mgr, &template_job, + 200)) + return 1; + printf("."); + } + + /* ======== test 201 + * DST = NULL + */ + for (order = CIPHER_HASH; order <= HASH_CIPHER; order++) + for (dir = ENCRYPT; dir <= DECRYPT; dir++) + for (cipher = CBC; cipher <= DES3; cipher++) { + if (cipher == NULL_CIPHER || + cipher == CUSTOM_CIPHER) + continue; + + fill_in_job(&template_job, cipher, dir, + hash, order); + template_job.dst = NULL; + if (!is_submit_invalid(mb_mgr, &template_job, + 201)) + return 1; + printf("."); + } + + /* ======== test 202 + * IV = NULL + */ + for (order = CIPHER_HASH; order <= HASH_CIPHER; order++) + for (dir = ENCRYPT; dir <= DECRYPT; dir++) + for (cipher = CBC; cipher <= DES3; cipher++) { + if (cipher == NULL_CIPHER || + cipher == CUSTOM_CIPHER) + continue; + + fill_in_job(&template_job, cipher, dir, + hash, order); + template_job.iv = NULL; + if (!is_submit_invalid(mb_mgr, &template_job, + 202)) + return 1; + printf("."); + } + + /* ======== test 203 (encrypt) + * AES_ENC_KEY_EXPANDED = NULL + * AES_DEC_KEY_EXPANDED = NULL + */ + for (order = CIPHER_HASH; order <= HASH_CIPHER; order++) + for (cipher = CBC; cipher <= DES3; cipher++) { + fill_in_job(&template_job, cipher, ENCRYPT, + hash, order); + switch (cipher) { + case CBC: + case CNTR: + case DOCSIS_SEC_BPI: + case GCM: + case DES: + case DOCSIS_DES: + case CCM: + case DES3: + template_job.aes_enc_key_expanded = NULL; + if (!is_submit_invalid(mb_mgr, &template_job, + 203)) + return 1; + break; + case NULL_CIPHER: + case CUSTOM_CIPHER: + default: + break; + } + printf("."); + } + + /* ======== test 204 (decrypt) + * AES_ENC_KEY_EXPANDED = NULL + * AES_DEC_KEY_EXPANDED = NULL + */ + for (order = CIPHER_HASH; order <= HASH_CIPHER; order++) + for (cipher = CBC; cipher <= DES3; cipher++) { + fill_in_job(&template_job, cipher, DECRYPT, + hash, order); + switch (cipher) { + case GCM: + case CBC: + case DES: + case DES3: + case DOCSIS_DES: + template_job.aes_dec_key_expanded = NULL; + if (!is_submit_invalid(mb_mgr, &template_job, + 204)) + return 1; + break; + case CNTR: + case CCM: + template_job.aes_enc_key_expanded = NULL; + if (!is_submit_invalid(mb_mgr, &template_job, + 204)) + return 1; + break; + case DOCSIS_SEC_BPI: + template_job.aes_enc_key_expanded = NULL; + if (!is_submit_invalid(mb_mgr, &template_job, + 204)) + return 1; + template_job.aes_enc_key_expanded = + template_job.aes_dec_key_expanded; + template_job.aes_dec_key_expanded = NULL; + if (!is_submit_invalid(mb_mgr, &template_job, + 204)) + return 1; + break; + case NULL_CIPHER: + case CUSTOM_CIPHER: + default: + break; + } + printf("."); + } + + /* clean up */ + while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL) + ; + + printf("\n"); + return 0; +} + +int +api_test(const enum arch_type arch, struct MB_MGR *mb_mgr) +{ + int errors = 0; + + (void) arch; /* unused */ + + errors += test_job_api(mb_mgr); + errors += test_job_invalid_mac_args(mb_mgr); + errors += test_job_invalid_cipher_args(mb_mgr); + + if (0 == errors) + printf("...Pass\n"); + else + printf("...Fail\n"); + + return errors; +} |