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