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