xref: /optee_os/ta/pkcs11/src/processing_symm.c (revision 4af447d4084e293800d4e463d65003c016b91f29)
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 
28 bool processing_is_tee_symm(enum pkcs11_mechanism_id proc_id)
29 {
30 	switch (proc_id) {
31 	/* Authentication */
32 	case PKCS11_CKM_MD5_HMAC:
33 	case PKCS11_CKM_SHA_1_HMAC:
34 	case PKCS11_CKM_SHA224_HMAC:
35 	case PKCS11_CKM_SHA256_HMAC:
36 	case PKCS11_CKM_SHA384_HMAC:
37 	case PKCS11_CKM_SHA512_HMAC:
38 	/* Cipherering */
39 	case PKCS11_CKM_AES_ECB:
40 	case PKCS11_CKM_AES_CBC:
41 	case PKCS11_CKM_AES_CBC_PAD:
42 	case PKCS11_CKM_AES_CTS:
43 	case PKCS11_CKM_AES_CTR:
44 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
45 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
46 		return true;
47 	default:
48 		return false;
49 	}
50 }
51 
52 static enum pkcs11_rc
53 pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params)
54 {
55 	static const struct {
56 		enum pkcs11_mechanism_id mech_id;
57 		uint32_t tee_id;
58 	} pkcs2tee_algo[] = {
59 		/* AES flavors */
60 		{ PKCS11_CKM_AES_ECB, TEE_ALG_AES_ECB_NOPAD },
61 		{ PKCS11_CKM_AES_CBC, TEE_ALG_AES_CBC_NOPAD },
62 		{ PKCS11_CKM_AES_CBC_PAD, TEE_ALG_AES_CBC_NOPAD },
63 		{ PKCS11_CKM_AES_ECB_ENCRYPT_DATA, TEE_ALG_AES_ECB_NOPAD },
64 		{ PKCS11_CKM_AES_CBC_ENCRYPT_DATA, TEE_ALG_AES_CBC_NOPAD },
65 		{ PKCS11_CKM_AES_CTR, TEE_ALG_AES_CTR },
66 		{ PKCS11_CKM_AES_CTS, TEE_ALG_AES_CTS },
67 		/* HMAC flavors */
68 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_HMAC_MD5 },
69 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_HMAC_SHA1 },
70 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_HMAC_SHA224 },
71 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_HMAC_SHA256 },
72 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_HMAC_SHA384 },
73 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_HMAC_SHA512 },
74 	};
75 	size_t n = 0;
76 
77 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) {
78 		if (proc_params->id == pkcs2tee_algo[n].mech_id) {
79 			*tee_id = pkcs2tee_algo[n].tee_id;
80 			return PKCS11_CKR_OK;
81 		}
82 	}
83 
84 	return PKCS11_RV_NOT_IMPLEMENTED;
85 }
86 
87 static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type,
88 					struct pkcs11_object *obj)
89 {
90 	static const struct {
91 		enum pkcs11_key_type key_type;
92 		uint32_t tee_id;
93 	} pkcs2tee_key_type[] = {
94 		{ PKCS11_CKK_AES, TEE_TYPE_AES },
95 		{ PKCS11_CKK_GENERIC_SECRET, TEE_TYPE_GENERIC_SECRET },
96 		{ PKCS11_CKK_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
97 		{ PKCS11_CKK_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
98 		{ PKCS11_CKK_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
99 		{ PKCS11_CKK_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
100 		{ PKCS11_CKK_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
101 		{ PKCS11_CKK_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
102 	};
103 	size_t n = 0;
104 	enum pkcs11_key_type key_type = get_key_type(obj->attributes);
105 
106 	assert(get_class(obj->attributes) == PKCS11_CKO_SECRET_KEY);
107 
108 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
109 		if (pkcs2tee_key_type[n].key_type == key_type) {
110 			*tee_type = pkcs2tee_key_type[n].tee_id;
111 			return PKCS11_CKR_OK;
112 		}
113 	}
114 
115 	return PKCS11_RV_NOT_FOUND;
116 }
117 
118 static enum pkcs11_rc pkcsmech2tee_key_type(uint32_t *tee_type,
119 					    enum pkcs11_mechanism_id mech_id)
120 {
121 	static const struct {
122 		enum pkcs11_mechanism_id mech;
123 		uint32_t tee_id;
124 	} pkcs2tee_key_type[] = {
125 		{ PKCS11_CKM_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
126 		{ PKCS11_CKM_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
127 		{ PKCS11_CKM_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
128 		{ PKCS11_CKM_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
129 		{ PKCS11_CKM_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
130 		{ PKCS11_CKM_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
131 	};
132 	size_t n = 0;
133 
134 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
135 		if (pkcs2tee_key_type[n].mech == mech_id) {
136 			*tee_type = pkcs2tee_key_type[n].tee_id;
137 			return PKCS11_CKR_OK;
138 		}
139 	}
140 
141 	return PKCS11_RV_NOT_FOUND;
142 }
143 
144 static enum pkcs11_rc hmac_to_tee_hash(uint32_t *algo,
145 				       enum pkcs11_mechanism_id mech_id)
146 {
147 	static const struct {
148 		enum pkcs11_mechanism_id mech;
149 		uint32_t tee_id;
150 	} hmac_hash[] = {
151 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_MD5 },
152 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_SHA1 },
153 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_SHA224 },
154 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_SHA256 },
155 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_SHA384 },
156 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_SHA512 },
157 	};
158 	size_t n = 0;
159 
160 	for (n = 0; n < ARRAY_SIZE(hmac_hash); n++) {
161 		if (hmac_hash[n].mech == mech_id) {
162 			*algo = hmac_hash[n].tee_id;
163 			return PKCS11_CKR_OK;
164 		}
165 	}
166 
167 	return PKCS11_RV_NOT_FOUND;
168 }
169 
170 static enum pkcs11_rc
171 allocate_tee_operation(struct pkcs11_session *session,
172 		       enum processing_func function,
173 		       struct pkcs11_attribute_head *params,
174 		       struct pkcs11_object *obj)
175 {
176 	uint32_t size = (uint32_t)get_object_key_bit_size(obj);
177 	uint32_t key_size = size / 8;
178 	uint32_t algo = 0;
179 	uint32_t mode = 0;
180 	uint32_t max_key_size = 0;
181 	uint32_t min_key_size = 0;
182 	TEE_Result res = TEE_ERROR_GENERIC;
183 
184 	assert(session->processing->tee_op_handle == TEE_HANDLE_NULL);
185 
186 	if (pkcs2tee_algorithm(&algo, params))
187 		return PKCS11_CKR_FUNCTION_FAILED;
188 
189 	/* Sign/Verify with AES or generic key relate to TEE MAC operation */
190 	switch (params->id) {
191 	case PKCS11_CKM_MD5_HMAC:
192 	case PKCS11_CKM_SHA_1_HMAC:
193 	case PKCS11_CKM_SHA224_HMAC:
194 	case PKCS11_CKM_SHA256_HMAC:
195 	case PKCS11_CKM_SHA384_HMAC:
196 	case PKCS11_CKM_SHA512_HMAC:
197 		mechanism_supported_key_sizes_bytes(params->id, &min_key_size,
198 						    &max_key_size);
199 		if (key_size < min_key_size)
200 			return PKCS11_CKR_KEY_SIZE_RANGE;
201 
202 		/*
203 		 * If size of generic key is greater than the size
204 		 * supported by TEE API, this is not considered an
205 		 * error. When loading TEE key, we will hash the key
206 		 * to generate the appropriate key for HMAC operation.
207 		 * This key size will not be greater than the
208 		 * max_key_size. So we can use max_key_size for
209 		 * TEE_AllocateOperation().
210 		 */
211 		if (key_size > max_key_size)
212 			size = max_key_size * 8;
213 
214 		mode = TEE_MODE_MAC;
215 		break;
216 	default:
217 		pkcs2tee_mode(&mode, function);
218 		break;
219 	}
220 
221 	res = TEE_AllocateOperation(&session->processing->tee_op_handle,
222 				    algo, mode, size);
223 	if (res)
224 		EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32,
225 		     algo, mode, size);
226 
227 	if (res == TEE_ERROR_NOT_SUPPORTED)
228 		return PKCS11_CKR_MECHANISM_INVALID;
229 
230 	return tee2pkcs_error(res);
231 }
232 
233 static enum pkcs11_rc hash_secret_helper(enum pkcs11_mechanism_id mech_id,
234 					 struct pkcs11_object *obj,
235 					 TEE_Attribute *tee_attr,
236 					 void **ctx,
237 					 size_t *object_size_bits)
238 {
239 	uint32_t algo = 0;
240 	void *hash_ptr = NULL;
241 	uint32_t hash_size = 0;
242 	enum pkcs11_rc rc = PKCS11_CKR_OK;
243 
244 	rc = hmac_to_tee_hash(&algo, mech_id);
245 	if (rc)
246 		return rc;
247 
248 	hash_size = TEE_ALG_GET_DIGEST_SIZE(algo);
249 	hash_ptr = TEE_Malloc(hash_size, 0);
250 	if (!hash_ptr)
251 		return PKCS11_CKR_DEVICE_MEMORY;
252 
253 	rc = pkcs2tee_load_hashed_attr(tee_attr, TEE_ATTR_SECRET_VALUE, obj,
254 				       PKCS11_CKA_VALUE, algo, hash_ptr,
255 				       &hash_size);
256 	if (rc) {
257 		EMSG("No secret/hash error");
258 		TEE_Free(hash_ptr);
259 		return rc;
260 	}
261 
262 	*ctx = hash_ptr;
263 
264 	*object_size_bits = hash_size * 8;
265 
266 	return PKCS11_CKR_OK;
267 }
268 
269 static enum pkcs11_rc load_tee_key(struct pkcs11_session *session,
270 				   struct pkcs11_object *obj,
271 				   struct pkcs11_attribute_head *proc_params)
272 {
273 	TEE_Attribute tee_attr = { };
274 	size_t object_size = 0;
275 	uint32_t tee_key_type = 0;
276 	enum pkcs11_key_type key_type = 0;
277 	enum pkcs11_rc rc = PKCS11_CKR_OK;
278 	TEE_Result res = TEE_ERROR_GENERIC;
279 	uint32_t max_key_size = 0;
280 	uint32_t min_key_size = 0;
281 
282 	if (obj->key_handle != TEE_HANDLE_NULL) {
283 		/* Key was already loaded and fits current need */
284 		goto key_ready;
285 	}
286 
287 	object_size = get_object_key_bit_size(obj);
288 	if (!object_size)
289 		return PKCS11_CKR_GENERAL_ERROR;
290 
291 	switch (proc_params->id) {
292 	case PKCS11_CKM_MD5_HMAC:
293 	case PKCS11_CKM_SHA_1_HMAC:
294 	case PKCS11_CKM_SHA224_HMAC:
295 	case PKCS11_CKM_SHA256_HMAC:
296 	case PKCS11_CKM_SHA384_HMAC:
297 	case PKCS11_CKM_SHA512_HMAC:
298 		key_type = get_key_type(obj->attributes);
299 		/*
300 		 * If Object Key type is PKCS11_CKK_GENERIC_SECRET,
301 		 * determine the tee_key_type using the
302 		 * mechanism instead of object key_type.
303 		 */
304 		if (key_type == PKCS11_CKK_GENERIC_SECRET)
305 			rc = pkcsmech2tee_key_type(&tee_key_type,
306 						   proc_params->id);
307 		else
308 			rc = pkcs2tee_key_type(&tee_key_type, obj);
309 
310 		if (rc)
311 			return rc;
312 
313 		mechanism_supported_key_sizes_bytes(proc_params->id,
314 						    &min_key_size,
315 						    &max_key_size);
316 
317 		if ((object_size / 8) > max_key_size) {
318 			rc = hash_secret_helper(proc_params->id, obj, &tee_attr,
319 						&session->processing->extra_ctx,
320 						&object_size);
321 			if (rc)
322 				return rc;
323 		} else {
324 			if (!pkcs2tee_load_attr(&tee_attr,
325 						TEE_ATTR_SECRET_VALUE,
326 						obj,
327 						PKCS11_CKA_VALUE)) {
328 				EMSG("No secret found");
329 				return PKCS11_CKR_FUNCTION_FAILED;
330 			}
331 		}
332 		break;
333 
334 	default:
335 		rc = pkcs2tee_key_type(&tee_key_type, obj);
336 		if (rc)
337 			return rc;
338 
339 		if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE,
340 					obj, PKCS11_CKA_VALUE)) {
341 			EMSG("No secret found");
342 			return PKCS11_CKR_FUNCTION_FAILED;
343 		}
344 		break;
345 	}
346 
347 	res = TEE_AllocateTransientObject(tee_key_type, object_size,
348 					  &obj->key_handle);
349 	if (res) {
350 		DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res);
351 		return tee2pkcs_error(res);
352 	}
353 
354 	res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1);
355 	if (res) {
356 		DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res);
357 		goto error;
358 	}
359 
360 key_ready:
361 	res = TEE_SetOperationKey(session->processing->tee_op_handle,
362 				  obj->key_handle);
363 	if (res) {
364 		DMSG("TEE_SetOperationKey failed, %#"PRIx32, res);
365 		goto error;
366 	}
367 
368 	return PKCS11_CKR_OK;
369 
370 error:
371 	TEE_FreeTransientObject(obj->key_handle);
372 	obj->key_handle = TEE_HANDLE_NULL;
373 
374 	return tee2pkcs_error(res);
375 }
376 
377 static enum pkcs11_rc
378 tee_init_derive_symm(struct active_processing *processing,
379 		     struct pkcs11_attribute_head *proc_params)
380 {
381 	struct serialargs args = { };
382 	enum pkcs11_rc rc = PKCS11_CKR_OK;
383 	struct input_data_ref *param = NULL;
384 	void *iv = NULL;
385 
386 	if (!proc_params)
387 		return PKCS11_CKR_ARGUMENTS_BAD;
388 
389 	param =	TEE_Malloc(sizeof(struct input_data_ref), TEE_MALLOC_FILL_ZERO);
390 	if (!param)
391 		return PKCS11_CKR_DEVICE_MEMORY;
392 
393 	serialargs_init(&args, proc_params->data, proc_params->size);
394 
395 	switch (proc_params->id) {
396 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
397 		rc = serialargs_get_ptr(&args, &iv, 16);
398 		if (rc)
399 			goto err;
400 		break;
401 	default:
402 		break;
403 	}
404 
405 	rc = serialargs_get(&args, &param->size, sizeof(uint32_t));
406 	if (rc)
407 		goto err;
408 
409 	rc = serialargs_get_ptr(&args, &param->data, param->size);
410 	if (rc)
411 		goto err;
412 
413 	if (serialargs_remaining_bytes(&args)) {
414 		rc = PKCS11_CKR_ARGUMENTS_BAD;
415 		goto err;
416 	}
417 
418 	processing->extra_ctx = param;
419 
420 	switch (proc_params->id) {
421 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
422 		if (param->size % TEE_AES_BLOCK_SIZE) {
423 			rc = PKCS11_CKR_DATA_LEN_RANGE;
424 			goto err;
425 		}
426 		TEE_CipherInit(processing->tee_op_handle, NULL, 0);
427 		break;
428 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
429 		if (param->size % TEE_AES_BLOCK_SIZE) {
430 			rc = PKCS11_CKR_DATA_LEN_RANGE;
431 			goto err;
432 		}
433 		TEE_CipherInit(processing->tee_op_handle, iv, 16);
434 		break;
435 	default:
436 		TEE_Panic(proc_params->id);
437 		break;
438 	}
439 
440 	return PKCS11_CKR_OK;
441 
442 err:
443 	processing->extra_ctx = NULL;
444 	TEE_Free(param);
445 	return rc;
446 }
447 
448 static enum pkcs11_rc
449 init_tee_operation(struct pkcs11_session *session,
450 		   struct pkcs11_attribute_head *proc_params)
451 {
452 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
453 
454 	switch (proc_params->id) {
455 	case PKCS11_CKM_MD5_HMAC:
456 	case PKCS11_CKM_SHA_1_HMAC:
457 	case PKCS11_CKM_SHA224_HMAC:
458 	case PKCS11_CKM_SHA256_HMAC:
459 	case PKCS11_CKM_SHA384_HMAC:
460 	case PKCS11_CKM_SHA512_HMAC:
461 		if (proc_params->size)
462 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
463 
464 		TEE_MACInit(session->processing->tee_op_handle, NULL, 0);
465 		rc = PKCS11_CKR_OK;
466 		break;
467 	case PKCS11_CKM_AES_ECB:
468 		if (proc_params->size)
469 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
470 
471 		TEE_CipherInit(session->processing->tee_op_handle, NULL, 0);
472 		rc = PKCS11_CKR_OK;
473 		break;
474 	case PKCS11_CKM_AES_CBC:
475 	case PKCS11_CKM_AES_CBC_PAD:
476 	case PKCS11_CKM_AES_CTS:
477 		if (proc_params->size != 16)
478 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
479 
480 		TEE_CipherInit(session->processing->tee_op_handle,
481 			       proc_params->data, 16);
482 		rc = PKCS11_CKR_OK;
483 		break;
484 	case PKCS11_CKM_AES_CTR:
485 		rc = tee_init_ctr_operation(session->processing,
486 					    proc_params->data,
487 					    proc_params->size);
488 		break;
489 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
490 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
491 		rc = tee_init_derive_symm(session->processing, proc_params);
492 		break;
493 	default:
494 		TEE_Panic(proc_params->id);
495 		break;
496 	}
497 
498 	return rc;
499 }
500 
501 enum pkcs11_rc init_symm_operation(struct pkcs11_session *session,
502 				   enum processing_func function,
503 				   struct pkcs11_attribute_head *proc_params,
504 				   struct pkcs11_object *obj)
505 {
506 	enum pkcs11_rc rc = PKCS11_CKR_OK;
507 
508 	assert(processing_is_tee_symm(proc_params->id));
509 
510 	rc = allocate_tee_operation(session, function, proc_params, obj);
511 	if (rc)
512 		return rc;
513 
514 	rc = load_tee_key(session, obj, proc_params);
515 	if (rc)
516 		return rc;
517 
518 	return init_tee_operation(session, proc_params);
519 }
520 
521 /* Validate input buffer size as per PKCS#11 constraints */
522 static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc,
523 					       enum processing_func function,
524 					       size_t in_size)
525 {
526 	switch (proc->mecha_type) {
527 	case PKCS11_CKM_AES_ECB:
528 	case PKCS11_CKM_AES_CBC:
529 		if (function == PKCS11_FUNCTION_ENCRYPT &&
530 		    in_size % TEE_AES_BLOCK_SIZE)
531 			return PKCS11_CKR_DATA_LEN_RANGE;
532 		if (function == PKCS11_FUNCTION_DECRYPT &&
533 		    in_size % TEE_AES_BLOCK_SIZE)
534 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
535 		break;
536 	case PKCS11_CKM_AES_CBC_PAD:
537 		if (function == PKCS11_FUNCTION_DECRYPT &&
538 		    in_size % TEE_AES_BLOCK_SIZE)
539 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
540 		break;
541 	case PKCS11_CKM_AES_CTS:
542 		if (function == PKCS11_FUNCTION_ENCRYPT &&
543 		    in_size < TEE_AES_BLOCK_SIZE)
544 			return PKCS11_CKR_DATA_LEN_RANGE;
545 		if (function == PKCS11_FUNCTION_DECRYPT &&
546 		    in_size < TEE_AES_BLOCK_SIZE)
547 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
548 		break;
549 	default:
550 		break;
551 	}
552 
553 	return PKCS11_CKR_OK;
554 }
555 
556 /* Validate input buffer size as per PKCS#11 constraints */
557 static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc,
558 					       size_t in_size)
559 {
560 	size_t sign_sz = 0;
561 
562 	switch (proc->mecha_type) {
563 	case PKCS11_CKM_MD5_HMAC:
564 		sign_sz = TEE_MD5_HASH_SIZE;
565 		break;
566 	case PKCS11_CKM_SHA_1_HMAC:
567 		sign_sz = TEE_SHA1_HASH_SIZE;
568 		break;
569 	case PKCS11_CKM_SHA224_HMAC:
570 		sign_sz = TEE_SHA224_HASH_SIZE;
571 		break;
572 	case PKCS11_CKM_SHA256_HMAC:
573 		sign_sz = TEE_SHA256_HASH_SIZE;
574 		break;
575 	case PKCS11_CKM_SHA384_HMAC:
576 		sign_sz = TEE_SHA384_HASH_SIZE;
577 		break;
578 	case PKCS11_CKM_SHA512_HMAC:
579 		sign_sz = TEE_SHA512_HASH_SIZE;
580 		break;
581 	default:
582 		return PKCS11_CKR_GENERAL_ERROR;
583 	}
584 
585 	if (in_size < sign_sz)
586 		return PKCS11_CKR_SIGNATURE_LEN_RANGE;
587 
588 	return PKCS11_CKR_OK;
589 }
590 
591 /*
592  * step_sym_cipher - processing symmetric (and related) cipher operation step
593  *
594  * @session - current session
595  * @function - processing function (encrypt, decrypt, sign, ...)
596  * @step - step ID in the processing (oneshot, update, final)
597  * @ptype - invocation parameter types
598  * @params - invocation parameter references
599  */
600 enum pkcs11_rc step_symm_operation(struct pkcs11_session *session,
601 				   enum processing_func function,
602 				   enum processing_step step,
603 				   uint32_t ptypes, TEE_Param *params)
604 {
605 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
606 	TEE_Result res = TEE_ERROR_GENERIC;
607 	void *in_buf = NULL;
608 	size_t in_size = 0;
609 	void *out_buf = NULL;
610 	uint32_t out_size = 0;
611 	void *in2_buf = NULL;
612 	uint32_t in2_size = 0;
613 	bool output_data = false;
614 	struct active_processing *proc = session->processing;
615 
616 	if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
617 		in_buf = params[1].memref.buffer;
618 		in_size = params[1].memref.size;
619 		if (in_size && !in_buf)
620 			return PKCS11_CKR_ARGUMENTS_BAD;
621 	}
622 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) {
623 		in2_buf = params[2].memref.buffer;
624 		in2_size = params[2].memref.size;
625 		if (in2_size && !in2_buf)
626 			return PKCS11_CKR_ARGUMENTS_BAD;
627 	}
628 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) {
629 		out_buf = params[2].memref.buffer;
630 		out_size = params[2].memref.size;
631 		if (out_size && !out_buf)
632 			return PKCS11_CKR_ARGUMENTS_BAD;
633 	}
634 	if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
635 		return PKCS11_CKR_ARGUMENTS_BAD;
636 
637 	switch (step) {
638 	case PKCS11_FUNC_STEP_ONESHOT:
639 	case PKCS11_FUNC_STEP_UPDATE:
640 	case PKCS11_FUNC_STEP_FINAL:
641 		break;
642 	default:
643 		return PKCS11_CKR_GENERAL_ERROR;
644 	}
645 
646 	if (step != PKCS11_FUNC_STEP_FINAL) {
647 		rc = input_data_size_is_valid(proc, function, in_size);
648 		if (rc)
649 			return rc;
650 	}
651 
652 	/*
653 	 * Feed active operation with data
654 	 */
655 	switch (proc->mecha_type) {
656 	case PKCS11_CKM_MD5_HMAC:
657 	case PKCS11_CKM_SHA_1_HMAC:
658 	case PKCS11_CKM_SHA224_HMAC:
659 	case PKCS11_CKM_SHA256_HMAC:
660 	case PKCS11_CKM_SHA384_HMAC:
661 	case PKCS11_CKM_SHA512_HMAC:
662 		if (step == PKCS11_FUNC_STEP_FINAL ||
663 		    step == PKCS11_FUNC_STEP_ONESHOT)
664 			break;
665 
666 		if (!in_buf) {
667 			DMSG("No input data");
668 			return PKCS11_CKR_ARGUMENTS_BAD;
669 		}
670 
671 		switch (function) {
672 		case PKCS11_FUNCTION_SIGN:
673 		case PKCS11_FUNCTION_VERIFY:
674 			TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size);
675 			rc = PKCS11_CKR_OK;
676 			break;
677 		default:
678 			TEE_Panic(function);
679 			break;
680 		}
681 		break;
682 
683 	case PKCS11_CKM_AES_ECB:
684 	case PKCS11_CKM_AES_CBC:
685 	case PKCS11_CKM_AES_CBC_PAD:
686 	case PKCS11_CKM_AES_CTS:
687 	case PKCS11_CKM_AES_CTR:
688 		if (step == PKCS11_FUNC_STEP_FINAL ||
689 		    step == PKCS11_FUNC_STEP_ONESHOT)
690 			break;
691 
692 		if (!in_buf) {
693 			EMSG("No input data");
694 			return PKCS11_CKR_ARGUMENTS_BAD;
695 		}
696 
697 		switch (function) {
698 		case PKCS11_FUNCTION_ENCRYPT:
699 		case PKCS11_FUNCTION_DECRYPT:
700 			res = TEE_CipherUpdate(proc->tee_op_handle,
701 					       in_buf, in_size,
702 						out_buf, &out_size);
703 			output_data = true;
704 			rc = tee2pkcs_error(res);
705 			break;
706 		default:
707 			TEE_Panic(function);
708 			break;
709 		}
710 		break;
711 
712 	default:
713 		TEE_Panic(proc->mecha_type);
714 		break;
715 	}
716 
717 	if (step == PKCS11_FUNC_STEP_UPDATE)
718 		goto out;
719 
720 	/*
721 	 * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation
722 	 */
723 	switch (session->processing->mecha_type) {
724 	case PKCS11_CKM_MD5_HMAC:
725 	case PKCS11_CKM_SHA_1_HMAC:
726 	case PKCS11_CKM_SHA224_HMAC:
727 	case PKCS11_CKM_SHA256_HMAC:
728 	case PKCS11_CKM_SHA384_HMAC:
729 	case PKCS11_CKM_SHA512_HMAC:
730 		switch (function) {
731 		case PKCS11_FUNCTION_SIGN:
732 			res = TEE_MACComputeFinal(proc->tee_op_handle,
733 						  in_buf, in_size, out_buf,
734 						  &out_size);
735 			output_data = true;
736 			rc = tee2pkcs_error(res);
737 			break;
738 		case PKCS11_FUNCTION_VERIFY:
739 			rc = input_sign_size_is_valid(proc, in2_size);
740 			if (rc)
741 				return rc;
742 			res = TEE_MACCompareFinal(proc->tee_op_handle,
743 						  in_buf, in_size, in2_buf,
744 						  in2_size);
745 			rc = tee2pkcs_error(res);
746 			break;
747 		default:
748 			TEE_Panic(function);
749 			break;
750 		}
751 
752 		break;
753 
754 	case PKCS11_CKM_AES_ECB:
755 	case PKCS11_CKM_AES_CBC:
756 	case PKCS11_CKM_AES_CBC_PAD:
757 	case PKCS11_CKM_AES_CTS:
758 	case PKCS11_CKM_AES_CTR:
759 		if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) {
760 			EMSG("No input data");
761 			return PKCS11_CKR_ARGUMENTS_BAD;
762 		}
763 
764 		switch (function) {
765 		case PKCS11_FUNCTION_ENCRYPT:
766 		case PKCS11_FUNCTION_DECRYPT:
767 			res = TEE_CipherDoFinal(proc->tee_op_handle,
768 						in_buf, in_size,
769 						out_buf, &out_size);
770 			output_data = true;
771 			rc = tee2pkcs_error(res);
772 			break;
773 		default:
774 			TEE_Panic(function);
775 			break;
776 		}
777 		break;
778 	default:
779 		TEE_Panic(proc->mecha_type);
780 		break;
781 	}
782 
783 out:
784 	if (output_data &&
785 	    (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) {
786 		switch (TEE_PARAM_TYPE_GET(ptypes, 2)) {
787 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
788 		case TEE_PARAM_TYPE_MEMREF_INOUT:
789 			params[2].memref.size = out_size;
790 			break;
791 		default:
792 			rc = PKCS11_CKR_ARGUMENTS_BAD;
793 			break;
794 		}
795 	}
796 
797 	return rc;
798 }
799 
800 enum pkcs11_rc derive_key_by_symm_enc(struct pkcs11_session *session,
801 				      void **out_buf, uint32_t *out_size)
802 {
803 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
804 	TEE_Result res = TEE_ERROR_GENERIC;
805 	struct active_processing *proc = session->processing;
806 	struct input_data_ref *input = proc->extra_ctx;
807 	void *in_buf = NULL;
808 	uint32_t in_size = 0;
809 
810 	switch (proc->mecha_type) {
811 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
812 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
813 		if (!proc->extra_ctx)
814 			return PKCS11_CKR_ARGUMENTS_BAD;
815 
816 		in_buf = input->data;
817 		in_size = input->size;
818 
819 		*out_size = in_size;
820 		*out_buf = TEE_Malloc(*out_size, 0);
821 		if (!*out_buf)
822 			return PKCS11_CKR_DEVICE_MEMORY;
823 
824 		res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_size,
825 					*out_buf, out_size);
826 		rc = tee2pkcs_error(res);
827 		if (rc)
828 			TEE_Free(*out_buf);
829 		break;
830 	default:
831 		return PKCS11_CKR_MECHANISM_INVALID;
832 	}
833 
834 	return rc;
835 }
836 
837 enum pkcs11_rc wrap_data_by_symm_enc(struct pkcs11_session *session,
838 				     void *data, uint32_t data_sz,
839 				     void *out_buf, uint32_t *out_sz)
840 {
841 	TEE_Result res = TEE_ERROR_GENERIC;
842 	struct active_processing *proc = session->processing;
843 	void *in_buf = NULL;
844 	uint32_t align = 0;
845 	uint32_t in_sz = data_sz;
846 	uint32_t tmp_sz = *out_sz;
847 	uint8_t *tmp_buf = out_buf;
848 
849 	switch (proc->mecha_type) {
850 	case PKCS11_CKM_AES_ECB:
851 	case PKCS11_CKM_AES_CBC:
852 		align = data_sz % TEE_AES_BLOCK_SIZE;
853 		if (align)
854 			in_sz = data_sz + (TEE_AES_BLOCK_SIZE - align);
855 
856 		if (*out_sz < in_sz) {
857 			*out_sz = in_sz;
858 			return PKCS11_CKR_BUFFER_TOO_SMALL;
859 		}
860 
861 		if (align) {
862 			if (data_sz > TEE_AES_BLOCK_SIZE) {
863 				in_sz = data_sz - align;
864 				res = TEE_CipherUpdate(proc->tee_op_handle,
865 						       data, in_sz, tmp_buf,
866 						       &tmp_sz);
867 				if (res) {
868 					assert(res != TEE_ERROR_SHORT_BUFFER);
869 					return tee2pkcs_error(res);
870 				}
871 				tmp_buf += tmp_sz;
872 				tmp_sz = *out_sz - tmp_sz;
873 			} else {
874 				in_sz = 0;
875 			}
876 
877 			in_buf = TEE_Malloc(TEE_AES_BLOCK_SIZE,
878 					    TEE_MALLOC_FILL_ZERO);
879 			if (!in_buf)
880 				return PKCS11_CKR_DEVICE_MEMORY;
881 
882 			TEE_MemMove(in_buf, (uint8_t *)data + in_sz, align);
883 			in_sz = TEE_AES_BLOCK_SIZE;
884 		} else {
885 			in_buf = data;
886 			in_sz = data_sz;
887 		}
888 
889 		res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_sz,
890 					tmp_buf, &tmp_sz);
891 		if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
892 			*out_sz = tmp_sz;
893 			if (align)
894 				*out_sz += tmp_buf - (uint8_t *)out_buf;
895 		}
896 
897 		if (align)
898 			TEE_Free(in_buf);
899 
900 		return tee2pkcs_error(res);
901 	default:
902 		return PKCS11_CKR_MECHANISM_INVALID;
903 	}
904 
905 	return PKCS11_CKR_GENERAL_ERROR;
906 }
907 
908 enum pkcs11_rc unwrap_key_by_symm(struct pkcs11_session *session, void *data,
909 				  uint32_t data_sz, void **out_buf,
910 				  uint32_t *out_sz)
911 {
912 	TEE_Result res = TEE_ERROR_GENERIC;
913 	struct active_processing *proc = session->processing;
914 
915 	if (input_data_size_is_valid(proc, PKCS11_FUNCTION_DECRYPT, data_sz))
916 		return PKCS11_CKR_WRAPPED_KEY_LEN_RANGE;
917 
918 	switch (proc->mecha_type) {
919 	case PKCS11_CKM_AES_ECB:
920 	case PKCS11_CKM_AES_CBC:
921 		*out_sz = 0;
922 		res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz,
923 					NULL, out_sz);
924 		if (res != TEE_ERROR_SHORT_BUFFER) {
925 			DMSG("TEE_CipherDoFinal() issue: %#"PRIx32, res);
926 			return PKCS11_CKR_GENERAL_ERROR;
927 		}
928 
929 		*out_buf = TEE_Malloc(*out_sz, TEE_MALLOC_FILL_ZERO);
930 		if (!*out_buf)
931 			return PKCS11_CKR_DEVICE_MEMORY;
932 
933 		res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz,
934 				        *out_buf, out_sz);
935 		if (tee2pkcs_error(res)) {
936 			TEE_Free(*out_buf);
937 			*out_buf = NULL;
938 			return PKCS11_CKR_WRAPPED_KEY_INVALID;
939 		}
940 		break;
941 	default:
942 		return PKCS11_CKR_MECHANISM_INVALID;
943 	}
944 
945 	return PKCS11_CKR_OK;
946 }
947