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