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