blob: 01ce89ef5e5d7a69f28a23237eee601bcd6a9326 [file] [log] [blame]
Etienne Carriere75141172020-05-16 11:58:23 +02001// SPDX-License-Identifier: BSD-2-Clause
Igor Opaniuk44aff4b2016-09-16 10:18:00 +03002/*
3 * Copyright (c) 2015, Linaro Limited
4 * All rights reserved.
Igor Opaniuk44aff4b2016-09-16 10:18:00 +03005 */
6
Etienne Carriereb85a5f92017-05-03 18:21:56 +02007#include <tee_internal_api_extensions.h>
Igor Opaniuk44aff4b2016-09-16 10:18:00 +03008#include <tee_internal_api.h>
9#include <tee_ta_api.h>
10#include <string.h>
11#include <trace.h>
12
13#include "ta_aes_perf.h"
14#include "ta_aes_perf_priv.h"
15
16#define CHECK(res, name, action) do { \
17 if ((res) != TEE_SUCCESS) { \
18 DMSG(name ": 0x%08x", (res)); \
19 action \
20 } \
21 } while(0)
22
Jens Wiklander3b2da642017-10-19 13:50:04 +020023#define TAG_LEN 128
24
Igor Opaniuk44aff4b2016-09-16 10:18:00 +030025static uint8_t iv[] = { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
26 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF };
27static int use_iv;
28
29static TEE_OperationHandle crypto_op = NULL;
Jens Wiklander3b2da642017-10-19 13:50:04 +020030static uint32_t algo;
Igor Opaniuk44aff4b2016-09-16 10:18:00 +030031
Etienne Carriereb85a5f92017-05-03 18:21:56 +020032static bool is_inbuf_a_secure_memref(TEE_Param *param)
33{
Etienne Carriere102092e2019-03-28 15:24:22 +010034 TEE_Result res = TEE_ERROR_GENERIC;
Igor Opaniuk44aff4b2016-09-16 10:18:00 +030035
Etienne Carriereb85a5f92017-05-03 18:21:56 +020036 /*
37 * Check secure attribute for the referenced buffer
38 * Trust core on validity of the memref size: test only 1st byte
39 * instead of the overall buffer, and if it's not secure, assume
40 * the buffer is nonsecure.
41 */
42 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_ANY_OWNER |
43 TEE_MEMORY_ACCESS_READ |
44 TEE_MEMORY_ACCESS_SECURE,
45 param->memref.buffer, 1);
46 return (res == TEE_SUCCESS);
47}
Igor Opaniuk44aff4b2016-09-16 10:18:00 +030048
Etienne Carriereb85a5f92017-05-03 18:21:56 +020049static bool is_outbuf_a_secure_memref(TEE_Param *param)
50{
Etienne Carriere102092e2019-03-28 15:24:22 +010051 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriereb85a5f92017-05-03 18:21:56 +020052
53 /*
54 * Check secure attribute for the referenced buffer
55 * Trust core on validity of the memref size: test only 1st byte
56 * instead of the overall buffer, and if it's not secure, assume
57 * the buffer is nonsecure.
58 */
59 res = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_ANY_OWNER |
60 TEE_MEMORY_ACCESS_WRITE |
61 TEE_MEMORY_ACCESS_SECURE,
62 param->memref.buffer, 1);
63 return (res == TEE_SUCCESS);
64}
65
66#if defined(CFG_CACHE_API)
67static TEE_Result flush_memref_buffer(TEE_Param *param)
68{
Etienne Carriere102092e2019-03-28 15:24:22 +010069 TEE_Result res = TEE_ERROR_GENERIC;
Etienne Carriereb85a5f92017-05-03 18:21:56 +020070
71 res = TEE_CacheFlush(param->memref.buffer,
72 param->memref.size);
73 CHECK(res, "TEE_CacheFlush(in)", return res;);
74 return res;
75}
76#else
77static __maybe_unused TEE_Result flush_memref_buffer(TEE_Param *param __unused)
78{
79 return TEE_SUCCESS;
80}
81#endif /* CFG_CACHE_API */
82
83TEE_Result cmd_process(uint32_t param_types,
84 TEE_Param params[TEE_NUM_PARAMS],
85 bool use_sdp)
Igor Opaniuk44aff4b2016-09-16 10:18:00 +030086{
Etienne Carriere102092e2019-03-28 15:24:22 +010087 TEE_Result res = TEE_ERROR_GENERIC;
88 int n = 0;
89 int unit = 0;
90 void *in = NULL;
91 void *out = NULL;
92 uint32_t insz = 0;
93 uint32_t outsz = 0;
Igor Opaniuk44aff4b2016-09-16 10:18:00 +030094 uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
95 TEE_PARAM_TYPE_MEMREF_INOUT,
96 TEE_PARAM_TYPE_VALUE_INPUT,
97 TEE_PARAM_TYPE_NONE);
Etienne Carriere102092e2019-03-28 15:24:22 +010098 bool secure_in = false;
Etienne Carriereb85a5f92017-05-03 18:21:56 +020099 bool secure_out = false;
Jerome Forissiera410edb2018-03-08 10:36:37 +0100100 TEE_Result (*do_update)(TEE_OperationHandle, const void *, uint32_t,
Etienne Carriere102092e2019-03-28 15:24:22 +0100101 void *, uint32_t *) = NULL;
Igor Opaniuk44aff4b2016-09-16 10:18:00 +0300102
103 if (param_types != exp_param_types)
104 return TEE_ERROR_BAD_PARAMETERS;
105
Etienne Carriereb85a5f92017-05-03 18:21:56 +0200106 if (use_sdp) {
107 /*
108 * Whatever is expected as memory reference, it is mandatory
109 * for SDP aware trusted applications of safely indentify all
110 * memory reference parameters. Hence these tests must be part
111 * of the performance test setup.
112 */
113 secure_in = is_inbuf_a_secure_memref(&params[0]);
114 secure_out = is_outbuf_a_secure_memref(&params[1]);
115
116 /*
117 * We could invalidate only the caches. We prefer to flush
118 * them in case 2 sub-buffers are accessed by TAs from a single
119 * allocated SDP memory buffer, and those are not cache-aligned.
120 * Invalidating might cause data loss in cache lines. Hence
121 * rather flush them all before accessing (in read or write).
122 */
123 if (secure_in) {
124 res = flush_memref_buffer(&params[0]);
125 CHECK(res, "pre-flush in memref param", return res;);
126 }
127 if (secure_out) {
128 res = flush_memref_buffer(&params[1]);
129 CHECK(res, "pre-flush out memref param", return res;);
130 }
131 }
132
Igor Opaniuk44aff4b2016-09-16 10:18:00 +0300133 in = params[0].memref.buffer;
134 insz = params[0].memref.size;
135 out = params[1].memref.buffer;
136 outsz = params[1].memref.size;
137 n = params[2].value.a;
Jerome Forissiera410edb2018-03-08 10:36:37 +0100138 unit = params[2].value.b;
139 if (!unit)
140 unit = insz;
Igor Opaniuk44aff4b2016-09-16 10:18:00 +0300141
Jerome Forissiera410edb2018-03-08 10:36:37 +0100142 if (algo == TEE_ALG_AES_GCM)
143 do_update = TEE_AEUpdate;
144 else
145 do_update = TEE_CipherUpdate;
146
147 while (n--) {
Etienne Carriere102092e2019-03-28 15:24:22 +0100148 uint32_t i = 0;
Jerome Forissiera410edb2018-03-08 10:36:37 +0100149 for (i = 0; i < insz / unit; i++) {
150 res = do_update(crypto_op, in, unit, out, &outsz);
151 CHECK(res, "TEE_CipherUpdate/TEE_AEUpdate", return res;);
152 in = (void *)((uintptr_t)in + unit);
153 out = (void *)((uintptr_t)out + unit);
Jens Wiklander3b2da642017-10-19 13:50:04 +0200154 }
Jerome Forissiera410edb2018-03-08 10:36:37 +0100155 if (insz % unit) {
156 res = do_update(crypto_op, in, insz % unit, out, &outsz);
157 CHECK(res, "TEE_CipherUpdate/TEE_AEUpdate", return res;);
Jens Wiklander3b2da642017-10-19 13:50:04 +0200158 }
Igor Opaniuk44aff4b2016-09-16 10:18:00 +0300159 }
Etienne Carriereb85a5f92017-05-03 18:21:56 +0200160
161 if (secure_out) {
162 /* intentionally flush output data from cache for SDP buffers */
163 res = flush_memref_buffer(&params[1]);
164 CHECK(res, "post-flush out memref param", return res;);
165 }
166
Igor Opaniuk44aff4b2016-09-16 10:18:00 +0300167 return TEE_SUCCESS;
168}
169
170TEE_Result cmd_prepare_key(uint32_t param_types, TEE_Param params[4])
171{
Etienne Carriere102092e2019-03-28 15:24:22 +0100172 TEE_Result res = TEE_ERROR_GENERIC;
173 TEE_ObjectHandle hkey = TEE_HANDLE_NULL;
174 TEE_ObjectHandle hkey2 = TEE_HANDLE_NULL;
175 TEE_Attribute attr = { };
176 uint32_t mode = 0;
177 uint32_t op_keysize = 0;
178 uint32_t keysize = 0;
179 const uint8_t *ivp = NULL;
180 size_t ivlen = 0;
Igor Opaniuk44aff4b2016-09-16 10:18:00 +0300181 static uint8_t aes_key[] = { 0x00, 0x01, 0x02, 0x03,
182 0x04, 0x05, 0x06, 0x07,
183 0x08, 0x09, 0x0A, 0x0B,
184 0x0C, 0x0D, 0x0E, 0x0F,
185 0x10, 0x11, 0x12, 0x13,
186 0x14, 0x15, 0x16, 0x17,
187 0x18, 0x19, 0x1A, 0x1B,
188 0x1C, 0x1D, 0x1E, 0x1F };
189 static uint8_t aes_key2[] = { 0x20, 0x21, 0x22, 0x23,
190 0x24, 0x25, 0x26, 0x27,
191 0x28, 0x29, 0x2A, 0x2B,
192 0x2C, 0x2D, 0x2E, 0x2F,
193 0x30, 0x31, 0x32, 0x33,
194 0x34, 0x35, 0x36, 0x37,
195 0x38, 0x39, 0x3A, 0x3B,
196 0x3C, 0x3D, 0x3E, 0x3F };
Igor Opaniuk44aff4b2016-09-16 10:18:00 +0300197 uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
198 TEE_PARAM_TYPE_VALUE_INPUT,
199 TEE_PARAM_TYPE_NONE,
200 TEE_PARAM_TYPE_NONE);
Etienne Carriere102092e2019-03-28 15:24:22 +0100201
Igor Opaniuk44aff4b2016-09-16 10:18:00 +0300202 if (param_types != exp_param_types)
203 return TEE_ERROR_BAD_PARAMETERS;
204
205 mode = params[0].value.a ? TEE_MODE_DECRYPT : TEE_MODE_ENCRYPT;
206 keysize = params[0].value.b;
207 op_keysize = keysize;
208
209 switch (params[1].value.a) {
210 case TA_AES_ECB:
211 algo = TEE_ALG_AES_ECB_NOPAD;
212 use_iv = 0;
213 break;
214 case TA_AES_CBC:
215 algo = TEE_ALG_AES_CBC_NOPAD;
216 use_iv = 1;
217 break;
218 case TA_AES_CTR:
219 algo = TEE_ALG_AES_CTR;
220 use_iv = 1;
221 break;
222 case TA_AES_XTS:
223 algo = TEE_ALG_AES_XTS;
224 use_iv = 1;
225 op_keysize *= 2;
226 break;
Jens Wiklander3b2da642017-10-19 13:50:04 +0200227 case TA_AES_GCM:
228 algo = TEE_ALG_AES_GCM;
229 use_iv = 1;
230 break;
Igor Opaniuk44aff4b2016-09-16 10:18:00 +0300231 default:
232 return TEE_ERROR_BAD_PARAMETERS;
233 }
234
235 cmd_clean_res();
236
237 res = TEE_AllocateOperation(&crypto_op, algo, mode, op_keysize);
238 CHECK(res, "TEE_AllocateOperation", return res;);
239
240 res = TEE_AllocateTransientObject(TEE_TYPE_AES, keysize, &hkey);
241 CHECK(res, "TEE_AllocateTransientObject", return res;);
242
243 attr.attributeID = TEE_ATTR_SECRET_VALUE;
244 attr.content.ref.buffer = aes_key;
245 attr.content.ref.length = keysize / 8;
246
247 res = TEE_PopulateTransientObject(hkey, &attr, 1);
248 CHECK(res, "TEE_PopulateTransientObject", return res;);
249
250 if (algo == TEE_ALG_AES_XTS) {
251 res = TEE_AllocateTransientObject(TEE_TYPE_AES, keysize,
252 &hkey2);
253 CHECK(res, "TEE_AllocateTransientObject", return res;);
254
255 attr.content.ref.buffer = aes_key2;
256
257 res = TEE_PopulateTransientObject(hkey2, &attr, 1);
258 CHECK(res, "TEE_PopulateTransientObject", return res;);
259
260 res = TEE_SetOperationKey2(crypto_op, hkey, hkey2);
261 CHECK(res, "TEE_SetOperationKey2", return res;);
262
263 TEE_FreeTransientObject(hkey2);
264 } else {
265 res = TEE_SetOperationKey(crypto_op, hkey);
266 CHECK(res, "TEE_SetOperationKey", return res;);
267 }
268
269 TEE_FreeTransientObject(hkey);
270
Jens Wiklander3b2da642017-10-19 13:50:04 +0200271 if (use_iv) {
272 ivp = iv;
273 ivlen = sizeof(iv);
274 } else {
275 ivp = NULL;
276 ivlen = 0;
277 }
Igor Opaniuk44aff4b2016-09-16 10:18:00 +0300278
Jens Wiklander3b2da642017-10-19 13:50:04 +0200279 if (algo == TEE_ALG_AES_GCM) {
280 return TEE_AEInit(crypto_op, ivp, ivlen, TAG_LEN, 0, 0);
281 } else {
282 TEE_CipherInit(crypto_op, ivp, ivlen);
283 return TEE_SUCCESS;
284 }
Igor Opaniuk44aff4b2016-09-16 10:18:00 +0300285}
286
287void cmd_clean_res(void)
288{
289 if (crypto_op)
290 TEE_FreeOperation(crypto_op);
291}