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 enum pkcs11_rc 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 = params + 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 enum pkcs11_rc 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 = params; 223 TEE_Param *out = params + 2; 224 enum pkcs11_rc rc = PKCS11_CKR_OK; 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 rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 246 if (rc) 247 return rc; 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 enum pkcs11_rc 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 = params; 272 TEE_Param *out = params + 2; 273 enum pkcs11_rc rc = PKCS11_CKR_OK; 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 .max_session_count = UINT32_MAX, 281 .max_rw_session_count = UINT32_MAX, 282 .max_pin_len = PKCS11_TOKEN_PIN_SIZE_MAX, 283 .min_pin_len = PKCS11_TOKEN_PIN_SIZE_MIN, 284 .total_public_memory = UINT32_MAX, 285 .free_public_memory = UINT32_MAX, 286 .total_private_memory = UINT32_MAX, 287 .free_private_memory = UINT32_MAX, 288 .hardware_version = PKCS11_TOKEN_HW_VERSION, 289 .firmware_version = PKCS11_TOKEN_FW_VERSION, 290 }; 291 char sn[sizeof(info.serial_number) + 1] = { 0 }; 292 int n = 0; 293 294 if (ptypes != exp_pt || out->memref.size != sizeof(info)) 295 return PKCS11_CKR_ARGUMENTS_BAD; 296 297 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 298 299 rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 300 if (rc) 301 return rc; 302 303 if (serialargs_remaining_bytes(&ctrlargs)) 304 return PKCS11_CKR_ARGUMENTS_BAD; 305 306 token = get_token(token_id); 307 if (!token) 308 return PKCS11_CKR_SLOT_ID_INVALID; 309 310 pad_str(info.manufacturer_id, sizeof(info.manufacturer_id)); 311 pad_str(info.model, sizeof(info.model)); 312 313 n = snprintf(sn, sizeof(sn), "%0*"PRIu32, 314 (int)sizeof(info.serial_number), token_id); 315 if (n != (int)sizeof(info.serial_number)) 316 TEE_Panic(0); 317 318 TEE_MemMove(info.serial_number, sn, sizeof(info.serial_number)); 319 pad_str(info.serial_number, sizeof(info.serial_number)); 320 321 TEE_MemMove(info.label, token->db_main->label, sizeof(info.label)); 322 323 info.flags = token->db_main->flags; 324 info.session_count = token->session_count; 325 info.rw_session_count = token->rw_session_count; 326 327 TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 328 329 return PKCS11_CKR_OK; 330 } 331 332 static void dmsg_print_supported_mechanism(unsigned int token_id __maybe_unused, 333 uint32_t *array __maybe_unused, 334 size_t count __maybe_unused) 335 { 336 size_t __maybe_unused n = 0; 337 338 if (TRACE_LEVEL < TRACE_DEBUG) 339 return; 340 341 for (n = 0; n < count; n++) 342 DMSG("PKCS11 token %"PRIu32": mechanism 0x%04"PRIx32": %s", 343 token_id, array[n], id2str_mechanism(array[n])); 344 } 345 346 enum pkcs11_rc entry_ck_token_mecha_ids(uint32_t ptypes, TEE_Param *params) 347 { 348 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 349 TEE_PARAM_TYPE_NONE, 350 TEE_PARAM_TYPE_MEMREF_OUTPUT, 351 TEE_PARAM_TYPE_NONE); 352 TEE_Param *ctrl = params; 353 TEE_Param *out = params + 2; 354 enum pkcs11_rc rc = PKCS11_CKR_OK; 355 struct serialargs ctrlargs = { }; 356 uint32_t token_id = 0; 357 struct ck_token __maybe_unused *token = NULL; 358 size_t count = 0; 359 uint32_t *array = NULL; 360 361 if (ptypes != exp_pt) 362 return PKCS11_CKR_ARGUMENTS_BAD; 363 364 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 365 366 rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 367 if (rc) 368 return rc; 369 370 if (serialargs_remaining_bytes(&ctrlargs)) 371 return PKCS11_CKR_ARGUMENTS_BAD; 372 373 token = get_token(token_id); 374 if (!token) 375 return PKCS11_CKR_SLOT_ID_INVALID; 376 377 count = out->memref.size / sizeof(*array); 378 array = tee_malloc_mechanism_list(&count); 379 380 if (out->memref.size < count * sizeof(*array)) { 381 assert(!array); 382 out->memref.size = count * sizeof(*array); 383 if (out->memref.buffer) 384 return PKCS11_CKR_BUFFER_TOO_SMALL; 385 else 386 return PKCS11_CKR_OK; 387 } 388 389 if (!array) 390 return PKCS11_CKR_DEVICE_MEMORY; 391 392 dmsg_print_supported_mechanism(token_id, array, count); 393 394 out->memref.size = count * sizeof(*array); 395 TEE_MemMove(out->memref.buffer, array, out->memref.size); 396 397 TEE_Free(array); 398 399 return rc; 400 } 401 402 static void supported_mechanism_key_size(uint32_t proc_id, 403 uint32_t *max_key_size, 404 uint32_t *min_key_size) 405 { 406 switch (proc_id) { 407 /* Will be filled once TA supports mechanisms */ 408 default: 409 *min_key_size = 0; 410 *max_key_size = 0; 411 break; 412 } 413 } 414 415 enum pkcs11_rc entry_ck_token_mecha_info(uint32_t ptypes, TEE_Param *params) 416 { 417 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 418 TEE_PARAM_TYPE_NONE, 419 TEE_PARAM_TYPE_MEMREF_OUTPUT, 420 TEE_PARAM_TYPE_NONE); 421 TEE_Param *ctrl = params; 422 TEE_Param *out = params + 2; 423 enum pkcs11_rc rc = PKCS11_CKR_OK; 424 struct serialargs ctrlargs = { }; 425 uint32_t token_id = 0; 426 uint32_t type = 0; 427 struct ck_token *token = NULL; 428 struct pkcs11_mechanism_info info = { }; 429 430 if (ptypes != exp_pt || out->memref.size != sizeof(info)) 431 return PKCS11_CKR_ARGUMENTS_BAD; 432 433 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 434 435 rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 436 if (rc) 437 return rc; 438 439 rc = serialargs_get(&ctrlargs, &type, sizeof(uint32_t)); 440 if (rc) 441 return rc; 442 443 if (serialargs_remaining_bytes(&ctrlargs)) 444 return PKCS11_CKR_ARGUMENTS_BAD; 445 446 token = get_token(token_id); 447 if (!token) 448 return PKCS11_CKR_SLOT_ID_INVALID; 449 450 if (!mechanism_is_valid(type)) 451 return PKCS11_CKR_MECHANISM_INVALID; 452 453 info.flags = mechanism_supported_flags(type); 454 455 supported_mechanism_key_size(type, &info.min_key_size, 456 &info.max_key_size); 457 458 TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 459 460 DMSG("PKCS11 token %"PRIu32": mechanism 0x%"PRIx32" info", 461 token_id, type); 462 463 return PKCS11_CKR_OK; 464 } 465 466 /* Select the ReadOnly or ReadWrite state for session login state */ 467 static void set_session_state(struct pkcs11_client *client, 468 struct pkcs11_session *session, bool readonly) 469 { 470 struct pkcs11_session *sess = NULL; 471 enum pkcs11_session_state state = PKCS11_CKS_RO_PUBLIC_SESSION; 472 473 /* Default to public session if no session already registered */ 474 if (readonly) 475 state = PKCS11_CKS_RO_PUBLIC_SESSION; 476 else 477 state = PKCS11_CKS_RW_PUBLIC_SESSION; 478 479 /* 480 * No need to check all client sessions, the first found in 481 * target token gives client login configuration. 482 */ 483 TAILQ_FOREACH(sess, &client->session_list, link) { 484 assert(sess != session); 485 486 if (sess->token == session->token) { 487 switch (sess->state) { 488 case PKCS11_CKS_RW_PUBLIC_SESSION: 489 case PKCS11_CKS_RO_PUBLIC_SESSION: 490 if (readonly) 491 state = PKCS11_CKS_RO_PUBLIC_SESSION; 492 else 493 state = PKCS11_CKS_RW_PUBLIC_SESSION; 494 break; 495 case PKCS11_CKS_RO_USER_FUNCTIONS: 496 case PKCS11_CKS_RW_USER_FUNCTIONS: 497 if (readonly) 498 state = PKCS11_CKS_RO_USER_FUNCTIONS; 499 else 500 state = PKCS11_CKS_RW_USER_FUNCTIONS; 501 break; 502 case PKCS11_CKS_RW_SO_FUNCTIONS: 503 if (readonly) 504 TEE_Panic(0); 505 else 506 state = PKCS11_CKS_RW_SO_FUNCTIONS; 507 break; 508 default: 509 TEE_Panic(0); 510 } 511 break; 512 } 513 } 514 515 session->state = state; 516 } 517 518 enum pkcs11_rc entry_ck_open_session(struct pkcs11_client *client, 519 uint32_t ptypes, TEE_Param *params) 520 { 521 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 522 TEE_PARAM_TYPE_NONE, 523 TEE_PARAM_TYPE_MEMREF_OUTPUT, 524 TEE_PARAM_TYPE_NONE); 525 TEE_Param *ctrl = params; 526 TEE_Param *out = params + 2; 527 enum pkcs11_rc rc = PKCS11_CKR_OK; 528 struct serialargs ctrlargs = { }; 529 uint32_t token_id = 0; 530 uint32_t flags = 0; 531 struct ck_token *token = NULL; 532 struct pkcs11_session *session = NULL; 533 bool readonly = false; 534 535 if (!client || ptypes != exp_pt || 536 out->memref.size != sizeof(session->handle)) 537 return PKCS11_CKR_ARGUMENTS_BAD; 538 539 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 540 541 rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 542 if (rc) 543 return rc; 544 545 rc = serialargs_get(&ctrlargs, &flags, sizeof(flags)); 546 if (rc) 547 return rc; 548 549 if (serialargs_remaining_bytes(&ctrlargs)) 550 return PKCS11_CKR_ARGUMENTS_BAD; 551 552 token = get_token(token_id); 553 if (!token) 554 return PKCS11_CKR_SLOT_ID_INVALID; 555 556 /* Sanitize session flags */ 557 if (!(flags & PKCS11_CKFSS_SERIAL_SESSION) || 558 (flags & ~(PKCS11_CKFSS_RW_SESSION | 559 PKCS11_CKFSS_SERIAL_SESSION))) 560 return PKCS11_CKR_ARGUMENTS_BAD; 561 562 readonly = !(flags & PKCS11_CKFSS_RW_SESSION); 563 564 if (!readonly && token->state == PKCS11_TOKEN_READ_ONLY) 565 return PKCS11_CKR_TOKEN_WRITE_PROTECTED; 566 567 if (readonly) { 568 /* Specifically reject read-only session under SO login */ 569 TAILQ_FOREACH(session, &client->session_list, link) 570 if (pkcs11_session_is_so(session)) 571 return PKCS11_CKR_SESSION_READ_WRITE_SO_EXISTS; 572 } 573 574 session = TEE_Malloc(sizeof(*session), TEE_MALLOC_FILL_ZERO); 575 if (!session) 576 return PKCS11_CKR_DEVICE_MEMORY; 577 578 session->handle = handle_get(&client->session_handle_db, session); 579 if (!session->handle) { 580 TEE_Free(session); 581 return PKCS11_CKR_DEVICE_MEMORY; 582 } 583 584 session->token = token; 585 session->client = client; 586 587 LIST_INIT(&session->object_list); 588 handle_db_init(&session->object_handle_db); 589 590 set_session_state(client, session, readonly); 591 592 TAILQ_INSERT_HEAD(&client->session_list, session, link); 593 594 session->token->session_count++; 595 if (!readonly) 596 session->token->rw_session_count++; 597 598 TEE_MemMove(out->memref.buffer, &session->handle, 599 sizeof(session->handle)); 600 601 DMSG("Open PKCS11 session %"PRIu32, session->handle); 602 603 return PKCS11_CKR_OK; 604 } 605 606 static void close_ck_session(struct pkcs11_session *session) 607 { 608 /* No need to put object handles, the whole database is destroyed */ 609 while (!LIST_EMPTY(&session->object_list)) 610 destroy_object(session, 611 LIST_FIRST(&session->object_list), true); 612 613 TAILQ_REMOVE(&session->client->session_list, session, link); 614 handle_put(&session->client->session_handle_db, session->handle); 615 handle_db_destroy(&session->object_handle_db); 616 617 session->token->session_count--; 618 if (pkcs11_session_is_read_write(session)) 619 session->token->rw_session_count--; 620 621 TEE_Free(session); 622 623 DMSG("Close PKCS11 session %"PRIu32, session->handle); 624 } 625 626 enum pkcs11_rc entry_ck_close_session(struct pkcs11_client *client, 627 uint32_t ptypes, TEE_Param *params) 628 { 629 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 630 TEE_PARAM_TYPE_NONE, 631 TEE_PARAM_TYPE_NONE, 632 TEE_PARAM_TYPE_NONE); 633 TEE_Param *ctrl = params; 634 enum pkcs11_rc rc = PKCS11_CKR_OK; 635 struct serialargs ctrlargs = { }; 636 struct pkcs11_session *session = NULL; 637 638 if (!client || ptypes != exp_pt) 639 return PKCS11_CKR_ARGUMENTS_BAD; 640 641 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 642 643 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 644 if (rc) 645 return rc; 646 647 if (serialargs_remaining_bytes(&ctrlargs)) 648 return PKCS11_CKR_ARGUMENTS_BAD; 649 650 close_ck_session(session); 651 652 return PKCS11_CKR_OK; 653 } 654 655 enum pkcs11_rc entry_ck_close_all_sessions(struct pkcs11_client *client, 656 uint32_t ptypes, TEE_Param *params) 657 { 658 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 659 TEE_PARAM_TYPE_NONE, 660 TEE_PARAM_TYPE_NONE, 661 TEE_PARAM_TYPE_NONE); 662 TEE_Param *ctrl = params; 663 enum pkcs11_rc rc = PKCS11_CKR_OK; 664 struct serialargs ctrlargs = { }; 665 uint32_t token_id = 0; 666 struct ck_token *token = NULL; 667 struct pkcs11_session *session = NULL; 668 struct pkcs11_session *next = NULL; 669 670 if (!client || ptypes != exp_pt) 671 return PKCS11_CKR_ARGUMENTS_BAD; 672 673 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 674 675 rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 676 if (rc) 677 return rc; 678 679 if (serialargs_remaining_bytes(&ctrlargs)) 680 return PKCS11_CKR_ARGUMENTS_BAD; 681 682 token = get_token(token_id); 683 if (!token) 684 return PKCS11_CKR_SLOT_ID_INVALID; 685 686 DMSG("Close all sessions for PKCS11 token %"PRIu32, token_id); 687 688 TAILQ_FOREACH_SAFE(session, &client->session_list, link, next) 689 if (session->token == token) 690 close_ck_session(session); 691 692 return PKCS11_CKR_OK; 693 } 694 695 enum pkcs11_rc entry_ck_session_info(struct pkcs11_client *client, 696 uint32_t ptypes, TEE_Param *params) 697 { 698 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 699 TEE_PARAM_TYPE_NONE, 700 TEE_PARAM_TYPE_MEMREF_OUTPUT, 701 TEE_PARAM_TYPE_NONE); 702 TEE_Param *ctrl = params; 703 TEE_Param *out = params + 2; 704 enum pkcs11_rc rc = PKCS11_CKR_OK; 705 struct serialargs ctrlargs = { }; 706 struct pkcs11_session *session = NULL; 707 struct pkcs11_session_info info = { 708 .flags = PKCS11_CKFSS_SERIAL_SESSION, 709 }; 710 711 if (!client || ptypes != exp_pt || out->memref.size != sizeof(info)) 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 info.slot_id = get_token_id(session->token); 724 info.state = session->state; 725 if (pkcs11_session_is_read_write(session)) 726 info.flags |= PKCS11_CKFSS_RW_SESSION; 727 728 TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 729 730 DMSG("Get find on PKCS11 session %"PRIu32, session->handle); 731 732 return PKCS11_CKR_OK; 733 } 734 735 enum pkcs11_rc entry_ck_token_initialize(uint32_t ptypes, TEE_Param *params) 736 { 737 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 738 TEE_PARAM_TYPE_NONE, 739 TEE_PARAM_TYPE_NONE, 740 TEE_PARAM_TYPE_NONE); 741 char label[PKCS11_TOKEN_LABEL_SIZE] = { 0 }; 742 struct pkcs11_client *client = NULL; 743 struct pkcs11_session *sess = NULL; 744 enum pkcs11_rc rc = PKCS11_CKR_OK; 745 struct serialargs ctrlargs = { }; 746 struct ck_token *token = NULL; 747 TEE_Param *ctrl = params; 748 uint32_t token_id = 0; 749 uint32_t pin_size = 0; 750 void *pin = NULL; 751 752 if (ptypes != exp_pt) 753 return PKCS11_CKR_ARGUMENTS_BAD; 754 755 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 756 757 rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 758 if (rc) 759 return rc; 760 761 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 762 if (rc) 763 return rc; 764 765 rc = serialargs_get(&ctrlargs, &label, PKCS11_TOKEN_LABEL_SIZE); 766 if (rc) 767 return rc; 768 769 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 770 if (rc) 771 return rc; 772 773 if (serialargs_remaining_bytes(&ctrlargs)) 774 return PKCS11_CKR_ARGUMENTS_BAD; 775 776 token = get_token(token_id); 777 if (!token) 778 return PKCS11_CKR_SLOT_ID_INVALID; 779 780 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) { 781 IMSG("Token %"PRIu32": SO PIN locked", token_id); 782 return PKCS11_CKR_PIN_LOCKED; 783 } 784 785 /* Check there's no open session on this token */ 786 TAILQ_FOREACH(client, &pkcs11_client_list, link) 787 TAILQ_FOREACH(sess, &client->session_list, link) 788 if (sess->token == token) 789 return PKCS11_CKR_SESSION_EXISTS; 790 791 if (!token->db_main->so_pin_salt) { 792 /* 793 * The spec doesn't permit returning 794 * PKCS11_CKR_PIN_LEN_RANGE for this function, take another 795 * error code. 796 */ 797 if (pin_size < PKCS11_TOKEN_PIN_SIZE_MIN || 798 pin_size > PKCS11_TOKEN_PIN_SIZE_MAX) 799 return PKCS11_CKR_ARGUMENTS_BAD; 800 801 rc = hash_pin(PKCS11_CKU_SO, pin, pin_size, 802 &token->db_main->so_pin_salt, 803 token->db_main->so_pin_hash); 804 if (rc) 805 return rc; 806 807 update_persistent_db(token); 808 809 goto inited; 810 } 811 812 rc = verify_pin(PKCS11_CKU_SO, pin, pin_size, 813 token->db_main->so_pin_salt, 814 token->db_main->so_pin_hash); 815 if (rc) { 816 unsigned int pin_count = 0; 817 818 if (rc != PKCS11_CKR_PIN_INCORRECT) 819 return rc; 820 821 token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW; 822 token->db_main->so_pin_count++; 823 824 pin_count = token->db_main->so_pin_count; 825 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1) 826 token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY; 827 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX) 828 token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED; 829 830 update_persistent_db(token); 831 832 return PKCS11_CKR_PIN_INCORRECT; 833 } 834 835 token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW | 836 PKCS11_CKFT_SO_PIN_FINAL_TRY); 837 token->db_main->so_pin_count = 0; 838 839 inited: 840 TEE_MemMove(token->db_main->label, label, PKCS11_TOKEN_LABEL_SIZE); 841 token->db_main->flags |= PKCS11_CKFT_TOKEN_INITIALIZED; 842 /* Reset user PIN */ 843 token->db_main->user_pin_salt = 0; 844 token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_INITIALIZED | 845 PKCS11_CKFT_USER_PIN_COUNT_LOW | 846 PKCS11_CKFT_USER_PIN_FINAL_TRY | 847 PKCS11_CKFT_USER_PIN_LOCKED | 848 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED); 849 850 update_persistent_db(token); 851 852 IMSG("PKCS11 token %"PRIu32": initialized", token_id); 853 854 return PKCS11_CKR_OK; 855 } 856 857 static enum pkcs11_rc set_pin(struct pkcs11_session *session, 858 uint8_t *new_pin, size_t new_pin_size, 859 enum pkcs11_user_type user_type) 860 { 861 enum pkcs11_rc rc = PKCS11_CKR_OK; 862 uint32_t flags_clear = 0; 863 uint32_t flags_set = 0; 864 865 if (session->token->db_main->flags & PKCS11_CKFT_WRITE_PROTECTED) 866 return PKCS11_CKR_TOKEN_WRITE_PROTECTED; 867 868 if (!pkcs11_session_is_read_write(session)) 869 return PKCS11_CKR_SESSION_READ_ONLY; 870 871 if (new_pin_size < PKCS11_TOKEN_PIN_SIZE_MIN || 872 new_pin_size > PKCS11_TOKEN_PIN_SIZE_MAX) 873 return PKCS11_CKR_PIN_LEN_RANGE; 874 875 switch (user_type) { 876 case PKCS11_CKU_SO: 877 rc = hash_pin(user_type, new_pin, new_pin_size, 878 &session->token->db_main->so_pin_salt, 879 session->token->db_main->so_pin_hash); 880 if (rc) 881 return rc; 882 session->token->db_main->so_pin_count = 0; 883 flags_clear = PKCS11_CKFT_SO_PIN_COUNT_LOW | 884 PKCS11_CKFT_SO_PIN_FINAL_TRY | 885 PKCS11_CKFT_SO_PIN_LOCKED | 886 PKCS11_CKFT_SO_PIN_TO_BE_CHANGED; 887 break; 888 case PKCS11_CKU_USER: 889 rc = hash_pin(user_type, new_pin, new_pin_size, 890 &session->token->db_main->user_pin_salt, 891 session->token->db_main->user_pin_hash); 892 if (rc) 893 return rc; 894 session->token->db_main->user_pin_count = 0; 895 flags_clear = PKCS11_CKFT_USER_PIN_COUNT_LOW | 896 PKCS11_CKFT_USER_PIN_FINAL_TRY | 897 PKCS11_CKFT_USER_PIN_LOCKED | 898 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED; 899 flags_set = PKCS11_CKFT_USER_PIN_INITIALIZED; 900 break; 901 default: 902 return PKCS11_CKR_FUNCTION_FAILED; 903 } 904 905 session->token->db_main->flags &= ~flags_clear; 906 session->token->db_main->flags |= flags_set; 907 908 update_persistent_db(session->token); 909 910 return PKCS11_CKR_OK; 911 } 912 913 enum pkcs11_rc entry_ck_init_pin(struct pkcs11_client *client, 914 uint32_t ptypes, TEE_Param *params) 915 { 916 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 917 TEE_PARAM_TYPE_NONE, 918 TEE_PARAM_TYPE_NONE, 919 TEE_PARAM_TYPE_NONE); 920 struct pkcs11_session *session = NULL; 921 enum pkcs11_rc rc = PKCS11_CKR_OK; 922 struct serialargs ctrlargs = { }; 923 TEE_Param *ctrl = params; 924 uint32_t pin_size = 0; 925 void *pin = NULL; 926 927 if (!client || ptypes != exp_pt) 928 return PKCS11_CKR_ARGUMENTS_BAD; 929 930 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 931 932 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 933 if (rc) 934 return rc; 935 936 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 937 if (rc) 938 return rc; 939 940 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 941 if (rc) 942 return rc; 943 944 if (serialargs_remaining_bytes(&ctrlargs)) 945 return PKCS11_CKR_ARGUMENTS_BAD; 946 947 if (!pkcs11_session_is_so(session)) 948 return PKCS11_CKR_USER_NOT_LOGGED_IN; 949 950 assert(session->token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED); 951 952 IMSG("PKCS11 session %"PRIu32": init PIN", session->handle); 953 954 return set_pin(session, pin, pin_size, PKCS11_CKU_USER); 955 } 956 957 static enum pkcs11_rc check_so_pin(struct pkcs11_session *session, 958 uint8_t *pin, size_t pin_size) 959 { 960 struct ck_token *token = session->token; 961 enum pkcs11_rc rc = PKCS11_CKR_OK; 962 963 assert(token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED); 964 965 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) 966 return PKCS11_CKR_PIN_LOCKED; 967 968 rc = verify_pin(PKCS11_CKU_SO, pin, pin_size, 969 token->db_main->so_pin_salt, 970 token->db_main->so_pin_hash); 971 if (rc) { 972 unsigned int pin_count = 0; 973 974 if (rc != PKCS11_CKR_PIN_INCORRECT) 975 return rc; 976 977 token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW; 978 token->db_main->so_pin_count++; 979 980 pin_count = token->db_main->so_pin_count; 981 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1) 982 token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY; 983 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX) 984 token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED; 985 986 update_persistent_db(token); 987 988 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) 989 return PKCS11_CKR_PIN_LOCKED; 990 991 return PKCS11_CKR_PIN_INCORRECT; 992 } 993 994 if (token->db_main->so_pin_count) { 995 token->db_main->so_pin_count = 0; 996 997 update_persistent_db(token); 998 } 999 1000 if (token->db_main->flags & (PKCS11_CKFT_SO_PIN_COUNT_LOW | 1001 PKCS11_CKFT_SO_PIN_FINAL_TRY)) { 1002 token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW | 1003 PKCS11_CKFT_SO_PIN_FINAL_TRY); 1004 1005 update_persistent_db(token); 1006 } 1007 1008 return PKCS11_CKR_OK; 1009 } 1010 1011 static enum pkcs11_rc check_user_pin(struct pkcs11_session *session, 1012 uint8_t *pin, size_t pin_size) 1013 { 1014 struct ck_token *token = session->token; 1015 enum pkcs11_rc rc = PKCS11_CKR_OK; 1016 1017 if (!token->db_main->user_pin_salt) 1018 return PKCS11_CKR_USER_PIN_NOT_INITIALIZED; 1019 1020 if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED) 1021 return PKCS11_CKR_PIN_LOCKED; 1022 1023 rc = verify_pin(PKCS11_CKU_USER, pin, pin_size, 1024 token->db_main->user_pin_salt, 1025 token->db_main->user_pin_hash); 1026 if (rc) { 1027 unsigned int pin_count = 0; 1028 1029 if (rc != PKCS11_CKR_PIN_INCORRECT) 1030 return rc; 1031 1032 token->db_main->flags |= PKCS11_CKFT_USER_PIN_COUNT_LOW; 1033 token->db_main->user_pin_count++; 1034 1035 pin_count = token->db_main->user_pin_count; 1036 if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX - 1) 1037 token->db_main->flags |= PKCS11_CKFT_USER_PIN_FINAL_TRY; 1038 if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX) 1039 token->db_main->flags |= PKCS11_CKFT_USER_PIN_LOCKED; 1040 1041 update_persistent_db(token); 1042 1043 if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED) 1044 return PKCS11_CKR_PIN_LOCKED; 1045 1046 return PKCS11_CKR_PIN_INCORRECT; 1047 } 1048 1049 if (token->db_main->user_pin_count) { 1050 token->db_main->user_pin_count = 0; 1051 1052 update_persistent_db(token); 1053 } 1054 1055 if (token->db_main->flags & (PKCS11_CKFT_USER_PIN_COUNT_LOW | 1056 PKCS11_CKFT_USER_PIN_FINAL_TRY)) { 1057 token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_COUNT_LOW | 1058 PKCS11_CKFT_USER_PIN_FINAL_TRY); 1059 1060 update_persistent_db(token); 1061 } 1062 1063 return PKCS11_CKR_OK; 1064 } 1065 1066 enum pkcs11_rc entry_ck_set_pin(struct pkcs11_client *client, 1067 uint32_t ptypes, TEE_Param *params) 1068 { 1069 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1070 TEE_PARAM_TYPE_NONE, 1071 TEE_PARAM_TYPE_NONE, 1072 TEE_PARAM_TYPE_NONE); 1073 struct pkcs11_session *session = NULL; 1074 enum pkcs11_rc rc = PKCS11_CKR_OK; 1075 struct serialargs ctrlargs = { }; 1076 uint32_t old_pin_size = 0; 1077 TEE_Param *ctrl = params; 1078 uint32_t pin_size = 0; 1079 void *old_pin = NULL; 1080 void *pin = NULL; 1081 1082 if (!client || ptypes != exp_pt) 1083 return PKCS11_CKR_ARGUMENTS_BAD; 1084 1085 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1086 1087 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1088 if (rc) 1089 return rc; 1090 1091 rc = serialargs_get(&ctrlargs, &old_pin_size, sizeof(uint32_t)); 1092 if (rc) 1093 return rc; 1094 1095 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 1096 if (rc) 1097 return rc; 1098 1099 rc = serialargs_get_ptr(&ctrlargs, &old_pin, old_pin_size); 1100 if (rc) 1101 return rc; 1102 1103 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 1104 if (rc) 1105 return rc; 1106 1107 if (serialargs_remaining_bytes(&ctrlargs)) 1108 return PKCS11_CKR_ARGUMENTS_BAD; 1109 1110 if (!pkcs11_session_is_read_write(session)) 1111 return PKCS11_CKR_SESSION_READ_ONLY; 1112 1113 if (pkcs11_session_is_so(session)) { 1114 if (!(session->token->db_main->flags & 1115 PKCS11_CKFT_TOKEN_INITIALIZED)) 1116 return PKCS11_CKR_GENERAL_ERROR; 1117 1118 rc = check_so_pin(session, old_pin, old_pin_size); 1119 if (rc) 1120 return rc; 1121 1122 IMSG("PKCS11 session %"PRIu32": set PIN", session->handle); 1123 1124 return set_pin(session, pin, pin_size, PKCS11_CKU_SO); 1125 } 1126 1127 if (!(session->token->db_main->flags & 1128 PKCS11_CKFT_USER_PIN_INITIALIZED)) 1129 return PKCS11_CKR_GENERAL_ERROR; 1130 1131 rc = check_user_pin(session, old_pin, old_pin_size); 1132 if (rc) 1133 return rc; 1134 1135 IMSG("PKCS11 session %"PRIu32": set PIN", session->handle); 1136 1137 return set_pin(session, pin, pin_size, PKCS11_CKU_USER); 1138 } 1139 1140 static void session_login_user(struct pkcs11_session *session) 1141 { 1142 struct pkcs11_client *client = session->client; 1143 struct pkcs11_session *sess = NULL; 1144 1145 TAILQ_FOREACH(sess, &client->session_list, link) { 1146 if (sess->token != session->token) 1147 continue; 1148 1149 if (pkcs11_session_is_read_write(sess)) 1150 sess->state = PKCS11_CKS_RW_USER_FUNCTIONS; 1151 else 1152 sess->state = PKCS11_CKS_RO_USER_FUNCTIONS; 1153 } 1154 } 1155 1156 static void session_login_so(struct pkcs11_session *session) 1157 { 1158 struct pkcs11_client *client = session->client; 1159 struct pkcs11_session *sess = NULL; 1160 1161 TAILQ_FOREACH(sess, &client->session_list, link) { 1162 if (sess->token != session->token) 1163 continue; 1164 1165 if (pkcs11_session_is_read_write(sess)) 1166 sess->state = PKCS11_CKS_RW_SO_FUNCTIONS; 1167 else 1168 TEE_Panic(0); 1169 } 1170 } 1171 1172 static void session_logout(struct pkcs11_session *session) 1173 { 1174 struct pkcs11_client *client = session->client; 1175 struct pkcs11_session *sess = NULL; 1176 1177 TAILQ_FOREACH(sess, &client->session_list, link) { 1178 if (sess->token != session->token) 1179 continue; 1180 1181 if (pkcs11_session_is_read_write(sess)) 1182 sess->state = PKCS11_CKS_RW_PUBLIC_SESSION; 1183 else 1184 sess->state = PKCS11_CKS_RO_PUBLIC_SESSION; 1185 } 1186 } 1187 1188 enum pkcs11_rc entry_ck_login(struct pkcs11_client *client, 1189 uint32_t ptypes, TEE_Param *params) 1190 { 1191 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1192 TEE_PARAM_TYPE_NONE, 1193 TEE_PARAM_TYPE_NONE, 1194 TEE_PARAM_TYPE_NONE); 1195 struct pkcs11_session *session = NULL; 1196 struct pkcs11_session *sess = NULL; 1197 enum pkcs11_rc rc = PKCS11_CKR_OK; 1198 struct serialargs ctrlargs = { }; 1199 TEE_Param *ctrl = params; 1200 uint32_t user_type = 0; 1201 uint32_t pin_size = 0; 1202 void *pin = NULL; 1203 1204 if (!client || ptypes != exp_pt) 1205 return PKCS11_CKR_ARGUMENTS_BAD; 1206 1207 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1208 1209 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1210 if (rc) 1211 return rc; 1212 1213 rc = serialargs_get(&ctrlargs, &user_type, sizeof(uint32_t)); 1214 if (rc) 1215 return rc; 1216 1217 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 1218 if (rc) 1219 return rc; 1220 1221 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 1222 if (rc) 1223 return rc; 1224 1225 if (serialargs_remaining_bytes(&ctrlargs)) 1226 return PKCS11_CKR_ARGUMENTS_BAD; 1227 1228 switch (user_type) { 1229 case PKCS11_CKU_SO: 1230 if (pkcs11_session_is_so(session)) 1231 return PKCS11_CKR_USER_ALREADY_LOGGED_IN; 1232 1233 if (pkcs11_session_is_user(session)) 1234 return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN; 1235 1236 TAILQ_FOREACH(sess, &client->session_list, link) 1237 if (sess->token == session->token && 1238 !pkcs11_session_is_read_write(sess)) 1239 return PKCS11_CKR_SESSION_READ_ONLY_EXISTS; 1240 1241 /* 1242 * This is the point where we could check if another client 1243 * has another user or SO logged in. 1244 * 1245 * The spec says: 1246 * CKR_USER_TOO_MANY_TYPES: An attempt was made to have 1247 * more distinct users simultaneously logged into the token 1248 * than the token and/or library permits. For example, if 1249 * some application has an open SO session, and another 1250 * application attempts to log the normal user into a 1251 * session, the attempt may return this error. It is not 1252 * required to, however. Only if the simultaneous distinct 1253 * users cannot be supported does C_Login have to return 1254 * this value. Note that this error code generalizes to 1255 * true multi-user tokens. 1256 * 1257 * So it's permitted to have another user or SO logged in 1258 * from another client. 1259 */ 1260 1261 rc = check_so_pin(session, pin, pin_size); 1262 if (!rc) 1263 session_login_so(session); 1264 1265 break; 1266 1267 case PKCS11_CKU_USER: 1268 if (pkcs11_session_is_so(session)) 1269 return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN; 1270 1271 if (pkcs11_session_is_user(session)) 1272 return PKCS11_CKR_USER_ALREADY_LOGGED_IN; 1273 1274 /* 1275 * This is the point where we could check if another client 1276 * has another user or SO logged in. 1277 * See comment on CKR_USER_TOO_MANY_TYPES above. 1278 */ 1279 1280 rc = check_user_pin(session, pin, pin_size); 1281 if (!rc) 1282 session_login_user(session); 1283 1284 break; 1285 1286 case PKCS11_CKU_CONTEXT_SPECIFIC: 1287 return PKCS11_CKR_OPERATION_NOT_INITIALIZED; 1288 1289 default: 1290 return PKCS11_CKR_USER_TYPE_INVALID; 1291 } 1292 1293 if (!rc) 1294 IMSG("PKCS11 session %"PRIu32": login", session->handle); 1295 1296 return rc; 1297 } 1298 1299 enum pkcs11_rc entry_ck_logout(struct pkcs11_client *client, 1300 uint32_t ptypes, TEE_Param *params) 1301 { 1302 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1303 TEE_PARAM_TYPE_NONE, 1304 TEE_PARAM_TYPE_NONE, 1305 TEE_PARAM_TYPE_NONE); 1306 struct pkcs11_session *session = NULL; 1307 enum pkcs11_rc rc = PKCS11_CKR_OK; 1308 struct serialargs ctrlargs = { }; 1309 TEE_Param *ctrl = params; 1310 1311 if (!client || ptypes != exp_pt) 1312 return PKCS11_CKR_ARGUMENTS_BAD; 1313 1314 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1315 1316 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1317 if (rc) 1318 return rc; 1319 1320 if (serialargs_remaining_bytes(&ctrlargs)) 1321 return PKCS11_CKR_ARGUMENTS_BAD; 1322 1323 if (pkcs11_session_is_public(session)) 1324 return PKCS11_CKR_USER_NOT_LOGGED_IN; 1325 1326 session_logout(session); 1327 1328 IMSG("PKCS11 session %"PRIu32": logout", session->handle); 1329 1330 return PKCS11_CKR_OK; 1331 } 1332