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