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