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