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