xref: /optee_os/ta/pkcs11/src/processing_symm.c (revision 5d2d37cd756d2f5b2342bf7c74b5800b5ed60cc6)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2017-2020, Linaro Limited
4  */
5 
6 #include <assert.h>
7 #include <pkcs11_ta.h>
8 #include <string.h>
9 #include <tee_api_defines.h>
10 #include <tee_internal_api.h>
11 #include <tee_internal_api_extensions.h>
12 #include <utee_defines.h>
13 #include <util.h>
14 
15 #include "attributes.h"
16 #include "object.h"
17 #include "pkcs11_attributes.h"
18 #include "pkcs11_helpers.h"
19 #include "pkcs11_token.h"
20 #include "processing.h"
21 #include "serializer.h"
22 
23 struct input_data_ref {
24 	size_t size;
25 	void *data;
26 };
27 
processing_is_tee_symm(enum pkcs11_mechanism_id proc_id)28 bool processing_is_tee_symm(enum pkcs11_mechanism_id proc_id)
29 {
30 	switch (proc_id) {
31 	/* Authentication */
32 	case PKCS11_CKM_AES_CMAC:
33 	case PKCS11_CKM_MD5_HMAC:
34 	case PKCS11_CKM_SHA_1_HMAC:
35 	case PKCS11_CKM_SHA224_HMAC:
36 	case PKCS11_CKM_SHA256_HMAC:
37 	case PKCS11_CKM_SHA384_HMAC:
38 	case PKCS11_CKM_SHA512_HMAC:
39 	case PKCS11_CKM_AES_CMAC_GENERAL:
40 	case PKCS11_CKM_MD5_HMAC_GENERAL:
41 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
42 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
43 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
44 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
45 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
46 	/* Ciphering */
47 	case PKCS11_CKM_AES_ECB:
48 	case PKCS11_CKM_AES_CBC:
49 	case PKCS11_CKM_AES_CTS:
50 	case PKCS11_CKM_AES_CTR:
51 	case PKCS11_CKM_AES_GCM:
52 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
53 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
54 		return true;
55 	default:
56 		return false;
57 	}
58 }
59 
60 static enum pkcs11_rc
pkcs2tee_algorithm(uint32_t * tee_id,struct pkcs11_attribute_head * proc_params)61 pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params)
62 {
63 	static const struct {
64 		enum pkcs11_mechanism_id mech_id;
65 		uint32_t tee_id;
66 	} pkcs2tee_algo[] = {
67 		/* AES flavors */
68 		{ PKCS11_CKM_AES_ECB, TEE_ALG_AES_ECB_NOPAD },
69 		{ PKCS11_CKM_AES_CBC, TEE_ALG_AES_CBC_NOPAD },
70 		{ PKCS11_CKM_AES_ECB_ENCRYPT_DATA, TEE_ALG_AES_ECB_NOPAD },
71 		{ PKCS11_CKM_AES_CBC_ENCRYPT_DATA, TEE_ALG_AES_CBC_NOPAD },
72 		{ PKCS11_CKM_AES_CTR, TEE_ALG_AES_CTR },
73 		{ PKCS11_CKM_AES_CTS, TEE_ALG_AES_CTS },
74 		{ PKCS11_CKM_AES_GCM, TEE_ALG_AES_GCM },
75 		{ PKCS11_CKM_AES_CMAC, TEE_ALG_AES_CMAC },
76 		{ PKCS11_CKM_AES_CMAC_GENERAL, TEE_ALG_AES_CMAC },
77 		/* HMAC flavors */
78 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_HMAC_MD5 },
79 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_HMAC_SHA1 },
80 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_HMAC_SHA224 },
81 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_HMAC_SHA256 },
82 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_HMAC_SHA384 },
83 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_HMAC_SHA512 },
84 		{ PKCS11_CKM_MD5_HMAC_GENERAL, TEE_ALG_HMAC_MD5 },
85 		{ PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_ALG_HMAC_SHA1 },
86 		{ PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_ALG_HMAC_SHA224 },
87 		{ PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_ALG_HMAC_SHA256 },
88 		{ PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_ALG_HMAC_SHA384 },
89 		{ PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_ALG_HMAC_SHA512 },
90 	};
91 	size_t n = 0;
92 
93 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) {
94 		if (proc_params->id == pkcs2tee_algo[n].mech_id) {
95 			*tee_id = pkcs2tee_algo[n].tee_id;
96 			return PKCS11_CKR_OK;
97 		}
98 	}
99 
100 	return PKCS11_RV_NOT_IMPLEMENTED;
101 }
102 
pkcs2tee_key_type(uint32_t * tee_type,struct pkcs11_object * obj)103 static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type,
104 					struct pkcs11_object *obj)
105 {
106 	static const struct {
107 		enum pkcs11_key_type key_type;
108 		uint32_t tee_id;
109 	} pkcs2tee_key_type[] = {
110 		{ PKCS11_CKK_AES, TEE_TYPE_AES },
111 		{ PKCS11_CKK_GENERIC_SECRET, TEE_TYPE_GENERIC_SECRET },
112 		{ PKCS11_CKK_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
113 		{ PKCS11_CKK_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
114 		{ PKCS11_CKK_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
115 		{ PKCS11_CKK_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
116 		{ PKCS11_CKK_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
117 		{ PKCS11_CKK_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
118 	};
119 	size_t n = 0;
120 	enum pkcs11_key_type key_type = get_key_type(obj->attributes);
121 
122 	assert(get_class(obj->attributes) == PKCS11_CKO_SECRET_KEY);
123 
124 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
125 		if (pkcs2tee_key_type[n].key_type == key_type) {
126 			*tee_type = pkcs2tee_key_type[n].tee_id;
127 			return PKCS11_CKR_OK;
128 		}
129 	}
130 
131 	return PKCS11_RV_NOT_FOUND;
132 }
133 
pkcsmech2tee_key_type(uint32_t * tee_type,enum pkcs11_mechanism_id mech_id)134 static enum pkcs11_rc pkcsmech2tee_key_type(uint32_t *tee_type,
135 					    enum pkcs11_mechanism_id mech_id)
136 {
137 	static const struct {
138 		enum pkcs11_mechanism_id mech;
139 		uint32_t tee_id;
140 	} pkcs2tee_key_type[] = {
141 		{ PKCS11_CKM_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
142 		{ PKCS11_CKM_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
143 		{ PKCS11_CKM_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
144 		{ PKCS11_CKM_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
145 		{ PKCS11_CKM_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
146 		{ PKCS11_CKM_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
147 		{ PKCS11_CKM_MD5_HMAC_GENERAL, TEE_TYPE_HMAC_MD5 },
148 		{ PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_TYPE_HMAC_SHA1 },
149 		{ PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_TYPE_HMAC_SHA224 },
150 		{ PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_TYPE_HMAC_SHA256 },
151 		{ PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_TYPE_HMAC_SHA384 },
152 		{ PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_TYPE_HMAC_SHA512 },
153 	};
154 	size_t n = 0;
155 
156 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
157 		if (pkcs2tee_key_type[n].mech == mech_id) {
158 			*tee_type = pkcs2tee_key_type[n].tee_id;
159 			return PKCS11_CKR_OK;
160 		}
161 	}
162 
163 	return PKCS11_RV_NOT_FOUND;
164 }
165 
hmac_to_tee_hash(uint32_t * algo,enum pkcs11_mechanism_id mech_id)166 static enum pkcs11_rc hmac_to_tee_hash(uint32_t *algo,
167 				       enum pkcs11_mechanism_id mech_id)
168 {
169 	static const struct {
170 		enum pkcs11_mechanism_id mech;
171 		uint32_t tee_id;
172 	} hmac_hash[] = {
173 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_MD5 },
174 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_SHA1 },
175 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_SHA224 },
176 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_SHA256 },
177 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_SHA384 },
178 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_SHA512 },
179 		{ PKCS11_CKM_MD5_HMAC_GENERAL, TEE_ALG_MD5 },
180 		{ PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_ALG_SHA1 },
181 		{ PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_ALG_SHA224 },
182 		{ PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_ALG_SHA256 },
183 		{ PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_ALG_SHA384 },
184 		{ PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_ALG_SHA512 },
185 	};
186 	size_t n = 0;
187 
188 	for (n = 0; n < ARRAY_SIZE(hmac_hash); n++) {
189 		if (hmac_hash[n].mech == mech_id) {
190 			*algo = hmac_hash[n].tee_id;
191 			return PKCS11_CKR_OK;
192 		}
193 	}
194 
195 	return PKCS11_RV_NOT_FOUND;
196 }
197 
198 static enum pkcs11_rc
allocate_tee_operation(struct pkcs11_session * session,enum processing_func function,struct pkcs11_attribute_head * params,struct pkcs11_object * obj)199 allocate_tee_operation(struct pkcs11_session *session,
200 		       enum processing_func function,
201 		       struct pkcs11_attribute_head *params,
202 		       struct pkcs11_object *obj)
203 {
204 	uint32_t size = (uint32_t)get_object_key_bit_size(obj);
205 	uint32_t key_size = size / 8;
206 	uint32_t algo = 0;
207 	uint32_t mode = 0;
208 	uint32_t max_key_size = 0;
209 	uint32_t min_key_size = 0;
210 	TEE_Result res = TEE_ERROR_GENERIC;
211 
212 	assert(session->processing->tee_op_handle == TEE_HANDLE_NULL &&
213 	       session->processing->tee_op_handle2 == TEE_HANDLE_NULL);
214 
215 	if (pkcs2tee_algorithm(&algo, params))
216 		return PKCS11_CKR_FUNCTION_FAILED;
217 
218 	/* Sign/Verify with AES or generic key relate to TEE MAC operation */
219 	switch (params->id) {
220 	case PKCS11_CKM_MD5_HMAC:
221 	case PKCS11_CKM_SHA_1_HMAC:
222 	case PKCS11_CKM_SHA224_HMAC:
223 	case PKCS11_CKM_SHA256_HMAC:
224 	case PKCS11_CKM_SHA384_HMAC:
225 	case PKCS11_CKM_SHA512_HMAC:
226 	case PKCS11_CKM_MD5_HMAC_GENERAL:
227 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
228 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
229 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
230 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
231 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
232 		mechanism_supported_key_sizes_bytes(params->id, &min_key_size,
233 						    &max_key_size);
234 		if (key_size < min_key_size)
235 			return PKCS11_CKR_KEY_SIZE_RANGE;
236 
237 		/*
238 		 * If size of generic key is greater than the size
239 		 * supported by TEE API, this is not considered an
240 		 * error. When loading TEE key, we will hash the key
241 		 * to generate the appropriate key for HMAC operation.
242 		 * This key size will not be greater than the
243 		 * max_key_size. So we can use max_key_size for
244 		 * TEE_AllocateOperation().
245 		 */
246 		if (key_size > max_key_size)
247 			size = max_key_size * 8;
248 
249 		mode = TEE_MODE_MAC;
250 		break;
251 	case PKCS11_CKM_AES_CMAC:
252 	case PKCS11_CKM_AES_CMAC_GENERAL:
253 		mode = TEE_MODE_MAC;
254 		break;
255 	default:
256 		pkcs2tee_mode(&mode, function);
257 		break;
258 	}
259 
260 	res = TEE_AllocateOperation(&session->processing->tee_op_handle,
261 				    algo, mode, size);
262 	if (res)
263 		EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32,
264 		     algo, mode, size);
265 
266 	if (res == TEE_ERROR_NOT_SUPPORTED)
267 		return PKCS11_CKR_MECHANISM_INVALID;
268 
269 	if (res == TEE_SUCCESS || params->id == PKCS11_CKM_AES_GCM) {
270 		/*
271 		 * Allocate a 2nd operation handler to save the operation state
272 		 * on AES GCM one-shot processing that queries the output
273 		 * buffer size. This is needed as we will need to reset and
274 		 * re-init the TEE operation once we report the expected output
275 		 * buffer size to client that we call again the AE processing
276 		 * function.
277 		 */
278 		TEE_OperationHandle *hdl = &session->processing->tee_op_handle2;
279 
280 		res = TEE_AllocateOperation(hdl, algo, mode, size);
281 	}
282 
283 	return tee2pkcs_error(res);
284 }
285 
hash_secret_helper(enum pkcs11_mechanism_id mech_id,struct pkcs11_object * obj,TEE_Attribute * tee_attr,void ** ctx,size_t * object_size_bits)286 static enum pkcs11_rc hash_secret_helper(enum pkcs11_mechanism_id mech_id,
287 					 struct pkcs11_object *obj,
288 					 TEE_Attribute *tee_attr,
289 					 void **ctx,
290 					 size_t *object_size_bits)
291 {
292 	uint32_t algo = 0;
293 	void *hash_ptr = NULL;
294 	uint32_t hash_size = 0;
295 	enum pkcs11_rc rc = PKCS11_CKR_OK;
296 
297 	rc = hmac_to_tee_hash(&algo, mech_id);
298 	if (rc)
299 		return rc;
300 
301 	hash_size = TEE_ALG_GET_DIGEST_SIZE(algo);
302 	hash_ptr = TEE_Malloc(hash_size, 0);
303 	if (!hash_ptr)
304 		return PKCS11_CKR_DEVICE_MEMORY;
305 
306 	rc = pkcs2tee_load_hashed_attr(tee_attr, TEE_ATTR_SECRET_VALUE, obj,
307 				       PKCS11_CKA_VALUE, algo, hash_ptr,
308 				       &hash_size);
309 	if (rc) {
310 		EMSG("No secret/hash error");
311 		TEE_Free(hash_ptr);
312 		return rc;
313 	}
314 
315 	*ctx = hash_ptr;
316 
317 	*object_size_bits = hash_size * 8;
318 
319 	return PKCS11_CKR_OK;
320 }
321 
load_tee_key(struct pkcs11_session * session,struct pkcs11_object * obj,struct pkcs11_attribute_head * proc_params)322 static enum pkcs11_rc load_tee_key(struct pkcs11_session *session,
323 				   struct pkcs11_object *obj,
324 				   struct pkcs11_attribute_head *proc_params)
325 {
326 	TEE_Attribute tee_attr = { };
327 	size_t object_size = 0;
328 	uint32_t tee_key_type = 0;
329 	enum pkcs11_key_type key_type = 0;
330 	enum pkcs11_rc rc = PKCS11_CKR_OK;
331 	TEE_Result res = TEE_ERROR_GENERIC;
332 	uint32_t max_key_size = 0;
333 	uint32_t min_key_size = 0;
334 
335 	if (obj->key_handle != TEE_HANDLE_NULL) {
336 		/* Key was already loaded and fits current need */
337 		goto key_ready;
338 	}
339 
340 	object_size = get_object_key_bit_size(obj);
341 	if (!object_size)
342 		return PKCS11_CKR_GENERAL_ERROR;
343 
344 	switch (proc_params->id) {
345 	case PKCS11_CKM_MD5_HMAC:
346 	case PKCS11_CKM_SHA_1_HMAC:
347 	case PKCS11_CKM_SHA224_HMAC:
348 	case PKCS11_CKM_SHA256_HMAC:
349 	case PKCS11_CKM_SHA384_HMAC:
350 	case PKCS11_CKM_SHA512_HMAC:
351 	case PKCS11_CKM_MD5_HMAC_GENERAL:
352 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
353 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
354 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
355 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
356 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
357 		key_type = get_key_type(obj->attributes);
358 		/*
359 		 * If Object Key type is PKCS11_CKK_GENERIC_SECRET,
360 		 * determine the tee_key_type using the
361 		 * mechanism instead of object key_type.
362 		 */
363 		if (key_type == PKCS11_CKK_GENERIC_SECRET)
364 			rc = pkcsmech2tee_key_type(&tee_key_type,
365 						   proc_params->id);
366 		else
367 			rc = pkcs2tee_key_type(&tee_key_type, obj);
368 
369 		if (rc)
370 			return rc;
371 
372 		mechanism_supported_key_sizes_bytes(proc_params->id,
373 						    &min_key_size,
374 						    &max_key_size);
375 
376 		if ((object_size / 8) > max_key_size) {
377 			rc = hash_secret_helper(proc_params->id, obj, &tee_attr,
378 						&session->processing->extra_ctx,
379 						&object_size);
380 			if (rc)
381 				return rc;
382 		} else {
383 			if (!pkcs2tee_load_attr(&tee_attr,
384 						TEE_ATTR_SECRET_VALUE,
385 						obj,
386 						PKCS11_CKA_VALUE)) {
387 				EMSG("No secret found");
388 				return PKCS11_CKR_FUNCTION_FAILED;
389 			}
390 		}
391 		break;
392 
393 	default:
394 		rc = pkcs2tee_key_type(&tee_key_type, obj);
395 		if (rc)
396 			return rc;
397 
398 		if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE,
399 					obj, PKCS11_CKA_VALUE)) {
400 			EMSG("No secret found");
401 			return PKCS11_CKR_FUNCTION_FAILED;
402 		}
403 		break;
404 	}
405 
406 	res = TEE_AllocateTransientObject(tee_key_type, object_size,
407 					  &obj->key_handle);
408 	if (res) {
409 		DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res);
410 		return tee2pkcs_error(res);
411 	}
412 
413 	res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1);
414 	if (res) {
415 		DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res);
416 		goto error;
417 	}
418 
419 key_ready:
420 	res = TEE_SetOperationKey(session->processing->tee_op_handle,
421 				  obj->key_handle);
422 	if (res) {
423 		DMSG("TEE_SetOperationKey failed, %#"PRIx32, res);
424 		goto error;
425 	}
426 
427 	return PKCS11_CKR_OK;
428 
429 error:
430 	TEE_FreeTransientObject(obj->key_handle);
431 	obj->key_handle = TEE_HANDLE_NULL;
432 
433 	return tee2pkcs_error(res);
434 }
435 
436 static enum pkcs11_rc
tee_init_derive_symm(struct active_processing * processing,struct pkcs11_attribute_head * proc_params)437 tee_init_derive_symm(struct active_processing *processing,
438 		     struct pkcs11_attribute_head *proc_params)
439 {
440 	struct serialargs args = { };
441 	enum pkcs11_rc rc = PKCS11_CKR_OK;
442 	struct input_data_ref *param = NULL;
443 	void *iv = NULL;
444 
445 	if (!proc_params)
446 		return PKCS11_CKR_ARGUMENTS_BAD;
447 
448 	param =	TEE_Malloc(sizeof(struct input_data_ref), TEE_MALLOC_FILL_ZERO);
449 	if (!param)
450 		return PKCS11_CKR_DEVICE_MEMORY;
451 
452 	serialargs_init(&args, proc_params->data, proc_params->size);
453 
454 	switch (proc_params->id) {
455 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
456 		rc = serialargs_get_ptr(&args, &iv, 16);
457 		if (rc)
458 			goto err;
459 		break;
460 	default:
461 		break;
462 	}
463 
464 	rc = serialargs_get(&args, &param->size, sizeof(uint32_t));
465 	if (rc)
466 		goto err;
467 
468 	rc = serialargs_get_ptr(&args, &param->data, param->size);
469 	if (rc)
470 		goto err;
471 
472 	if (serialargs_remaining_bytes(&args)) {
473 		rc = PKCS11_CKR_ARGUMENTS_BAD;
474 		goto err;
475 	}
476 
477 	processing->extra_ctx = param;
478 
479 	switch (proc_params->id) {
480 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
481 		if (param->size % TEE_AES_BLOCK_SIZE) {
482 			rc = PKCS11_CKR_DATA_LEN_RANGE;
483 			goto err;
484 		}
485 		TEE_CipherInit(processing->tee_op_handle, NULL, 0);
486 		break;
487 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
488 		if (param->size % TEE_AES_BLOCK_SIZE) {
489 			rc = PKCS11_CKR_DATA_LEN_RANGE;
490 			goto err;
491 		}
492 		TEE_CipherInit(processing->tee_op_handle, iv, 16);
493 		break;
494 	default:
495 		TEE_Panic(proc_params->id);
496 		break;
497 	}
498 
499 	return PKCS11_CKR_OK;
500 
501 err:
502 	processing->extra_ctx = NULL;
503 	TEE_Free(param);
504 	return rc;
505 }
506 
507 static enum pkcs11_rc
input_hmac_len_is_valid(struct pkcs11_attribute_head * proc_params,uint32_t hmac_len)508 input_hmac_len_is_valid(struct pkcs11_attribute_head *proc_params,
509 			uint32_t hmac_len)
510 {
511 	uint32_t sign_sz = 0;
512 
513 	switch (proc_params->id) {
514 	case PKCS11_CKM_MD5_HMAC_GENERAL:
515 		sign_sz = TEE_MD5_HASH_SIZE;
516 		break;
517 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
518 		sign_sz = TEE_SHA1_HASH_SIZE;
519 		break;
520 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
521 		sign_sz = TEE_SHA224_HASH_SIZE;
522 		break;
523 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
524 		sign_sz = TEE_SHA256_HASH_SIZE;
525 		break;
526 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
527 		sign_sz = TEE_SHA384_HASH_SIZE;
528 		break;
529 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
530 		sign_sz = TEE_SHA512_HASH_SIZE;
531 		break;
532 	case PKCS11_CKM_AES_CMAC_GENERAL:
533 		sign_sz = TEE_AES_BLOCK_SIZE;
534 		break;
535 	default:
536 		return PKCS11_CKR_MECHANISM_INVALID;
537 	}
538 
539 	if (!hmac_len || hmac_len > sign_sz)
540 		return PKCS11_CKR_SIGNATURE_LEN_RANGE;
541 
542 	return PKCS11_CKR_OK;
543 }
544 
545 static enum pkcs11_rc
init_tee_operation(struct pkcs11_session * session,struct pkcs11_attribute_head * proc_params)546 init_tee_operation(struct pkcs11_session *session,
547 		   struct pkcs11_attribute_head *proc_params)
548 {
549 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
550 	uint32_t *pkcs11_data = NULL;
551 
552 	switch (proc_params->id) {
553 	case PKCS11_CKM_AES_CMAC:
554 	case PKCS11_CKM_MD5_HMAC:
555 	case PKCS11_CKM_SHA_1_HMAC:
556 	case PKCS11_CKM_SHA224_HMAC:
557 	case PKCS11_CKM_SHA256_HMAC:
558 	case PKCS11_CKM_SHA384_HMAC:
559 	case PKCS11_CKM_SHA512_HMAC:
560 		if (proc_params->size)
561 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
562 
563 		TEE_MACInit(session->processing->tee_op_handle, NULL, 0);
564 		rc = PKCS11_CKR_OK;
565 		break;
566 	case PKCS11_CKM_AES_CMAC_GENERAL:
567 	case PKCS11_CKM_MD5_HMAC_GENERAL:
568 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
569 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
570 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
571 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
572 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
573 		if (proc_params->size != sizeof(uint32_t))
574 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
575 
576 		pkcs11_data = TEE_Malloc(sizeof(uint32_t),
577 					 TEE_MALLOC_FILL_ZERO);
578 		if (!pkcs11_data)
579 			return PKCS11_CKR_DEVICE_MEMORY;
580 
581 		TEE_MemMove(pkcs11_data, proc_params->data, sizeof(uint32_t));
582 
583 		rc = input_hmac_len_is_valid(proc_params, *pkcs11_data);
584 		if (rc) {
585 			TEE_Free(pkcs11_data);
586 			return rc;
587 		}
588 
589 		session->processing->extra_ctx = (void *)pkcs11_data;
590 
591 		TEE_MACInit(session->processing->tee_op_handle, NULL, 0);
592 		rc = PKCS11_CKR_OK;
593 		break;
594 	case PKCS11_CKM_AES_ECB:
595 		if (proc_params->size)
596 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
597 
598 		TEE_CipherInit(session->processing->tee_op_handle, NULL, 0);
599 		rc = PKCS11_CKR_OK;
600 		break;
601 	case PKCS11_CKM_AES_CBC:
602 	case PKCS11_CKM_AES_CTS:
603 		if (proc_params->size != 16)
604 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
605 
606 		TEE_CipherInit(session->processing->tee_op_handle,
607 			       proc_params->data, 16);
608 		rc = PKCS11_CKR_OK;
609 		break;
610 	case PKCS11_CKM_AES_CTR:
611 		rc = tee_init_ctr_operation(session->processing,
612 					    proc_params->data,
613 					    proc_params->size);
614 		break;
615 	case PKCS11_CKM_AES_GCM:
616 		rc = tee_init_gcm_operation(session,
617 					    proc_params->data,
618 					    proc_params->size);
619 		break;
620 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
621 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
622 		rc = tee_init_derive_symm(session->processing, proc_params);
623 		break;
624 	default:
625 		TEE_Panic(proc_params->id);
626 		break;
627 	}
628 
629 	return rc;
630 }
631 
init_symm_operation(struct pkcs11_session * session,enum processing_func function,struct pkcs11_attribute_head * proc_params,struct pkcs11_object * obj)632 enum pkcs11_rc init_symm_operation(struct pkcs11_session *session,
633 				   enum processing_func function,
634 				   struct pkcs11_attribute_head *proc_params,
635 				   struct pkcs11_object *obj)
636 {
637 	enum pkcs11_rc rc = PKCS11_CKR_OK;
638 
639 	assert(processing_is_tee_symm(proc_params->id));
640 
641 	rc = allocate_tee_operation(session, function, proc_params, obj);
642 	if (rc)
643 		return rc;
644 
645 	rc = load_tee_key(session, obj, proc_params);
646 	if (rc)
647 		return rc;
648 
649 	rc = init_tee_operation(session, proc_params);
650 	if (!rc)
651 		session->processing->mecha_type = proc_params->id;
652 
653 	return rc;
654 }
655 
656 /* Validate input buffer size as per PKCS#11 constraints */
input_data_size_is_valid(struct active_processing * proc,enum processing_func function,size_t in_size)657 static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc,
658 					       enum processing_func function,
659 					       size_t in_size)
660 {
661 	switch (proc->mecha_type) {
662 	case PKCS11_CKM_AES_ECB:
663 	case PKCS11_CKM_AES_CBC:
664 		if (function == PKCS11_FUNCTION_ENCRYPT &&
665 		    in_size % TEE_AES_BLOCK_SIZE)
666 			return PKCS11_CKR_DATA_LEN_RANGE;
667 		if (function == PKCS11_FUNCTION_DECRYPT &&
668 		    in_size % TEE_AES_BLOCK_SIZE)
669 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
670 		break;
671 	case PKCS11_CKM_AES_CTS:
672 		if (function == PKCS11_FUNCTION_ENCRYPT &&
673 		    in_size < TEE_AES_BLOCK_SIZE)
674 			return PKCS11_CKR_DATA_LEN_RANGE;
675 		if (function == PKCS11_FUNCTION_DECRYPT &&
676 		    in_size < TEE_AES_BLOCK_SIZE)
677 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
678 		break;
679 	default:
680 		break;
681 	}
682 
683 	return PKCS11_CKR_OK;
684 }
685 
686 /* Validate input buffer size as per PKCS#11 constraints */
input_sign_size_is_valid(struct active_processing * proc,size_t in_size)687 static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc,
688 					       size_t in_size)
689 {
690 	size_t sign_sz = 0;
691 
692 	switch (proc->mecha_type) {
693 	case PKCS11_CKM_MD5_HMAC:
694 		sign_sz = TEE_MD5_HASH_SIZE;
695 		break;
696 	case PKCS11_CKM_SHA_1_HMAC:
697 		sign_sz = TEE_SHA1_HASH_SIZE;
698 		break;
699 	case PKCS11_CKM_SHA224_HMAC:
700 		sign_sz = TEE_SHA224_HASH_SIZE;
701 		break;
702 	case PKCS11_CKM_SHA256_HMAC:
703 		sign_sz = TEE_SHA256_HASH_SIZE;
704 		break;
705 	case PKCS11_CKM_SHA384_HMAC:
706 		sign_sz = TEE_SHA384_HASH_SIZE;
707 		break;
708 	case PKCS11_CKM_SHA512_HMAC:
709 		sign_sz = TEE_SHA512_HASH_SIZE;
710 		break;
711 	case PKCS11_CKM_AES_CMAC:
712 		sign_sz = TEE_AES_BLOCK_SIZE;
713 		break;
714 	default:
715 		return PKCS11_CKR_GENERAL_ERROR;
716 	}
717 
718 	if (in_size != sign_sz)
719 		return PKCS11_CKR_SIGNATURE_LEN_RANGE;
720 
721 	return PKCS11_CKR_OK;
722 }
723 
724 /*
725  * step_sym_cipher - processing symmetric (and related) cipher operation step
726  *
727  * @session - current session
728  * @function - processing function (encrypt, decrypt, sign, ...)
729  * @step - step ID in the processing (oneshot, update, final)
730  * @ptype - invocation parameter types
731  * @params - invocation parameter references
732  */
step_symm_operation(struct pkcs11_session * session,enum processing_func function,enum processing_step step,uint32_t ptypes,TEE_Param * params)733 enum pkcs11_rc step_symm_operation(struct pkcs11_session *session,
734 				   enum processing_func function,
735 				   enum processing_step step,
736 				   uint32_t ptypes, TEE_Param *params)
737 {
738 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
739 	TEE_Result res = TEE_ERROR_GENERIC;
740 	void *in_buf = NULL;
741 	size_t in_size = 0;
742 	void *out_buf = NULL;
743 	size_t out_size = 0;
744 	void *in2_buf = NULL;
745 	uint32_t in2_size = 0;
746 	bool output_data = false;
747 	struct active_processing *proc = session->processing;
748 	uint32_t hmac_len = 0;
749 	uint8_t computed_mac[TEE_MAX_HASH_SIZE] = { 0 };
750 	size_t computed_mac_size = TEE_MAX_HASH_SIZE;
751 	size_t ae_out_size = 0;
752 
753 	if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
754 		in_buf = params[1].memref.buffer;
755 		in_size = params[1].memref.size;
756 		if (in_size && !in_buf)
757 			return PKCS11_CKR_ARGUMENTS_BAD;
758 	}
759 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) {
760 		in2_buf = params[2].memref.buffer;
761 		in2_size = params[2].memref.size;
762 		if (in2_size && !in2_buf)
763 			return PKCS11_CKR_ARGUMENTS_BAD;
764 	}
765 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) {
766 		out_buf = params[2].memref.buffer;
767 		out_size = params[2].memref.size;
768 		ae_out_size = out_size;
769 		if (out_size && !out_buf)
770 			return PKCS11_CKR_ARGUMENTS_BAD;
771 	}
772 	if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
773 		return PKCS11_CKR_ARGUMENTS_BAD;
774 
775 	switch (step) {
776 	case PKCS11_FUNC_STEP_ONESHOT:
777 	case PKCS11_FUNC_STEP_UPDATE:
778 	case PKCS11_FUNC_STEP_FINAL:
779 		break;
780 	default:
781 		return PKCS11_CKR_GENERAL_ERROR;
782 	}
783 
784 	if (step != PKCS11_FUNC_STEP_FINAL) {
785 		rc = input_data_size_is_valid(proc, function, in_size);
786 		if (rc)
787 			return rc;
788 	}
789 
790 	/*
791 	 * Feed active operation with data
792 	 */
793 	switch (proc->mecha_type) {
794 	case PKCS11_CKM_AES_CMAC:
795 	case PKCS11_CKM_MD5_HMAC:
796 	case PKCS11_CKM_SHA_1_HMAC:
797 	case PKCS11_CKM_SHA224_HMAC:
798 	case PKCS11_CKM_SHA256_HMAC:
799 	case PKCS11_CKM_SHA384_HMAC:
800 	case PKCS11_CKM_SHA512_HMAC:
801 	case PKCS11_CKM_AES_CMAC_GENERAL:
802 	case PKCS11_CKM_MD5_HMAC_GENERAL:
803 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
804 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
805 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
806 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
807 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
808 		if (step == PKCS11_FUNC_STEP_FINAL ||
809 		    step == PKCS11_FUNC_STEP_ONESHOT)
810 			break;
811 
812 		if (!in_buf) {
813 			DMSG("No input data");
814 			return PKCS11_CKR_ARGUMENTS_BAD;
815 		}
816 
817 		switch (function) {
818 		case PKCS11_FUNCTION_SIGN:
819 		case PKCS11_FUNCTION_VERIFY:
820 			TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size);
821 			rc = PKCS11_CKR_OK;
822 			break;
823 		default:
824 			TEE_Panic(function);
825 			break;
826 		}
827 		break;
828 
829 	case PKCS11_CKM_AES_ECB:
830 	case PKCS11_CKM_AES_CBC:
831 	case PKCS11_CKM_AES_CTS:
832 	case PKCS11_CKM_AES_CTR:
833 		if (step == PKCS11_FUNC_STEP_FINAL ||
834 		    step == PKCS11_FUNC_STEP_ONESHOT)
835 			break;
836 
837 		if (!in_buf) {
838 			EMSG("No input data");
839 			return PKCS11_CKR_ARGUMENTS_BAD;
840 		}
841 
842 		switch (function) {
843 		case PKCS11_FUNCTION_ENCRYPT:
844 		case PKCS11_FUNCTION_DECRYPT:
845 			res = TEE_CipherUpdate(proc->tee_op_handle,
846 					       in_buf, in_size,
847 						out_buf, &out_size);
848 			output_data = true;
849 			rc = tee2pkcs_error(res);
850 			break;
851 		default:
852 			TEE_Panic(function);
853 			break;
854 		}
855 		break;
856 	case PKCS11_CKM_AES_GCM:
857 		if (step == PKCS11_FUNC_STEP_FINAL)
858 			break;
859 
860 		switch (function) {
861 		case PKCS11_FUNCTION_ENCRYPT:
862 			res = TEE_AEUpdate(proc->tee_op_handle,
863 					   in_buf, in_size, out_buf, &out_size);
864 
865 			output_data = true;
866 			rc = tee2pkcs_error(res);
867 			if (rc && rc != PKCS11_CKR_BUFFER_TOO_SMALL)
868 				return rc;
869 			if (step == PKCS11_FUNC_STEP_ONESHOT) {
870 				if (rc == PKCS11_CKR_BUFFER_TOO_SMALL) {
871 					/* Return output data size incl. tag*/
872 					out_size += 16;
873 					goto out;
874 				}
875 				out_buf = (char *)out_buf + out_size;
876 				/* Remaining space for the tag data */
877 				ae_out_size -= out_size;
878 			}
879 			break;
880 		case PKCS11_FUNCTION_DECRYPT:
881 			rc = tee_ae_decrypt_update(session, in_buf, in_size);
882 			assert(rc != PKCS11_CKR_BUFFER_TOO_SMALL);
883 			if (rc)
884 				return rc;
885 			/* Do not output decrypted data until tag is verified */
886 			out_size = 0;
887 			output_data = true;
888 			break;
889 		default:
890 			TEE_Panic(function);
891 			break;
892 		}
893 		break;
894 	default:
895 		TEE_Panic(proc->mecha_type);
896 		break;
897 	}
898 
899 	if (step == PKCS11_FUNC_STEP_UPDATE)
900 		goto out;
901 
902 	/*
903 	 * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation
904 	 */
905 	switch (proc->mecha_type) {
906 	case PKCS11_CKM_AES_CMAC:
907 	case PKCS11_CKM_MD5_HMAC:
908 	case PKCS11_CKM_SHA_1_HMAC:
909 	case PKCS11_CKM_SHA224_HMAC:
910 	case PKCS11_CKM_SHA256_HMAC:
911 	case PKCS11_CKM_SHA384_HMAC:
912 	case PKCS11_CKM_SHA512_HMAC:
913 		switch (function) {
914 		case PKCS11_FUNCTION_SIGN:
915 			res = TEE_MACComputeFinal(proc->tee_op_handle,
916 						  in_buf, in_size, out_buf,
917 						  &out_size);
918 			output_data = true;
919 			rc = tee2pkcs_error(res);
920 			break;
921 		case PKCS11_FUNCTION_VERIFY:
922 			rc = input_sign_size_is_valid(proc, in2_size);
923 			if (rc)
924 				return rc;
925 			res = TEE_MACCompareFinal(proc->tee_op_handle,
926 						  in_buf, in_size, in2_buf,
927 						  in2_size);
928 			rc = tee2pkcs_error(res);
929 			break;
930 		default:
931 			TEE_Panic(function);
932 			break;
933 		}
934 
935 		break;
936 
937 	case PKCS11_CKM_AES_CMAC_GENERAL:
938 	case PKCS11_CKM_MD5_HMAC_GENERAL:
939 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
940 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
941 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
942 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
943 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
944 		assert(proc->extra_ctx);
945 		hmac_len = *(uint32_t *)proc->extra_ctx;
946 
947 		switch (function) {
948 		case PKCS11_FUNCTION_SIGN:
949 			if (out_size < hmac_len) {
950 				/* inform client of required size */
951 				out_size = hmac_len;
952 				output_data = true;
953 				rc = PKCS11_CKR_BUFFER_TOO_SMALL;
954 				goto out;
955 			}
956 
957 			res = TEE_MACComputeFinal(proc->tee_op_handle,
958 						  in_buf, in_size,
959 						  computed_mac,
960 						  &computed_mac_size);
961 			if (res == TEE_SUCCESS) {
962 				/* truncate to hmac_len */
963 				TEE_MemMove(out_buf, computed_mac, hmac_len);
964 				output_data = true;
965 			}
966 
967 			/* inform client of required size */
968 			out_size = hmac_len;
969 			rc = tee2pkcs_error(res);
970 			break;
971 		case PKCS11_FUNCTION_VERIFY:
972 			/* must compute full MAC before comparing partial */
973 			res = TEE_MACComputeFinal(proc->tee_op_handle, in_buf,
974 						  in_size, computed_mac,
975 						  &computed_mac_size);
976 
977 			if (!in2_size || in2_size > computed_mac_size) {
978 				EMSG("Invalid signature size: %"PRIu32,
979 				     in2_size);
980 				return PKCS11_CKR_SIGNATURE_LEN_RANGE;
981 			}
982 
983 			if (res == TEE_SUCCESS) {
984 				/*
985 				 * Only the first in2_size bytes of the
986 				 * signature to be verified is passed in from
987 				 * caller
988 				 */
989 				if (TEE_MemCompare(in2_buf, computed_mac,
990 						   in2_size)) {
991 					res = TEE_ERROR_MAC_INVALID;
992 				}
993 			}
994 
995 			rc = tee2pkcs_error(res);
996 			break;
997 		default:
998 			TEE_Panic(function);
999 			break;
1000 		}
1001 
1002 		break;
1003 
1004 	case PKCS11_CKM_AES_ECB:
1005 	case PKCS11_CKM_AES_CBC:
1006 	case PKCS11_CKM_AES_CTS:
1007 	case PKCS11_CKM_AES_CTR:
1008 		if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) {
1009 			EMSG("No input data");
1010 			return PKCS11_CKR_ARGUMENTS_BAD;
1011 		}
1012 
1013 		switch (function) {
1014 		case PKCS11_FUNCTION_ENCRYPT:
1015 		case PKCS11_FUNCTION_DECRYPT:
1016 			res = TEE_CipherDoFinal(proc->tee_op_handle,
1017 						in_buf, in_size,
1018 						out_buf, &out_size);
1019 			output_data = true;
1020 			rc = tee2pkcs_error(res);
1021 			break;
1022 		default:
1023 			TEE_Panic(function);
1024 			break;
1025 		}
1026 		break;
1027 	case PKCS11_CKM_AES_GCM:
1028 		switch (function) {
1029 		case PKCS11_FUNCTION_ENCRYPT:
1030 			rc = tee_ae_encrypt_final(session, out_buf,
1031 						  &ae_out_size);
1032 			output_data = true;
1033 			if (step == PKCS11_FUNC_STEP_ONESHOT)
1034 				out_size += ae_out_size;
1035 			else
1036 				out_size = ae_out_size;
1037 			break;
1038 		case PKCS11_FUNCTION_DECRYPT:
1039 			/* Now we're ready to reveal data */
1040 			out_size = ae_out_size;
1041 			rc = tee_ae_decrypt_final(session, out_buf, &out_size);
1042 			output_data = true;
1043 			break;
1044 		default:
1045 			TEE_Panic(function);
1046 			break;
1047 		}
1048 
1049 		if (step == PKCS11_FUNC_STEP_ONESHOT &&
1050 		    rc == PKCS11_CKR_BUFFER_TOO_SMALL) {
1051 			enum pkcs11_rc rc2 = PKCS11_CKR_OK;
1052 
1053 			/*
1054 			 * Change operation state to its initial state
1055 			 * as client will likely request again the
1056 			 * one-shot processing but possibly with
1057 			 * different input data.
1058 			 */
1059 			rc2 = tee_ae_reinit_gcm_operation(session);
1060 			if (rc2)
1061 				return rc2;
1062 		}
1063 		break;
1064 	default:
1065 		TEE_Panic(proc->mecha_type);
1066 		break;
1067 	}
1068 
1069 out:
1070 	if (output_data &&
1071 	    (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) {
1072 		switch (TEE_PARAM_TYPE_GET(ptypes, 2)) {
1073 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
1074 		case TEE_PARAM_TYPE_MEMREF_INOUT:
1075 			params[2].memref.size = out_size;
1076 			break;
1077 		default:
1078 			rc = PKCS11_CKR_ARGUMENTS_BAD;
1079 			break;
1080 		}
1081 	}
1082 
1083 	return rc;
1084 }
1085 
derive_key_by_symm_enc(struct pkcs11_session * session,void ** out_buf,uint32_t * out_size)1086 enum pkcs11_rc derive_key_by_symm_enc(struct pkcs11_session *session,
1087 				      void **out_buf, uint32_t *out_size)
1088 {
1089 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
1090 	TEE_Result res = TEE_ERROR_GENERIC;
1091 	struct active_processing *proc = session->processing;
1092 	struct input_data_ref *input = proc->extra_ctx;
1093 	void *in_buf = NULL;
1094 	void *dest_buf = NULL;
1095 	uint32_t in_size = 0;
1096 	size_t tmp_sz = 0;
1097 
1098 	switch (proc->mecha_type) {
1099 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
1100 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
1101 		if (!proc->extra_ctx)
1102 			return PKCS11_CKR_ARGUMENTS_BAD;
1103 
1104 		in_buf = input->data;
1105 		in_size = input->size;
1106 
1107 		*out_size = in_size;
1108 		dest_buf = TEE_Malloc(*out_size, 0);
1109 		if (!dest_buf)
1110 			return PKCS11_CKR_DEVICE_MEMORY;
1111 
1112 		tmp_sz = *out_size;
1113 		res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_size,
1114 					dest_buf, &tmp_sz);
1115 		*out_size = tmp_sz;
1116 		rc = tee2pkcs_error(res);
1117 		if (rc) {
1118 			TEE_Free(dest_buf);
1119 			return rc;
1120 		}
1121 
1122 		*out_buf = dest_buf;
1123 		break;
1124 	default:
1125 		return PKCS11_CKR_MECHANISM_INVALID;
1126 	}
1127 
1128 	return rc;
1129 }
1130 
wrap_data_by_symm_enc(struct pkcs11_session * session,void * data,uint32_t data_sz,void * out_buf,uint32_t * out_sz)1131 enum pkcs11_rc wrap_data_by_symm_enc(struct pkcs11_session *session,
1132 				     void *data, uint32_t data_sz,
1133 				     void *out_buf, uint32_t *out_sz)
1134 {
1135 	TEE_Result res = TEE_ERROR_GENERIC;
1136 	struct active_processing *proc = session->processing;
1137 	void *in_buf = NULL;
1138 	uint32_t align = 0;
1139 	uint32_t in_sz = data_sz;
1140 	size_t tmp_sz = *out_sz;
1141 	uint8_t *tmp_buf = out_buf;
1142 
1143 	switch (proc->mecha_type) {
1144 	case PKCS11_CKM_AES_ECB:
1145 	case PKCS11_CKM_AES_CBC:
1146 		align = data_sz % TEE_AES_BLOCK_SIZE;
1147 		if (align)
1148 			in_sz = data_sz + (TEE_AES_BLOCK_SIZE - align);
1149 
1150 		if (*out_sz < in_sz) {
1151 			*out_sz = in_sz;
1152 			return PKCS11_CKR_BUFFER_TOO_SMALL;
1153 		}
1154 
1155 		if (align) {
1156 			if (data_sz > TEE_AES_BLOCK_SIZE) {
1157 				in_sz = data_sz - align;
1158 				res = TEE_CipherUpdate(proc->tee_op_handle,
1159 						       data, in_sz, tmp_buf,
1160 						       &tmp_sz);
1161 				if (res) {
1162 					assert(res != TEE_ERROR_SHORT_BUFFER);
1163 					return tee2pkcs_error(res);
1164 				}
1165 				tmp_buf += tmp_sz;
1166 				tmp_sz = *out_sz - tmp_sz;
1167 			} else {
1168 				in_sz = 0;
1169 			}
1170 
1171 			in_buf = TEE_Malloc(TEE_AES_BLOCK_SIZE,
1172 					    TEE_MALLOC_FILL_ZERO);
1173 			if (!in_buf)
1174 				return PKCS11_CKR_DEVICE_MEMORY;
1175 
1176 			TEE_MemMove(in_buf, (uint8_t *)data + in_sz, align);
1177 			in_sz = TEE_AES_BLOCK_SIZE;
1178 		} else {
1179 			in_buf = data;
1180 			in_sz = data_sz;
1181 		}
1182 
1183 		res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_sz,
1184 					tmp_buf, &tmp_sz);
1185 		if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
1186 			*out_sz = tmp_sz;
1187 			if (align)
1188 				*out_sz += tmp_buf - (uint8_t *)out_buf;
1189 		}
1190 
1191 		if (align)
1192 			TEE_Free(in_buf);
1193 
1194 		return tee2pkcs_error(res);
1195 	default:
1196 		return PKCS11_CKR_MECHANISM_INVALID;
1197 	}
1198 
1199 	return PKCS11_CKR_GENERAL_ERROR;
1200 }
1201 
unwrap_key_by_symm(struct pkcs11_session * session,void * data,uint32_t data_sz,void ** out_buf,uint32_t * out_sz)1202 enum pkcs11_rc unwrap_key_by_symm(struct pkcs11_session *session, void *data,
1203 				  uint32_t data_sz, void **out_buf,
1204 				  uint32_t *out_sz)
1205 {
1206 	TEE_Result res = TEE_ERROR_GENERIC;
1207 	struct active_processing *proc = session->processing;
1208 	size_t tmp_sz = 0;
1209 
1210 	if (input_data_size_is_valid(proc, PKCS11_FUNCTION_DECRYPT, data_sz))
1211 		return PKCS11_CKR_WRAPPED_KEY_LEN_RANGE;
1212 
1213 	switch (proc->mecha_type) {
1214 	case PKCS11_CKM_AES_ECB:
1215 	case PKCS11_CKM_AES_CBC:
1216 		*out_sz = 0;
1217 		res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz,
1218 					NULL, &tmp_sz);
1219 		*out_sz = tmp_sz;
1220 		if (res != TEE_ERROR_SHORT_BUFFER) {
1221 			DMSG("TEE_CipherDoFinal() issue: %#"PRIx32, res);
1222 			return PKCS11_CKR_GENERAL_ERROR;
1223 		}
1224 
1225 		*out_buf = TEE_Malloc(*out_sz, TEE_MALLOC_FILL_ZERO);
1226 		if (!*out_buf)
1227 			return PKCS11_CKR_DEVICE_MEMORY;
1228 
1229 		res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz,
1230 					*out_buf, &tmp_sz);
1231 		*out_sz = tmp_sz;
1232 		if (tee2pkcs_error(res)) {
1233 			TEE_Free(*out_buf);
1234 			*out_buf = NULL;
1235 			return PKCS11_CKR_WRAPPED_KEY_INVALID;
1236 		}
1237 		break;
1238 	default:
1239 		return PKCS11_CKR_MECHANISM_INVALID;
1240 	}
1241 
1242 	return PKCS11_CKR_OK;
1243 }
1244