185898338SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
285898338SJens Wiklander /*
385898338SJens Wiklander * Copyright (c) 2020, Linaro Limited
485898338SJens Wiklander */
585898338SJens Wiklander
6*919a5a68SJerome Forissier #include <compiler.h>
785898338SJens Wiklander #include <crypto/crypto.h>
885898338SJens Wiklander #include <pta_invoke_tests.h>
985898338SJens Wiklander #include <tee_api_defines.h>
1085898338SJens Wiklander #include <tee_api_types.h>
1185898338SJens Wiklander #include <trace.h>
1285898338SJens Wiklander #include <types_ext.h>
1385898338SJens Wiklander #include <utee_defines.h>
1485898338SJens Wiklander
1585898338SJens Wiklander #include "misc.h"
1685898338SJens Wiklander
1785898338SJens Wiklander /*
1885898338SJens Wiklander * These keys and iv are copied from optee_test/ta/aes_perf/ta_aes_perf.c,
1985898338SJens Wiklander * not because their actual values are important, rather that there's no
2085898338SJens Wiklander * reason to use different values.
2185898338SJens Wiklander */
2285898338SJens Wiklander
2385898338SJens Wiklander static const uint8_t aes_key[] = {
2485898338SJens Wiklander 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2585898338SJens Wiklander 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
2685898338SJens Wiklander 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
2785898338SJens Wiklander 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
2885898338SJens Wiklander };
2985898338SJens Wiklander
3085898338SJens Wiklander static const uint8_t aes_key2[] = {
3185898338SJens Wiklander 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
3285898338SJens Wiklander 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
3385898338SJens Wiklander 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
3485898338SJens Wiklander 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
3585898338SJens Wiklander };
3685898338SJens Wiklander
3785898338SJens Wiklander static uint8_t aes_iv[] = {
3885898338SJens Wiklander 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
3985898338SJens Wiklander 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF
4085898338SJens Wiklander };
4185898338SJens Wiklander
free_ctx(void ** ctx,uint32_t algo)4285898338SJens Wiklander static void free_ctx(void **ctx, uint32_t algo)
4385898338SJens Wiklander {
4485898338SJens Wiklander if (algo == TEE_ALG_AES_GCM)
4585898338SJens Wiklander crypto_authenc_free_ctx(*ctx);
4685898338SJens Wiklander else
4785898338SJens Wiklander crypto_cipher_free_ctx(*ctx);
4885898338SJens Wiklander
4985898338SJens Wiklander *ctx = NULL;
5085898338SJens Wiklander }
5185898338SJens Wiklander
init_ctx(void ** ctx,uint32_t algo,TEE_OperationMode mode,size_t key_size_bits,size_t payload_len)5285898338SJens Wiklander static TEE_Result init_ctx(void **ctx, uint32_t algo, TEE_OperationMode mode,
5385898338SJens Wiklander size_t key_size_bits, size_t payload_len)
5485898338SJens Wiklander {
5585898338SJens Wiklander TEE_Result res = TEE_SUCCESS;
5685898338SJens Wiklander const uint8_t *key2 = NULL;
5785898338SJens Wiklander const uint8_t *iv = NULL;
5885898338SJens Wiklander size_t key2_len = 0;
5985898338SJens Wiklander size_t key_len = 0;
6085898338SJens Wiklander size_t iv_len = 0;
6185898338SJens Wiklander
6285898338SJens Wiklander if (key_size_bits % 8)
6385898338SJens Wiklander return TEE_ERROR_BAD_PARAMETERS;
6485898338SJens Wiklander key_len = key_size_bits / 8;
6585898338SJens Wiklander if (key_len > sizeof(aes_key))
6685898338SJens Wiklander return TEE_ERROR_BAD_PARAMETERS;
6785898338SJens Wiklander
6885898338SJens Wiklander /* Alloc ctx */
6985898338SJens Wiklander switch (algo) {
7085898338SJens Wiklander case TEE_ALG_AES_XTS:
7185898338SJens Wiklander key2_len = key_len;
7285898338SJens Wiklander key2 = aes_key2;
73*919a5a68SJerome Forissier fallthrough;
7485898338SJens Wiklander case TEE_ALG_AES_ECB_NOPAD:
7585898338SJens Wiklander case TEE_ALG_AES_CBC_NOPAD:
7685898338SJens Wiklander case TEE_ALG_AES_CTR:
7785898338SJens Wiklander res = crypto_cipher_alloc_ctx(ctx, algo);
7885898338SJens Wiklander break;
7985898338SJens Wiklander case TEE_ALG_AES_GCM:
8085898338SJens Wiklander res = crypto_authenc_alloc_ctx(ctx, algo);
8185898338SJens Wiklander break;
8285898338SJens Wiklander default:
8385898338SJens Wiklander return TEE_ERROR_BAD_PARAMETERS;
8485898338SJens Wiklander }
8585898338SJens Wiklander if (res)
8685898338SJens Wiklander return res;
8785898338SJens Wiklander
8885898338SJens Wiklander /* Init ctx */
8985898338SJens Wiklander switch (algo) {
9085898338SJens Wiklander case TEE_ALG_AES_CBC_NOPAD:
9185898338SJens Wiklander case TEE_ALG_AES_CTR:
9285898338SJens Wiklander case TEE_ALG_AES_XTS:
9385898338SJens Wiklander iv = aes_iv;
9485898338SJens Wiklander iv_len = sizeof(aes_iv);
95*919a5a68SJerome Forissier fallthrough;
9685898338SJens Wiklander case TEE_ALG_AES_ECB_NOPAD:
9785898338SJens Wiklander res = crypto_cipher_init(*ctx, mode, aes_key, key_len, key2,
9885898338SJens Wiklander key2_len, iv, iv_len);
9985898338SJens Wiklander break;
10085898338SJens Wiklander case TEE_ALG_AES_GCM:
10185898338SJens Wiklander res = crypto_authenc_init(*ctx, mode, aes_key, key_len, aes_iv,
10285898338SJens Wiklander sizeof(aes_iv), TEE_AES_BLOCK_SIZE,
10385898338SJens Wiklander 0, payload_len);
10485898338SJens Wiklander break;
10585898338SJens Wiklander default:
10685898338SJens Wiklander return TEE_ERROR_BAD_PARAMETERS;
10785898338SJens Wiklander }
10885898338SJens Wiklander
10985898338SJens Wiklander if (res)
11085898338SJens Wiklander free_ctx(ctx, algo);
11185898338SJens Wiklander
11285898338SJens Wiklander return res;
11385898338SJens Wiklander }
11485898338SJens Wiklander
update_ae(void * ctx,TEE_OperationMode mode,const void * src,size_t len,void * dst)11585898338SJens Wiklander static TEE_Result update_ae(void *ctx, TEE_OperationMode mode,
11685898338SJens Wiklander const void *src, size_t len, void *dst)
11785898338SJens Wiklander {
11885898338SJens Wiklander size_t dlen = len;
11985898338SJens Wiklander
12085898338SJens Wiklander return crypto_authenc_update_payload(ctx, mode, src, len, dst, &dlen);
12185898338SJens Wiklander }
12285898338SJens Wiklander
update_cipher(void * ctx,TEE_OperationMode mode,const void * src,size_t len,void * dst)12385898338SJens Wiklander static TEE_Result update_cipher(void *ctx, TEE_OperationMode mode,
12485898338SJens Wiklander const void *src, size_t len, void *dst)
12585898338SJens Wiklander {
12685898338SJens Wiklander return crypto_cipher_update(ctx, mode, false, src, len, dst);
12785898338SJens Wiklander }
12885898338SJens Wiklander
do_update(void * ctx,uint32_t algo,TEE_OperationMode mode,unsigned int rep_count,unsigned int unit_size,const uint8_t * in,size_t sz,uint8_t * out)12985898338SJens Wiklander static TEE_Result do_update(void *ctx, uint32_t algo, TEE_OperationMode mode,
13085898338SJens Wiklander unsigned int rep_count, unsigned int unit_size,
13185898338SJens Wiklander const uint8_t *in, size_t sz, uint8_t *out)
13285898338SJens Wiklander {
13385898338SJens Wiklander TEE_Result (*update_func)(void *ctx, TEE_OperationMode mode,
13485898338SJens Wiklander const void *src, size_t len,
13585898338SJens Wiklander void *dst) = NULL;
13685898338SJens Wiklander TEE_Result res = TEE_SUCCESS;
13785898338SJens Wiklander unsigned int n = 0;
13885898338SJens Wiklander unsigned int m = 0;
13985898338SJens Wiklander
14085898338SJens Wiklander if (algo == TEE_ALG_AES_GCM)
14185898338SJens Wiklander update_func = update_ae;
14285898338SJens Wiklander else
14385898338SJens Wiklander update_func = update_cipher;
14485898338SJens Wiklander
14585898338SJens Wiklander for (n = 0; n < rep_count; n++) {
14685898338SJens Wiklander for (m = 0; m < sz / unit_size; m++) {
14785898338SJens Wiklander res = update_func(ctx, mode, in + m * unit_size,
14885898338SJens Wiklander unit_size, out + m * unit_size);
14985898338SJens Wiklander if (res)
15085898338SJens Wiklander return res;
15185898338SJens Wiklander }
15285898338SJens Wiklander if (sz % unit_size)
15385898338SJens Wiklander res = update_func(ctx, mode, in + m * unit_size,
15485898338SJens Wiklander sz % unit_size, out + m * unit_size);
15585898338SJens Wiklander }
15685898338SJens Wiklander
15785898338SJens Wiklander return res;
15885898338SJens Wiklander }
15985898338SJens Wiklander
core_aes_perf_tests(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])16085898338SJens Wiklander TEE_Result core_aes_perf_tests(uint32_t param_types,
16185898338SJens Wiklander TEE_Param params[TEE_NUM_PARAMS])
16285898338SJens Wiklander {
16385898338SJens Wiklander uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
16485898338SJens Wiklander TEE_PARAM_TYPE_VALUE_INPUT,
16585898338SJens Wiklander TEE_PARAM_TYPE_MEMREF_INOUT,
16685898338SJens Wiklander TEE_PARAM_TYPE_MEMREF_INOUT);
16785898338SJens Wiklander TEE_Result res = TEE_SUCCESS;
16885898338SJens Wiklander TEE_OperationMode mode = 0;
16985898338SJens Wiklander unsigned int rep_count = 0;
17085898338SJens Wiklander unsigned int unit_size = 0;
17185898338SJens Wiklander size_t key_size_bits = 0;
17285898338SJens Wiklander uint32_t algo = 0;
17385898338SJens Wiklander void *ctx = NULL;
17485898338SJens Wiklander
17585898338SJens Wiklander if (param_types != exp_param_types)
17685898338SJens Wiklander return TEE_ERROR_BAD_PARAMETERS;
17785898338SJens Wiklander
17885898338SJens Wiklander switch (params[0].value.b) {
17985898338SJens Wiklander case PTA_INVOKE_TESTS_AES_ECB:
18085898338SJens Wiklander algo = TEE_ALG_AES_ECB_NOPAD;
18185898338SJens Wiklander break;
18285898338SJens Wiklander case PTA_INVOKE_TESTS_AES_CBC:
18385898338SJens Wiklander algo = TEE_ALG_AES_CBC_NOPAD;
18485898338SJens Wiklander break;
18585898338SJens Wiklander case PTA_INVOKE_TESTS_AES_CTR:
18685898338SJens Wiklander algo = TEE_ALG_AES_CTR;
18785898338SJens Wiklander break;
18885898338SJens Wiklander case PTA_INVOKE_TESTS_AES_XTS:
18985898338SJens Wiklander algo = TEE_ALG_AES_XTS;
19085898338SJens Wiklander break;
19185898338SJens Wiklander case PTA_INVOKE_TESTS_AES_GCM:
19285898338SJens Wiklander algo = TEE_ALG_AES_GCM;
19385898338SJens Wiklander break;
19485898338SJens Wiklander default:
19585898338SJens Wiklander return TEE_ERROR_BAD_PARAMETERS;
19685898338SJens Wiklander }
19785898338SJens Wiklander
19885898338SJens Wiklander if (params[0].value.a >> 16)
19985898338SJens Wiklander mode = TEE_MODE_DECRYPT;
20085898338SJens Wiklander else
20185898338SJens Wiklander mode = TEE_MODE_ENCRYPT;
20285898338SJens Wiklander
20385898338SJens Wiklander key_size_bits = params[0].value.a & 0xffff;
20485898338SJens Wiklander
20585898338SJens Wiklander rep_count = params[1].value.a;
20685898338SJens Wiklander unit_size = params[1].value.b;
20785898338SJens Wiklander
20885898338SJens Wiklander if (params[2].memref.size > params[3].memref.size)
20985898338SJens Wiklander return TEE_ERROR_BAD_PARAMETERS;
21085898338SJens Wiklander
21185898338SJens Wiklander res = init_ctx(&ctx, algo, mode, key_size_bits, params[2].memref.size);
21285898338SJens Wiklander if (res)
21385898338SJens Wiklander return res;
21485898338SJens Wiklander
21585898338SJens Wiklander res = do_update(ctx, algo, mode, rep_count, unit_size,
21685898338SJens Wiklander params[2].memref.buffer, params[2].memref.size,
21785898338SJens Wiklander params[3].memref.buffer);
21885898338SJens Wiklander
21985898338SJens Wiklander free_ctx(&ctx, algo);
22085898338SJens Wiklander return res;
22185898338SJens Wiklander }
222