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 <util.h>
13
14 #include "attributes.h"
15 #include "object.h"
16 #include "pkcs11_attributes.h"
17 #include "pkcs11_helpers.h"
18 #include "pkcs11_token.h"
19 #include "processing.h"
20 #include "serializer.h"
21
get_ready_session(struct pkcs11_session * session)22 static enum pkcs11_rc get_ready_session(struct pkcs11_session *session)
23 {
24 if (session_is_active(session))
25 return PKCS11_CKR_OPERATION_ACTIVE;
26
27 return PKCS11_CKR_OK;
28 }
29
func_for_cmd(enum pkcs11_ta_cmd cmd)30 static enum processing_func func_for_cmd(enum pkcs11_ta_cmd cmd)
31 {
32 switch (cmd) {
33 case PKCS11_CMD_ENCRYPT_UPDATE:
34 case PKCS11_CMD_ENCRYPT_ONESHOT:
35 case PKCS11_CMD_ENCRYPT_FINAL:
36 return PKCS11_FUNCTION_ENCRYPT;
37 case PKCS11_CMD_DECRYPT_UPDATE:
38 case PKCS11_CMD_DECRYPT_ONESHOT:
39 case PKCS11_CMD_DECRYPT_FINAL:
40 return PKCS11_FUNCTION_DECRYPT;
41 case PKCS11_CMD_SIGN_ONESHOT:
42 case PKCS11_CMD_SIGN_UPDATE:
43 case PKCS11_CMD_SIGN_FINAL:
44 return PKCS11_FUNCTION_SIGN;
45 case PKCS11_CMD_VERIFY_ONESHOT:
46 case PKCS11_CMD_VERIFY_UPDATE:
47 case PKCS11_CMD_VERIFY_FINAL:
48 return PKCS11_FUNCTION_VERIFY;
49 case PKCS11_CMD_DIGEST_UPDATE:
50 case PKCS11_CMD_DIGEST_KEY:
51 case PKCS11_CMD_DIGEST_ONESHOT:
52 case PKCS11_CMD_DIGEST_FINAL:
53 return PKCS11_FUNCTION_DIGEST;
54 default:
55 return PKCS11_FUNCTION_UNKNOWN;
56 }
57 }
58
func_matches_state(enum processing_func function,enum pkcs11_proc_state state)59 static bool func_matches_state(enum processing_func function,
60 enum pkcs11_proc_state state)
61 {
62 switch (function) {
63 case PKCS11_FUNCTION_ENCRYPT:
64 return state == PKCS11_SESSION_ENCRYPTING ||
65 state == PKCS11_SESSION_DIGESTING_ENCRYPTING ||
66 state == PKCS11_SESSION_SIGNING_ENCRYPTING;
67 case PKCS11_FUNCTION_DECRYPT:
68 return state == PKCS11_SESSION_DECRYPTING ||
69 state == PKCS11_SESSION_DECRYPTING_DIGESTING ||
70 state == PKCS11_SESSION_DECRYPTING_VERIFYING;
71 case PKCS11_FUNCTION_DIGEST:
72 return state == PKCS11_SESSION_DIGESTING ||
73 state == PKCS11_SESSION_DIGESTING_ENCRYPTING;
74 case PKCS11_FUNCTION_SIGN:
75 return state == PKCS11_SESSION_SIGNING ||
76 state == PKCS11_SESSION_SIGNING_ENCRYPTING;
77 case PKCS11_FUNCTION_VERIFY:
78 return state == PKCS11_SESSION_VERIFYING ||
79 state == PKCS11_SESSION_DECRYPTING_VERIFYING;
80 case PKCS11_FUNCTION_SIGN_RECOVER:
81 return state == PKCS11_SESSION_SIGNING_RECOVER;
82 case PKCS11_FUNCTION_VERIFY_RECOVER:
83 return state == PKCS11_SESSION_SIGNING_RECOVER;
84 default:
85 TEE_Panic(function);
86 return false;
87 }
88 }
89
get_active_session(struct pkcs11_session * session,enum processing_func function)90 static enum pkcs11_rc get_active_session(struct pkcs11_session *session,
91 enum processing_func function)
92 {
93 enum pkcs11_rc rc = PKCS11_CKR_OPERATION_NOT_INITIALIZED;
94
95 if (session->processing &&
96 func_matches_state(function, session->processing->state))
97 rc = PKCS11_CKR_OK;
98
99 return rc;
100 }
101
release_active_processing(struct pkcs11_session * session)102 void release_active_processing(struct pkcs11_session *session)
103 {
104 if (!session->processing)
105 return;
106
107 switch (session->processing->mecha_type) {
108 case PKCS11_CKM_AES_GCM:
109 tee_release_gcm_operation(session);
110 break;
111 default:
112 break;
113 }
114
115 if (session->processing->tee_op_handle != TEE_HANDLE_NULL) {
116 TEE_FreeOperation(session->processing->tee_op_handle);
117 session->processing->tee_op_handle = TEE_HANDLE_NULL;
118 }
119
120 if (session->processing->tee_op_handle2 != TEE_HANDLE_NULL) {
121 TEE_FreeOperation(session->processing->tee_op_handle2);
122 session->processing->tee_op_handle2 = TEE_HANDLE_NULL;
123 }
124
125 TEE_Free(session->processing->extra_ctx);
126
127 TEE_Free(session->processing);
128 session->processing = NULL;
129 }
130
get_object_key_bit_size(struct pkcs11_object * obj)131 size_t get_object_key_bit_size(struct pkcs11_object *obj)
132 {
133 void *a_ptr = NULL;
134 uint32_t a_size = 0;
135 struct obj_attrs *attrs = obj->attributes;
136
137 switch (get_key_type(attrs)) {
138 case PKCS11_CKK_AES:
139 case PKCS11_CKK_GENERIC_SECRET:
140 case PKCS11_CKK_MD5_HMAC:
141 case PKCS11_CKK_SHA_1_HMAC:
142 case PKCS11_CKK_SHA224_HMAC:
143 case PKCS11_CKK_SHA256_HMAC:
144 case PKCS11_CKK_SHA384_HMAC:
145 case PKCS11_CKK_SHA512_HMAC:
146 if (get_attribute_ptr(attrs, PKCS11_CKA_VALUE, NULL, &a_size))
147 return 0;
148
149 return a_size * 8;
150 case PKCS11_CKK_RSA:
151 if (get_attribute_ptr(attrs, PKCS11_CKA_MODULUS, NULL, &a_size))
152 return 0;
153
154 return a_size * 8;
155 case PKCS11_CKK_EC:
156 if (get_attribute_ptr(attrs, PKCS11_CKA_EC_PARAMS,
157 &a_ptr, &a_size) || !a_ptr)
158 return 0;
159
160 return ec_params2tee_keysize(a_ptr, a_size);
161 case PKCS11_CKK_EC_EDWARDS:
162 if (get_attribute_ptr(attrs, PKCS11_CKA_EC_POINT, NULL,
163 &a_size))
164 return 0;
165
166 return a_size * 8;
167 default:
168 TEE_Panic(0);
169 return 0;
170 }
171 }
172
generate_random_key_value(struct obj_attrs ** head)173 static enum pkcs11_rc generate_random_key_value(struct obj_attrs **head)
174 {
175 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
176 uint32_t data_size = 0;
177 uint32_t value_len = 0;
178 void *value = NULL;
179 void *data = NULL;
180
181 if (!*head)
182 return PKCS11_CKR_TEMPLATE_INCONSISTENT;
183
184 rc = get_attribute_ptr(*head, PKCS11_CKA_VALUE_LEN, &data, &data_size);
185 if (rc || data_size != sizeof(uint32_t)) {
186 DMSG("%s", rc ? "No attribute value_len found" :
187 "Invalid size for attribute VALUE_LEN");
188
189 return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID;
190 }
191 TEE_MemMove(&value_len, data, data_size);
192
193 /* Remove the default empty value attribute if found */
194 rc = remove_empty_attribute(head, PKCS11_CKA_VALUE);
195 if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
196 return PKCS11_CKR_GENERAL_ERROR;
197
198 value = TEE_Malloc(value_len, TEE_USER_MEM_HINT_NO_FILL_ZERO);
199 if (!value)
200 return PKCS11_CKR_DEVICE_MEMORY;
201
202 TEE_GenerateRandom(value, value_len);
203
204 rc = add_attribute(head, PKCS11_CKA_VALUE, value, value_len);
205
206 if (rc == PKCS11_CKR_OK)
207 rc = set_check_value_attr(head);
208
209 TEE_Free(value);
210
211 return rc;
212 }
213
entry_generate_secret(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)214 enum pkcs11_rc entry_generate_secret(struct pkcs11_client *client,
215 uint32_t ptypes, TEE_Param *params)
216 {
217 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
218 TEE_PARAM_TYPE_NONE,
219 TEE_PARAM_TYPE_MEMREF_OUTPUT,
220 TEE_PARAM_TYPE_NONE);
221 TEE_Param *ctrl = params;
222 TEE_Param *out = params + 2;
223 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
224 struct serialargs ctrlargs = { };
225 struct pkcs11_session *session = NULL;
226 struct pkcs11_attribute_head *proc_params = NULL;
227 struct obj_attrs *head = NULL;
228 struct pkcs11_object_head *template = NULL;
229 size_t template_size = 0;
230 uint32_t obj_handle = 0;
231
232 if (!client || ptypes != exp_pt ||
233 out->memref.size != sizeof(obj_handle))
234 return PKCS11_CKR_ARGUMENTS_BAD;
235
236 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
237
238 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
239 if (rc)
240 return rc;
241
242 rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params);
243 if (rc)
244 goto out;
245
246 rc = serialargs_alloc_get_attributes(&ctrlargs, &template);
247 if (rc)
248 goto out;
249
250 if (serialargs_remaining_bytes(&ctrlargs)) {
251 rc = PKCS11_CKR_ARGUMENTS_BAD;
252 goto out;
253 }
254
255 rc = get_ready_session(session);
256 if (rc)
257 goto out;
258
259 template_size = sizeof(*template) + template->attrs_size;
260
261 rc = check_mechanism_against_processing(session, proc_params->id,
262 PKCS11_FUNCTION_GENERATE,
263 PKCS11_FUNC_STEP_INIT);
264 if (rc) {
265 DMSG("Invalid mechanism %#"PRIx32": %#x", proc_params->id, rc);
266 goto out;
267 }
268
269 /*
270 * Prepare a clean initial state for the requested object attributes.
271 * Free temporary template once done.
272 */
273 rc = create_attributes_from_template(&head, template, template_size,
274 NULL, PKCS11_FUNCTION_GENERATE,
275 proc_params->id,
276 PKCS11_CKO_UNDEFINED_ID);
277 if (rc)
278 goto out;
279
280 TEE_Free(template);
281 template = NULL;
282
283 rc = check_created_attrs(head, NULL);
284 if (rc)
285 goto out;
286
287 rc = check_created_attrs_against_processing(proc_params->id, head);
288 if (rc)
289 goto out;
290
291 rc = check_created_attrs_against_token(session, head);
292 if (rc)
293 goto out;
294
295 /*
296 * Execute target processing and add value as attribute
297 * PKCS11_CKA_VALUE. Symm key generation: depends on target
298 * processing to be used.
299 */
300 switch (proc_params->id) {
301 case PKCS11_CKM_GENERIC_SECRET_KEY_GEN:
302 case PKCS11_CKM_AES_KEY_GEN:
303 /* Generate random of size specified by attribute VALUE_LEN */
304 rc = generate_random_key_value(&head);
305 if (rc)
306 goto out;
307 break;
308
309 default:
310 rc = PKCS11_CKR_MECHANISM_INVALID;
311 goto out;
312 }
313
314 TEE_Free(proc_params);
315 proc_params = NULL;
316
317 /*
318 * Object is ready, register it and return a handle.
319 */
320 rc = create_object(session, head, &obj_handle);
321 if (rc)
322 goto out;
323
324 /*
325 * Now obj_handle (through the related struct pkcs11_object instance)
326 * owns the serialized buffer that holds the object attributes.
327 * We reset head to NULL as it is no more the buffer owner and would
328 * be freed at function out.
329 */
330 head = NULL;
331
332 TEE_MemMove(out->memref.buffer, &obj_handle, sizeof(obj_handle));
333 out->memref.size = sizeof(obj_handle);
334
335 DMSG("PKCS11 session %"PRIu32": generate secret %#"PRIx32,
336 session->handle, obj_handle);
337
338 out:
339 TEE_Free(proc_params);
340 TEE_Free(template);
341 TEE_Free(head);
342
343 return rc;
344 }
345
alloc_get_tee_attribute_data(TEE_ObjectHandle tee_obj,uint32_t attribute,void ** data,size_t * size)346 enum pkcs11_rc alloc_get_tee_attribute_data(TEE_ObjectHandle tee_obj,
347 uint32_t attribute,
348 void **data, size_t *size)
349 {
350 TEE_Result res = TEE_ERROR_GENERIC;
351 void *ptr = NULL;
352 size_t sz = 0;
353
354 res = TEE_GetObjectBufferAttribute(tee_obj, attribute, NULL, &sz);
355 if (res != TEE_ERROR_SHORT_BUFFER)
356 return PKCS11_CKR_FUNCTION_FAILED;
357
358 ptr = TEE_Malloc(sz, TEE_USER_MEM_HINT_NO_FILL_ZERO);
359 if (!ptr)
360 return PKCS11_CKR_DEVICE_MEMORY;
361
362 res = TEE_GetObjectBufferAttribute(tee_obj, attribute, ptr, &sz);
363 if (res) {
364 TEE_Free(ptr);
365 } else {
366 *data = ptr;
367 *size = sz;
368 }
369
370 return tee2pkcs_error(res);
371 }
372
tee2pkcs_add_attribute(struct obj_attrs ** head,uint32_t pkcs11_id,TEE_ObjectHandle tee_obj,uint32_t tee_id)373 enum pkcs11_rc tee2pkcs_add_attribute(struct obj_attrs **head,
374 uint32_t pkcs11_id,
375 TEE_ObjectHandle tee_obj,
376 uint32_t tee_id)
377 {
378 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
379 void *a_ptr = NULL;
380 size_t a_size = 0;
381
382 rc = alloc_get_tee_attribute_data(tee_obj, tee_id, &a_ptr, &a_size);
383 if (rc)
384 goto out;
385
386 rc = add_attribute(head, pkcs11_id, a_ptr, a_size);
387
388 TEE_Free(a_ptr);
389
390 out:
391 if (rc)
392 EMSG("Failed TEE attribute %#"PRIx32" for %#"PRIx32"/%s",
393 tee_id, pkcs11_id, id2str_attr(pkcs11_id));
394 return rc;
395 }
396
entry_generate_key_pair(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)397 enum pkcs11_rc entry_generate_key_pair(struct pkcs11_client *client,
398 uint32_t ptypes, TEE_Param *params)
399 {
400 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
401 TEE_PARAM_TYPE_NONE,
402 TEE_PARAM_TYPE_MEMREF_OUTPUT,
403 TEE_PARAM_TYPE_NONE);
404 TEE_Param *ctrl = params;
405 TEE_Param *out = params + 2;
406 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
407 struct serialargs ctrlargs = { };
408 struct pkcs11_session *session = NULL;
409 struct pkcs11_attribute_head *proc_params = NULL;
410 struct obj_attrs *pub_head = NULL;
411 struct obj_attrs *priv_head = NULL;
412 struct pkcs11_object_head *pub_template = NULL;
413 struct pkcs11_object_head *priv_template = NULL;
414 struct pkcs11_object *object = NULL;
415 size_t pub_template_size = 0;
416 size_t priv_template_size = 0;
417 uint32_t pubkey_handle = 0;
418 uint32_t privkey_handle = 0;
419 uint32_t *hdl_ptr = NULL;
420 size_t out_ref_size = sizeof(pubkey_handle) + sizeof(privkey_handle);
421
422 if (!client || ptypes != exp_pt || out->memref.size != out_ref_size)
423 return PKCS11_CKR_ARGUMENTS_BAD;
424
425 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
426
427 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
428 if (rc)
429 return rc;
430
431 rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params);
432 if (rc)
433 goto out;
434
435 rc = serialargs_alloc_get_attributes(&ctrlargs, &pub_template);
436 if (rc)
437 goto out;
438
439 rc = serialargs_alloc_get_attributes(&ctrlargs, &priv_template);
440 if (rc)
441 goto out;
442
443 if (serialargs_remaining_bytes(&ctrlargs)) {
444 rc = PKCS11_CKR_ARGUMENTS_BAD;
445 goto out;
446 }
447
448 rc = get_ready_session(session);
449 if (rc)
450 goto out;
451
452 rc = check_mechanism_against_processing(session, proc_params->id,
453 PKCS11_FUNCTION_GENERATE_PAIR,
454 PKCS11_FUNC_STEP_INIT);
455 if (rc)
456 goto out;
457
458 pub_template_size = sizeof(*pub_template) + pub_template->attrs_size;
459
460 rc = create_attributes_from_template(&pub_head, pub_template,
461 pub_template_size, NULL,
462 PKCS11_FUNCTION_GENERATE_PAIR,
463 proc_params->id,
464 PKCS11_CKO_PUBLIC_KEY);
465 if (rc)
466 goto out;
467
468 TEE_Free(pub_template);
469 pub_template = NULL;
470
471 priv_template_size = sizeof(*priv_template) +
472 priv_template->attrs_size;
473
474 rc = create_attributes_from_template(&priv_head, priv_template,
475 priv_template_size, NULL,
476 PKCS11_FUNCTION_GENERATE_PAIR,
477 proc_params->id,
478 PKCS11_CKO_PRIVATE_KEY);
479 if (rc)
480 goto out;
481
482 TEE_Free(priv_template);
483 priv_template = NULL;
484
485 /* Generate CKA_ID for keys if not specified by the templates */
486 rc = add_missing_attribute_id(&pub_head, &priv_head);
487 if (rc)
488 goto out;
489
490 /* Check created object against processing and token state */
491 rc = check_created_attrs(pub_head, priv_head);
492 if (rc)
493 goto out;
494
495 rc = check_created_attrs_against_processing(proc_params->id, pub_head);
496 if (rc)
497 goto out;
498
499 rc = check_created_attrs_against_processing(proc_params->id,
500 priv_head);
501 if (rc)
502 goto out;
503
504 rc = check_created_attrs_against_token(session, pub_head);
505 if (rc)
506 goto out;
507
508 rc = check_access_attrs_against_token(session, pub_head);
509 if (rc)
510 goto out;
511
512 rc = check_created_attrs_against_token(session, priv_head);
513 if (rc)
514 goto out;
515
516 rc = check_access_attrs_against_token(session, priv_head);
517 if (rc)
518 goto out;
519
520 /* Generate key pair */
521 switch (proc_params->id) {
522 case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN:
523 rc = generate_eddsa_keys(proc_params, &pub_head, &priv_head);
524 break;
525 case PKCS11_CKM_EC_KEY_PAIR_GEN:
526 rc = generate_ec_keys(proc_params, &pub_head, &priv_head);
527 break;
528 case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN:
529 rc = generate_rsa_keys(proc_params, &pub_head, &priv_head);
530 break;
531 default:
532 rc = PKCS11_CKR_MECHANISM_INVALID;
533 break;
534 }
535 if (rc)
536 goto out;
537
538 TEE_Free(proc_params);
539 proc_params = NULL;
540
541 /*
542 * Object is ready, register it and return a handle.
543 */
544 rc = create_object(session, pub_head, &pubkey_handle);
545 if (rc)
546 goto out;
547
548 /*
549 * Now obj_handle (through the related struct pkcs11_object instance)
550 * owns the serialized buffer that holds the object attributes.
551 * We reset local pub_head to NULL to mark that ownership has been
552 * transferred.
553 */
554 pub_head = NULL;
555
556 rc = create_object(session, priv_head, &privkey_handle);
557 if (rc)
558 goto out;
559
560 /* Ownership has been transferred so mark it with NULL */
561 priv_head = NULL;
562
563 hdl_ptr = (uint32_t *)out->memref.buffer;
564
565 TEE_MemMove(hdl_ptr, &pubkey_handle, sizeof(pubkey_handle));
566 TEE_MemMove(hdl_ptr + 1, &privkey_handle, sizeof(privkey_handle));
567
568 DMSG("PKCS11 session %"PRIu32": create key pair %#"PRIx32"/%#"PRIx32,
569 session->handle, privkey_handle, pubkey_handle);
570
571 pubkey_handle = 0;
572 privkey_handle = 0;
573 out:
574 if (pubkey_handle) {
575 object = pkcs11_handle2object(pubkey_handle, session);
576 if (!object)
577 TEE_Panic(0);
578 destroy_object(session, object, false);
579 }
580 TEE_Free(priv_head);
581 TEE_Free(pub_head);
582 TEE_Free(priv_template);
583 TEE_Free(pub_template);
584 TEE_Free(proc_params);
585
586 return rc;
587 }
588
589 /*
590 * entry_processing_init - Generic entry for initializing a processing
591 *
592 * @client = client reference
593 * @ptype = Invocation parameter types
594 * @params = Invocation parameters reference
595 * @function - encrypt, decrypt, sign, verify, digest, ...
596 */
entry_processing_init(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params,enum processing_func function)597 enum pkcs11_rc entry_processing_init(struct pkcs11_client *client,
598 uint32_t ptypes, TEE_Param *params,
599 enum processing_func function)
600 {
601 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
602 TEE_PARAM_TYPE_NONE,
603 TEE_PARAM_TYPE_NONE,
604 TEE_PARAM_TYPE_NONE);
605 TEE_Param *ctrl = params;
606 enum pkcs11_rc rc = PKCS11_CKR_OK;
607 struct serialargs ctrlargs = { };
608 struct pkcs11_session *session = NULL;
609 struct pkcs11_attribute_head *proc_params = NULL;
610 uint32_t key_handle = 0;
611 struct pkcs11_object *obj = NULL;
612
613 if (!client || ptypes != exp_pt)
614 return PKCS11_CKR_ARGUMENTS_BAD;
615
616 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
617
618 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
619 if (rc)
620 return rc;
621
622 if (function != PKCS11_FUNCTION_DIGEST) {
623 rc = serialargs_get(&ctrlargs, &key_handle, sizeof(uint32_t));
624 if (rc)
625 return rc;
626 }
627
628 rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params);
629 if (rc)
630 return rc;
631
632 if (serialargs_remaining_bytes(&ctrlargs)) {
633 rc = PKCS11_CKR_ARGUMENTS_BAD;
634 goto out_free;
635 }
636
637 rc = get_ready_session(session);
638 if (rc)
639 goto out_free;
640
641 if (function != PKCS11_FUNCTION_DIGEST) {
642 obj = pkcs11_handle2object(key_handle, session);
643 if (!obj) {
644 rc = PKCS11_CKR_KEY_HANDLE_INVALID;
645 goto out_free;
646 }
647 }
648
649 rc = set_processing_state(session, function, obj, NULL);
650 if (rc)
651 goto out;
652
653 rc = check_mechanism_against_processing(session, proc_params->id,
654 function,
655 PKCS11_FUNC_STEP_INIT);
656 if (rc)
657 goto out;
658
659 if (obj) {
660 rc = check_parent_attrs_against_processing(proc_params->id,
661 function,
662 obj->attributes);
663 if (rc)
664 goto out;
665
666 rc = check_access_attrs_against_token(session,
667 obj->attributes);
668 if (rc)
669 goto out;
670 }
671
672 if (processing_is_tee_symm(proc_params->id))
673 rc = init_symm_operation(session, function, proc_params, obj);
674 else if (processing_is_tee_asymm(proc_params->id))
675 rc = init_asymm_operation(session, function, proc_params, obj);
676 else if (processing_is_tee_digest(proc_params->id))
677 rc = init_digest_operation(session, proc_params);
678 else
679 rc = PKCS11_CKR_MECHANISM_INVALID;
680
681 if (rc == PKCS11_CKR_OK) {
682 DMSG("PKCS11 session %"PRIu32": init processing %s %s",
683 session->handle, id2str_proc(proc_params->id),
684 id2str_function(function));
685 }
686
687 out:
688 if (rc)
689 release_active_processing(session);
690 out_free:
691 TEE_Free(proc_params);
692
693 return rc;
694 }
695
696 /*
697 * entry_processing_step - Generic entry on active processing
698 *
699 * @client = client reference
700 * @ptype = Invocation parameter types
701 * @params = Invocation parameters reference
702 * @function - encrypt, decrypt, sign, verify, digest, ...
703 * @step - update, oneshot, final
704 */
entry_processing_step(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params,enum processing_func function,enum processing_step step)705 enum pkcs11_rc entry_processing_step(struct pkcs11_client *client,
706 uint32_t ptypes, TEE_Param *params,
707 enum processing_func function,
708 enum processing_step step)
709 {
710 TEE_Param *ctrl = params;
711 enum pkcs11_rc rc = PKCS11_CKR_OK;
712 struct serialargs ctrlargs = { };
713 struct pkcs11_session *session = NULL;
714 enum pkcs11_mechanism_id mecha_type = PKCS11_CKM_UNDEFINED_ID;
715 uint32_t key_handle = 0;
716 struct pkcs11_object *obj = NULL;
717
718 if (!client ||
719 TEE_PARAM_TYPE_GET(ptypes, 0) != TEE_PARAM_TYPE_MEMREF_INOUT)
720 return PKCS11_CKR_ARGUMENTS_BAD;
721
722 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
723
724 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
725 if (rc)
726 return rc;
727
728 if (step == PKCS11_FUNC_STEP_UPDATE_KEY) {
729 assert(function == PKCS11_FUNCTION_DIGEST);
730
731 rc = serialargs_get(&ctrlargs, &key_handle, sizeof(uint32_t));
732 if (rc)
733 return rc;
734 }
735
736 if (serialargs_remaining_bytes(&ctrlargs))
737 return PKCS11_CKR_ARGUMENTS_BAD;
738
739 rc = get_active_session(session, function);
740 if (rc)
741 return rc;
742
743 if (step == PKCS11_FUNC_STEP_UPDATE_KEY) {
744 assert(function == PKCS11_FUNCTION_DIGEST);
745
746 obj = pkcs11_handle2object(key_handle, session);
747 if (!obj) {
748 rc = PKCS11_CKR_KEY_HANDLE_INVALID;
749 goto out;
750 }
751
752 rc = check_access_attrs_against_token(session,
753 obj->attributes);
754 if (rc) {
755 rc = PKCS11_CKR_KEY_HANDLE_INVALID;
756 goto out;
757 }
758 }
759
760 mecha_type = session->processing->mecha_type;
761 rc = check_mechanism_against_processing(session, mecha_type,
762 function, step);
763 if (rc)
764 goto out;
765
766 if (processing_is_tee_symm(mecha_type))
767 rc = step_symm_operation(session, function, step,
768 ptypes, params);
769 else if (processing_is_tee_asymm(mecha_type))
770 rc = step_asymm_operation(session, function, step,
771 ptypes, params);
772 else if (processing_is_tee_digest(mecha_type))
773 rc = step_digest_operation(session, step, obj, ptypes, params);
774 else
775 rc = PKCS11_CKR_MECHANISM_INVALID;
776
777 if (rc == PKCS11_CKR_OK && (step == PKCS11_FUNC_STEP_UPDATE ||
778 step == PKCS11_FUNC_STEP_UPDATE_KEY)) {
779 session->processing->step = PKCS11_FUNC_STEP_UPDATE;
780 DMSG("PKCS11 session%"PRIu32": processing %s %s",
781 session->handle, id2str_proc(mecha_type),
782 id2str_function(function));
783 }
784
785 if (rc == PKCS11_CKR_BUFFER_TOO_SMALL &&
786 step == PKCS11_FUNC_STEP_ONESHOT)
787 session->processing->step = PKCS11_FUNC_STEP_ONESHOT;
788
789 if (rc == PKCS11_CKR_BUFFER_TOO_SMALL && step == PKCS11_FUNC_STEP_FINAL)
790 session->processing->step = PKCS11_FUNC_STEP_FINAL;
791
792 out:
793 switch (step) {
794 case PKCS11_FUNC_STEP_UPDATE:
795 case PKCS11_FUNC_STEP_UPDATE_KEY:
796 if (rc != PKCS11_CKR_OK && rc != PKCS11_CKR_BUFFER_TOO_SMALL)
797 release_active_processing(session);
798 break;
799 default:
800 /* ONESHOT and FINAL terminates processing on success */
801 if (rc != PKCS11_CKR_BUFFER_TOO_SMALL)
802 release_active_processing(session);
803 break;
804 }
805
806 return rc;
807 }
808
entry_processing_key(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params,enum processing_func function)809 enum pkcs11_rc entry_processing_key(struct pkcs11_client *client,
810 uint32_t ptypes, TEE_Param *params,
811 enum processing_func function)
812 {
813 TEE_Param *ctrl = params;
814 TEE_Param *out = params + 2;
815 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
816 struct serialargs ctrlargs = { };
817 struct pkcs11_session *session = NULL;
818 struct pkcs11_attribute_head *proc_params = NULL;
819 struct pkcs11_object_head *template = NULL;
820 uint32_t parent_handle = 0;
821 uint32_t obj_handle = 0;
822 struct pkcs11_object *parent = NULL;
823 struct obj_attrs *head = NULL;
824 size_t template_size = 0;
825 void *in_buf = NULL;
826 uint32_t in_size = 0;
827 void *out_buf = NULL;
828 uint32_t out_size = 0;
829 enum processing_func operation = PKCS11_FUNCTION_UNKNOWN;
830
831 if (!client ||
832 TEE_PARAM_TYPE_GET(ptypes, 0) != TEE_PARAM_TYPE_MEMREF_INOUT ||
833 TEE_PARAM_TYPE_GET(ptypes, 2) != TEE_PARAM_TYPE_MEMREF_OUTPUT ||
834 out->memref.size != sizeof(obj_handle) ||
835 TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
836 return PKCS11_CKR_ARGUMENTS_BAD;
837
838 switch (function) {
839 case PKCS11_FUNCTION_UNWRAP:
840 if (TEE_PARAM_TYPE_GET(ptypes, 1) !=
841 TEE_PARAM_TYPE_MEMREF_INPUT)
842 return PKCS11_CKR_ARGUMENTS_BAD;
843
844 in_buf = params[1].memref.buffer;
845 in_size = params[1].memref.size;
846 if (in_size && !in_buf)
847 return PKCS11_CKR_ARGUMENTS_BAD;
848
849 /*
850 * Some unwrap mechanisms require encryption to be
851 * performed on the data passed in proc_params by parent
852 * key. Hence set operation as PKCS11_FUNCTION_DECRYPT
853 * to be used with init_symm_operation()
854 */
855 operation = PKCS11_FUNCTION_DECRYPT;
856 break;
857 case PKCS11_FUNCTION_DERIVE:
858 if (TEE_PARAM_TYPE_GET(ptypes, 1) != TEE_PARAM_TYPE_NONE)
859 return PKCS11_CKR_ARGUMENTS_BAD;
860
861 /*
862 * Some derivation mechanism require encryption to be
863 * performed on the data passed in proc_params by parent
864 * key. Hence set operation as PKCS11_FUNCTION_ENCRYPT
865 * to be used with init_symm_operation()
866 */
867 operation = PKCS11_FUNCTION_ENCRYPT;
868 break;
869 default:
870 return PKCS11_CKR_ARGUMENTS_BAD;
871 }
872
873 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
874
875 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
876 if (rc)
877 return rc;
878
879 rc = serialargs_get(&ctrlargs, &parent_handle, sizeof(uint32_t));
880 if (rc)
881 return rc;
882
883 rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params);
884 if (rc)
885 return rc;
886
887 rc = serialargs_alloc_get_attributes(&ctrlargs, &template);
888 if (rc)
889 goto out_free;
890
891 if (serialargs_remaining_bytes(&ctrlargs)) {
892 rc = PKCS11_CKR_ARGUMENTS_BAD;
893 goto out_free;
894 }
895
896 /* Return error if processing already active */
897 rc = get_ready_session(session);
898 if (rc)
899 goto out_free;
900
901 /* Check parent handle */
902 parent = pkcs11_handle2object(parent_handle, session);
903 if (!parent) {
904 rc = PKCS11_CKR_KEY_HANDLE_INVALID;
905 goto out_free;
906 }
907
908 /* Check if mechanism can be used for derivation function */
909 rc = check_mechanism_against_processing(session, proc_params->id,
910 function,
911 PKCS11_FUNC_STEP_INIT);
912 if (rc)
913 goto out_free;
914
915 /* Set the processing state to active */
916 rc = set_processing_state(session, function, parent, NULL);
917 if (rc)
918 goto out_free;
919
920 /*
921 * Check if base/parent key has CKA_DERIVE set and its key type is
922 * compatible with the mechanism passed
923 */
924 rc = check_parent_attrs_against_processing(proc_params->id, function,
925 parent->attributes);
926 if (rc) {
927 /*
928 * CKR_KEY_FUNCTION_NOT_PERMITTED is not in the list of errors
929 * specified with C_Derive/Unwrap() in the specification. So
930 * return the next most appropriate error.
931 */
932 if (rc == PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED) {
933 if (function == PKCS11_FUNCTION_UNWRAP)
934 rc =
935 PKCS11_CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
936 else
937 rc = PKCS11_CKR_KEY_TYPE_INCONSISTENT;
938 }
939 goto out;
940 }
941
942 /* Check access of base/parent key */
943 rc = check_access_attrs_against_token(session, parent->attributes);
944 if (rc)
945 goto out;
946
947 template_size = sizeof(*template) + template->attrs_size;
948 /*
949 * Prepare a clean initial state for the requested object attributes
950 * using base/parent key attributes. Free temporary template once done.
951 */
952 rc = create_attributes_from_template(&head, template, template_size,
953 parent->attributes,
954 function,
955 proc_params->id,
956 PKCS11_CKO_UNDEFINED_ID);
957 if (rc)
958 goto out;
959
960 TEE_Free(template);
961 template = NULL;
962
963 /* check_created_attrs() is called later once key size is known */
964
965 rc = check_created_attrs_against_processing(proc_params->id, head);
966 if (rc)
967 goto out;
968
969 rc = check_created_attrs_against_token(session, head);
970 if (rc)
971 goto out;
972
973 rc = check_access_attrs_against_token(session, head);
974 if (rc)
975 goto out;
976
977 if (processing_is_tee_symm(proc_params->id)) {
978 rc = init_symm_operation(session, operation, proc_params,
979 parent);
980 if (rc)
981 goto out;
982
983 switch (function) {
984 case PKCS11_FUNCTION_DERIVE:
985 rc = derive_key_by_symm_enc(session, &out_buf,
986 &out_size);
987 break;
988 case PKCS11_FUNCTION_UNWRAP:
989 rc = unwrap_key_by_symm(session, in_buf, in_size,
990 &out_buf, &out_size);
991 break;
992 default:
993 TEE_Panic(function);
994 }
995 if (rc)
996 goto out;
997
998 } else if (processing_is_tee_asymm(proc_params->id)) {
999 switch (function) {
1000 case PKCS11_FUNCTION_DERIVE:
1001 rc = init_asymm_operation(session, function,
1002 proc_params, parent);
1003 if (rc)
1004 goto out;
1005
1006 rc = do_asymm_derivation(session, proc_params, &head);
1007 if (!rc)
1008 goto done;
1009 break;
1010 case PKCS11_FUNCTION_UNWRAP:
1011 rc = init_asymm_operation(session, operation,
1012 proc_params, parent);
1013 if (rc)
1014 goto out;
1015
1016 rc = unwrap_key_by_asymm(session, in_buf, in_size,
1017 &out_buf, &out_size);
1018 break;
1019 default:
1020 TEE_Panic(function);
1021 }
1022
1023 if (rc)
1024 goto out;
1025 } else {
1026 rc = PKCS11_CKR_MECHANISM_INVALID;
1027 goto out;
1028 }
1029
1030 rc = set_key_data(&head, out_buf, out_size);
1031 if (rc)
1032 goto out;
1033
1034 done:
1035 TEE_Free(out_buf);
1036 out_buf = NULL;
1037
1038 TEE_Free(proc_params);
1039 proc_params = NULL;
1040
1041 /*
1042 * Object is ready, register it and return a handle.
1043 */
1044 rc = create_object(session, head, &obj_handle);
1045 if (rc)
1046 goto out;
1047
1048 /*
1049 * Now obj_handle (through the related struct pkcs11_object instance)
1050 * owns the serialized buffer that holds the object attributes.
1051 * We reset head to NULL as it is no more the buffer owner and would
1052 * be freed at function out.
1053 */
1054 head = NULL;
1055
1056 TEE_MemMove(out->memref.buffer, &obj_handle, sizeof(obj_handle));
1057 out->memref.size = sizeof(obj_handle);
1058
1059 DMSG("PKCS11 session %"PRIu32": derive secret %#"PRIx32,
1060 session->handle, obj_handle);
1061
1062 out:
1063 release_active_processing(session);
1064 out_free:
1065 TEE_Free(proc_params);
1066 TEE_Free(template);
1067 TEE_Free(head);
1068 TEE_Free(out_buf);
1069
1070 return rc;
1071 }
1072
entry_release_active_processing(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)1073 enum pkcs11_rc entry_release_active_processing(struct pkcs11_client *client,
1074 uint32_t ptypes,
1075 TEE_Param *params)
1076 {
1077 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1078 TEE_PARAM_TYPE_NONE,
1079 TEE_PARAM_TYPE_NONE,
1080 TEE_PARAM_TYPE_NONE);
1081 TEE_Param *ctrl = params;
1082 enum pkcs11_rc rc = PKCS11_CKR_OK;
1083 struct serialargs ctrlargs = { };
1084 struct pkcs11_session *session = NULL;
1085 enum processing_func function = PKCS11_FUNCTION_UNKNOWN;
1086 uint32_t cmd = 0;
1087
1088 if (!client || ptypes != exp_pt)
1089 return PKCS11_CKR_ARGUMENTS_BAD;
1090
1091 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1092
1093 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
1094 if (rc)
1095 return rc;
1096
1097 rc = serialargs_get_u32(&ctrlargs, &cmd);
1098
1099 if (serialargs_remaining_bytes(&ctrlargs))
1100 return PKCS11_CKR_ARGUMENTS_BAD;
1101
1102 function = func_for_cmd(cmd);
1103 if (function == PKCS11_FUNCTION_UNKNOWN)
1104 return PKCS11_CKR_ARGUMENTS_BAD;
1105
1106 rc = get_active_session(session, function);
1107 if (rc)
1108 return rc;
1109
1110 release_active_processing(session);
1111
1112 DMSG("PKCS11 session %"PRIu32": release processing", session->handle);
1113
1114 return PKCS11_CKR_OK;
1115 }
1116
entry_wrap_key(struct pkcs11_client * client,uint32_t ptypes,TEE_Param * params)1117 enum pkcs11_rc entry_wrap_key(struct pkcs11_client *client,
1118 uint32_t ptypes, TEE_Param *params)
1119 {
1120 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1121 TEE_PARAM_TYPE_NONE,
1122 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1123 TEE_PARAM_TYPE_NONE);
1124 TEE_Param *ctrl = params;
1125 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
1126 struct serialargs ctrlargs = { };
1127 struct pkcs11_session *session = NULL;
1128 struct pkcs11_attribute_head *proc_params = NULL;
1129 struct pkcs11_object *wrapping_key = NULL;
1130 struct pkcs11_object *key = NULL;
1131 void *req_attrs = NULL;
1132 uint32_t wrapping_key_handle = 0;
1133 uint32_t key_handle = 0;
1134 uint32_t size = 0;
1135 void *key_data = NULL;
1136 uint32_t key_sz = 0;
1137 void *out_buf = params[2].memref.buffer;
1138 uint32_t out_size = params[2].memref.size;
1139 const enum processing_func function = PKCS11_FUNCTION_WRAP;
1140
1141 if (!client || ptypes != exp_pt ||
1142 (out_size && !out_buf))
1143 return PKCS11_CKR_ARGUMENTS_BAD;
1144
1145 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1146
1147 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
1148 if (rc)
1149 return rc;
1150
1151 rc = serialargs_get(&ctrlargs, &wrapping_key_handle, sizeof(uint32_t));
1152 if (rc)
1153 return rc;
1154
1155 rc = serialargs_get(&ctrlargs, &key_handle, sizeof(uint32_t));
1156 if (rc)
1157 return rc;
1158
1159 rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params);
1160 if (rc)
1161 return rc;
1162
1163 if (serialargs_remaining_bytes(&ctrlargs)) {
1164 rc = PKCS11_CKR_ARGUMENTS_BAD;
1165 goto out_free;
1166 }
1167
1168 rc = get_ready_session(session);
1169 if (rc)
1170 goto out_free;
1171
1172 wrapping_key = pkcs11_handle2object(wrapping_key_handle, session);
1173 if (!wrapping_key) {
1174 rc = PKCS11_CKR_WRAPPING_KEY_HANDLE_INVALID;
1175 goto out_free;
1176 }
1177
1178 key = pkcs11_handle2object(key_handle, session);
1179 if (!key) {
1180 rc = PKCS11_CKR_KEY_HANDLE_INVALID;
1181 goto out_free;
1182 }
1183
1184 /*
1185 * The wrapping key and key to be wrapped shouldn't be same.
1186 * PKCS#11 spec doesn't explicitly state that but logically this isn't
1187 * a use case and also acts as an attack vector, so explicitly
1188 * disallow this.
1189 */
1190 if (key == wrapping_key) {
1191 rc = PKCS11_CKR_WRAPPING_KEY_HANDLE_INVALID;
1192 goto out_free;
1193 }
1194
1195 rc = set_processing_state(session, function, wrapping_key, NULL);
1196 if (rc)
1197 goto out_free;
1198
1199 /* Check if mechanism can be used for wrapping function */
1200 rc = check_mechanism_against_processing(session, proc_params->id,
1201 function,
1202 PKCS11_FUNC_STEP_INIT);
1203 if (rc)
1204 goto out;
1205
1206 /*
1207 * Check if wrapping key has CKA_WRAP set and its key type is
1208 * compatible with the mechanism passed
1209 */
1210 rc = check_parent_attrs_against_processing(proc_params->id, function,
1211 wrapping_key->attributes);
1212 if (rc) {
1213 /*
1214 * CKR_KEY_FUNCTION_NOT_PERMITTED is not in the list of errors
1215 * specified with C_Wrap() in the specification. So
1216 * return the next most appropriate error.
1217 */
1218 if (rc == PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED)
1219 rc = PKCS11_CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
1220
1221 goto out;
1222 }
1223
1224 /* Check access of wrapping key */
1225 rc = check_access_attrs_against_token(session,
1226 wrapping_key->attributes);
1227 if (rc)
1228 goto out;
1229
1230 switch (get_class(key->attributes)) {
1231 case PKCS11_CKO_SECRET_KEY:
1232 case PKCS11_CKO_PRIVATE_KEY:
1233 break;
1234 default:
1235 rc = PKCS11_CKR_KEY_NOT_WRAPPABLE;
1236 goto out;
1237 }
1238
1239 /* Check if key to be wrapped is extractable */
1240 if (!get_bool(key->attributes, PKCS11_CKA_EXTRACTABLE)) {
1241 DMSG("Extractable property is false");
1242 rc = PKCS11_CKR_KEY_UNEXTRACTABLE;
1243 goto out;
1244 }
1245
1246 if (get_bool(key->attributes, PKCS11_CKA_WRAP_WITH_TRUSTED) &&
1247 !get_bool(wrapping_key->attributes, PKCS11_CKA_TRUSTED)) {
1248 DMSG("Wrap with trusted not satisfied");
1249 rc = PKCS11_CKR_KEY_NOT_WRAPPABLE;
1250 goto out;
1251 }
1252
1253 rc = check_access_attrs_against_token(session, key->attributes);
1254 if (rc)
1255 goto out;
1256
1257 rc = get_attribute_ptr(wrapping_key->attributes,
1258 PKCS11_CKA_WRAP_TEMPLATE, &req_attrs, &size);
1259 if (rc == PKCS11_CKR_OK && size != 0) {
1260 if (!attributes_match_reference(key->attributes, req_attrs)) {
1261 rc = PKCS11_CKR_KEY_HANDLE_INVALID;
1262 goto out;
1263 }
1264 }
1265
1266 rc = alloc_key_data_to_wrap(key->attributes, &key_data, &key_sz);
1267 if (rc)
1268 goto out;
1269
1270 if (processing_is_tee_symm(proc_params->id)) {
1271 rc = init_symm_operation(session, PKCS11_FUNCTION_ENCRYPT,
1272 proc_params, wrapping_key);
1273 if (rc)
1274 goto out;
1275
1276 rc = wrap_data_by_symm_enc(session, key_data, key_sz, out_buf,
1277 &out_size);
1278 } else {
1279 rc = init_asymm_operation(session, PKCS11_FUNCTION_ENCRYPT,
1280 proc_params, wrapping_key);
1281 if (rc)
1282 goto out;
1283
1284 rc = wrap_data_by_asymm_enc(session, key_data, key_sz, out_buf,
1285 &out_size);
1286 }
1287
1288 if (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)
1289 params[2].memref.size = out_size;
1290
1291 out:
1292 release_active_processing(session);
1293 out_free:
1294 TEE_Free(key_data);
1295 TEE_Free(proc_params);
1296 return rc;
1297 }
1298