xref: /optee_os/core/pta/tests/aes_perf.c (revision 5ca2c36555d169a2be60964e2cbe39340c5245a4)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2020, Linaro Limited
4  */
5 
6 #include <compiler.h>
7 #include <crypto/crypto.h>
8 #include <pta_invoke_tests.h>
9 #include <tee_api_defines.h>
10 #include <tee_api_types.h>
11 #include <trace.h>
12 #include <types_ext.h>
13 #include <utee_defines.h>
14 
15 #include "misc.h"
16 
17 /*
18  * These keys and iv are copied from optee_test/ta/aes_perf/ta_aes_perf.c,
19  * not because their actual values are important, rather that there's no
20  * reason to use different values.
21  */
22 
23 static const uint8_t aes_key[] = {
24 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
25 	0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
26 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
27 	0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
28 };
29 
30 static const uint8_t aes_key2[] = {
31 	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
32 	0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
33 	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
34 	0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
35 };
36 
37 static uint8_t aes_iv[] = {
38 	0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
39 	0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF
40 };
41 
free_ctx(void ** ctx,uint32_t algo)42 static void free_ctx(void **ctx, uint32_t algo)
43 {
44 	if (algo == TEE_ALG_AES_GCM)
45 		crypto_authenc_free_ctx(*ctx);
46 	else
47 		crypto_cipher_free_ctx(*ctx);
48 
49 	*ctx = NULL;
50 }
51 
init_ctx(void ** ctx,uint32_t algo,TEE_OperationMode mode,size_t key_size_bits,size_t payload_len)52 static TEE_Result init_ctx(void **ctx, uint32_t algo, TEE_OperationMode mode,
53 			   size_t key_size_bits, size_t payload_len)
54 {
55 	TEE_Result res = TEE_SUCCESS;
56 	const uint8_t *key2 = NULL;
57 	const uint8_t *iv = NULL;
58 	size_t key2_len = 0;
59 	size_t key_len = 0;
60 	size_t iv_len = 0;
61 
62 	if (key_size_bits % 8)
63 		return TEE_ERROR_BAD_PARAMETERS;
64 	key_len = key_size_bits / 8;
65 	if (key_len > sizeof(aes_key))
66 		return TEE_ERROR_BAD_PARAMETERS;
67 
68 	/* Alloc ctx */
69 	switch (algo) {
70 	case TEE_ALG_AES_XTS:
71 		key2_len = key_len;
72 		key2 = aes_key2;
73 		fallthrough;
74 	case TEE_ALG_AES_ECB_NOPAD:
75 	case TEE_ALG_AES_CBC_NOPAD:
76 	case TEE_ALG_AES_CTR:
77 		res = crypto_cipher_alloc_ctx(ctx, algo);
78 		break;
79 	case TEE_ALG_AES_GCM:
80 		res = crypto_authenc_alloc_ctx(ctx, algo);
81 		break;
82 	default:
83 		return TEE_ERROR_BAD_PARAMETERS;
84 	}
85 	if (res)
86 		return res;
87 
88 	/* Init ctx */
89 	switch (algo) {
90 	case TEE_ALG_AES_CBC_NOPAD:
91 	case TEE_ALG_AES_CTR:
92 	case TEE_ALG_AES_XTS:
93 		iv = aes_iv;
94 		iv_len = sizeof(aes_iv);
95 		fallthrough;
96 	case TEE_ALG_AES_ECB_NOPAD:
97 		res = crypto_cipher_init(*ctx, mode, aes_key, key_len, key2,
98 					 key2_len, iv, iv_len);
99 		break;
100 	case TEE_ALG_AES_GCM:
101 		res = crypto_authenc_init(*ctx, mode, aes_key, key_len, aes_iv,
102 					  sizeof(aes_iv), TEE_AES_BLOCK_SIZE,
103 					  0, payload_len);
104 		break;
105 	default:
106 		return TEE_ERROR_BAD_PARAMETERS;
107 	}
108 
109 	if (res)
110 		free_ctx(ctx, algo);
111 
112 	return res;
113 }
114 
update_ae(void * ctx,TEE_OperationMode mode,const void * src,size_t len,void * dst)115 static TEE_Result update_ae(void *ctx, TEE_OperationMode mode,
116 			    const void *src, size_t len, void *dst)
117 {
118 	size_t dlen = len;
119 
120 	return crypto_authenc_update_payload(ctx, mode, src, len, dst, &dlen);
121 }
122 
update_cipher(void * ctx,TEE_OperationMode mode,const void * src,size_t len,void * dst)123 static TEE_Result update_cipher(void *ctx, TEE_OperationMode mode,
124 				const void *src, size_t len, void *dst)
125 {
126 	return crypto_cipher_update(ctx, mode, false, src, len, dst);
127 }
128 
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)129 static TEE_Result do_update(void *ctx, uint32_t algo, TEE_OperationMode mode,
130 			    unsigned int rep_count, unsigned int unit_size,
131 			    const uint8_t *in, size_t sz, uint8_t *out)
132 {
133 	TEE_Result (*update_func)(void *ctx, TEE_OperationMode mode,
134 				  const void *src, size_t len,
135 				  void *dst) = NULL;
136 	TEE_Result res = TEE_SUCCESS;
137 	unsigned int n = 0;
138 	unsigned int m = 0;
139 
140 	if (algo == TEE_ALG_AES_GCM)
141 		update_func = update_ae;
142 	else
143 		update_func = update_cipher;
144 
145 	for (n = 0; n < rep_count; n++) {
146 		for (m = 0; m < sz / unit_size; m++) {
147 			res = update_func(ctx, mode, in + m * unit_size,
148 					  unit_size, out + m * unit_size);
149 			if (res)
150 				return res;
151 		}
152 		if (sz % unit_size)
153 			res = update_func(ctx, mode, in + m * unit_size,
154 					  sz % unit_size, out + m * unit_size);
155 	}
156 
157 	return res;
158 }
159 
core_aes_perf_tests(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])160 TEE_Result core_aes_perf_tests(uint32_t param_types,
161 			       TEE_Param params[TEE_NUM_PARAMS])
162 {
163 	uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
164 						   TEE_PARAM_TYPE_VALUE_INPUT,
165 						   TEE_PARAM_TYPE_MEMREF_INOUT,
166 						   TEE_PARAM_TYPE_MEMREF_INOUT);
167 	TEE_Result res = TEE_SUCCESS;
168 	TEE_OperationMode mode = 0;
169 	unsigned int rep_count = 0;
170 	unsigned int unit_size = 0;
171 	size_t key_size_bits = 0;
172 	uint32_t algo = 0;
173 	void *ctx = NULL;
174 
175 	if (param_types != exp_param_types)
176 		return TEE_ERROR_BAD_PARAMETERS;
177 
178 	switch (params[0].value.b) {
179 	case PTA_INVOKE_TESTS_AES_ECB:
180 		algo = TEE_ALG_AES_ECB_NOPAD;
181 		break;
182 	case PTA_INVOKE_TESTS_AES_CBC:
183 		algo = TEE_ALG_AES_CBC_NOPAD;
184 		break;
185 	case PTA_INVOKE_TESTS_AES_CTR:
186 		algo = TEE_ALG_AES_CTR;
187 		break;
188 	case PTA_INVOKE_TESTS_AES_XTS:
189 		algo = TEE_ALG_AES_XTS;
190 		break;
191 	case PTA_INVOKE_TESTS_AES_GCM:
192 		algo = TEE_ALG_AES_GCM;
193 		break;
194 	default:
195 		return TEE_ERROR_BAD_PARAMETERS;
196 	}
197 
198 	if (params[0].value.a >> 16)
199 		mode = TEE_MODE_DECRYPT;
200 	else
201 		mode = TEE_MODE_ENCRYPT;
202 
203 	key_size_bits = params[0].value.a & 0xffff;
204 
205 	rep_count = params[1].value.a;
206 	unit_size = params[1].value.b;
207 
208 	if (params[2].memref.size > params[3].memref.size)
209 		return TEE_ERROR_BAD_PARAMETERS;
210 
211 	res = init_ctx(&ctx, algo, mode, key_size_bits, params[2].memref.size);
212 	if (res)
213 		return res;
214 
215 	res = do_update(ctx, algo, mode, rep_count, unit_size,
216 			params[2].memref.buffer, params[2].memref.size,
217 			params[3].memref.buffer);
218 
219 	free_ctx(&ctx, algo);
220 	return res;
221 }
222