2025-05-10 21:49:39 +08:00

502 lines
12 KiB
C

/*
* Copyright (c) 2022 Rockchip Electronics Co. Ltd.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "rkcrypto_core.h"
#include "rkcrypto_mem.h"
#include "cmode_adapter.h"
#include "test_ae.h"
#include "test_utils.h"
#define DATA_BUTT 0xFFFFFFFF
#define TEST_DATA_MAX (1024 * 1024)
#define TEST_AAD_MAX (1 * 1024)
struct test_ae_item {
uint32_t algo[2];
uint32_t modes[RK_CIPHER_MODE_MAX];
uint32_t key_lens[3];
uint32_t data_lens[3];
uint32_t aad_lens[3];
};
static struct test_ae_item test_item_tbl[] = {
{
.algo = {RK_ALGO_AES, RK_ALGO_SM4},
.modes = {
RK_CIPHER_MODE_GCM,
DATA_BUTT,
},
.key_lens = {16, 24, 32},
.data_lens = {256, 32 * 1024, TEST_DATA_MAX},
.aad_lens = {20, 256, TEST_AAD_MAX},
},
};
static RK_RES test_ae_item_virt(const struct test_ae_item *item, int verbose)
{
RK_RES res = RK_CRYPTO_ERR_GENERIC;
uint32_t h, i, k, l, n;
rk_handle handle = 0;
rk_ae_config ae_cfg;
uint8_t *plain = NULL, *ae_soft = NULL, *ae_hard = NULL, *aad = NULL;
uint8_t iv_tmp[32];
uint32_t algo = 0, mode = 0, key_len, iv_len, data_len, aad_len, operation;
uint32_t tag_len = 16;
uint8_t tag_hard[16], tag_soft[16];
size_t page_size = getpagesize();
if (posix_memalign((void *)&plain, page_size, TEST_DATA_MAX) || !plain) {
printf("plain malloc %dByte error!\n", TEST_DATA_MAX);
goto exit;
}
if (posix_memalign((void *)&ae_soft, page_size, TEST_DATA_MAX) || !ae_soft) {
printf("ae_soft malloc %dByte error!\n", TEST_DATA_MAX);
goto exit;
}
if (posix_memalign((void *)&ae_hard, page_size, TEST_DATA_MAX) || !ae_hard) {
printf("ae_hard malloc %dByte error!\n", TEST_DATA_MAX);
goto exit;
}
if (posix_memalign((void *)&aad, page_size, TEST_AAD_MAX) || !aad) {
printf("aad malloc %dByte error!\n", TEST_AAD_MAX);
goto exit;
}
iv_len = 12;
for (h = 0; h < ARRAY_SIZE(item->algo); h++) {
algo = item->algo[h];
for (i = 0; i < ARRAY_SIZE(item->modes); i++) {
mode = item->modes[i];
if (mode == DATA_BUTT)
break;
for (k = 0; k < ARRAY_SIZE(item->key_lens); k++) {
key_len = item->key_lens[k];
if (algo == RK_ALGO_SM4 && key_len !=16)
continue;
for (l = 0; l < ARRAY_SIZE(item->data_lens); l++) {
data_len = item->data_lens[l];
test_get_rng(plain, data_len);
for (n = 0; n < ARRAY_SIZE(item->aad_lens); n++) {
aad_len = item->aad_lens[n];
memset(ae_soft, 0x00, data_len);
memset(ae_hard, 0x00, data_len);
memset(tag_hard, 0x00, sizeof(tag_hard));
memset(tag_soft, 0x00, sizeof(tag_soft));
/* encryption */
operation = RK_OP_CIPHER_ENC;
memset(&ae_cfg, 0x00, sizeof(ae_cfg));
ae_cfg.algo = algo;
ae_cfg.mode = mode;
ae_cfg.operation = operation;
ae_cfg.key_len = key_len;
ae_cfg.iv_len = iv_len;
ae_cfg.aad_len = aad_len;
ae_cfg.tag_len = tag_len;
test_get_rng(ae_cfg.key, key_len);
test_get_rng(ae_cfg.iv, iv_len);
test_get_rng(aad, aad_len);
memcpy(iv_tmp, ae_cfg.iv, iv_len);
res = rk_ae_init(&ae_cfg, &handle);
if (res) {
if (res != RK_CRYPTO_ERR_NOT_SUPPORTED) {
printf("rk_ae_init error[%x]\n", res);
goto exit;
}
if (verbose)
printf("virt:\t[%s-%u]\t%s\t%s\tN/A\n",
test_algo_name(algo), key_len * 8,
test_mode_name(mode),
test_op_name(operation));
res = RK_CRYPTO_SUCCESS;
continue;
}
if (is_no_multi_blocksize(mode))
data_len = data_len - 3;
res = rk_ae_set_aad_virt(handle, aad);
if (res) {
rk_ae_final(handle);
printf("rk_ae_set_aad_virt error[%x]\n", res);
goto exit;
}
res = rk_ae_crypt_virt(handle, plain, ae_hard, data_len, tag_hard);
if (res) {
rk_ae_final(handle);
printf("rk_ae_crypt_virt error[%x]\n", res);
goto exit;
}
rk_ae_final(handle);
res = soft_ae(algo, mode, operation,
ae_cfg.key, ae_cfg.key_len, iv_tmp, iv_len,
aad, ae_cfg.aad_len, ae_cfg.tag_len,
plain, data_len, ae_soft, tag_soft);
if (res) {
printf("soft_ae error[%x]\n", res);
goto exit;
}
/* Verify the result */
if (memcmp(ae_hard, ae_soft, data_len) != 0) {
printf("rkcrypto_test_ae_virt compare data failed.\n");
res = RK_CRYPTO_ERR_GENERIC;
goto exit;
}
if (memcmp(tag_hard, tag_soft, ae_cfg.tag_len) != 0) {
printf("rkcrypto_test_ae_virt compare tag failed.\n");
res = RK_CRYPTO_ERR_GENERIC;
goto exit;
}
if (verbose)
printf("virt:\t[%s-%u]\t%s\t%s\tPASS\n",
test_algo_name(algo), key_len * 8,
test_mode_name(mode), test_op_name(operation));
/* decryption */
operation = RK_OP_CIPHER_DEC;
ae_cfg.operation = operation;
memcpy(ae_cfg.iv, iv_tmp, iv_len);
res = rk_ae_init(&ae_cfg, &handle);
if (res) {
if (res != RK_CRYPTO_ERR_NOT_SUPPORTED) {
printf("rk_ae_init error[%x]\n", res);
goto exit;
}
if (verbose)
printf("virt:\t[%s-%u]\t%s\t%s\tN/A\n",
test_algo_name(algo), key_len * 8,
test_mode_name(mode),
test_op_name(operation));
res = RK_CRYPTO_SUCCESS;
continue;
}
res = rk_ae_set_aad_virt(handle, aad);
if (res) {
rk_ae_final(handle);
printf("rk_ae_set_aad_virt error[%x]\n", res);
goto exit;
}
res = rk_ae_crypt_virt(handle, ae_hard, ae_hard, data_len, tag_hard);
if (res) {
rk_ae_final(handle);
printf("rk_ae_crypt_virt error[%x]\n", res);
goto exit;
}
rk_ae_final(handle);
/* Verify the result */
if (memcmp(ae_hard, plain, data_len) != 0) {
printf("rkcrypto_test_ae_virt compare data failed.\n");
res = RK_CRYPTO_ERR_GENERIC;
goto exit;
}
if (verbose)
printf("virt:\t[%s-%u]\t%s\t%s\tPASS\n",
test_algo_name(algo), key_len * 8,
test_mode_name(mode), test_op_name(operation));
}
}
}
}
}
res = RK_CRYPTO_SUCCESS;
exit:
if (plain)
free(plain);
if (ae_soft)
free(ae_soft);
if (ae_hard)
free(ae_hard);
if (aad)
free(aad);
if (res)
printf("virt:\t[%s-%u]\t%s\t%s\tFAIL\n",
test_algo_name(algo), key_len * 8,
test_mode_name(mode), test_op_name(operation));
return res;
}
static RK_RES test_ae_item_fd(const struct test_ae_item *item, int verbose)
{
RK_RES res = RK_CRYPTO_ERR_GENERIC;
uint32_t h, i, k, l, n;
rk_handle handle = 0;
rk_ae_config ae_cfg;
rk_crypto_mem *plain = NULL, *ae_soft = NULL, *ae_hard = NULL, *aad = NULL;
uint8_t iv_tmp[32];
uint32_t algo = 0, mode = 0, key_len, iv_len, data_len, aad_len, operation;
uint32_t tag_len = 16;
uint8_t tag_hard[16], tag_soft[16];
plain = rk_crypto_mem_alloc(TEST_DATA_MAX);
if (!plain) {
printf("plain malloc %dByte error!\n", TEST_DATA_MAX);
goto exit;
}
ae_soft = rk_crypto_mem_alloc(TEST_DATA_MAX);
if (!ae_soft) {
printf("ae_soft malloc %dByte error!\n", TEST_DATA_MAX);
goto exit;
}
ae_hard = rk_crypto_mem_alloc(TEST_DATA_MAX);
if (!ae_hard) {
printf("ae_hard malloc %dByte error!\n", TEST_DATA_MAX);
goto exit;
}
aad = rk_crypto_mem_alloc(TEST_AAD_MAX);
if (!aad) {
printf("aad malloc %dByte error!\n", TEST_AAD_MAX);
goto exit;
}
memset(tag_hard, 0x00, sizeof(tag_hard));
memset(tag_soft, 0x00, sizeof(tag_soft));
iv_len = 12;
for (h = 0; h < ARRAY_SIZE(item->algo); h++) {
algo = item->algo[h];
for (i = 0; i < ARRAY_SIZE(item->modes); i++) {
mode = item->modes[i];
if (mode == DATA_BUTT)
break;
for (k = 0; k < ARRAY_SIZE(item->key_lens); k++) {
key_len = item->key_lens[k];
if (algo == RK_ALGO_SM4 && key_len !=16)
continue;
for (l = 0; l < ARRAY_SIZE(item->data_lens); l++) {
data_len = item->data_lens[l];
test_get_rng(plain->vaddr, data_len);
for (n = 0; n < ARRAY_SIZE(item->aad_lens); n++) {
aad_len = item->aad_lens[n];
/* encryption */
operation = RK_OP_CIPHER_ENC;
memset(&ae_cfg, 0x00, sizeof(ae_cfg));
ae_cfg.algo = algo;
ae_cfg.mode = mode;
ae_cfg.operation = operation;
ae_cfg.key_len = key_len;
ae_cfg.iv_len = iv_len;
ae_cfg.aad_len = aad_len;
ae_cfg.tag_len = tag_len;
test_get_rng(ae_cfg.key, key_len);
test_get_rng(ae_cfg.iv, iv_len);
test_get_rng(aad->vaddr, aad_len);
memcpy(iv_tmp, ae_cfg.iv, iv_len);
res = rk_ae_init(&ae_cfg, &handle);
if (res) {
if (res != RK_CRYPTO_ERR_NOT_SUPPORTED) {
printf("rk_ae_init error[%x]\n", res);
goto exit;
}
if (verbose)
printf("dma_fd:\t[%s-%u]\t%s\t%s\tN/A\n",
test_algo_name(algo), key_len * 8,
test_mode_name(mode),
test_op_name(operation));
res = RK_CRYPTO_SUCCESS;
continue;
}
if (is_no_multi_blocksize(mode))
data_len = data_len - 3;
res = rk_ae_set_aad(handle, aad->dma_fd);
if (res) {
rk_ae_final(handle);
printf("rk_ae_set_aad_virt error[%x]\n", res);
goto exit;
}
res = rk_ae_crypt(handle, plain->dma_fd, ae_hard->dma_fd, data_len, tag_hard);
if (res) {
rk_ae_final(handle);
printf("rk_ae_crypt error[%x]\n", res);
goto exit;
}
rk_ae_final(handle);
res = soft_ae(algo, mode, operation,
ae_cfg.key, ae_cfg.key_len, iv_tmp, iv_len,
aad->vaddr, aad_len, ae_cfg.tag_len,
plain->vaddr, data_len, ae_soft->vaddr, tag_soft);
if (res) {
printf("soft_ae error[%x]\n", res);
goto exit;
}
/* Verify the result */
if (memcmp(ae_hard->vaddr, ae_soft->vaddr, data_len) != 0) {
printf("rkcrypto_test_ae compare data failed.\n");
res = RK_CRYPTO_ERR_GENERIC;
goto exit;
}
if (memcmp(tag_hard, tag_soft, ae_cfg.tag_len) != 0) {
printf("rkcrypto_test_ae compare tag failed.\n");
res = RK_CRYPTO_ERR_GENERIC;
goto exit;
}
if (verbose)
printf("dma_fd:\t[%s-%u]\t%s\t%s\tPASS\n",
test_algo_name(algo), key_len * 8,
test_mode_name(mode), test_op_name(operation));
/* decryption */
operation = RK_OP_CIPHER_DEC;
ae_cfg.operation = operation;
memcpy(ae_cfg.iv, iv_tmp, iv_len);
res = rk_ae_init(&ae_cfg, &handle);
if (res) {
if (res != RK_CRYPTO_ERR_NOT_SUPPORTED) {
printf("rk_ae_init error[%x]\n", res);
goto exit;
}
if (verbose)
printf("dma_fd:\t[%s-%u]\t%s\t%s\tN/A\n",
test_algo_name(algo), key_len * 8,
test_mode_name(mode),
test_op_name(operation));
res = RK_CRYPTO_SUCCESS;
continue;
}
res = rk_ae_set_aad(handle, aad->dma_fd);
if (res) {
rk_ae_final(handle);
printf("rk_ae_set_aad_virt error[%x]\n", res);
goto exit;
}
res = rk_ae_crypt(handle, ae_hard->dma_fd, ae_hard->dma_fd, data_len, tag_hard);
if (res) {
rk_ae_final(handle);
printf("rk_ae_crypt error[%x]\n", res);
goto exit;
}
rk_ae_final(handle);
/* Verify the result */
if (memcmp(ae_hard->vaddr, plain->vaddr, data_len) != 0) {
printf("rkcrypto_test_ae compare data failed.\n");
res = RK_CRYPTO_ERR_GENERIC;
goto exit;
}
if (verbose)
printf("dma_fd:\t[%s-%u]\t%s\t%s\tPASS\n",
test_algo_name(algo), key_len * 8,
test_mode_name(mode), test_op_name(operation));
}
}
}
}
}
res = RK_CRYPTO_SUCCESS;
exit:
if (plain)
rk_crypto_mem_free(plain);
if (ae_soft)
rk_crypto_mem_free(ae_soft);
if (ae_hard)
rk_crypto_mem_free(ae_hard);
if (aad)
rk_crypto_mem_free(aad);
if (res)
printf("dma_fd:\t[%s-%u]\t%s\t%s\tFAIL\n",
test_algo_name(algo), key_len * 8,
test_mode_name(mode), test_op_name(operation));
return res;
}
RK_RES test_ae(int verbose)
{
RK_RES res = RK_CRYPTO_ERR_GENERIC;
uint32_t i;
res = rk_crypto_init();
if (res) {
printf("rk_crypto_init error %08x\n", res);
return res;
}
for (i = 0; i < ARRAY_SIZE(test_item_tbl); i++) {
res = test_ae_item_virt(&test_item_tbl[i], verbose);
if (res)
goto exit;
res = test_ae_item_fd(&test_item_tbl[i], verbose);
if (res)
goto exit;
if (verbose)
printf("\n");
}
exit:
rk_crypto_deinit();
return res;
}