xref: /optee_os/core/pta/tests/aes_perf.c (revision 5ca2c36555d169a2be60964e2cbe39340c5245a4)
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