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