xref: /optee_os/ta/pkcs11/src/processing_symm.c (revision 2d0cd82984c733229b9f4d73e4b940845ea9ce01)
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 bool processing_is_tee_symm(enum pkcs11_mechanism_id proc_id)
24 {
25 	switch (proc_id) {
26 	/* Authentication */
27 	case PKCS11_CKM_MD5_HMAC:
28 	case PKCS11_CKM_SHA_1_HMAC:
29 	case PKCS11_CKM_SHA224_HMAC:
30 	case PKCS11_CKM_SHA256_HMAC:
31 	case PKCS11_CKM_SHA384_HMAC:
32 	case PKCS11_CKM_SHA512_HMAC:
33 	/* Cipherering */
34 	case PKCS11_CKM_AES_ECB:
35 	case PKCS11_CKM_AES_CBC:
36 	case PKCS11_CKM_AES_CBC_PAD:
37 	case PKCS11_CKM_AES_CTS:
38 	case PKCS11_CKM_AES_CTR:
39 		return true;
40 	default:
41 		return false;
42 	}
43 }
44 
45 static enum pkcs11_rc
46 pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params)
47 {
48 	static const struct {
49 		enum pkcs11_mechanism_id mech_id;
50 		uint32_t tee_id;
51 	} pkcs2tee_algo[] = {
52 		/* AES flavors */
53 		{ PKCS11_CKM_AES_ECB, TEE_ALG_AES_ECB_NOPAD },
54 		{ PKCS11_CKM_AES_CBC, TEE_ALG_AES_CBC_NOPAD },
55 		{ PKCS11_CKM_AES_CBC_PAD, TEE_ALG_AES_CBC_NOPAD },
56 		{ PKCS11_CKM_AES_CTR, TEE_ALG_AES_CTR },
57 		{ PKCS11_CKM_AES_CTS, TEE_ALG_AES_CTS },
58 		/* HMAC flavors */
59 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_HMAC_MD5 },
60 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_HMAC_SHA1 },
61 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_HMAC_SHA224 },
62 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_HMAC_SHA256 },
63 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_HMAC_SHA384 },
64 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_HMAC_SHA512 },
65 	};
66 	size_t n = 0;
67 
68 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) {
69 		if (proc_params->id == pkcs2tee_algo[n].mech_id) {
70 			*tee_id = pkcs2tee_algo[n].tee_id;
71 			return PKCS11_CKR_OK;
72 		}
73 	}
74 
75 	return PKCS11_RV_NOT_IMPLEMENTED;
76 }
77 
78 static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type,
79 					struct pkcs11_object *obj)
80 {
81 	static const struct {
82 		enum pkcs11_key_type key_type;
83 		uint32_t tee_id;
84 	} pkcs2tee_key_type[] = {
85 		{ PKCS11_CKK_AES, TEE_TYPE_AES },
86 		{ PKCS11_CKK_GENERIC_SECRET, TEE_TYPE_GENERIC_SECRET },
87 		{ PKCS11_CKK_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
88 		{ PKCS11_CKK_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
89 		{ PKCS11_CKK_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
90 		{ PKCS11_CKK_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
91 		{ PKCS11_CKK_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
92 		{ PKCS11_CKK_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
93 	};
94 	size_t n = 0;
95 	enum pkcs11_key_type key_type = get_key_type(obj->attributes);
96 
97 	assert(get_class(obj->attributes) == PKCS11_CKO_SECRET_KEY);
98 
99 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
100 		if (pkcs2tee_key_type[n].key_type == key_type) {
101 			*tee_type = pkcs2tee_key_type[n].tee_id;
102 			return PKCS11_CKR_OK;
103 		}
104 	}
105 
106 	return PKCS11_RV_NOT_FOUND;
107 }
108 
109 static enum pkcs11_rc pkcsmech2tee_key_type(uint32_t *tee_type,
110 					    enum pkcs11_mechanism_id mech_id)
111 {
112 	static const struct {
113 		enum pkcs11_mechanism_id mech;
114 		uint32_t tee_id;
115 	} pkcs2tee_key_type[] = {
116 		{ PKCS11_CKM_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
117 		{ PKCS11_CKM_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
118 		{ PKCS11_CKM_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
119 		{ PKCS11_CKM_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
120 		{ PKCS11_CKM_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
121 		{ PKCS11_CKM_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
122 	};
123 	size_t n = 0;
124 
125 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
126 		if (pkcs2tee_key_type[n].mech == mech_id) {
127 			*tee_type = pkcs2tee_key_type[n].tee_id;
128 			return PKCS11_CKR_OK;
129 		}
130 	}
131 
132 	return PKCS11_RV_NOT_FOUND;
133 }
134 
135 static enum pkcs11_rc hmac_to_tee_hash(uint32_t *algo,
136 				       enum pkcs11_mechanism_id mech_id)
137 {
138 	static const struct {
139 		enum pkcs11_mechanism_id mech;
140 		uint32_t tee_id;
141 	} hmac_hash[] = {
142 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_MD5 },
143 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_SHA1 },
144 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_SHA224 },
145 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_SHA256 },
146 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_SHA384 },
147 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_SHA512 },
148 	};
149 	size_t n = 0;
150 
151 	for (n = 0; n < ARRAY_SIZE(hmac_hash); n++) {
152 		if (hmac_hash[n].mech == mech_id) {
153 			*algo = hmac_hash[n].tee_id;
154 			return PKCS11_CKR_OK;
155 		}
156 	}
157 
158 	return PKCS11_RV_NOT_FOUND;
159 }
160 
161 static enum pkcs11_rc
162 allocate_tee_operation(struct pkcs11_session *session,
163 		       enum processing_func function,
164 		       struct pkcs11_attribute_head *params,
165 		       struct pkcs11_object *obj)
166 {
167 	uint32_t size = (uint32_t)get_object_key_bit_size(obj);
168 	uint32_t key_size = size / 8;
169 	uint32_t algo = 0;
170 	uint32_t mode = 0;
171 	uint32_t max_key_size = 0;
172 	uint32_t min_key_size = 0;
173 	TEE_Result res = TEE_ERROR_GENERIC;
174 
175 	assert(session->processing->tee_op_handle == TEE_HANDLE_NULL);
176 
177 	if (pkcs2tee_algorithm(&algo, params))
178 		return PKCS11_CKR_FUNCTION_FAILED;
179 
180 	/* Sign/Verify with AES or generic key relate to TEE MAC operation */
181 	switch (params->id) {
182 	case PKCS11_CKM_MD5_HMAC:
183 	case PKCS11_CKM_SHA_1_HMAC:
184 	case PKCS11_CKM_SHA224_HMAC:
185 	case PKCS11_CKM_SHA256_HMAC:
186 	case PKCS11_CKM_SHA384_HMAC:
187 	case PKCS11_CKM_SHA512_HMAC:
188 		mechanism_supported_key_sizes_bytes(params->id, &min_key_size,
189 						    &max_key_size);
190 		if (key_size < min_key_size)
191 			return PKCS11_CKR_KEY_SIZE_RANGE;
192 
193 		/*
194 		 * If size of generic key is greater than the size
195 		 * supported by TEE API, this is not considered an
196 		 * error. When loading TEE key, we will hash the key
197 		 * to generate the appropriate key for HMAC operation.
198 		 * This key size will not be greater than the
199 		 * max_key_size. So we can use max_key_size for
200 		 * TEE_AllocateOperation().
201 		 */
202 		if (key_size > max_key_size)
203 			size = max_key_size * 8;
204 
205 		mode = TEE_MODE_MAC;
206 		break;
207 	default:
208 		pkcs2tee_mode(&mode, function);
209 		break;
210 	}
211 
212 	res = TEE_AllocateOperation(&session->processing->tee_op_handle,
213 				    algo, mode, size);
214 	if (res)
215 		EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32,
216 		     algo, mode, size);
217 
218 	if (res == TEE_ERROR_NOT_SUPPORTED)
219 		return PKCS11_CKR_MECHANISM_INVALID;
220 
221 	return tee2pkcs_error(res);
222 }
223 
224 static enum pkcs11_rc hash_secret_helper(enum pkcs11_mechanism_id mech_id,
225 					 struct pkcs11_object *obj,
226 					 TEE_Attribute *tee_attr,
227 					 void **ctx,
228 					 size_t *object_size_bits)
229 {
230 	uint32_t algo = 0;
231 	void *hash_ptr = NULL;
232 	uint32_t hash_size = 0;
233 	enum pkcs11_rc rc = PKCS11_CKR_OK;
234 
235 	rc = hmac_to_tee_hash(&algo, mech_id);
236 	if (rc)
237 		return rc;
238 
239 	hash_size = TEE_ALG_GET_DIGEST_SIZE(algo);
240 	hash_ptr = TEE_Malloc(hash_size, 0);
241 	if (!hash_ptr)
242 		return PKCS11_CKR_DEVICE_MEMORY;
243 
244 	rc = pkcs2tee_load_hashed_attr(tee_attr, TEE_ATTR_SECRET_VALUE, obj,
245 				       PKCS11_CKA_VALUE, algo, hash_ptr,
246 				       &hash_size);
247 	if (rc) {
248 		EMSG("No secret/hash error");
249 		TEE_Free(hash_ptr);
250 		return rc;
251 	}
252 
253 	*ctx = hash_ptr;
254 
255 	*object_size_bits = hash_size * 8;
256 
257 	return PKCS11_CKR_OK;
258 }
259 
260 static enum pkcs11_rc load_tee_key(struct pkcs11_session *session,
261 				   struct pkcs11_object *obj,
262 				   struct pkcs11_attribute_head *proc_params)
263 {
264 	TEE_Attribute tee_attr = { };
265 	size_t object_size = 0;
266 	uint32_t tee_key_type = 0;
267 	enum pkcs11_key_type key_type = 0;
268 	enum pkcs11_rc rc = PKCS11_CKR_OK;
269 	TEE_Result res = TEE_ERROR_GENERIC;
270 	uint32_t max_key_size = 0;
271 	uint32_t min_key_size = 0;
272 
273 	if (obj->key_handle != TEE_HANDLE_NULL) {
274 		/* Key was already loaded and fits current need */
275 		goto key_ready;
276 	}
277 
278 	object_size = get_object_key_bit_size(obj);
279 	if (!object_size)
280 		return PKCS11_CKR_GENERAL_ERROR;
281 
282 	switch (proc_params->id) {
283 	case PKCS11_CKM_MD5_HMAC:
284 	case PKCS11_CKM_SHA_1_HMAC:
285 	case PKCS11_CKM_SHA224_HMAC:
286 	case PKCS11_CKM_SHA256_HMAC:
287 	case PKCS11_CKM_SHA384_HMAC:
288 	case PKCS11_CKM_SHA512_HMAC:
289 		key_type = get_key_type(obj->attributes);
290 		/*
291 		 * If Object Key type is PKCS11_CKK_GENERIC_SECRET,
292 		 * determine the tee_key_type using the
293 		 * mechanism instead of object key_type.
294 		 */
295 		if (key_type == PKCS11_CKK_GENERIC_SECRET)
296 			rc = pkcsmech2tee_key_type(&tee_key_type,
297 						   proc_params->id);
298 		else
299 			rc = pkcs2tee_key_type(&tee_key_type, obj);
300 
301 		if (rc)
302 			return rc;
303 
304 		mechanism_supported_key_sizes_bytes(proc_params->id,
305 						    &min_key_size,
306 						    &max_key_size);
307 
308 		if ((object_size / 8) > max_key_size) {
309 			rc = hash_secret_helper(proc_params->id, obj, &tee_attr,
310 						&session->processing->extra_ctx,
311 						&object_size);
312 			if (rc)
313 				return rc;
314 		} else {
315 			if (!pkcs2tee_load_attr(&tee_attr,
316 						TEE_ATTR_SECRET_VALUE,
317 						obj,
318 						PKCS11_CKA_VALUE)) {
319 				EMSG("No secret found");
320 				return PKCS11_CKR_FUNCTION_FAILED;
321 			}
322 		}
323 		break;
324 
325 	default:
326 		rc = pkcs2tee_key_type(&tee_key_type, obj);
327 		if (rc)
328 			return rc;
329 
330 		if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE,
331 					obj, PKCS11_CKA_VALUE)) {
332 			EMSG("No secret found");
333 			return PKCS11_CKR_FUNCTION_FAILED;
334 		}
335 		break;
336 	}
337 
338 	res = TEE_AllocateTransientObject(tee_key_type, object_size,
339 					  &obj->key_handle);
340 	if (res) {
341 		DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res);
342 		return tee2pkcs_error(res);
343 	}
344 
345 	res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1);
346 	if (res) {
347 		DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res);
348 		goto error;
349 	}
350 
351 key_ready:
352 	res = TEE_SetOperationKey(session->processing->tee_op_handle,
353 				  obj->key_handle);
354 	if (res) {
355 		DMSG("TEE_SetOperationKey failed, %#"PRIx32, res);
356 		goto error;
357 	}
358 
359 	return PKCS11_CKR_OK;
360 
361 error:
362 	TEE_FreeTransientObject(obj->key_handle);
363 	obj->key_handle = TEE_HANDLE_NULL;
364 
365 	return tee2pkcs_error(res);
366 }
367 
368 static enum pkcs11_rc
369 init_tee_operation(struct pkcs11_session *session,
370 		   struct pkcs11_attribute_head *proc_params)
371 {
372 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
373 
374 	switch (proc_params->id) {
375 	case PKCS11_CKM_MD5_HMAC:
376 	case PKCS11_CKM_SHA_1_HMAC:
377 	case PKCS11_CKM_SHA224_HMAC:
378 	case PKCS11_CKM_SHA256_HMAC:
379 	case PKCS11_CKM_SHA384_HMAC:
380 	case PKCS11_CKM_SHA512_HMAC:
381 		if (proc_params->size)
382 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
383 
384 		TEE_MACInit(session->processing->tee_op_handle, NULL, 0);
385 		rc = PKCS11_CKR_OK;
386 		break;
387 	case PKCS11_CKM_AES_ECB:
388 		if (proc_params->size)
389 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
390 
391 		TEE_CipherInit(session->processing->tee_op_handle, NULL, 0);
392 		rc = PKCS11_CKR_OK;
393 		break;
394 	case PKCS11_CKM_AES_CBC:
395 	case PKCS11_CKM_AES_CBC_PAD:
396 	case PKCS11_CKM_AES_CTS:
397 		if (proc_params->size != 16)
398 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
399 
400 		TEE_CipherInit(session->processing->tee_op_handle,
401 			       proc_params->data, 16);
402 		rc = PKCS11_CKR_OK;
403 		break;
404 	case PKCS11_CKM_AES_CTR:
405 		rc = tee_init_ctr_operation(session->processing,
406 					    proc_params->data,
407 					    proc_params->size);
408 		break;
409 	default:
410 		TEE_Panic(proc_params->id);
411 		break;
412 	}
413 
414 	return rc;
415 }
416 
417 enum pkcs11_rc init_symm_operation(struct pkcs11_session *session,
418 				   enum processing_func function,
419 				   struct pkcs11_attribute_head *proc_params,
420 				   struct pkcs11_object *obj)
421 {
422 	enum pkcs11_rc rc = PKCS11_CKR_OK;
423 
424 	assert(processing_is_tee_symm(proc_params->id));
425 
426 	rc = allocate_tee_operation(session, function, proc_params, obj);
427 	if (rc)
428 		return rc;
429 
430 	rc = load_tee_key(session, obj, proc_params);
431 	if (rc)
432 		return rc;
433 
434 	return init_tee_operation(session, proc_params);
435 }
436 
437 /* Validate input buffer size as per PKCS#11 constraints */
438 static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc,
439 					       enum processing_func function,
440 					       size_t in_size)
441 {
442 	switch (proc->mecha_type) {
443 	case PKCS11_CKM_AES_ECB:
444 	case PKCS11_CKM_AES_CBC:
445 		if (function == PKCS11_FUNCTION_ENCRYPT &&
446 		    in_size % TEE_AES_BLOCK_SIZE)
447 			return PKCS11_CKR_DATA_LEN_RANGE;
448 		if (function == PKCS11_FUNCTION_DECRYPT &&
449 		    in_size % TEE_AES_BLOCK_SIZE)
450 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
451 		break;
452 	case PKCS11_CKM_AES_CBC_PAD:
453 		if (function == PKCS11_FUNCTION_DECRYPT &&
454 		    in_size % TEE_AES_BLOCK_SIZE)
455 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
456 		break;
457 	case PKCS11_CKM_AES_CTS:
458 		if (function == PKCS11_FUNCTION_ENCRYPT &&
459 		    in_size < TEE_AES_BLOCK_SIZE)
460 			return PKCS11_CKR_DATA_LEN_RANGE;
461 		if (function == PKCS11_FUNCTION_DECRYPT &&
462 		    in_size < TEE_AES_BLOCK_SIZE)
463 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
464 		break;
465 	default:
466 		break;
467 	}
468 
469 	return PKCS11_CKR_OK;
470 }
471 
472 /* Validate input buffer size as per PKCS#11 constraints */
473 static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc,
474 					       size_t in_size)
475 {
476 	size_t sign_sz = 0;
477 
478 	switch (proc->mecha_type) {
479 	case PKCS11_CKM_MD5_HMAC:
480 		sign_sz = TEE_MD5_HASH_SIZE;
481 		break;
482 	case PKCS11_CKM_SHA_1_HMAC:
483 		sign_sz = TEE_SHA1_HASH_SIZE;
484 		break;
485 	case PKCS11_CKM_SHA224_HMAC:
486 		sign_sz = TEE_SHA224_HASH_SIZE;
487 		break;
488 	case PKCS11_CKM_SHA256_HMAC:
489 		sign_sz = TEE_SHA256_HASH_SIZE;
490 		break;
491 	case PKCS11_CKM_SHA384_HMAC:
492 		sign_sz = TEE_SHA384_HASH_SIZE;
493 		break;
494 	case PKCS11_CKM_SHA512_HMAC:
495 		sign_sz = TEE_SHA512_HASH_SIZE;
496 		break;
497 	default:
498 		return PKCS11_CKR_GENERAL_ERROR;
499 	}
500 
501 	if (in_size < sign_sz)
502 		return PKCS11_CKR_SIGNATURE_LEN_RANGE;
503 
504 	return PKCS11_CKR_OK;
505 }
506 
507 /*
508  * step_sym_cipher - processing symmetric (and related) cipher operation step
509  *
510  * @session - current session
511  * @function - processing function (encrypt, decrypt, sign, ...)
512  * @step - step ID in the processing (oneshot, update, final)
513  * @ptype - invocation parameter types
514  * @params - invocation parameter references
515  */
516 enum pkcs11_rc step_symm_operation(struct pkcs11_session *session,
517 				   enum processing_func function,
518 				   enum processing_step step,
519 				   uint32_t ptypes, TEE_Param *params)
520 {
521 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
522 	TEE_Result res = TEE_ERROR_GENERIC;
523 	void *in_buf = NULL;
524 	size_t in_size = 0;
525 	void *out_buf = NULL;
526 	uint32_t out_size = 0;
527 	void *in2_buf = NULL;
528 	uint32_t in2_size = 0;
529 	bool output_data = false;
530 	struct active_processing *proc = session->processing;
531 
532 	if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
533 		in_buf = params[1].memref.buffer;
534 		in_size = params[1].memref.size;
535 		if (in_size && !in_buf)
536 			return PKCS11_CKR_ARGUMENTS_BAD;
537 	}
538 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) {
539 		in2_buf = params[2].memref.buffer;
540 		in2_size = params[2].memref.size;
541 		if (in2_size && !in2_buf)
542 			return PKCS11_CKR_ARGUMENTS_BAD;
543 	}
544 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) {
545 		out_buf = params[2].memref.buffer;
546 		out_size = params[2].memref.size;
547 		if (out_size && !out_buf)
548 			return PKCS11_CKR_ARGUMENTS_BAD;
549 	}
550 	if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
551 		return PKCS11_CKR_ARGUMENTS_BAD;
552 
553 	switch (step) {
554 	case PKCS11_FUNC_STEP_ONESHOT:
555 	case PKCS11_FUNC_STEP_UPDATE:
556 	case PKCS11_FUNC_STEP_FINAL:
557 		break;
558 	default:
559 		return PKCS11_CKR_GENERAL_ERROR;
560 	}
561 
562 	if (step != PKCS11_FUNC_STEP_FINAL) {
563 		rc = input_data_size_is_valid(proc, function, in_size);
564 		if (rc)
565 			return rc;
566 	}
567 
568 	/*
569 	 * Feed active operation with data
570 	 */
571 	switch (proc->mecha_type) {
572 	case PKCS11_CKM_MD5_HMAC:
573 	case PKCS11_CKM_SHA_1_HMAC:
574 	case PKCS11_CKM_SHA224_HMAC:
575 	case PKCS11_CKM_SHA256_HMAC:
576 	case PKCS11_CKM_SHA384_HMAC:
577 	case PKCS11_CKM_SHA512_HMAC:
578 		if (step == PKCS11_FUNC_STEP_FINAL ||
579 		    step == PKCS11_FUNC_STEP_ONESHOT)
580 			break;
581 
582 		if (!in_buf) {
583 			DMSG("No input data");
584 			return PKCS11_CKR_ARGUMENTS_BAD;
585 		}
586 
587 		switch (function) {
588 		case PKCS11_FUNCTION_SIGN:
589 		case PKCS11_FUNCTION_VERIFY:
590 			TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size);
591 			rc = PKCS11_CKR_OK;
592 			break;
593 		default:
594 			TEE_Panic(function);
595 			break;
596 		}
597 		break;
598 
599 	case PKCS11_CKM_AES_ECB:
600 	case PKCS11_CKM_AES_CBC:
601 	case PKCS11_CKM_AES_CBC_PAD:
602 	case PKCS11_CKM_AES_CTS:
603 	case PKCS11_CKM_AES_CTR:
604 		if (step == PKCS11_FUNC_STEP_FINAL ||
605 		    step == PKCS11_FUNC_STEP_ONESHOT)
606 			break;
607 
608 		if (!in_buf) {
609 			EMSG("No input data");
610 			return PKCS11_CKR_ARGUMENTS_BAD;
611 		}
612 
613 		switch (function) {
614 		case PKCS11_FUNCTION_ENCRYPT:
615 		case PKCS11_FUNCTION_DECRYPT:
616 			res = TEE_CipherUpdate(proc->tee_op_handle,
617 					       in_buf, in_size,
618 						out_buf, &out_size);
619 			output_data = true;
620 			rc = tee2pkcs_error(res);
621 			break;
622 		default:
623 			TEE_Panic(function);
624 			break;
625 		}
626 		break;
627 
628 	default:
629 		TEE_Panic(proc->mecha_type);
630 		break;
631 	}
632 
633 	if (step == PKCS11_FUNC_STEP_UPDATE)
634 		goto out;
635 
636 	/*
637 	 * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation
638 	 */
639 	switch (session->processing->mecha_type) {
640 	case PKCS11_CKM_MD5_HMAC:
641 	case PKCS11_CKM_SHA_1_HMAC:
642 	case PKCS11_CKM_SHA224_HMAC:
643 	case PKCS11_CKM_SHA256_HMAC:
644 	case PKCS11_CKM_SHA384_HMAC:
645 	case PKCS11_CKM_SHA512_HMAC:
646 		switch (function) {
647 		case PKCS11_FUNCTION_SIGN:
648 			res = TEE_MACComputeFinal(proc->tee_op_handle,
649 						  in_buf, in_size, out_buf,
650 						  &out_size);
651 			output_data = true;
652 			rc = tee2pkcs_error(res);
653 			break;
654 		case PKCS11_FUNCTION_VERIFY:
655 			rc = input_sign_size_is_valid(proc, in2_size);
656 			if (rc)
657 				return rc;
658 			res = TEE_MACCompareFinal(proc->tee_op_handle,
659 						  in_buf, in_size, in2_buf,
660 						  in2_size);
661 			rc = tee2pkcs_error(res);
662 			break;
663 		default:
664 			TEE_Panic(function);
665 			break;
666 		}
667 
668 		break;
669 
670 	case PKCS11_CKM_AES_ECB:
671 	case PKCS11_CKM_AES_CBC:
672 	case PKCS11_CKM_AES_CBC_PAD:
673 	case PKCS11_CKM_AES_CTS:
674 	case PKCS11_CKM_AES_CTR:
675 		if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) {
676 			EMSG("No input data");
677 			return PKCS11_CKR_ARGUMENTS_BAD;
678 		}
679 
680 		switch (function) {
681 		case PKCS11_FUNCTION_ENCRYPT:
682 		case PKCS11_FUNCTION_DECRYPT:
683 			res = TEE_CipherDoFinal(proc->tee_op_handle,
684 						in_buf, in_size,
685 						out_buf, &out_size);
686 			output_data = true;
687 			rc = tee2pkcs_error(res);
688 			break;
689 		default:
690 			TEE_Panic(function);
691 			break;
692 		}
693 		break;
694 	default:
695 		TEE_Panic(proc->mecha_type);
696 		break;
697 	}
698 
699 out:
700 	if (output_data &&
701 	    (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) {
702 		switch (TEE_PARAM_TYPE_GET(ptypes, 2)) {
703 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
704 		case TEE_PARAM_TYPE_MEMREF_INOUT:
705 			params[2].memref.size = out_size;
706 			break;
707 		default:
708 			rc = PKCS11_CKR_ARGUMENTS_BAD;
709 			break;
710 		}
711 	}
712 
713 	return rc;
714 }
715