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