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 /* 313 * entry_processing_init - Generic entry for initializing a processing 314 * 315 * @client = client reference 316 * @ptype = Invocation parameter types 317 * @params = Invocation parameters reference 318 * @function - encrypt, decrypt, sign, verify, digest, ... 319 */ 320 enum pkcs11_rc entry_processing_init(struct pkcs11_client *client, 321 uint32_t ptypes, TEE_Param *params, 322 enum processing_func function) 323 { 324 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 325 TEE_PARAM_TYPE_NONE, 326 TEE_PARAM_TYPE_NONE, 327 TEE_PARAM_TYPE_NONE); 328 TEE_Param *ctrl = params; 329 enum pkcs11_rc rc = PKCS11_CKR_OK; 330 struct serialargs ctrlargs = { }; 331 struct pkcs11_session *session = NULL; 332 struct pkcs11_attribute_head *proc_params = NULL; 333 uint32_t key_handle = 0; 334 struct pkcs11_object *obj = NULL; 335 336 if (!client || ptypes != exp_pt) 337 return PKCS11_CKR_ARGUMENTS_BAD; 338 339 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 340 341 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 342 if (rc) 343 return rc; 344 345 if (function != PKCS11_FUNCTION_DIGEST) { 346 rc = serialargs_get(&ctrlargs, &key_handle, sizeof(uint32_t)); 347 if (rc) 348 return rc; 349 } 350 351 rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params); 352 if (rc) 353 return rc; 354 355 if (serialargs_remaining_bytes(&ctrlargs)) { 356 rc = PKCS11_CKR_ARGUMENTS_BAD; 357 goto out; 358 } 359 360 rc = get_ready_session(session); 361 if (rc) 362 goto out; 363 364 if (function != PKCS11_FUNCTION_DIGEST) { 365 obj = pkcs11_handle2object(key_handle, session); 366 if (!obj) { 367 rc = PKCS11_CKR_KEY_HANDLE_INVALID; 368 goto out; 369 } 370 } 371 372 rc = set_processing_state(session, function, obj, NULL); 373 if (rc) 374 goto out; 375 376 rc = check_mechanism_against_processing(session, proc_params->id, 377 function, 378 PKCS11_FUNC_STEP_INIT); 379 if (rc) 380 goto out; 381 382 if (obj) { 383 rc = check_parent_attrs_against_processing(proc_params->id, 384 function, 385 obj->attributes); 386 if (rc) 387 goto out; 388 389 rc = check_access_attrs_against_token(session, 390 obj->attributes); 391 if (rc) 392 goto out; 393 } 394 395 if (processing_is_tee_symm(proc_params->id)) 396 rc = init_symm_operation(session, function, proc_params, obj); 397 else if (processing_is_tee_digest(proc_params->id)) 398 rc = init_digest_operation(session, proc_params); 399 else 400 rc = PKCS11_CKR_MECHANISM_INVALID; 401 402 if (rc == PKCS11_CKR_OK) { 403 session->processing->mecha_type = proc_params->id; 404 DMSG("PKCS11 session %"PRIu32": init processing %s %s", 405 session->handle, id2str_proc(proc_params->id), 406 id2str_function(function)); 407 } 408 409 out: 410 if (rc && session) 411 release_active_processing(session); 412 413 TEE_Free(proc_params); 414 415 return rc; 416 } 417 418 /* 419 * entry_processing_step - Generic entry on active processing 420 * 421 * @client = client reference 422 * @ptype = Invocation parameter types 423 * @params = Invocation parameters reference 424 * @function - encrypt, decrypt, sign, verify, digest, ... 425 * @step - update, oneshot, final 426 */ 427 enum pkcs11_rc entry_processing_step(struct pkcs11_client *client, 428 uint32_t ptypes, TEE_Param *params, 429 enum processing_func function, 430 enum processing_step step) 431 { 432 TEE_Param *ctrl = params; 433 enum pkcs11_rc rc = PKCS11_CKR_OK; 434 struct serialargs ctrlargs = { }; 435 struct pkcs11_session *session = NULL; 436 enum pkcs11_mechanism_id mecha_type = PKCS11_CKM_UNDEFINED_ID; 437 uint32_t key_handle = 0; 438 struct pkcs11_object *obj = NULL; 439 440 if (!client || 441 TEE_PARAM_TYPE_GET(ptypes, 0) != TEE_PARAM_TYPE_MEMREF_INOUT) 442 return PKCS11_CKR_ARGUMENTS_BAD; 443 444 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 445 446 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 447 if (rc) 448 return rc; 449 450 if (step == PKCS11_FUNC_STEP_UPDATE_KEY) { 451 assert(function == PKCS11_FUNCTION_DIGEST); 452 453 rc = serialargs_get(&ctrlargs, &key_handle, sizeof(uint32_t)); 454 if (rc) 455 return rc; 456 } 457 458 if (serialargs_remaining_bytes(&ctrlargs)) 459 return PKCS11_CKR_ARGUMENTS_BAD; 460 461 rc = get_active_session(session, function); 462 if (rc) 463 return rc; 464 465 if (step == PKCS11_FUNC_STEP_UPDATE_KEY) { 466 assert(function == PKCS11_FUNCTION_DIGEST); 467 468 obj = pkcs11_handle2object(key_handle, session); 469 if (!obj) { 470 rc = PKCS11_CKR_KEY_HANDLE_INVALID; 471 goto out; 472 } 473 474 rc = check_access_attrs_against_token(session, 475 obj->attributes); 476 if (rc) { 477 rc = PKCS11_CKR_KEY_HANDLE_INVALID; 478 goto out; 479 } 480 } 481 482 mecha_type = session->processing->mecha_type; 483 rc = check_mechanism_against_processing(session, mecha_type, 484 function, step); 485 if (rc) 486 goto out; 487 488 if (processing_is_tee_symm(mecha_type)) 489 rc = step_symm_operation(session, function, step, 490 ptypes, params); 491 else if (processing_is_tee_digest(mecha_type)) 492 rc = step_digest_operation(session, step, obj, ptypes, params); 493 else 494 rc = PKCS11_CKR_MECHANISM_INVALID; 495 496 if (rc == PKCS11_CKR_OK && (step == PKCS11_FUNC_STEP_UPDATE || 497 step == PKCS11_FUNC_STEP_UPDATE_KEY)) { 498 session->processing->updated = true; 499 DMSG("PKCS11 session%"PRIu32": processing %s %s", 500 session->handle, id2str_proc(mecha_type), 501 id2str_function(function)); 502 } 503 504 out: 505 switch (step) { 506 case PKCS11_FUNC_STEP_UPDATE: 507 case PKCS11_FUNC_STEP_UPDATE_KEY: 508 if (rc != PKCS11_CKR_OK && rc != PKCS11_CKR_BUFFER_TOO_SMALL) 509 release_active_processing(session); 510 break; 511 default: 512 /* ONESHOT and FINAL terminates processing on success */ 513 if (rc != PKCS11_CKR_BUFFER_TOO_SMALL) 514 release_active_processing(session); 515 break; 516 } 517 518 return rc; 519 } 520 521 enum pkcs11_rc entry_processing_key(struct pkcs11_client *client, 522 uint32_t ptypes, TEE_Param *params, 523 enum processing_func function) 524 { 525 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 526 TEE_PARAM_TYPE_NONE, 527 TEE_PARAM_TYPE_MEMREF_OUTPUT, 528 TEE_PARAM_TYPE_NONE); 529 TEE_Param *ctrl = params; 530 TEE_Param *out = params + 2; 531 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 532 struct serialargs ctrlargs = { }; 533 struct pkcs11_session *session = NULL; 534 struct pkcs11_attribute_head *proc_params = NULL; 535 struct pkcs11_object_head *template = NULL; 536 uint32_t parent_handle = 0; 537 uint32_t obj_handle = 0; 538 struct pkcs11_object *parent = NULL; 539 struct obj_attrs *head = NULL; 540 size_t template_size = 0; 541 void *out_buf = NULL; 542 uint32_t out_size = 0; 543 544 if (!client || ptypes != exp_pt || 545 out->memref.size != sizeof(obj_handle)) 546 return PKCS11_CKR_ARGUMENTS_BAD; 547 548 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 549 550 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 551 if (rc) 552 return rc; 553 554 rc = serialargs_get(&ctrlargs, &parent_handle, sizeof(uint32_t)); 555 if (rc) 556 return rc; 557 558 rc = serialargs_alloc_get_one_attribute(&ctrlargs, &proc_params); 559 if (rc) 560 goto out_free; 561 562 rc = serialargs_alloc_get_attributes(&ctrlargs, &template); 563 if (rc) 564 goto out_free; 565 566 if (serialargs_remaining_bytes(&ctrlargs)) { 567 rc = PKCS11_CKR_ARGUMENTS_BAD; 568 goto out_free; 569 } 570 571 /* Return error if processing already active */ 572 rc = get_ready_session(session); 573 if (rc) 574 goto out_free; 575 576 /* Check parent handle */ 577 parent = pkcs11_handle2object(parent_handle, session); 578 if (!parent) { 579 rc = PKCS11_CKR_KEY_HANDLE_INVALID; 580 goto out_free; 581 } 582 583 /* Check if mechanism can be used for derivation function */ 584 rc = check_mechanism_against_processing(session, proc_params->id, 585 function, 586 PKCS11_FUNC_STEP_INIT); 587 if (rc) 588 goto out_free; 589 590 /* Set the processing state to active */ 591 rc = set_processing_state(session, function, parent, NULL); 592 if (rc) 593 goto out_free; 594 595 /* 596 * Check if base/parent key has CKA_DERIVE set and its key type is 597 * compatible with the mechanism passed 598 */ 599 rc = check_parent_attrs_against_processing(proc_params->id, function, 600 parent->attributes); 601 if (rc) { 602 /* 603 * CKR_KEY_FUNCTION_NOT_PERMITTED is not in the list of errors 604 * specified with C_Derive/Unwrap() in the specification. So 605 * return the next most appropriate error. 606 */ 607 if (rc == PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED) 608 rc = PKCS11_CKR_KEY_TYPE_INCONSISTENT; 609 goto out; 610 } 611 612 /* Check access of base/parent key */ 613 rc = check_access_attrs_against_token(session, parent->attributes); 614 if (rc) 615 goto out; 616 617 template_size = sizeof(*template) + template->attrs_size; 618 /* 619 * Prepare a clean initial state for the requested object attributes 620 * using base/parent key attributes. Free temporary template once done. 621 */ 622 rc = create_attributes_from_template(&head, template, template_size, 623 parent->attributes, 624 function, 625 proc_params->id, 626 PKCS11_CKO_UNDEFINED_ID); 627 if (rc) 628 goto out; 629 630 TEE_Free(template); 631 template = NULL; 632 633 /* check_created_attrs() is called later once key size is known */ 634 635 rc = check_created_attrs_against_processing(proc_params->id, head); 636 if (rc) 637 goto out; 638 639 rc = check_created_attrs_against_token(session, head); 640 if (rc) 641 goto out; 642 643 if (processing_is_tee_symm(proc_params->id)) { 644 /* 645 * These derivation mechanism require encryption to be 646 * performed on the data passed in proc_params by parent 647 * key. Hence pass function as PKCS11_FUNCTION_ENCRYPT 648 * to init_symm_operation() 649 */ 650 rc = init_symm_operation(session, PKCS11_FUNCTION_ENCRYPT, 651 proc_params, parent); 652 if (rc) 653 goto out; 654 655 session->processing->mecha_type = proc_params->id; 656 657 rc = derive_key_by_symm_enc(session, &out_buf, &out_size); 658 if (rc) 659 goto out; 660 } else { 661 rc = PKCS11_CKR_MECHANISM_INVALID; 662 goto out; 663 } 664 665 rc = set_key_data(&head, out_buf, out_size); 666 if (rc) 667 goto out; 668 669 TEE_Free(out_buf); 670 out_buf = NULL; 671 672 TEE_Free(proc_params); 673 proc_params = NULL; 674 675 /* 676 * Object is ready, register it and return a handle. 677 */ 678 rc = create_object(session, head, &obj_handle); 679 if (rc) 680 goto out; 681 682 /* 683 * Now obj_handle (through the related struct pkcs11_object instance) 684 * owns the serialized buffer that holds the object attributes. 685 * We reset head to NULL as it is no more the buffer owner and would 686 * be freed at function out. 687 */ 688 head = NULL; 689 690 TEE_MemMove(out->memref.buffer, &obj_handle, sizeof(obj_handle)); 691 out->memref.size = sizeof(obj_handle); 692 693 DMSG("PKCS11 session %"PRIu32": derive secret %#"PRIx32, 694 session->handle, obj_handle); 695 696 out: 697 release_active_processing(session); 698 out_free: 699 TEE_Free(proc_params); 700 TEE_Free(template); 701 TEE_Free(head); 702 TEE_Free(out_buf); 703 704 return rc; 705 } 706 707 enum pkcs11_rc entry_release_active_processing(struct pkcs11_client *client, 708 uint32_t ptypes, 709 TEE_Param *params) 710 { 711 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 712 TEE_PARAM_TYPE_NONE, 713 TEE_PARAM_TYPE_NONE, 714 TEE_PARAM_TYPE_NONE); 715 TEE_Param *ctrl = params; 716 enum pkcs11_rc rc = PKCS11_CKR_OK; 717 struct serialargs ctrlargs = { }; 718 struct pkcs11_session *session = NULL; 719 enum processing_func function = PKCS11_FUNCTION_UNKNOWN; 720 uint32_t cmd = 0; 721 722 if (!client || ptypes != exp_pt) 723 return PKCS11_CKR_ARGUMENTS_BAD; 724 725 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 726 727 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 728 if (rc) 729 return rc; 730 731 rc = serialargs_get_u32(&ctrlargs, &cmd); 732 733 if (serialargs_remaining_bytes(&ctrlargs)) 734 return PKCS11_CKR_ARGUMENTS_BAD; 735 736 function = func_for_cmd(cmd); 737 if (function == PKCS11_FUNCTION_UNKNOWN) 738 return PKCS11_CKR_ARGUMENTS_BAD; 739 740 rc = get_active_session(session, function); 741 if (rc) 742 return rc; 743 744 release_active_processing(session); 745 746 DMSG("PKCS11 session %"PRIu32": release processing", session->handle); 747 748 return PKCS11_CKR_OK; 749 } 750