xref: /optee_os/ta/pkcs11/src/processing_symm.c (revision 460ba6215552b8b7fde6131e5fd9e2b3a81c641f)
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
136 allocate_tee_operation(struct pkcs11_session *session,
137 		       enum processing_func function,
138 		       struct pkcs11_attribute_head *params,
139 		       struct pkcs11_object *obj)
140 {
141 	uint32_t size = (uint32_t)get_object_key_bit_size(obj);
142 	uint32_t key_size = size / 8;
143 	uint32_t algo = 0;
144 	uint32_t mode = 0;
145 	uint32_t max_key_size = 0;
146 	uint32_t min_key_size = 0;
147 	TEE_Result res = TEE_ERROR_GENERIC;
148 
149 	assert(session->processing->tee_op_handle == TEE_HANDLE_NULL);
150 
151 	if (pkcs2tee_algorithm(&algo, params))
152 		return PKCS11_CKR_FUNCTION_FAILED;
153 
154 	/* Sign/Verify with AES or generic key relate to TEE MAC operation */
155 	switch (params->id) {
156 	case PKCS11_CKM_MD5_HMAC:
157 	case PKCS11_CKM_SHA_1_HMAC:
158 	case PKCS11_CKM_SHA224_HMAC:
159 	case PKCS11_CKM_SHA256_HMAC:
160 	case PKCS11_CKM_SHA384_HMAC:
161 	case PKCS11_CKM_SHA512_HMAC:
162 		mechanism_supported_key_sizes(params->id,
163 					      &min_key_size,
164 					      &max_key_size);
165 		if (key_size < min_key_size)
166 			return PKCS11_CKR_KEY_SIZE_RANGE;
167 		mode = TEE_MODE_MAC;
168 		break;
169 	default:
170 		pkcs2tee_mode(&mode, function);
171 		break;
172 	}
173 
174 	res = TEE_AllocateOperation(&session->processing->tee_op_handle,
175 				    algo, mode, size);
176 	if (res)
177 		EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32,
178 		     algo, mode, size);
179 
180 	if (res == TEE_ERROR_NOT_SUPPORTED)
181 		return PKCS11_CKR_MECHANISM_INVALID;
182 
183 	return tee2pkcs_error(res);
184 }
185 
186 static enum pkcs11_rc load_tee_key(struct pkcs11_session *session,
187 				   struct pkcs11_object *obj,
188 				   struct pkcs11_attribute_head *proc_params)
189 {
190 	TEE_Attribute tee_attr = { };
191 	size_t object_size = 0;
192 	uint32_t tee_key_type = 0;
193 	enum pkcs11_key_type key_type = 0;
194 	enum pkcs11_rc rc = PKCS11_CKR_OK;
195 	TEE_Result res = TEE_ERROR_GENERIC;
196 
197 	if (obj->key_handle != TEE_HANDLE_NULL) {
198 		/* Key was already loaded and fits current need */
199 		goto key_ready;
200 	}
201 
202 	if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE,
203 				obj, PKCS11_CKA_VALUE)) {
204 		EMSG("No secret found");
205 		return PKCS11_CKR_FUNCTION_FAILED;
206 	}
207 
208 	switch (proc_params->id) {
209 	case PKCS11_CKM_MD5_HMAC:
210 	case PKCS11_CKM_SHA_1_HMAC:
211 	case PKCS11_CKM_SHA224_HMAC:
212 	case PKCS11_CKM_SHA256_HMAC:
213 	case PKCS11_CKM_SHA384_HMAC:
214 	case PKCS11_CKM_SHA512_HMAC:
215 		key_type = get_key_type(obj->attributes);
216 		/*
217 		 * If Object Key type is PKCS11_CKK_GENERIC_SECRET,
218 		 * determine the tee_key_type using the
219 		 * mechanism instead of object key_type.
220 		 */
221 		if (key_type == PKCS11_CKK_GENERIC_SECRET)
222 			rc = pkcsmech2tee_key_type(&tee_key_type,
223 						   proc_params->id);
224 		else
225 			rc = pkcs2tee_key_type(&tee_key_type, obj);
226 
227 		break;
228 	default:
229 		/*
230 		 * For all other mechanisms, use object key_type
231 		 * to determine the corresponding tee_key_type
232 		 */
233 		rc = pkcs2tee_key_type(&tee_key_type, obj);
234 		break;
235 	}
236 
237 	if (rc)
238 		return rc;
239 
240 	object_size = get_object_key_bit_size(obj);
241 	if (!object_size)
242 		return PKCS11_CKR_GENERAL_ERROR;
243 
244 	res = TEE_AllocateTransientObject(tee_key_type, object_size,
245 					  &obj->key_handle);
246 	if (res) {
247 		DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res);
248 		return tee2pkcs_error(res);
249 	}
250 
251 	res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1);
252 	if (res) {
253 		DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res);
254 		goto error;
255 	}
256 
257 key_ready:
258 	res = TEE_SetOperationKey(session->processing->tee_op_handle,
259 				  obj->key_handle);
260 	if (res) {
261 		DMSG("TEE_SetOperationKey failed, %#"PRIx32, res);
262 		goto error;
263 	}
264 
265 	return PKCS11_CKR_OK;
266 
267 error:
268 	TEE_FreeTransientObject(obj->key_handle);
269 	obj->key_handle = TEE_HANDLE_NULL;
270 
271 	return tee2pkcs_error(res);
272 }
273 
274 static enum pkcs11_rc
275 init_tee_operation(struct pkcs11_session *session,
276 		   struct pkcs11_attribute_head *proc_params)
277 {
278 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
279 
280 	switch (proc_params->id) {
281 	case PKCS11_CKM_MD5_HMAC:
282 	case PKCS11_CKM_SHA_1_HMAC:
283 	case PKCS11_CKM_SHA224_HMAC:
284 	case PKCS11_CKM_SHA256_HMAC:
285 	case PKCS11_CKM_SHA384_HMAC:
286 	case PKCS11_CKM_SHA512_HMAC:
287 		if (proc_params->size)
288 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
289 
290 		TEE_MACInit(session->processing->tee_op_handle, NULL, 0);
291 		rc = PKCS11_CKR_OK;
292 		break;
293 	case PKCS11_CKM_AES_ECB:
294 		if (proc_params->size)
295 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
296 
297 		TEE_CipherInit(session->processing->tee_op_handle, NULL, 0);
298 		rc = PKCS11_CKR_OK;
299 		break;
300 	case PKCS11_CKM_AES_CBC:
301 	case PKCS11_CKM_AES_CBC_PAD:
302 	case PKCS11_CKM_AES_CTS:
303 		if (proc_params->size != 16)
304 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
305 
306 		TEE_CipherInit(session->processing->tee_op_handle,
307 			       proc_params->data, 16);
308 		rc = PKCS11_CKR_OK;
309 		break;
310 	case PKCS11_CKM_AES_CTR:
311 		rc = tee_init_ctr_operation(session->processing,
312 					    proc_params->data,
313 					    proc_params->size);
314 		break;
315 	default:
316 		TEE_Panic(proc_params->id);
317 		break;
318 	}
319 
320 	return rc;
321 }
322 
323 enum pkcs11_rc init_symm_operation(struct pkcs11_session *session,
324 				   enum processing_func function,
325 				   struct pkcs11_attribute_head *proc_params,
326 				   struct pkcs11_object *obj)
327 {
328 	enum pkcs11_rc rc = PKCS11_CKR_OK;
329 
330 	assert(processing_is_tee_symm(proc_params->id));
331 
332 	rc = allocate_tee_operation(session, function, proc_params, obj);
333 	if (rc)
334 		return rc;
335 
336 	rc = load_tee_key(session, obj, proc_params);
337 	if (rc)
338 		return rc;
339 
340 	return init_tee_operation(session, proc_params);
341 }
342 
343 /* Validate input buffer size as per PKCS#11 constraints */
344 static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc,
345 					       enum processing_func function,
346 					       size_t in_size)
347 {
348 	switch (proc->mecha_type) {
349 	case PKCS11_CKM_AES_ECB:
350 	case PKCS11_CKM_AES_CBC:
351 		if (function == PKCS11_FUNCTION_ENCRYPT &&
352 		    in_size % TEE_AES_BLOCK_SIZE)
353 			return PKCS11_CKR_DATA_LEN_RANGE;
354 		if (function == PKCS11_FUNCTION_DECRYPT &&
355 		    in_size % TEE_AES_BLOCK_SIZE)
356 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
357 		break;
358 	case PKCS11_CKM_AES_CBC_PAD:
359 		if (function == PKCS11_FUNCTION_DECRYPT &&
360 		    in_size % TEE_AES_BLOCK_SIZE)
361 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
362 		break;
363 	case PKCS11_CKM_AES_CTS:
364 		if (function == PKCS11_FUNCTION_ENCRYPT &&
365 		    in_size < TEE_AES_BLOCK_SIZE)
366 			return PKCS11_CKR_DATA_LEN_RANGE;
367 		if (function == PKCS11_FUNCTION_DECRYPT &&
368 		    in_size < TEE_AES_BLOCK_SIZE)
369 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
370 		break;
371 	default:
372 		break;
373 	}
374 
375 	return PKCS11_CKR_OK;
376 }
377 
378 /* Validate input buffer size as per PKCS#11 constraints */
379 static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc,
380 					       size_t in_size)
381 {
382 	size_t sign_sz = 0;
383 
384 	switch (proc->mecha_type) {
385 	case PKCS11_CKM_MD5_HMAC:
386 		sign_sz = TEE_MD5_HASH_SIZE;
387 		break;
388 	case PKCS11_CKM_SHA_1_HMAC:
389 		sign_sz = TEE_SHA1_HASH_SIZE;
390 		break;
391 	case PKCS11_CKM_SHA224_HMAC:
392 		sign_sz = TEE_SHA224_HASH_SIZE;
393 		break;
394 	case PKCS11_CKM_SHA256_HMAC:
395 		sign_sz = TEE_SHA256_HASH_SIZE;
396 		break;
397 	case PKCS11_CKM_SHA384_HMAC:
398 		sign_sz = TEE_SHA384_HASH_SIZE;
399 		break;
400 	case PKCS11_CKM_SHA512_HMAC:
401 		sign_sz = TEE_SHA512_HASH_SIZE;
402 		break;
403 	default:
404 		return PKCS11_CKR_GENERAL_ERROR;
405 	}
406 
407 	if (in_size < sign_sz)
408 		return PKCS11_CKR_SIGNATURE_LEN_RANGE;
409 
410 	return PKCS11_CKR_OK;
411 }
412 
413 /*
414  * step_sym_cipher - processing symmetric (and related) cipher operation step
415  *
416  * @session - current session
417  * @function - processing function (encrypt, decrypt, sign, ...)
418  * @step - step ID in the processing (oneshot, update, final)
419  * @ptype - invocation parameter types
420  * @params - invocation parameter references
421  */
422 enum pkcs11_rc step_symm_operation(struct pkcs11_session *session,
423 				   enum processing_func function,
424 				   enum processing_step step,
425 				   uint32_t ptypes, TEE_Param *params)
426 {
427 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
428 	TEE_Result res = TEE_ERROR_GENERIC;
429 	void *in_buf = NULL;
430 	size_t in_size = 0;
431 	void *out_buf = NULL;
432 	uint32_t out_size = 0;
433 	void *in2_buf = NULL;
434 	uint32_t in2_size = 0;
435 	bool output_data = false;
436 	struct active_processing *proc = session->processing;
437 
438 	if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
439 		in_buf = params[1].memref.buffer;
440 		in_size = params[1].memref.size;
441 		if (in_size && !in_buf)
442 			return PKCS11_CKR_ARGUMENTS_BAD;
443 	}
444 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) {
445 		in2_buf = params[2].memref.buffer;
446 		in2_size = params[2].memref.size;
447 		if (in2_size && !in2_buf)
448 			return PKCS11_CKR_ARGUMENTS_BAD;
449 	}
450 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) {
451 		out_buf = params[2].memref.buffer;
452 		out_size = params[2].memref.size;
453 		if (out_size && !out_buf)
454 			return PKCS11_CKR_ARGUMENTS_BAD;
455 	}
456 	if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
457 		return PKCS11_CKR_ARGUMENTS_BAD;
458 
459 	switch (step) {
460 	case PKCS11_FUNC_STEP_ONESHOT:
461 	case PKCS11_FUNC_STEP_UPDATE:
462 	case PKCS11_FUNC_STEP_FINAL:
463 		break;
464 	default:
465 		return PKCS11_CKR_GENERAL_ERROR;
466 	}
467 
468 	if (step != PKCS11_FUNC_STEP_FINAL) {
469 		rc = input_data_size_is_valid(proc, function, in_size);
470 		if (rc)
471 			return rc;
472 	}
473 
474 	/*
475 	 * Feed active operation with data
476 	 */
477 	switch (proc->mecha_type) {
478 	case PKCS11_CKM_MD5_HMAC:
479 	case PKCS11_CKM_SHA_1_HMAC:
480 	case PKCS11_CKM_SHA224_HMAC:
481 	case PKCS11_CKM_SHA256_HMAC:
482 	case PKCS11_CKM_SHA384_HMAC:
483 	case PKCS11_CKM_SHA512_HMAC:
484 		if (step == PKCS11_FUNC_STEP_FINAL ||
485 		    step == PKCS11_FUNC_STEP_ONESHOT)
486 			break;
487 
488 		if (!in_buf) {
489 			DMSG("No input data");
490 			return PKCS11_CKR_ARGUMENTS_BAD;
491 		}
492 
493 		switch (function) {
494 		case PKCS11_FUNCTION_SIGN:
495 		case PKCS11_FUNCTION_VERIFY:
496 			TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size);
497 			rc = PKCS11_CKR_OK;
498 			break;
499 		default:
500 			TEE_Panic(function);
501 			break;
502 		}
503 		break;
504 
505 	case PKCS11_CKM_AES_ECB:
506 	case PKCS11_CKM_AES_CBC:
507 	case PKCS11_CKM_AES_CBC_PAD:
508 	case PKCS11_CKM_AES_CTS:
509 	case PKCS11_CKM_AES_CTR:
510 		if (step == PKCS11_FUNC_STEP_FINAL ||
511 		    step == PKCS11_FUNC_STEP_ONESHOT)
512 			break;
513 
514 		if (!in_buf) {
515 			EMSG("No input data");
516 			return PKCS11_CKR_ARGUMENTS_BAD;
517 		}
518 
519 		switch (function) {
520 		case PKCS11_FUNCTION_ENCRYPT:
521 		case PKCS11_FUNCTION_DECRYPT:
522 			res = TEE_CipherUpdate(proc->tee_op_handle,
523 					       in_buf, in_size,
524 						out_buf, &out_size);
525 			output_data = true;
526 			rc = tee2pkcs_error(res);
527 			break;
528 		default:
529 			TEE_Panic(function);
530 			break;
531 		}
532 		break;
533 
534 	default:
535 		TEE_Panic(proc->mecha_type);
536 		break;
537 	}
538 
539 	if (step == PKCS11_FUNC_STEP_UPDATE)
540 		goto out;
541 
542 	/*
543 	 * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation
544 	 */
545 	switch (session->processing->mecha_type) {
546 	case PKCS11_CKM_MD5_HMAC:
547 	case PKCS11_CKM_SHA_1_HMAC:
548 	case PKCS11_CKM_SHA224_HMAC:
549 	case PKCS11_CKM_SHA256_HMAC:
550 	case PKCS11_CKM_SHA384_HMAC:
551 	case PKCS11_CKM_SHA512_HMAC:
552 		switch (function) {
553 		case PKCS11_FUNCTION_SIGN:
554 			res = TEE_MACComputeFinal(proc->tee_op_handle,
555 						  in_buf, in_size, out_buf,
556 						  &out_size);
557 			output_data = true;
558 			rc = tee2pkcs_error(res);
559 			break;
560 		case PKCS11_FUNCTION_VERIFY:
561 			rc = input_sign_size_is_valid(proc, in2_size);
562 			if (rc)
563 				return rc;
564 			res = TEE_MACCompareFinal(proc->tee_op_handle,
565 						  in_buf, in_size, in2_buf,
566 						  in2_size);
567 			rc = tee2pkcs_error(res);
568 			break;
569 		default:
570 			TEE_Panic(function);
571 			break;
572 		}
573 		break;
574 
575 	case PKCS11_CKM_AES_ECB:
576 	case PKCS11_CKM_AES_CBC:
577 	case PKCS11_CKM_AES_CBC_PAD:
578 	case PKCS11_CKM_AES_CTS:
579 	case PKCS11_CKM_AES_CTR:
580 		if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) {
581 			EMSG("No input data");
582 			return PKCS11_CKR_ARGUMENTS_BAD;
583 		}
584 
585 		switch (function) {
586 		case PKCS11_FUNCTION_ENCRYPT:
587 		case PKCS11_FUNCTION_DECRYPT:
588 			res = TEE_CipherDoFinal(proc->tee_op_handle,
589 						in_buf, in_size,
590 						out_buf, &out_size);
591 			output_data = true;
592 			rc = tee2pkcs_error(res);
593 			break;
594 		default:
595 			TEE_Panic(function);
596 			break;
597 		}
598 		break;
599 	default:
600 		TEE_Panic(proc->mecha_type);
601 		break;
602 	}
603 
604 out:
605 	if (output_data &&
606 	    (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) {
607 		switch (TEE_PARAM_TYPE_GET(ptypes, 2)) {
608 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
609 		case TEE_PARAM_TYPE_MEMREF_INOUT:
610 			params[2].memref.size = out_size;
611 			break;
612 		default:
613 			rc = PKCS11_CKR_ARGUMENTS_BAD;
614 			break;
615 		}
616 	}
617 
618 	return rc;
619 }
620