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_op_handle != TEE_HANDLE_NULL) { 108 TEE_FreeOperation(session->processing->tee_op_handle); 109 session->processing->tee_op_handle = TEE_HANDLE_NULL; 110 } 111 112 TEE_Free(session->processing->extra_ctx); 113 114 TEE_Free(session->processing); 115 session->processing = NULL; 116 } 117 118 size_t get_object_key_bit_size(struct pkcs11_object *obj) 119 { 120 uint32_t a_size = 0; 121 struct obj_attrs *attrs = obj->attributes; 122 123 switch (get_key_type(attrs)) { 124 case PKCS11_CKK_AES: 125 case PKCS11_CKK_GENERIC_SECRET: 126 case PKCS11_CKK_MD5_HMAC: 127 case PKCS11_CKK_SHA_1_HMAC: 128 case PKCS11_CKK_SHA224_HMAC: 129 case PKCS11_CKK_SHA256_HMAC: 130 case PKCS11_CKK_SHA384_HMAC: 131 case PKCS11_CKK_SHA512_HMAC: 132 if (get_attribute_ptr(attrs, PKCS11_CKA_VALUE, NULL, &a_size)) 133 return 0; 134 135 return a_size * 8; 136 default: 137 TEE_Panic(0); 138 return 0; 139 } 140 } 141 142 static enum pkcs11_rc generate_random_key_value(struct obj_attrs **head) 143 { 144 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 145 void *data = NULL; 146 uint32_t data_size = 0; 147 uint32_t value_len = 0; 148 void *value = NULL; 149 150 if (!*head) 151 return PKCS11_CKR_TEMPLATE_INCONSISTENT; 152 153 rc = get_attribute_ptr(*head, PKCS11_CKA_VALUE_LEN, &data, &data_size); 154 if (rc || data_size != sizeof(uint32_t)) { 155 DMSG("%s", rc ? "No attribute value_len found" : 156 "Invalid size for attribute VALUE_LEN"); 157 158 return PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; 159 } 160 TEE_MemMove(&value_len, data, data_size); 161 162 /* Remove the default empty value attribute if found */ 163 rc = remove_empty_attribute(head, PKCS11_CKA_VALUE); 164 if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 165 return PKCS11_CKR_GENERAL_ERROR; 166 167 value = TEE_Malloc(value_len, TEE_USER_MEM_HINT_NO_FILL_ZERO); 168 if (!value) 169 return PKCS11_CKR_DEVICE_MEMORY; 170 171 TEE_GenerateRandom(value, value_len); 172 173 rc = add_attribute(head, PKCS11_CKA_VALUE, value, value_len); 174 175 TEE_Free(value); 176 177 return rc; 178 } 179 180 enum pkcs11_rc entry_generate_secret(struct pkcs11_client *client, 181 uint32_t ptypes, TEE_Param *params) 182 { 183 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 184 TEE_PARAM_TYPE_NONE, 185 TEE_PARAM_TYPE_MEMREF_OUTPUT, 186 TEE_PARAM_TYPE_NONE); 187 TEE_Param *ctrl = params; 188 TEE_Param *out = params + 2; 189 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 190 struct serialargs ctrlargs = { }; 191 struct pkcs11_session *session = NULL; 192 struct pkcs11_attribute_head *proc_params = NULL; 193 struct obj_attrs *head = NULL; 194 struct pkcs11_object_head *template = NULL; 195 size_t template_size = 0; 196 uint32_t obj_handle = 0; 197 198 if (!client || ptypes != exp_pt || 199 out->memref.size != sizeof(obj_handle)) 200 return PKCS11_CKR_ARGUMENTS_BAD; 201 202 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 203 204 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 205 if (rc) 206 return rc; 207 208 rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params); 209 if (rc) 210 goto out; 211 212 rc = serialargs_alloc_get_attributes(&ctrlargs, &template); 213 if (rc) 214 goto out; 215 216 if (serialargs_remaining_bytes(&ctrlargs)) { 217 rc = PKCS11_CKR_ARGUMENTS_BAD; 218 goto out; 219 } 220 221 rc = get_ready_session(session); 222 if (rc) 223 goto out; 224 225 template_size = sizeof(*template) + template->attrs_size; 226 227 rc = check_mechanism_against_processing(session, proc_params->id, 228 PKCS11_FUNCTION_GENERATE, 229 PKCS11_FUNC_STEP_INIT); 230 if (rc) { 231 DMSG("Invalid mechanism %#"PRIx32": %#x", proc_params->id, rc); 232 goto out; 233 } 234 235 /* 236 * Prepare a clean initial state for the requested object attributes. 237 * Free temporary template once done. 238 */ 239 rc = create_attributes_from_template(&head, template, template_size, 240 NULL, PKCS11_FUNCTION_GENERATE, 241 proc_params->id, 242 PKCS11_CKO_UNDEFINED_ID); 243 if (rc) 244 goto out; 245 246 TEE_Free(template); 247 template = NULL; 248 249 rc = check_created_attrs(head, NULL); 250 if (rc) 251 goto out; 252 253 rc = check_created_attrs_against_processing(proc_params->id, head); 254 if (rc) 255 goto out; 256 257 rc = check_created_attrs_against_token(session, head); 258 if (rc) 259 goto out; 260 261 /* 262 * Execute target processing and add value as attribute 263 * PKCS11_CKA_VALUE. Symm key generation: depends on target 264 * processing to be used. 265 */ 266 switch (proc_params->id) { 267 case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: 268 case PKCS11_CKM_AES_KEY_GEN: 269 /* Generate random of size specified by attribute VALUE_LEN */ 270 rc = generate_random_key_value(&head); 271 if (rc) 272 goto out; 273 break; 274 275 default: 276 rc = PKCS11_CKR_MECHANISM_INVALID; 277 goto out; 278 } 279 280 TEE_Free(proc_params); 281 proc_params = NULL; 282 283 /* 284 * Object is ready, register it and return a handle. 285 */ 286 rc = create_object(session, head, &obj_handle); 287 if (rc) 288 goto out; 289 290 /* 291 * Now obj_handle (through the related struct pkcs11_object instance) 292 * owns the serialized buffer that holds the object attributes. 293 * We reset head to NULL as it is no more the buffer owner and would 294 * be freed at function out. 295 */ 296 head = NULL; 297 298 TEE_MemMove(out->memref.buffer, &obj_handle, sizeof(obj_handle)); 299 out->memref.size = sizeof(obj_handle); 300 301 DMSG("PKCS11 session %"PRIu32": generate secret %#"PRIx32, 302 session->handle, obj_handle); 303 304 out: 305 TEE_Free(proc_params); 306 TEE_Free(template); 307 TEE_Free(head); 308 309 return rc; 310 } 311 312 enum pkcs11_rc alloc_get_tee_attribute_data(TEE_ObjectHandle tee_obj, 313 uint32_t attribute, 314 void **data, size_t *size) 315 { 316 TEE_Result res = TEE_ERROR_GENERIC; 317 void *ptr = NULL; 318 uint32_t sz = 0; 319 320 res = TEE_GetObjectBufferAttribute(tee_obj, attribute, NULL, &sz); 321 if (res != TEE_ERROR_SHORT_BUFFER) 322 return PKCS11_CKR_FUNCTION_FAILED; 323 324 ptr = TEE_Malloc(sz, TEE_USER_MEM_HINT_NO_FILL_ZERO); 325 if (!ptr) 326 return PKCS11_CKR_DEVICE_MEMORY; 327 328 res = TEE_GetObjectBufferAttribute(tee_obj, attribute, ptr, &sz); 329 if (res) { 330 TEE_Free(ptr); 331 } else { 332 *data = ptr; 333 *size = sz; 334 } 335 336 return tee2pkcs_error(res); 337 } 338 339 enum pkcs11_rc tee2pkcs_add_attribute(struct obj_attrs **head, 340 uint32_t pkcs11_id, 341 TEE_ObjectHandle tee_obj, 342 uint32_t tee_id) 343 { 344 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 345 void *a_ptr = NULL; 346 size_t a_size = 0; 347 348 rc = alloc_get_tee_attribute_data(tee_obj, tee_id, &a_ptr, &a_size); 349 if (rc) 350 goto out; 351 352 rc = add_attribute(head, pkcs11_id, a_ptr, a_size); 353 354 TEE_Free(a_ptr); 355 356 out: 357 if (rc) 358 EMSG("Failed TEE attribute %#"PRIx32" for %#"PRIx32"/%s", 359 tee_id, pkcs11_id, id2str_attr(pkcs11_id)); 360 return rc; 361 } 362 363 enum pkcs11_rc entry_generate_key_pair(struct pkcs11_client *client, 364 uint32_t ptypes, TEE_Param *params) 365 { 366 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 367 TEE_PARAM_TYPE_NONE, 368 TEE_PARAM_TYPE_MEMREF_OUTPUT, 369 TEE_PARAM_TYPE_NONE); 370 TEE_Param *ctrl = params; 371 TEE_Param *out = params + 2; 372 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 373 struct serialargs ctrlargs = { }; 374 struct pkcs11_session *session = NULL; 375 struct pkcs11_attribute_head *proc_params = NULL; 376 struct obj_attrs *pub_head = NULL; 377 struct obj_attrs *priv_head = NULL; 378 struct pkcs11_object_head *pub_template = NULL; 379 struct pkcs11_object_head *priv_template = NULL; 380 struct pkcs11_object *object = NULL; 381 size_t pub_template_size = 0; 382 size_t priv_template_size = 0; 383 uint32_t pubkey_handle = 0; 384 uint32_t privkey_handle = 0; 385 uint32_t *hdl_ptr = NULL; 386 size_t out_ref_size = sizeof(pubkey_handle) + sizeof(privkey_handle); 387 388 if (!client || ptypes != exp_pt || out->memref.size != out_ref_size) 389 return PKCS11_CKR_ARGUMENTS_BAD; 390 391 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 392 393 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 394 if (rc) 395 return rc; 396 397 rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params); 398 if (rc) 399 goto out; 400 401 rc = serialargs_alloc_get_attributes(&ctrlargs, &pub_template); 402 if (rc) 403 goto out; 404 405 rc = serialargs_alloc_get_attributes(&ctrlargs, &priv_template); 406 if (rc) 407 goto out; 408 409 if (serialargs_remaining_bytes(&ctrlargs)) { 410 rc = PKCS11_CKR_ARGUMENTS_BAD; 411 goto out; 412 } 413 414 rc = get_ready_session(session); 415 if (rc) 416 goto out; 417 418 rc = check_mechanism_against_processing(session, proc_params->id, 419 PKCS11_FUNCTION_GENERATE_PAIR, 420 PKCS11_FUNC_STEP_INIT); 421 if (rc) 422 goto out; 423 424 pub_template_size = sizeof(*pub_template) + pub_template->attrs_size; 425 426 rc = create_attributes_from_template(&pub_head, pub_template, 427 pub_template_size, NULL, 428 PKCS11_FUNCTION_GENERATE_PAIR, 429 proc_params->id, 430 PKCS11_CKO_PUBLIC_KEY); 431 if (rc) 432 goto out; 433 434 TEE_Free(pub_template); 435 pub_template = NULL; 436 437 priv_template_size = sizeof(*priv_template) + 438 priv_template->attrs_size; 439 440 rc = create_attributes_from_template(&priv_head, priv_template, 441 priv_template_size, NULL, 442 PKCS11_FUNCTION_GENERATE_PAIR, 443 proc_params->id, 444 PKCS11_CKO_PRIVATE_KEY); 445 if (rc) 446 goto out; 447 448 TEE_Free(priv_template); 449 priv_template = NULL; 450 451 /* Generate CKA_ID for keys if not specified by the templates */ 452 rc = add_missing_attribute_id(&pub_head, &priv_head); 453 if (rc) 454 goto out; 455 456 /* Check created object against processing and token state */ 457 rc = check_created_attrs(pub_head, priv_head); 458 if (rc) 459 goto out; 460 461 rc = check_created_attrs_against_processing(proc_params->id, pub_head); 462 if (rc) 463 goto out; 464 465 rc = check_created_attrs_against_processing(proc_params->id, 466 priv_head); 467 if (rc) 468 goto out; 469 470 rc = check_created_attrs_against_token(session, pub_head); 471 if (rc) 472 goto out; 473 474 rc = check_access_attrs_against_token(session, pub_head); 475 if (rc) 476 goto out; 477 478 rc = check_created_attrs_against_token(session, priv_head); 479 if (rc) 480 goto out; 481 482 rc = check_access_attrs_against_token(session, priv_head); 483 if (rc) 484 goto out; 485 486 /* Generate key pair */ 487 switch (proc_params->id) { 488 case PKCS11_CKM_EC_KEY_PAIR_GEN: 489 rc = generate_ec_keys(proc_params, &pub_head, &priv_head); 490 break; 491 default: 492 rc = PKCS11_CKR_MECHANISM_INVALID; 493 break; 494 } 495 if (rc) 496 goto out; 497 498 TEE_Free(proc_params); 499 proc_params = NULL; 500 501 /* 502 * Object is ready, register it and return a handle. 503 */ 504 rc = create_object(session, pub_head, &pubkey_handle); 505 if (rc) 506 goto out; 507 508 /* 509 * Now obj_handle (through the related struct pkcs11_object instance) 510 * owns the serialized buffer that holds the object attributes. 511 * We reset local pub_head to NULL to mark that ownership has been 512 * transferred. 513 */ 514 pub_head = NULL; 515 516 rc = create_object(session, priv_head, &privkey_handle); 517 if (rc) 518 goto out; 519 520 /* Ownership has been transferred so mark it with NULL */ 521 priv_head = NULL; 522 523 hdl_ptr = (uint32_t *)out->memref.buffer; 524 525 TEE_MemMove(hdl_ptr, &pubkey_handle, sizeof(pubkey_handle)); 526 TEE_MemMove(hdl_ptr + 1, &privkey_handle, sizeof(privkey_handle)); 527 528 pubkey_handle = 0; 529 privkey_handle = 0; 530 531 DMSG("PKCS11 session %"PRIu32": create key pair %#"PRIx32"/%#"PRIx32, 532 session->handle, privkey_handle, pubkey_handle); 533 534 out: 535 if (pubkey_handle) { 536 object = pkcs11_handle2object(pubkey_handle, session); 537 if (!object) 538 TEE_Panic(0); 539 destroy_object(session, object, false); 540 } 541 TEE_Free(priv_head); 542 TEE_Free(pub_head); 543 TEE_Free(priv_template); 544 TEE_Free(pub_template); 545 TEE_Free(proc_params); 546 547 return rc; 548 } 549 550 /* 551 * entry_processing_init - Generic entry for initializing a processing 552 * 553 * @client = client reference 554 * @ptype = Invocation parameter types 555 * @params = Invocation parameters reference 556 * @function - encrypt, decrypt, sign, verify, digest, ... 557 */ 558 enum pkcs11_rc entry_processing_init(struct pkcs11_client *client, 559 uint32_t ptypes, TEE_Param *params, 560 enum processing_func function) 561 { 562 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 563 TEE_PARAM_TYPE_NONE, 564 TEE_PARAM_TYPE_NONE, 565 TEE_PARAM_TYPE_NONE); 566 TEE_Param *ctrl = params; 567 enum pkcs11_rc rc = PKCS11_CKR_OK; 568 struct serialargs ctrlargs = { }; 569 struct pkcs11_session *session = NULL; 570 struct pkcs11_attribute_head *proc_params = NULL; 571 uint32_t key_handle = 0; 572 struct pkcs11_object *obj = NULL; 573 574 if (!client || ptypes != exp_pt) 575 return PKCS11_CKR_ARGUMENTS_BAD; 576 577 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 578 579 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 580 if (rc) 581 return rc; 582 583 if (function != PKCS11_FUNCTION_DIGEST) { 584 rc = serialargs_get(&ctrlargs, &key_handle, sizeof(uint32_t)); 585 if (rc) 586 return rc; 587 } 588 589 rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params); 590 if (rc) 591 return rc; 592 593 if (serialargs_remaining_bytes(&ctrlargs)) { 594 rc = PKCS11_CKR_ARGUMENTS_BAD; 595 goto out; 596 } 597 598 rc = get_ready_session(session); 599 if (rc) 600 goto out; 601 602 if (function != PKCS11_FUNCTION_DIGEST) { 603 obj = pkcs11_handle2object(key_handle, session); 604 if (!obj) { 605 rc = PKCS11_CKR_KEY_HANDLE_INVALID; 606 goto out; 607 } 608 } 609 610 rc = set_processing_state(session, function, obj, NULL); 611 if (rc) 612 goto out; 613 614 rc = check_mechanism_against_processing(session, proc_params->id, 615 function, 616 PKCS11_FUNC_STEP_INIT); 617 if (rc) 618 goto out; 619 620 if (obj) { 621 rc = check_parent_attrs_against_processing(proc_params->id, 622 function, 623 obj->attributes); 624 if (rc) 625 goto out; 626 627 rc = check_access_attrs_against_token(session, 628 obj->attributes); 629 if (rc) 630 goto out; 631 } 632 633 if (processing_is_tee_symm(proc_params->id)) 634 rc = init_symm_operation(session, function, proc_params, obj); 635 else if (processing_is_tee_digest(proc_params->id)) 636 rc = init_digest_operation(session, proc_params); 637 else 638 rc = PKCS11_CKR_MECHANISM_INVALID; 639 640 if (rc == PKCS11_CKR_OK) { 641 session->processing->mecha_type = proc_params->id; 642 DMSG("PKCS11 session %"PRIu32": init processing %s %s", 643 session->handle, id2str_proc(proc_params->id), 644 id2str_function(function)); 645 } 646 647 out: 648 if (rc && session) 649 release_active_processing(session); 650 651 TEE_Free(proc_params); 652 653 return rc; 654 } 655 656 /* 657 * entry_processing_step - Generic entry on active processing 658 * 659 * @client = client reference 660 * @ptype = Invocation parameter types 661 * @params = Invocation parameters reference 662 * @function - encrypt, decrypt, sign, verify, digest, ... 663 * @step - update, oneshot, final 664 */ 665 enum pkcs11_rc entry_processing_step(struct pkcs11_client *client, 666 uint32_t ptypes, TEE_Param *params, 667 enum processing_func function, 668 enum processing_step step) 669 { 670 TEE_Param *ctrl = params; 671 enum pkcs11_rc rc = PKCS11_CKR_OK; 672 struct serialargs ctrlargs = { }; 673 struct pkcs11_session *session = NULL; 674 enum pkcs11_mechanism_id mecha_type = PKCS11_CKM_UNDEFINED_ID; 675 uint32_t key_handle = 0; 676 struct pkcs11_object *obj = NULL; 677 678 if (!client || 679 TEE_PARAM_TYPE_GET(ptypes, 0) != TEE_PARAM_TYPE_MEMREF_INOUT) 680 return PKCS11_CKR_ARGUMENTS_BAD; 681 682 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 683 684 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 685 if (rc) 686 return rc; 687 688 if (step == PKCS11_FUNC_STEP_UPDATE_KEY) { 689 assert(function == PKCS11_FUNCTION_DIGEST); 690 691 rc = serialargs_get(&ctrlargs, &key_handle, sizeof(uint32_t)); 692 if (rc) 693 return rc; 694 } 695 696 if (serialargs_remaining_bytes(&ctrlargs)) 697 return PKCS11_CKR_ARGUMENTS_BAD; 698 699 rc = get_active_session(session, function); 700 if (rc) 701 return rc; 702 703 if (step == PKCS11_FUNC_STEP_UPDATE_KEY) { 704 assert(function == PKCS11_FUNCTION_DIGEST); 705 706 obj = pkcs11_handle2object(key_handle, session); 707 if (!obj) { 708 rc = PKCS11_CKR_KEY_HANDLE_INVALID; 709 goto out; 710 } 711 712 rc = check_access_attrs_against_token(session, 713 obj->attributes); 714 if (rc) { 715 rc = PKCS11_CKR_KEY_HANDLE_INVALID; 716 goto out; 717 } 718 } 719 720 mecha_type = session->processing->mecha_type; 721 rc = check_mechanism_against_processing(session, mecha_type, 722 function, step); 723 if (rc) 724 goto out; 725 726 if (processing_is_tee_symm(mecha_type)) 727 rc = step_symm_operation(session, function, step, 728 ptypes, params); 729 else if (processing_is_tee_digest(mecha_type)) 730 rc = step_digest_operation(session, step, obj, ptypes, params); 731 else 732 rc = PKCS11_CKR_MECHANISM_INVALID; 733 734 if (rc == PKCS11_CKR_OK && (step == PKCS11_FUNC_STEP_UPDATE || 735 step == PKCS11_FUNC_STEP_UPDATE_KEY)) { 736 session->processing->updated = true; 737 DMSG("PKCS11 session%"PRIu32": processing %s %s", 738 session->handle, id2str_proc(mecha_type), 739 id2str_function(function)); 740 } 741 742 out: 743 switch (step) { 744 case PKCS11_FUNC_STEP_UPDATE: 745 case PKCS11_FUNC_STEP_UPDATE_KEY: 746 if (rc != PKCS11_CKR_OK && rc != PKCS11_CKR_BUFFER_TOO_SMALL) 747 release_active_processing(session); 748 break; 749 default: 750 /* ONESHOT and FINAL terminates processing on success */ 751 if (rc != PKCS11_CKR_BUFFER_TOO_SMALL) 752 release_active_processing(session); 753 break; 754 } 755 756 return rc; 757 } 758 759 enum pkcs11_rc entry_processing_key(struct pkcs11_client *client, 760 uint32_t ptypes, TEE_Param *params, 761 enum processing_func function) 762 { 763 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 764 TEE_PARAM_TYPE_NONE, 765 TEE_PARAM_TYPE_MEMREF_OUTPUT, 766 TEE_PARAM_TYPE_NONE); 767 TEE_Param *ctrl = params; 768 TEE_Param *out = params + 2; 769 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 770 struct serialargs ctrlargs = { }; 771 struct pkcs11_session *session = NULL; 772 struct pkcs11_attribute_head *proc_params = NULL; 773 struct pkcs11_object_head *template = NULL; 774 uint32_t parent_handle = 0; 775 uint32_t obj_handle = 0; 776 struct pkcs11_object *parent = NULL; 777 struct obj_attrs *head = NULL; 778 size_t template_size = 0; 779 void *out_buf = NULL; 780 uint32_t out_size = 0; 781 782 if (!client || ptypes != exp_pt || 783 out->memref.size != sizeof(obj_handle)) 784 return PKCS11_CKR_ARGUMENTS_BAD; 785 786 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 787 788 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 789 if (rc) 790 return rc; 791 792 rc = serialargs_get(&ctrlargs, &parent_handle, sizeof(uint32_t)); 793 if (rc) 794 return rc; 795 796 rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params); 797 if (rc) 798 goto out_free; 799 800 rc = serialargs_alloc_get_attributes(&ctrlargs, &template); 801 if (rc) 802 goto out_free; 803 804 if (serialargs_remaining_bytes(&ctrlargs)) { 805 rc = PKCS11_CKR_ARGUMENTS_BAD; 806 goto out_free; 807 } 808 809 /* Return error if processing already active */ 810 rc = get_ready_session(session); 811 if (rc) 812 goto out_free; 813 814 /* Check parent handle */ 815 parent = pkcs11_handle2object(parent_handle, session); 816 if (!parent) { 817 rc = PKCS11_CKR_KEY_HANDLE_INVALID; 818 goto out_free; 819 } 820 821 /* Check if mechanism can be used for derivation function */ 822 rc = check_mechanism_against_processing(session, proc_params->id, 823 function, 824 PKCS11_FUNC_STEP_INIT); 825 if (rc) 826 goto out_free; 827 828 /* Set the processing state to active */ 829 rc = set_processing_state(session, function, parent, NULL); 830 if (rc) 831 goto out_free; 832 833 /* 834 * Check if base/parent key has CKA_DERIVE set and its key type is 835 * compatible with the mechanism passed 836 */ 837 rc = check_parent_attrs_against_processing(proc_params->id, function, 838 parent->attributes); 839 if (rc) { 840 /* 841 * CKR_KEY_FUNCTION_NOT_PERMITTED is not in the list of errors 842 * specified with C_Derive/Unwrap() in the specification. So 843 * return the next most appropriate error. 844 */ 845 if (rc == PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED) 846 rc = PKCS11_CKR_KEY_TYPE_INCONSISTENT; 847 goto out; 848 } 849 850 /* Check access of base/parent key */ 851 rc = check_access_attrs_against_token(session, parent->attributes); 852 if (rc) 853 goto out; 854 855 template_size = sizeof(*template) + template->attrs_size; 856 /* 857 * Prepare a clean initial state for the requested object attributes 858 * using base/parent key attributes. Free temporary template once done. 859 */ 860 rc = create_attributes_from_template(&head, template, template_size, 861 parent->attributes, 862 function, 863 proc_params->id, 864 PKCS11_CKO_UNDEFINED_ID); 865 if (rc) 866 goto out; 867 868 TEE_Free(template); 869 template = NULL; 870 871 /* check_created_attrs() is called later once key size is known */ 872 873 rc = check_created_attrs_against_processing(proc_params->id, head); 874 if (rc) 875 goto out; 876 877 rc = check_created_attrs_against_token(session, head); 878 if (rc) 879 goto out; 880 881 if (processing_is_tee_symm(proc_params->id)) { 882 /* 883 * These derivation mechanism require encryption to be 884 * performed on the data passed in proc_params by parent 885 * key. Hence pass function as PKCS11_FUNCTION_ENCRYPT 886 * to init_symm_operation() 887 */ 888 rc = init_symm_operation(session, PKCS11_FUNCTION_ENCRYPT, 889 proc_params, parent); 890 if (rc) 891 goto out; 892 893 session->processing->mecha_type = proc_params->id; 894 895 rc = derive_key_by_symm_enc(session, &out_buf, &out_size); 896 if (rc) 897 goto out; 898 } else { 899 rc = PKCS11_CKR_MECHANISM_INVALID; 900 goto out; 901 } 902 903 rc = set_key_data(&head, out_buf, out_size); 904 if (rc) 905 goto out; 906 907 TEE_Free(out_buf); 908 out_buf = NULL; 909 910 TEE_Free(proc_params); 911 proc_params = NULL; 912 913 /* 914 * Object is ready, register it and return a handle. 915 */ 916 rc = create_object(session, head, &obj_handle); 917 if (rc) 918 goto out; 919 920 /* 921 * Now obj_handle (through the related struct pkcs11_object instance) 922 * owns the serialized buffer that holds the object attributes. 923 * We reset head to NULL as it is no more the buffer owner and would 924 * be freed at function out. 925 */ 926 head = NULL; 927 928 TEE_MemMove(out->memref.buffer, &obj_handle, sizeof(obj_handle)); 929 out->memref.size = sizeof(obj_handle); 930 931 DMSG("PKCS11 session %"PRIu32": derive secret %#"PRIx32, 932 session->handle, obj_handle); 933 934 out: 935 release_active_processing(session); 936 out_free: 937 TEE_Free(proc_params); 938 TEE_Free(template); 939 TEE_Free(head); 940 TEE_Free(out_buf); 941 942 return rc; 943 } 944 945 enum pkcs11_rc entry_release_active_processing(struct pkcs11_client *client, 946 uint32_t ptypes, 947 TEE_Param *params) 948 { 949 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 950 TEE_PARAM_TYPE_NONE, 951 TEE_PARAM_TYPE_NONE, 952 TEE_PARAM_TYPE_NONE); 953 TEE_Param *ctrl = params; 954 enum pkcs11_rc rc = PKCS11_CKR_OK; 955 struct serialargs ctrlargs = { }; 956 struct pkcs11_session *session = NULL; 957 enum processing_func function = PKCS11_FUNCTION_UNKNOWN; 958 uint32_t cmd = 0; 959 960 if (!client || ptypes != exp_pt) 961 return PKCS11_CKR_ARGUMENTS_BAD; 962 963 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 964 965 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 966 if (rc) 967 return rc; 968 969 rc = serialargs_get_u32(&ctrlargs, &cmd); 970 971 if (serialargs_remaining_bytes(&ctrlargs)) 972 return PKCS11_CKR_ARGUMENTS_BAD; 973 974 function = func_for_cmd(cmd); 975 if (function == PKCS11_FUNCTION_UNKNOWN) 976 return PKCS11_CKR_ARGUMENTS_BAD; 977 978 rc = get_active_session(session, function); 979 if (rc) 980 return rc; 981 982 release_active_processing(session); 983 984 DMSG("PKCS11 session %"PRIu32": release processing", session->handle); 985 986 return PKCS11_CKR_OK; 987 } 988