1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2017-2020, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <config.h> 8 #include <confine_array_index.h> 9 #include <pkcs11_ta.h> 10 #include <printk.h> 11 #include <pta_system.h> 12 #include <string.h> 13 #include <string_ext.h> 14 #include <sys/queue.h> 15 #include <tee_api_types.h> 16 #include <tee_internal_api_extensions.h> 17 #include <util.h> 18 19 #include "attributes.h" 20 #include "handle.h" 21 #include "pkcs11_helpers.h" 22 #include "pkcs11_token.h" 23 #include "processing.h" 24 #include "serializer.h" 25 #include "token_capabilities.h" 26 27 /* Provide 3 slots/tokens, ID is token index */ 28 #ifndef CFG_PKCS11_TA_TOKEN_COUNT 29 #define TOKEN_COUNT 3 30 #else 31 #define TOKEN_COUNT CFG_PKCS11_TA_TOKEN_COUNT 32 #endif 33 34 /* RNG chunk size used to split RNG generation to smaller sizes */ 35 #define RNG_CHUNK_SIZE 512U 36 37 /* 38 * Structure tracking client applications 39 * 40 * @link - chained list of registered client applications 41 * @sessions - list of the PKCS11 sessions opened by the client application 42 * @object_handle_db - Database for object handles in name space of client 43 */ 44 struct pkcs11_client { 45 TAILQ_ENTRY(pkcs11_client) link; 46 struct session_list session_list; 47 struct handle_db session_handle_db; 48 struct handle_db object_handle_db; 49 }; 50 51 /* Static allocation of tokens runtime instances (reset to 0 at load) */ 52 struct ck_token ck_token[TOKEN_COUNT]; 53 54 static struct client_list pkcs11_client_list = 55 TAILQ_HEAD_INITIALIZER(pkcs11_client_list); 56 57 static void close_ck_session(struct pkcs11_session *session); 58 59 struct ck_token *get_token(unsigned int token_id) 60 { 61 if (token_id < TOKEN_COUNT) 62 return &ck_token[confine_array_index(token_id, TOKEN_COUNT)]; 63 64 return NULL; 65 } 66 67 unsigned int get_token_id(struct ck_token *token) 68 { 69 ptrdiff_t id = token - ck_token; 70 71 assert(id >= 0 && id < TOKEN_COUNT); 72 return id; 73 } 74 75 struct handle_db *get_object_handle_db(struct pkcs11_session *session) 76 { 77 return &session->client->object_handle_db; 78 } 79 80 struct session_list *get_session_list(struct pkcs11_session *session) 81 { 82 return &session->client->session_list; 83 } 84 85 struct pkcs11_client *tee_session2client(void *tee_session) 86 { 87 struct pkcs11_client *client = NULL; 88 89 TAILQ_FOREACH(client, &pkcs11_client_list, link) 90 if (client == tee_session) 91 break; 92 93 return client; 94 } 95 96 struct pkcs11_session *pkcs11_handle2session(uint32_t handle, 97 struct pkcs11_client *client) 98 { 99 return handle_lookup(&client->session_handle_db, handle); 100 } 101 102 struct pkcs11_client *register_client(void) 103 { 104 struct pkcs11_client *client = NULL; 105 106 client = TEE_Malloc(sizeof(*client), TEE_MALLOC_FILL_ZERO); 107 if (!client) 108 return NULL; 109 110 TAILQ_INSERT_HEAD(&pkcs11_client_list, client, link); 111 TAILQ_INIT(&client->session_list); 112 handle_db_init(&client->session_handle_db); 113 handle_db_init(&client->object_handle_db); 114 115 return client; 116 } 117 118 void unregister_client(struct pkcs11_client *client) 119 { 120 struct pkcs11_session *session = NULL; 121 struct pkcs11_session *next = NULL; 122 123 if (!client) { 124 EMSG("Invalid TEE session handle"); 125 return; 126 } 127 128 TAILQ_FOREACH_SAFE(session, &client->session_list, link, next) 129 close_ck_session(session); 130 131 TAILQ_REMOVE(&pkcs11_client_list, client, link); 132 handle_db_destroy(&client->object_handle_db); 133 handle_db_destroy(&client->session_handle_db); 134 TEE_Free(client); 135 } 136 137 static TEE_Result pkcs11_token_init(unsigned int id) 138 { 139 struct ck_token *token = init_persistent_db(id); 140 141 if (!token) 142 return TEE_ERROR_SECURITY; 143 144 if (token->state == PKCS11_TOKEN_RESET) { 145 /* As per PKCS#11 spec, token resets to read/write state */ 146 token->state = PKCS11_TOKEN_READ_WRITE; 147 token->session_count = 0; 148 token->rw_session_count = 0; 149 } 150 151 return TEE_SUCCESS; 152 } 153 154 TEE_Result pkcs11_init(void) 155 { 156 unsigned int id = 0; 157 TEE_Result ret = TEE_ERROR_GENERIC; 158 159 for (id = 0; id < TOKEN_COUNT; id++) { 160 ret = pkcs11_token_init(id); 161 if (ret) 162 break; 163 } 164 165 return ret; 166 } 167 168 void pkcs11_deinit(void) 169 { 170 unsigned int id = 0; 171 172 for (id = 0; id < TOKEN_COUNT; id++) 173 close_persistent_db(get_token(id)); 174 } 175 176 /* 177 * Currently no support for dual operations. 178 */ 179 enum pkcs11_rc set_processing_state(struct pkcs11_session *session, 180 enum processing_func function, 181 struct pkcs11_object *obj1, 182 struct pkcs11_object *obj2) 183 { 184 enum pkcs11_proc_state state = PKCS11_SESSION_READY; 185 struct active_processing *proc = NULL; 186 187 if (session->processing) 188 return PKCS11_CKR_OPERATION_ACTIVE; 189 190 switch (function) { 191 case PKCS11_FUNCTION_ENCRYPT: 192 state = PKCS11_SESSION_ENCRYPTING; 193 break; 194 case PKCS11_FUNCTION_DECRYPT: 195 state = PKCS11_SESSION_DECRYPTING; 196 break; 197 case PKCS11_FUNCTION_SIGN: 198 state = PKCS11_SESSION_SIGNING; 199 break; 200 case PKCS11_FUNCTION_VERIFY: 201 state = PKCS11_SESSION_VERIFYING; 202 break; 203 case PKCS11_FUNCTION_DIGEST: 204 state = PKCS11_SESSION_DIGESTING; 205 break; 206 case PKCS11_FUNCTION_DERIVE: 207 case PKCS11_FUNCTION_WRAP: 208 case PKCS11_FUNCTION_UNWRAP: 209 state = PKCS11_SESSION_BUSY; 210 break; 211 default: 212 TEE_Panic(function); 213 return -1; 214 } 215 216 proc = TEE_Malloc(sizeof(*proc), TEE_MALLOC_FILL_ZERO); 217 if (!proc) 218 return PKCS11_CKR_DEVICE_MEMORY; 219 220 /* Boolean are default to false and pointers to NULL */ 221 proc->state = state; 222 proc->tee_op_handle = TEE_HANDLE_NULL; 223 proc->tee_hash_algo = 0; 224 proc->tee_hash_op_handle = TEE_HANDLE_NULL; 225 226 if (obj1 && get_bool(obj1->attributes, PKCS11_CKA_ALWAYS_AUTHENTICATE)) 227 proc->always_authen = true; 228 229 if (obj2 && get_bool(obj2->attributes, PKCS11_CKA_ALWAYS_AUTHENTICATE)) 230 proc->always_authen = true; 231 232 session->processing = proc; 233 234 return PKCS11_CKR_OK; 235 } 236 237 enum pkcs11_rc entry_ck_slot_list(uint32_t ptypes, TEE_Param *params) 238 { 239 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 240 TEE_PARAM_TYPE_NONE, 241 TEE_PARAM_TYPE_MEMREF_OUTPUT, 242 TEE_PARAM_TYPE_NONE); 243 TEE_Param *out = params + 2; 244 uint32_t token_id = 0; 245 const size_t out_size = sizeof(token_id) * TOKEN_COUNT; 246 uint8_t *id = NULL; 247 248 if (ptypes != exp_pt || 249 params[0].memref.size != TEE_PARAM0_SIZE_MIN) 250 return PKCS11_CKR_ARGUMENTS_BAD; 251 252 if (out->memref.size < out_size) { 253 out->memref.size = out_size; 254 255 if (out->memref.buffer) 256 return PKCS11_CKR_BUFFER_TOO_SMALL; 257 else 258 return PKCS11_CKR_OK; 259 } 260 261 for (token_id = 0, id = out->memref.buffer; token_id < TOKEN_COUNT; 262 token_id++, id += sizeof(token_id)) 263 TEE_MemMove(id, &token_id, sizeof(token_id)); 264 265 out->memref.size = out_size; 266 267 return PKCS11_CKR_OK; 268 } 269 270 static void pad_str(uint8_t *str, size_t size) 271 { 272 int n = strnlen((char *)str, size); 273 274 TEE_MemFill(str + n, ' ', size - n); 275 } 276 277 static void set_token_description(struct pkcs11_slot_info *info) 278 { 279 char desc[sizeof(info->slot_description) + 1] = { 0 }; 280 TEE_UUID dev_id = { }; 281 TEE_Result res = TEE_ERROR_GENERIC; 282 int n = 0; 283 284 res = TEE_GetPropertyAsUUID(TEE_PROPSET_TEE_IMPLEMENTATION, 285 "gpd.tee.deviceID", &dev_id); 286 if (res == TEE_SUCCESS) { 287 n = snprintk(desc, sizeof(desc), PKCS11_SLOT_DESCRIPTION 288 " - TEE UUID %pUl", (void *)&dev_id); 289 } else { 290 n = snprintf(desc, sizeof(desc), PKCS11_SLOT_DESCRIPTION 291 " - No TEE UUID"); 292 } 293 if (n < 0 || n >= (int)sizeof(desc)) 294 TEE_Panic(0); 295 296 TEE_MemMove(info->slot_description, desc, n); 297 pad_str(info->slot_description, sizeof(info->slot_description)); 298 } 299 300 enum pkcs11_rc entry_ck_slot_info(uint32_t ptypes, TEE_Param *params) 301 { 302 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 303 TEE_PARAM_TYPE_NONE, 304 TEE_PARAM_TYPE_MEMREF_OUTPUT, 305 TEE_PARAM_TYPE_NONE); 306 TEE_Param *ctrl = params; 307 TEE_Param *out = params + 2; 308 enum pkcs11_rc rc = PKCS11_CKR_OK; 309 struct serialargs ctrlargs = { }; 310 uint32_t token_id = 0; 311 struct pkcs11_slot_info info = { 312 .slot_description = PKCS11_SLOT_DESCRIPTION, 313 .manufacturer_id = PKCS11_SLOT_MANUFACTURER, 314 .flags = PKCS11_CKFS_TOKEN_PRESENT, 315 .hardware_version = PKCS11_SLOT_HW_VERSION, 316 .firmware_version = PKCS11_SLOT_FW_VERSION, 317 }; 318 319 COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_DESCRIPTION) <= 320 sizeof(info.slot_description)); 321 COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_MANUFACTURER) <= 322 sizeof(info.manufacturer_id)); 323 324 if (ptypes != exp_pt || out->memref.size != sizeof(info)) 325 return PKCS11_CKR_ARGUMENTS_BAD; 326 327 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 328 329 rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 330 if (rc) 331 return rc; 332 333 if (serialargs_remaining_bytes(&ctrlargs)) 334 return PKCS11_CKR_ARGUMENTS_BAD; 335 336 if (!get_token(token_id)) 337 return PKCS11_CKR_SLOT_ID_INVALID; 338 339 set_token_description(&info); 340 341 pad_str(info.manufacturer_id, sizeof(info.manufacturer_id)); 342 343 out->memref.size = sizeof(info); 344 TEE_MemMove(out->memref.buffer, &info, out->memref.size); 345 346 return PKCS11_CKR_OK; 347 } 348 349 enum pkcs11_rc entry_ck_token_info(uint32_t ptypes, TEE_Param *params) 350 { 351 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 352 TEE_PARAM_TYPE_NONE, 353 TEE_PARAM_TYPE_MEMREF_OUTPUT, 354 TEE_PARAM_TYPE_NONE); 355 TEE_Param *ctrl = params; 356 TEE_Param *out = params + 2; 357 enum pkcs11_rc rc = PKCS11_CKR_OK; 358 struct serialargs ctrlargs = { }; 359 uint32_t token_id = 0; 360 struct ck_token *token = NULL; 361 struct pkcs11_token_info info = { 362 .manufacturer_id = PKCS11_TOKEN_MANUFACTURER, 363 .model = PKCS11_TOKEN_MODEL, 364 .max_session_count = UINT32_MAX, 365 .max_rw_session_count = UINT32_MAX, 366 .max_pin_len = PKCS11_TOKEN_PIN_SIZE_MAX, 367 .min_pin_len = PKCS11_TOKEN_PIN_SIZE_MIN, 368 .total_public_memory = UINT32_MAX, 369 .free_public_memory = UINT32_MAX, 370 .total_private_memory = UINT32_MAX, 371 .free_private_memory = UINT32_MAX, 372 .hardware_version = PKCS11_TOKEN_HW_VERSION, 373 .firmware_version = PKCS11_TOKEN_FW_VERSION, 374 }; 375 char sn[sizeof(info.serial_number) + 1] = { 0 }; 376 int n = 0; 377 378 if (ptypes != exp_pt || out->memref.size != sizeof(info)) 379 return PKCS11_CKR_ARGUMENTS_BAD; 380 381 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 382 383 rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 384 if (rc) 385 return rc; 386 387 if (serialargs_remaining_bytes(&ctrlargs)) 388 return PKCS11_CKR_ARGUMENTS_BAD; 389 390 token = get_token(token_id); 391 if (!token) 392 return PKCS11_CKR_SLOT_ID_INVALID; 393 394 pad_str(info.manufacturer_id, sizeof(info.manufacturer_id)); 395 pad_str(info.model, sizeof(info.model)); 396 397 n = snprintf(sn, sizeof(sn), "%0*"PRIu32, 398 (int)sizeof(info.serial_number), token_id); 399 if (n != (int)sizeof(info.serial_number)) 400 TEE_Panic(0); 401 402 TEE_MemMove(info.serial_number, sn, sizeof(info.serial_number)); 403 pad_str(info.serial_number, sizeof(info.serial_number)); 404 405 TEE_MemMove(info.label, token->db_main->label, sizeof(info.label)); 406 407 info.flags = token->db_main->flags; 408 info.session_count = token->session_count; 409 info.rw_session_count = token->rw_session_count; 410 411 TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 412 413 return PKCS11_CKR_OK; 414 } 415 416 static void dmsg_print_supported_mechanism(unsigned int token_id __maybe_unused, 417 uint32_t *array __maybe_unused, 418 size_t count __maybe_unused) 419 { 420 size_t __maybe_unused n = 0; 421 422 if (TRACE_LEVEL < TRACE_DEBUG) 423 return; 424 425 for (n = 0; n < count; n++) 426 DMSG("PKCS11 token %"PRIu32": mechanism 0x%04"PRIx32": %s", 427 token_id, array[n], id2str_mechanism(array[n])); 428 } 429 430 enum pkcs11_rc entry_ck_token_mecha_ids(uint32_t ptypes, TEE_Param *params) 431 { 432 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 433 TEE_PARAM_TYPE_NONE, 434 TEE_PARAM_TYPE_MEMREF_OUTPUT, 435 TEE_PARAM_TYPE_NONE); 436 TEE_Param *ctrl = params; 437 TEE_Param *out = params + 2; 438 enum pkcs11_rc rc = PKCS11_CKR_OK; 439 struct serialargs ctrlargs = { }; 440 uint32_t token_id = 0; 441 struct ck_token __maybe_unused *token = NULL; 442 size_t count = 0; 443 uint32_t *array = NULL; 444 445 if (ptypes != exp_pt) 446 return PKCS11_CKR_ARGUMENTS_BAD; 447 448 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 449 450 rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 451 if (rc) 452 return rc; 453 454 if (serialargs_remaining_bytes(&ctrlargs)) 455 return PKCS11_CKR_ARGUMENTS_BAD; 456 457 token = get_token(token_id); 458 if (!token) 459 return PKCS11_CKR_SLOT_ID_INVALID; 460 461 count = out->memref.size / sizeof(*array); 462 array = tee_malloc_mechanism_list(&count); 463 464 if (out->memref.size < count * sizeof(*array)) { 465 assert(!array); 466 out->memref.size = count * sizeof(*array); 467 if (out->memref.buffer) 468 return PKCS11_CKR_BUFFER_TOO_SMALL; 469 else 470 return PKCS11_CKR_OK; 471 } 472 473 if (!array) 474 return PKCS11_CKR_DEVICE_MEMORY; 475 476 dmsg_print_supported_mechanism(token_id, array, count); 477 478 out->memref.size = count * sizeof(*array); 479 TEE_MemMove(out->memref.buffer, array, out->memref.size); 480 481 TEE_Free(array); 482 483 return rc; 484 } 485 486 enum pkcs11_rc entry_ck_token_mecha_info(uint32_t ptypes, TEE_Param *params) 487 { 488 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 489 TEE_PARAM_TYPE_NONE, 490 TEE_PARAM_TYPE_MEMREF_OUTPUT, 491 TEE_PARAM_TYPE_NONE); 492 TEE_Param *ctrl = params; 493 TEE_Param *out = params + 2; 494 enum pkcs11_rc rc = PKCS11_CKR_OK; 495 struct serialargs ctrlargs = { }; 496 uint32_t token_id = 0; 497 uint32_t type = 0; 498 struct ck_token *token = NULL; 499 struct pkcs11_mechanism_info info = { }; 500 501 if (ptypes != exp_pt || out->memref.size != sizeof(info)) 502 return PKCS11_CKR_ARGUMENTS_BAD; 503 504 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 505 506 rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 507 if (rc) 508 return rc; 509 510 rc = serialargs_get(&ctrlargs, &type, sizeof(uint32_t)); 511 if (rc) 512 return rc; 513 514 if (serialargs_remaining_bytes(&ctrlargs)) 515 return PKCS11_CKR_ARGUMENTS_BAD; 516 517 token = get_token(token_id); 518 if (!token) 519 return PKCS11_CKR_SLOT_ID_INVALID; 520 521 if (!mechanism_is_valid(type)) 522 return PKCS11_CKR_MECHANISM_INVALID; 523 524 info.flags = mechanism_supported_flags(type); 525 526 pkcs11_mechanism_supported_key_sizes(type, &info.min_key_size, 527 &info.max_key_size); 528 529 TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 530 531 DMSG("PKCS11 token %"PRIu32": mechanism 0x%"PRIx32" info", 532 token_id, type); 533 534 return PKCS11_CKR_OK; 535 } 536 537 /* Select the ReadOnly or ReadWrite state for session login state */ 538 static void set_session_state(struct pkcs11_client *client, 539 struct pkcs11_session *session, bool readonly) 540 { 541 struct pkcs11_session *sess = NULL; 542 enum pkcs11_session_state state = PKCS11_CKS_RO_PUBLIC_SESSION; 543 544 /* Default to public session if no session already registered */ 545 if (readonly) 546 state = PKCS11_CKS_RO_PUBLIC_SESSION; 547 else 548 state = PKCS11_CKS_RW_PUBLIC_SESSION; 549 550 /* 551 * No need to check all client sessions, the first found in 552 * target token gives client login configuration. 553 */ 554 TAILQ_FOREACH(sess, &client->session_list, link) { 555 assert(sess != session); 556 557 if (sess->token == session->token) { 558 switch (sess->state) { 559 case PKCS11_CKS_RW_PUBLIC_SESSION: 560 case PKCS11_CKS_RO_PUBLIC_SESSION: 561 if (readonly) 562 state = PKCS11_CKS_RO_PUBLIC_SESSION; 563 else 564 state = PKCS11_CKS_RW_PUBLIC_SESSION; 565 break; 566 case PKCS11_CKS_RO_USER_FUNCTIONS: 567 case PKCS11_CKS_RW_USER_FUNCTIONS: 568 if (readonly) 569 state = PKCS11_CKS_RO_USER_FUNCTIONS; 570 else 571 state = PKCS11_CKS_RW_USER_FUNCTIONS; 572 break; 573 case PKCS11_CKS_RW_SO_FUNCTIONS: 574 if (readonly) 575 TEE_Panic(0); 576 else 577 state = PKCS11_CKS_RW_SO_FUNCTIONS; 578 break; 579 default: 580 TEE_Panic(0); 581 } 582 break; 583 } 584 } 585 586 session->state = state; 587 } 588 589 enum pkcs11_rc entry_ck_open_session(struct pkcs11_client *client, 590 uint32_t ptypes, TEE_Param *params) 591 { 592 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 593 TEE_PARAM_TYPE_NONE, 594 TEE_PARAM_TYPE_MEMREF_OUTPUT, 595 TEE_PARAM_TYPE_NONE); 596 TEE_Param *ctrl = params; 597 TEE_Param *out = params + 2; 598 enum pkcs11_rc rc = PKCS11_CKR_OK; 599 struct serialargs ctrlargs = { }; 600 uint32_t token_id = 0; 601 uint32_t flags = 0; 602 struct ck_token *token = NULL; 603 struct pkcs11_session *session = NULL; 604 bool readonly = false; 605 606 if (!client || ptypes != exp_pt || 607 out->memref.size != sizeof(session->handle)) 608 return PKCS11_CKR_ARGUMENTS_BAD; 609 610 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 611 612 rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 613 if (rc) 614 return rc; 615 616 rc = serialargs_get(&ctrlargs, &flags, sizeof(flags)); 617 if (rc) 618 return rc; 619 620 if (serialargs_remaining_bytes(&ctrlargs)) 621 return PKCS11_CKR_ARGUMENTS_BAD; 622 623 token = get_token(token_id); 624 if (!token) 625 return PKCS11_CKR_SLOT_ID_INVALID; 626 627 /* Sanitize session flags */ 628 if (!(flags & PKCS11_CKFSS_SERIAL_SESSION)) 629 return PKCS11_CKR_SESSION_PARALLEL_NOT_SUPPORTED; 630 631 if (flags & ~(PKCS11_CKFSS_RW_SESSION | PKCS11_CKFSS_SERIAL_SESSION)) 632 return PKCS11_CKR_ARGUMENTS_BAD; 633 634 readonly = !(flags & PKCS11_CKFSS_RW_SESSION); 635 636 if (!readonly && token->state == PKCS11_TOKEN_READ_ONLY) 637 return PKCS11_CKR_TOKEN_WRITE_PROTECTED; 638 639 if (readonly) { 640 /* Specifically reject read-only session under SO login */ 641 TAILQ_FOREACH(session, &client->session_list, link) 642 if (pkcs11_session_is_so(session)) 643 return PKCS11_CKR_SESSION_READ_WRITE_SO_EXISTS; 644 } 645 646 session = TEE_Malloc(sizeof(*session), TEE_MALLOC_FILL_ZERO); 647 if (!session) 648 return PKCS11_CKR_DEVICE_MEMORY; 649 650 session->handle = handle_get(&client->session_handle_db, session); 651 if (!session->handle) { 652 TEE_Free(session); 653 return PKCS11_CKR_DEVICE_MEMORY; 654 } 655 656 session->token = token; 657 session->client = client; 658 659 LIST_INIT(&session->object_list); 660 661 set_session_state(client, session, readonly); 662 663 TAILQ_INSERT_HEAD(&client->session_list, session, link); 664 665 session->token->session_count++; 666 if (!readonly) 667 session->token->rw_session_count++; 668 669 TEE_MemMove(out->memref.buffer, &session->handle, 670 sizeof(session->handle)); 671 672 DMSG("Open PKCS11 session %"PRIu32, session->handle); 673 674 return PKCS11_CKR_OK; 675 } 676 677 static void close_ck_session(struct pkcs11_session *session) 678 { 679 release_active_processing(session); 680 release_session_find_obj_context(session); 681 682 /* Release all session objects */ 683 while (!LIST_EMPTY(&session->object_list)) 684 destroy_object(session, 685 LIST_FIRST(&session->object_list), true); 686 687 TAILQ_REMOVE(&session->client->session_list, session, link); 688 handle_put(&session->client->session_handle_db, session->handle); 689 690 session->token->session_count--; 691 if (pkcs11_session_is_read_write(session)) 692 session->token->rw_session_count--; 693 694 TEE_Free(session); 695 696 DMSG("Close PKCS11 session %"PRIu32, session->handle); 697 } 698 699 enum pkcs11_rc entry_ck_close_session(struct pkcs11_client *client, 700 uint32_t ptypes, TEE_Param *params) 701 { 702 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 703 TEE_PARAM_TYPE_NONE, 704 TEE_PARAM_TYPE_NONE, 705 TEE_PARAM_TYPE_NONE); 706 TEE_Param *ctrl = params; 707 enum pkcs11_rc rc = PKCS11_CKR_OK; 708 struct serialargs ctrlargs = { }; 709 struct pkcs11_session *session = NULL; 710 711 if (!client || ptypes != exp_pt) 712 return PKCS11_CKR_ARGUMENTS_BAD; 713 714 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 715 716 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 717 if (rc) 718 return rc; 719 720 if (serialargs_remaining_bytes(&ctrlargs)) 721 return PKCS11_CKR_ARGUMENTS_BAD; 722 723 close_ck_session(session); 724 725 return PKCS11_CKR_OK; 726 } 727 728 enum pkcs11_rc entry_ck_close_all_sessions(struct pkcs11_client *client, 729 uint32_t ptypes, TEE_Param *params) 730 { 731 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 732 TEE_PARAM_TYPE_NONE, 733 TEE_PARAM_TYPE_NONE, 734 TEE_PARAM_TYPE_NONE); 735 TEE_Param *ctrl = params; 736 enum pkcs11_rc rc = PKCS11_CKR_OK; 737 struct serialargs ctrlargs = { }; 738 uint32_t token_id = 0; 739 struct ck_token *token = NULL; 740 struct pkcs11_session *session = NULL; 741 struct pkcs11_session *next = NULL; 742 743 if (!client || ptypes != exp_pt) 744 return PKCS11_CKR_ARGUMENTS_BAD; 745 746 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 747 748 rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 749 if (rc) 750 return rc; 751 752 if (serialargs_remaining_bytes(&ctrlargs)) 753 return PKCS11_CKR_ARGUMENTS_BAD; 754 755 token = get_token(token_id); 756 if (!token) 757 return PKCS11_CKR_SLOT_ID_INVALID; 758 759 DMSG("Close all sessions for PKCS11 token %"PRIu32, token_id); 760 761 TAILQ_FOREACH_SAFE(session, &client->session_list, link, next) 762 if (session->token == token) 763 close_ck_session(session); 764 765 return PKCS11_CKR_OK; 766 } 767 768 enum pkcs11_rc entry_ck_session_info(struct pkcs11_client *client, 769 uint32_t ptypes, TEE_Param *params) 770 { 771 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 772 TEE_PARAM_TYPE_NONE, 773 TEE_PARAM_TYPE_MEMREF_OUTPUT, 774 TEE_PARAM_TYPE_NONE); 775 TEE_Param *ctrl = params; 776 TEE_Param *out = params + 2; 777 enum pkcs11_rc rc = PKCS11_CKR_OK; 778 struct serialargs ctrlargs = { }; 779 struct pkcs11_session *session = NULL; 780 struct pkcs11_session_info info = { 781 .flags = PKCS11_CKFSS_SERIAL_SESSION, 782 }; 783 784 if (!client || ptypes != exp_pt || out->memref.size != sizeof(info)) 785 return PKCS11_CKR_ARGUMENTS_BAD; 786 787 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 788 789 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 790 if (rc) 791 return rc; 792 793 if (serialargs_remaining_bytes(&ctrlargs)) 794 return PKCS11_CKR_ARGUMENTS_BAD; 795 796 info.slot_id = get_token_id(session->token); 797 info.state = session->state; 798 if (pkcs11_session_is_read_write(session)) 799 info.flags |= PKCS11_CKFSS_RW_SESSION; 800 801 TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 802 803 DMSG("Get find on PKCS11 session %"PRIu32, session->handle); 804 805 return PKCS11_CKR_OK; 806 } 807 808 enum pkcs11_rc entry_ck_token_initialize(uint32_t ptypes, TEE_Param *params) 809 { 810 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 811 TEE_PARAM_TYPE_NONE, 812 TEE_PARAM_TYPE_NONE, 813 TEE_PARAM_TYPE_NONE); 814 char label[PKCS11_TOKEN_LABEL_SIZE] = { 0 }; 815 struct pkcs11_client *client = NULL; 816 struct pkcs11_session *sess = NULL; 817 enum pkcs11_rc rc = PKCS11_CKR_OK; 818 struct serialargs ctrlargs = { }; 819 struct ck_token *token = NULL; 820 TEE_Param *ctrl = params; 821 uint32_t token_id = 0; 822 uint32_t pin_size = 0; 823 void *pin = NULL; 824 struct pkcs11_object *obj = NULL; 825 826 if (ptypes != exp_pt) 827 return PKCS11_CKR_ARGUMENTS_BAD; 828 829 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 830 831 rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 832 if (rc) 833 return rc; 834 835 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 836 if (rc) 837 return rc; 838 839 rc = serialargs_get(&ctrlargs, &label, PKCS11_TOKEN_LABEL_SIZE); 840 if (rc) 841 return rc; 842 843 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 844 if (rc) 845 return rc; 846 847 if (serialargs_remaining_bytes(&ctrlargs)) 848 return PKCS11_CKR_ARGUMENTS_BAD; 849 850 token = get_token(token_id); 851 if (!token) 852 return PKCS11_CKR_SLOT_ID_INVALID; 853 854 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) { 855 IMSG("Token %"PRIu32": SO PIN locked", token_id); 856 return PKCS11_CKR_PIN_LOCKED; 857 } 858 859 /* Check there's no open session on this token */ 860 TAILQ_FOREACH(client, &pkcs11_client_list, link) 861 TAILQ_FOREACH(sess, &client->session_list, link) 862 if (sess->token == token) 863 return PKCS11_CKR_SESSION_EXISTS; 864 865 #if defined(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) 866 /* Check TEE Identity based authentication if enabled */ 867 if (token->db_main->flags & PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH) { 868 rc = verify_identity_auth(token, PKCS11_CKU_SO); 869 if (rc) 870 return rc; 871 } 872 873 /* Detect TEE Identity based ACL usage activation with NULL PIN */ 874 if (!pin) { 875 rc = setup_so_identity_auth_from_client(token); 876 if (rc) 877 return rc; 878 879 goto inited; 880 } else { 881 /* De-activate TEE Identity based authentication */ 882 token->db_main->flags &= 883 ~PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH; 884 } 885 #endif /* CFG_PKCS11_TA_AUTH_TEE_IDENTITY */ 886 887 if (!token->db_main->so_pin_salt) { 888 /* 889 * The spec doesn't permit returning 890 * PKCS11_CKR_PIN_LEN_RANGE for this function, take another 891 * error code. 892 */ 893 if (pin_size < PKCS11_TOKEN_PIN_SIZE_MIN || 894 pin_size > PKCS11_TOKEN_PIN_SIZE_MAX) 895 return PKCS11_CKR_ARGUMENTS_BAD; 896 897 rc = hash_pin(PKCS11_CKU_SO, pin, pin_size, 898 &token->db_main->so_pin_salt, 899 token->db_main->so_pin_hash); 900 if (rc) 901 return rc; 902 903 goto inited; 904 } 905 906 rc = verify_pin(PKCS11_CKU_SO, pin, pin_size, 907 token->db_main->so_pin_salt, 908 token->db_main->so_pin_hash); 909 if (rc) { 910 unsigned int pin_count = 0; 911 912 if (rc != PKCS11_CKR_PIN_INCORRECT) 913 return rc; 914 915 token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW; 916 token->db_main->so_pin_count++; 917 918 pin_count = token->db_main->so_pin_count; 919 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1) 920 token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY; 921 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX) 922 token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED; 923 924 update_persistent_db(token); 925 926 return PKCS11_CKR_PIN_INCORRECT; 927 } 928 929 inited: 930 /* Make sure SO PIN counters are zeroed */ 931 token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW | 932 PKCS11_CKFT_SO_PIN_FINAL_TRY | 933 PKCS11_CKFT_SO_PIN_LOCKED | 934 PKCS11_CKFT_SO_PIN_TO_BE_CHANGED); 935 token->db_main->so_pin_count = 0; 936 937 TEE_MemMove(token->db_main->label, label, PKCS11_TOKEN_LABEL_SIZE); 938 token->db_main->flags |= PKCS11_CKFT_TOKEN_INITIALIZED; 939 /* Reset user PIN */ 940 token->db_main->user_pin_salt = 0; 941 token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_INITIALIZED | 942 PKCS11_CKFT_USER_PIN_COUNT_LOW | 943 PKCS11_CKFT_USER_PIN_FINAL_TRY | 944 PKCS11_CKFT_USER_PIN_LOCKED | 945 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED); 946 947 update_persistent_db(token); 948 949 /* Remove all persistent objects */ 950 while (!LIST_EMPTY(&token->object_list)) { 951 obj = LIST_FIRST(&token->object_list); 952 953 /* Try twice otherwise panic! */ 954 if (unregister_persistent_object(token, obj->uuid) && 955 unregister_persistent_object(token, obj->uuid)) 956 TEE_Panic(0); 957 958 cleanup_persistent_object(obj, token); 959 } 960 961 IMSG("PKCS11 token %"PRIu32": initialized", token_id); 962 963 return PKCS11_CKR_OK; 964 } 965 966 static enum pkcs11_rc set_pin(struct pkcs11_session *session, 967 uint8_t *new_pin, size_t new_pin_size, 968 enum pkcs11_user_type user_type) 969 { 970 struct ck_token *token = session->token; 971 enum pkcs11_rc rc = PKCS11_CKR_OK; 972 uint32_t flags_clear = 0; 973 uint32_t flags_set = 0; 974 975 if (token->db_main->flags & PKCS11_CKFT_WRITE_PROTECTED) 976 return PKCS11_CKR_TOKEN_WRITE_PROTECTED; 977 978 if (!pkcs11_session_is_read_write(session)) 979 return PKCS11_CKR_SESSION_READ_ONLY; 980 981 if (IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) && 982 token->db_main->flags & PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH) { 983 rc = setup_identity_auth_from_pin(token, user_type, new_pin, 984 new_pin_size); 985 if (rc) 986 return rc; 987 988 goto update_db; 989 } 990 991 if (new_pin_size < PKCS11_TOKEN_PIN_SIZE_MIN || 992 new_pin_size > PKCS11_TOKEN_PIN_SIZE_MAX) 993 return PKCS11_CKR_PIN_LEN_RANGE; 994 995 switch (user_type) { 996 case PKCS11_CKU_SO: 997 rc = hash_pin(user_type, new_pin, new_pin_size, 998 &token->db_main->so_pin_salt, 999 token->db_main->so_pin_hash); 1000 if (rc) 1001 return rc; 1002 token->db_main->so_pin_count = 0; 1003 flags_clear = PKCS11_CKFT_SO_PIN_COUNT_LOW | 1004 PKCS11_CKFT_SO_PIN_FINAL_TRY | 1005 PKCS11_CKFT_SO_PIN_LOCKED | 1006 PKCS11_CKFT_SO_PIN_TO_BE_CHANGED; 1007 break; 1008 case PKCS11_CKU_USER: 1009 rc = hash_pin(user_type, new_pin, new_pin_size, 1010 &token->db_main->user_pin_salt, 1011 token->db_main->user_pin_hash); 1012 if (rc) 1013 return rc; 1014 token->db_main->user_pin_count = 0; 1015 flags_clear = PKCS11_CKFT_USER_PIN_COUNT_LOW | 1016 PKCS11_CKFT_USER_PIN_FINAL_TRY | 1017 PKCS11_CKFT_USER_PIN_LOCKED | 1018 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED; 1019 flags_set = PKCS11_CKFT_USER_PIN_INITIALIZED; 1020 break; 1021 default: 1022 return PKCS11_CKR_FUNCTION_FAILED; 1023 } 1024 1025 update_db: 1026 token->db_main->flags &= ~flags_clear; 1027 token->db_main->flags |= flags_set; 1028 1029 update_persistent_db(token); 1030 1031 return PKCS11_CKR_OK; 1032 } 1033 1034 enum pkcs11_rc entry_ck_init_pin(struct pkcs11_client *client, 1035 uint32_t ptypes, TEE_Param *params) 1036 { 1037 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1038 TEE_PARAM_TYPE_NONE, 1039 TEE_PARAM_TYPE_NONE, 1040 TEE_PARAM_TYPE_NONE); 1041 struct pkcs11_session *session = NULL; 1042 enum pkcs11_rc rc = PKCS11_CKR_OK; 1043 struct serialargs ctrlargs = { }; 1044 TEE_Param *ctrl = params; 1045 uint32_t pin_size = 0; 1046 void *pin = NULL; 1047 1048 if (!client || ptypes != exp_pt) 1049 return PKCS11_CKR_ARGUMENTS_BAD; 1050 1051 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1052 1053 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1054 if (rc) 1055 return rc; 1056 1057 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 1058 if (rc) 1059 return rc; 1060 1061 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 1062 if (rc) 1063 return rc; 1064 1065 if (serialargs_remaining_bytes(&ctrlargs)) 1066 return PKCS11_CKR_ARGUMENTS_BAD; 1067 1068 if (!pkcs11_session_is_so(session)) 1069 return PKCS11_CKR_USER_NOT_LOGGED_IN; 1070 1071 assert(session->token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED); 1072 1073 IMSG("PKCS11 session %"PRIu32": init PIN", session->handle); 1074 1075 return set_pin(session, pin, pin_size, PKCS11_CKU_USER); 1076 } 1077 1078 static enum pkcs11_rc check_so_pin(struct pkcs11_session *session, 1079 uint8_t *pin, size_t pin_size) 1080 { 1081 struct ck_token *token = session->token; 1082 enum pkcs11_rc rc = PKCS11_CKR_OK; 1083 1084 assert(token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED); 1085 1086 if (IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) && 1087 token->db_main->flags & PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH) 1088 return verify_identity_auth(token, PKCS11_CKU_SO); 1089 1090 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) 1091 return PKCS11_CKR_PIN_LOCKED; 1092 1093 rc = verify_pin(PKCS11_CKU_SO, pin, pin_size, 1094 token->db_main->so_pin_salt, 1095 token->db_main->so_pin_hash); 1096 if (rc) { 1097 unsigned int pin_count = 0; 1098 1099 if (rc != PKCS11_CKR_PIN_INCORRECT) 1100 return rc; 1101 1102 token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW; 1103 token->db_main->so_pin_count++; 1104 1105 pin_count = token->db_main->so_pin_count; 1106 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1) 1107 token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY; 1108 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX) 1109 token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED; 1110 1111 update_persistent_db(token); 1112 1113 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) 1114 return PKCS11_CKR_PIN_LOCKED; 1115 1116 return PKCS11_CKR_PIN_INCORRECT; 1117 } 1118 1119 if (token->db_main->so_pin_count) { 1120 token->db_main->so_pin_count = 0; 1121 1122 update_persistent_db(token); 1123 } 1124 1125 if (token->db_main->flags & (PKCS11_CKFT_SO_PIN_COUNT_LOW | 1126 PKCS11_CKFT_SO_PIN_FINAL_TRY)) { 1127 token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW | 1128 PKCS11_CKFT_SO_PIN_FINAL_TRY); 1129 1130 update_persistent_db(token); 1131 } 1132 1133 return PKCS11_CKR_OK; 1134 } 1135 1136 static enum pkcs11_rc check_user_pin(struct pkcs11_session *session, 1137 uint8_t *pin, size_t pin_size) 1138 { 1139 struct ck_token *token = session->token; 1140 enum pkcs11_rc rc = PKCS11_CKR_OK; 1141 1142 if (IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) && 1143 token->db_main->flags & PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH) 1144 return verify_identity_auth(token, PKCS11_CKU_USER); 1145 1146 if (!token->db_main->user_pin_salt) 1147 return PKCS11_CKR_USER_PIN_NOT_INITIALIZED; 1148 1149 if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED) 1150 return PKCS11_CKR_PIN_LOCKED; 1151 1152 rc = verify_pin(PKCS11_CKU_USER, pin, pin_size, 1153 token->db_main->user_pin_salt, 1154 token->db_main->user_pin_hash); 1155 if (rc) { 1156 unsigned int pin_count = 0; 1157 1158 if (rc != PKCS11_CKR_PIN_INCORRECT) 1159 return rc; 1160 1161 token->db_main->flags |= PKCS11_CKFT_USER_PIN_COUNT_LOW; 1162 token->db_main->user_pin_count++; 1163 1164 pin_count = token->db_main->user_pin_count; 1165 if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX - 1) 1166 token->db_main->flags |= PKCS11_CKFT_USER_PIN_FINAL_TRY; 1167 if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX) 1168 token->db_main->flags |= PKCS11_CKFT_USER_PIN_LOCKED; 1169 1170 update_persistent_db(token); 1171 1172 if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED) 1173 return PKCS11_CKR_PIN_LOCKED; 1174 1175 return PKCS11_CKR_PIN_INCORRECT; 1176 } 1177 1178 if (token->db_main->user_pin_count) { 1179 token->db_main->user_pin_count = 0; 1180 1181 update_persistent_db(token); 1182 } 1183 1184 if (token->db_main->flags & (PKCS11_CKFT_USER_PIN_COUNT_LOW | 1185 PKCS11_CKFT_USER_PIN_FINAL_TRY)) { 1186 token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_COUNT_LOW | 1187 PKCS11_CKFT_USER_PIN_FINAL_TRY); 1188 1189 update_persistent_db(token); 1190 } 1191 1192 return PKCS11_CKR_OK; 1193 } 1194 1195 enum pkcs11_rc entry_ck_set_pin(struct pkcs11_client *client, 1196 uint32_t ptypes, TEE_Param *params) 1197 { 1198 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1199 TEE_PARAM_TYPE_NONE, 1200 TEE_PARAM_TYPE_NONE, 1201 TEE_PARAM_TYPE_NONE); 1202 struct pkcs11_session *session = NULL; 1203 enum pkcs11_rc rc = PKCS11_CKR_OK; 1204 struct serialargs ctrlargs = { }; 1205 uint32_t old_pin_size = 0; 1206 TEE_Param *ctrl = params; 1207 uint32_t pin_size = 0; 1208 void *old_pin = NULL; 1209 void *pin = NULL; 1210 1211 if (!client || ptypes != exp_pt) 1212 return PKCS11_CKR_ARGUMENTS_BAD; 1213 1214 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1215 1216 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1217 if (rc) 1218 return rc; 1219 1220 rc = serialargs_get(&ctrlargs, &old_pin_size, sizeof(uint32_t)); 1221 if (rc) 1222 return rc; 1223 1224 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 1225 if (rc) 1226 return rc; 1227 1228 rc = serialargs_get_ptr(&ctrlargs, &old_pin, old_pin_size); 1229 if (rc) 1230 return rc; 1231 1232 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 1233 if (rc) 1234 return rc; 1235 1236 if (serialargs_remaining_bytes(&ctrlargs)) 1237 return PKCS11_CKR_ARGUMENTS_BAD; 1238 1239 if (!pkcs11_session_is_read_write(session)) 1240 return PKCS11_CKR_SESSION_READ_ONLY; 1241 1242 if (pkcs11_session_is_so(session)) { 1243 if (!(session->token->db_main->flags & 1244 PKCS11_CKFT_TOKEN_INITIALIZED)) 1245 return PKCS11_CKR_GENERAL_ERROR; 1246 1247 rc = check_so_pin(session, old_pin, old_pin_size); 1248 if (rc) 1249 return rc; 1250 1251 IMSG("PKCS11 session %"PRIu32": set PIN", session->handle); 1252 1253 return set_pin(session, pin, pin_size, PKCS11_CKU_SO); 1254 } 1255 1256 if (!(session->token->db_main->flags & 1257 PKCS11_CKFT_USER_PIN_INITIALIZED)) 1258 return PKCS11_CKR_GENERAL_ERROR; 1259 1260 rc = check_user_pin(session, old_pin, old_pin_size); 1261 if (rc) 1262 return rc; 1263 1264 IMSG("PKCS11 session %"PRIu32": set PIN", session->handle); 1265 1266 return set_pin(session, pin, pin_size, PKCS11_CKU_USER); 1267 } 1268 1269 static void session_login_user(struct pkcs11_session *session) 1270 { 1271 struct pkcs11_client *client = session->client; 1272 struct pkcs11_session *sess = NULL; 1273 1274 TAILQ_FOREACH(sess, &client->session_list, link) { 1275 if (sess->token != session->token) 1276 continue; 1277 1278 if (pkcs11_session_is_read_write(sess)) 1279 sess->state = PKCS11_CKS_RW_USER_FUNCTIONS; 1280 else 1281 sess->state = PKCS11_CKS_RO_USER_FUNCTIONS; 1282 } 1283 } 1284 1285 static void session_login_so(struct pkcs11_session *session) 1286 { 1287 struct pkcs11_client *client = session->client; 1288 struct pkcs11_session *sess = NULL; 1289 1290 TAILQ_FOREACH(sess, &client->session_list, link) { 1291 if (sess->token != session->token) 1292 continue; 1293 1294 if (pkcs11_session_is_read_write(sess)) 1295 sess->state = PKCS11_CKS_RW_SO_FUNCTIONS; 1296 else 1297 TEE_Panic(0); 1298 } 1299 } 1300 1301 static void session_logout(struct pkcs11_session *session) 1302 { 1303 struct pkcs11_client *client = session->client; 1304 struct pkcs11_session *sess = NULL; 1305 1306 TAILQ_FOREACH(sess, &client->session_list, link) { 1307 struct pkcs11_object *obj = NULL; 1308 struct pkcs11_object *tobj = NULL; 1309 uint32_t handle = 0; 1310 1311 if (sess->token != session->token) 1312 continue; 1313 1314 release_active_processing(session); 1315 1316 /* Destroy private session objects */ 1317 LIST_FOREACH_SAFE(obj, &sess->object_list, link, tobj) { 1318 if (object_is_private(obj->attributes)) 1319 destroy_object(sess, obj, true); 1320 } 1321 1322 /* 1323 * Remove handle of token private objects from 1324 * sessions object_handle_db 1325 */ 1326 LIST_FOREACH(obj, &session->token->object_list, link) { 1327 handle = pkcs11_object2handle(obj, session); 1328 1329 if (handle && object_is_private(obj->attributes)) 1330 handle_put(get_object_handle_db(sess), handle); 1331 } 1332 1333 release_session_find_obj_context(session); 1334 1335 if (pkcs11_session_is_read_write(sess)) 1336 sess->state = PKCS11_CKS_RW_PUBLIC_SESSION; 1337 else 1338 sess->state = PKCS11_CKS_RO_PUBLIC_SESSION; 1339 } 1340 } 1341 1342 enum pkcs11_rc entry_ck_login(struct pkcs11_client *client, 1343 uint32_t ptypes, TEE_Param *params) 1344 { 1345 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1346 TEE_PARAM_TYPE_NONE, 1347 TEE_PARAM_TYPE_NONE, 1348 TEE_PARAM_TYPE_NONE); 1349 struct pkcs11_session *session = NULL; 1350 struct pkcs11_session *sess = NULL; 1351 enum pkcs11_rc rc = PKCS11_CKR_OK; 1352 struct serialargs ctrlargs = { }; 1353 TEE_Param *ctrl = params; 1354 uint32_t user_type = 0; 1355 uint32_t pin_size = 0; 1356 void *pin = NULL; 1357 1358 if (!client || ptypes != exp_pt) 1359 return PKCS11_CKR_ARGUMENTS_BAD; 1360 1361 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1362 1363 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1364 if (rc) 1365 return rc; 1366 1367 rc = serialargs_get(&ctrlargs, &user_type, sizeof(uint32_t)); 1368 if (rc) 1369 return rc; 1370 1371 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 1372 if (rc) 1373 return rc; 1374 1375 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 1376 if (rc) 1377 return rc; 1378 1379 if (serialargs_remaining_bytes(&ctrlargs)) 1380 return PKCS11_CKR_ARGUMENTS_BAD; 1381 1382 switch (user_type) { 1383 case PKCS11_CKU_SO: 1384 if (pkcs11_session_is_so(session)) 1385 return PKCS11_CKR_USER_ALREADY_LOGGED_IN; 1386 1387 if (pkcs11_session_is_user(session)) 1388 return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN; 1389 1390 TAILQ_FOREACH(sess, &client->session_list, link) 1391 if (sess->token == session->token && 1392 !pkcs11_session_is_read_write(sess)) 1393 return PKCS11_CKR_SESSION_READ_ONLY_EXISTS; 1394 1395 /* 1396 * This is the point where we could check if another client 1397 * has another user or SO logged in. 1398 * 1399 * The spec says: 1400 * CKR_USER_TOO_MANY_TYPES: An attempt was made to have 1401 * more distinct users simultaneously logged into the token 1402 * than the token and/or library permits. For example, if 1403 * some application has an open SO session, and another 1404 * application attempts to log the normal user into a 1405 * session, the attempt may return this error. It is not 1406 * required to, however. Only if the simultaneous distinct 1407 * users cannot be supported does C_Login have to return 1408 * this value. Note that this error code generalizes to 1409 * true multi-user tokens. 1410 * 1411 * So it's permitted to have another user or SO logged in 1412 * from another client. 1413 */ 1414 1415 rc = check_so_pin(session, pin, pin_size); 1416 if (!rc) 1417 session_login_so(session); 1418 1419 break; 1420 1421 case PKCS11_CKU_USER: 1422 if (pkcs11_session_is_so(session)) 1423 return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN; 1424 1425 if (pkcs11_session_is_user(session)) 1426 return PKCS11_CKR_USER_ALREADY_LOGGED_IN; 1427 1428 /* 1429 * This is the point where we could check if another client 1430 * has another user or SO logged in. 1431 * See comment on CKR_USER_TOO_MANY_TYPES above. 1432 */ 1433 1434 rc = check_user_pin(session, pin, pin_size); 1435 if (!rc) 1436 session_login_user(session); 1437 1438 break; 1439 1440 case PKCS11_CKU_CONTEXT_SPECIFIC: 1441 return PKCS11_CKR_OPERATION_NOT_INITIALIZED; 1442 1443 default: 1444 return PKCS11_CKR_USER_TYPE_INVALID; 1445 } 1446 1447 if (!rc) 1448 IMSG("PKCS11 session %"PRIu32": login", session->handle); 1449 1450 return rc; 1451 } 1452 1453 enum pkcs11_rc entry_ck_logout(struct pkcs11_client *client, 1454 uint32_t ptypes, TEE_Param *params) 1455 { 1456 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1457 TEE_PARAM_TYPE_NONE, 1458 TEE_PARAM_TYPE_NONE, 1459 TEE_PARAM_TYPE_NONE); 1460 struct pkcs11_session *session = NULL; 1461 enum pkcs11_rc rc = PKCS11_CKR_OK; 1462 struct serialargs ctrlargs = { }; 1463 TEE_Param *ctrl = params; 1464 1465 if (!client || ptypes != exp_pt) 1466 return PKCS11_CKR_ARGUMENTS_BAD; 1467 1468 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1469 1470 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1471 if (rc) 1472 return rc; 1473 1474 if (serialargs_remaining_bytes(&ctrlargs)) 1475 return PKCS11_CKR_ARGUMENTS_BAD; 1476 1477 if (pkcs11_session_is_public(session)) 1478 return PKCS11_CKR_USER_NOT_LOGGED_IN; 1479 1480 session_logout(session); 1481 1482 IMSG("PKCS11 session %"PRIu32": logout", session->handle); 1483 1484 return PKCS11_CKR_OK; 1485 } 1486 1487 static TEE_Result seed_rng_pool(void *seed, size_t length) 1488 { 1489 static const TEE_UUID system_uuid = PTA_SYSTEM_UUID; 1490 uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 1491 TEE_PARAM_TYPE_NONE, 1492 TEE_PARAM_TYPE_NONE, 1493 TEE_PARAM_TYPE_NONE); 1494 TEE_Param params[TEE_NUM_PARAMS] = { }; 1495 TEE_TASessionHandle sess = TEE_HANDLE_NULL; 1496 TEE_Result res = TEE_ERROR_GENERIC; 1497 uint32_t ret_orig = 0; 1498 1499 params[0].memref.buffer = seed; 1500 params[0].memref.size = (uint32_t)length; 1501 1502 res = TEE_OpenTASession(&system_uuid, TEE_TIMEOUT_INFINITE, 0, NULL, 1503 &sess, &ret_orig); 1504 if (res != TEE_SUCCESS) { 1505 EMSG("Can't open session to system PTA"); 1506 return res; 1507 } 1508 1509 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE, 1510 PTA_SYSTEM_ADD_RNG_ENTROPY, 1511 param_types, params, &ret_orig); 1512 if (res != TEE_SUCCESS) 1513 EMSG("Can't invoke system PTA"); 1514 1515 TEE_CloseTASession(sess); 1516 return res; 1517 } 1518 1519 enum pkcs11_rc entry_ck_seed_random(struct pkcs11_client *client, 1520 uint32_t ptypes, TEE_Param *params) 1521 { 1522 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1523 TEE_PARAM_TYPE_MEMREF_INPUT, 1524 TEE_PARAM_TYPE_NONE, 1525 TEE_PARAM_TYPE_NONE); 1526 TEE_Param *ctrl = params; 1527 TEE_Param *in = params + 1; 1528 enum pkcs11_rc rc = PKCS11_CKR_OK; 1529 struct serialargs ctrlargs = { }; 1530 struct pkcs11_session *session = NULL; 1531 TEE_Result res = TEE_SUCCESS; 1532 1533 if (!client || ptypes != exp_pt) 1534 return PKCS11_CKR_ARGUMENTS_BAD; 1535 1536 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1537 1538 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1539 if (rc) 1540 return rc; 1541 1542 if (serialargs_remaining_bytes(&ctrlargs)) 1543 return PKCS11_CKR_ARGUMENTS_BAD; 1544 1545 if (in->memref.size && !in->memref.buffer) 1546 return PKCS11_CKR_ARGUMENTS_BAD; 1547 1548 if (!in->memref.size) 1549 return PKCS11_CKR_OK; 1550 1551 res = seed_rng_pool(in->memref.buffer, in->memref.size); 1552 if (res != TEE_SUCCESS) 1553 return PKCS11_CKR_FUNCTION_FAILED; 1554 1555 DMSG("PKCS11 session %"PRIu32": seed random", session->handle); 1556 1557 return PKCS11_CKR_OK; 1558 } 1559 1560 enum pkcs11_rc entry_ck_generate_random(struct pkcs11_client *client, 1561 uint32_t ptypes, TEE_Param *params) 1562 { 1563 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1564 TEE_PARAM_TYPE_NONE, 1565 TEE_PARAM_TYPE_MEMREF_OUTPUT, 1566 TEE_PARAM_TYPE_NONE); 1567 TEE_Param *ctrl = params; 1568 TEE_Param *out = params + 2; 1569 enum pkcs11_rc rc = PKCS11_CKR_OK; 1570 struct serialargs ctrlargs = { }; 1571 struct pkcs11_session *session = NULL; 1572 void *buffer = NULL; 1573 size_t buffer_size = 0; 1574 uint8_t *data = NULL; 1575 size_t left = 0; 1576 1577 if (!client || ptypes != exp_pt) 1578 return PKCS11_CKR_ARGUMENTS_BAD; 1579 1580 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1581 1582 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1583 if (rc) 1584 return rc; 1585 1586 if (serialargs_remaining_bytes(&ctrlargs)) 1587 return PKCS11_CKR_ARGUMENTS_BAD; 1588 1589 if (out->memref.size && !out->memref.buffer) 1590 return PKCS11_CKR_ARGUMENTS_BAD; 1591 1592 if (!out->memref.size) 1593 return PKCS11_CKR_OK; 1594 1595 buffer_size = MIN(out->memref.size, RNG_CHUNK_SIZE); 1596 buffer = TEE_Malloc(buffer_size, TEE_MALLOC_FILL_ZERO); 1597 if (!buffer) 1598 return PKCS11_CKR_DEVICE_MEMORY; 1599 1600 data = out->memref.buffer; 1601 left = out->memref.size; 1602 1603 while (left) { 1604 size_t count = MIN(left, buffer_size); 1605 1606 TEE_GenerateRandom(buffer, count); 1607 TEE_MemMove(data, buffer, count); 1608 1609 data += count; 1610 left -= count; 1611 } 1612 1613 DMSG("PKCS11 session %"PRIu32": generate random", session->handle); 1614 1615 TEE_Free(buffer); 1616 1617 return PKCS11_CKR_OK; 1618 } 1619