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 .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 rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 300 if (rv) 301 return rv; 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 uint32_t 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 = ¶ms[0]; 353 TEE_Param *out = ¶ms[2]; 354 uint32_t rv = 0; 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 rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 367 if (rv) 368 return rv; 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 rv; 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 uint32_t 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 = ¶ms[0]; 422 TEE_Param *out = ¶ms[2]; 423 uint32_t rv = 0; 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 rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 436 if (rv) 437 return rv; 438 439 rv = serialargs_get(&ctrlargs, &type, sizeof(uint32_t)); 440 if (rv) 441 return rv; 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 uint32_t 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 = ¶ms[0]; 526 TEE_Param *out = ¶ms[2]; 527 uint32_t rv = 0; 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 rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 542 if (rv) 543 return rv; 544 545 rv = serialargs_get(&ctrlargs, &flags, sizeof(flags)); 546 if (rv) 547 return rv; 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 set_session_state(client, session, readonly); 588 589 TAILQ_INSERT_HEAD(&client->session_list, session, link); 590 591 session->token->session_count++; 592 if (!readonly) 593 session->token->rw_session_count++; 594 595 TEE_MemMove(out->memref.buffer, &session->handle, 596 sizeof(session->handle)); 597 598 DMSG("Open PKCS11 session %"PRIu32, session->handle); 599 600 return PKCS11_CKR_OK; 601 } 602 603 static void close_ck_session(struct pkcs11_session *session) 604 { 605 TAILQ_REMOVE(&session->client->session_list, session, link); 606 handle_put(&session->client->session_handle_db, session->handle); 607 608 session->token->session_count--; 609 if (pkcs11_session_is_read_write(session)) 610 session->token->rw_session_count--; 611 612 TEE_Free(session); 613 614 DMSG("Close PKCS11 session %"PRIu32, session->handle); 615 } 616 617 uint32_t entry_ck_close_session(struct pkcs11_client *client, 618 uint32_t ptypes, TEE_Param *params) 619 { 620 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 621 TEE_PARAM_TYPE_NONE, 622 TEE_PARAM_TYPE_NONE, 623 TEE_PARAM_TYPE_NONE); 624 TEE_Param *ctrl = ¶ms[0]; 625 uint32_t rv = 0; 626 struct serialargs ctrlargs = { }; 627 uint32_t session_handle = 0; 628 struct pkcs11_session *session = NULL; 629 630 if (!client || ptypes != exp_pt) 631 return PKCS11_CKR_ARGUMENTS_BAD; 632 633 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 634 635 rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t)); 636 if (rv) 637 return rv; 638 639 if (serialargs_remaining_bytes(&ctrlargs)) 640 return PKCS11_CKR_ARGUMENTS_BAD; 641 642 session = pkcs11_handle2session(session_handle, client); 643 if (!session) 644 return PKCS11_CKR_SESSION_HANDLE_INVALID; 645 646 close_ck_session(session); 647 648 return PKCS11_CKR_OK; 649 } 650 651 uint32_t entry_ck_close_all_sessions(struct pkcs11_client *client, 652 uint32_t ptypes, TEE_Param *params) 653 { 654 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 655 TEE_PARAM_TYPE_NONE, 656 TEE_PARAM_TYPE_NONE, 657 TEE_PARAM_TYPE_NONE); 658 TEE_Param *ctrl = ¶ms[0]; 659 uint32_t rv = 0; 660 struct serialargs ctrlargs = { }; 661 uint32_t token_id = 0; 662 struct ck_token *token = NULL; 663 struct pkcs11_session *session = NULL; 664 struct pkcs11_session *next = NULL; 665 666 if (!client || ptypes != exp_pt) 667 return PKCS11_CKR_ARGUMENTS_BAD; 668 669 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 670 671 rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 672 if (rv) 673 return rv; 674 675 if (serialargs_remaining_bytes(&ctrlargs)) 676 return PKCS11_CKR_ARGUMENTS_BAD; 677 678 token = get_token(token_id); 679 if (!token) 680 return PKCS11_CKR_SLOT_ID_INVALID; 681 682 DMSG("Close all sessions for PKCS11 token %"PRIu32, token_id); 683 684 TAILQ_FOREACH_SAFE(session, &client->session_list, link, next) 685 if (session->token == token) 686 close_ck_session(session); 687 688 return PKCS11_CKR_OK; 689 } 690 691 uint32_t entry_ck_session_info(struct pkcs11_client *client, 692 uint32_t ptypes, TEE_Param *params) 693 { 694 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 695 TEE_PARAM_TYPE_NONE, 696 TEE_PARAM_TYPE_MEMREF_OUTPUT, 697 TEE_PARAM_TYPE_NONE); 698 TEE_Param *ctrl = ¶ms[0]; 699 TEE_Param *out = ¶ms[2]; 700 uint32_t rv = 0; 701 struct serialargs ctrlargs = { }; 702 uint32_t session_handle = 0; 703 struct pkcs11_session *session = NULL; 704 struct pkcs11_session_info info = { 705 .flags = PKCS11_CKFSS_SERIAL_SESSION, 706 }; 707 708 if (!client || ptypes != exp_pt || out->memref.size != sizeof(info)) 709 return PKCS11_CKR_ARGUMENTS_BAD; 710 711 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 712 713 rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t)); 714 if (rv) 715 return rv; 716 717 if (serialargs_remaining_bytes(&ctrlargs)) 718 return PKCS11_CKR_ARGUMENTS_BAD; 719 720 session = pkcs11_handle2session(session_handle, client); 721 if (!session) 722 return PKCS11_CKR_SESSION_HANDLE_INVALID; 723 724 info.slot_id = get_token_id(session->token); 725 info.state = session->state; 726 if (pkcs11_session_is_read_write(session)) 727 info.flags |= PKCS11_CKFSS_RW_SESSION; 728 729 TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 730 731 DMSG("Get find on PKCS11 session %"PRIu32, session->handle); 732 733 return PKCS11_CKR_OK; 734 } 735 736 uint32_t entry_ck_token_initialize(uint32_t ptypes, TEE_Param *params) 737 { 738 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 739 TEE_PARAM_TYPE_NONE, 740 TEE_PARAM_TYPE_NONE, 741 TEE_PARAM_TYPE_NONE); 742 char label[PKCS11_TOKEN_LABEL_SIZE] = { 0 }; 743 struct pkcs11_client *client = NULL; 744 struct pkcs11_session *sess = NULL; 745 enum pkcs11_rc rc = PKCS11_CKR_OK; 746 struct serialargs ctrlargs = { }; 747 struct ck_token *token = NULL; 748 TEE_Param *ctrl = params; 749 uint32_t token_id = 0; 750 uint32_t pin_size = 0; 751 void *pin = NULL; 752 753 if (ptypes != exp_pt) 754 return PKCS11_CKR_ARGUMENTS_BAD; 755 756 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 757 758 rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 759 if (rc) 760 return rc; 761 762 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 763 if (rc) 764 return rc; 765 766 rc = serialargs_get(&ctrlargs, &label, PKCS11_TOKEN_LABEL_SIZE); 767 if (rc) 768 return rc; 769 770 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 771 if (rc) 772 return rc; 773 774 if (serialargs_remaining_bytes(&ctrlargs)) 775 return PKCS11_CKR_ARGUMENTS_BAD; 776 777 token = get_token(token_id); 778 if (!token) 779 return PKCS11_CKR_SLOT_ID_INVALID; 780 781 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) { 782 IMSG("Token %"PRIu32": SO PIN locked", token_id); 783 return PKCS11_CKR_PIN_LOCKED; 784 } 785 786 /* Check there's no open session on this token */ 787 TAILQ_FOREACH(client, &pkcs11_client_list, link) 788 TAILQ_FOREACH(sess, &client->session_list, link) 789 if (sess->token == token) 790 return PKCS11_CKR_SESSION_EXISTS; 791 792 if (!token->db_main->so_pin_salt) { 793 /* 794 * The spec doesn't permit returning 795 * PKCS11_CKR_PIN_LEN_RANGE for this function, take another 796 * error code. 797 */ 798 if (pin_size < PKCS11_TOKEN_PIN_SIZE_MIN || 799 pin_size > PKCS11_TOKEN_PIN_SIZE_MAX) 800 return PKCS11_CKR_ARGUMENTS_BAD; 801 802 rc = hash_pin(PKCS11_CKU_SO, pin, pin_size, 803 &token->db_main->so_pin_salt, 804 token->db_main->so_pin_hash); 805 if (rc) 806 return rc; 807 808 update_persistent_db(token); 809 810 goto inited; 811 } 812 813 rc = verify_pin(PKCS11_CKU_SO, pin, pin_size, 814 token->db_main->so_pin_salt, 815 token->db_main->so_pin_hash); 816 if (rc) { 817 unsigned int pin_count = 0; 818 819 if (rc != PKCS11_CKR_PIN_INCORRECT) 820 return rc; 821 822 token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW; 823 token->db_main->so_pin_count++; 824 825 pin_count = token->db_main->so_pin_count; 826 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1) 827 token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY; 828 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX) 829 token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED; 830 831 update_persistent_db(token); 832 833 return PKCS11_CKR_PIN_INCORRECT; 834 } 835 836 token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW | 837 PKCS11_CKFT_SO_PIN_FINAL_TRY); 838 token->db_main->so_pin_count = 0; 839 840 inited: 841 TEE_MemMove(token->db_main->label, label, PKCS11_TOKEN_LABEL_SIZE); 842 token->db_main->flags |= PKCS11_CKFT_TOKEN_INITIALIZED; 843 /* Reset user PIN */ 844 token->db_main->user_pin_salt = 0; 845 token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_INITIALIZED | 846 PKCS11_CKFT_USER_PIN_COUNT_LOW | 847 PKCS11_CKFT_USER_PIN_FINAL_TRY | 848 PKCS11_CKFT_USER_PIN_LOCKED | 849 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED); 850 851 update_persistent_db(token); 852 853 IMSG("PKCS11 token %"PRIu32": initialized", token_id); 854 855 return PKCS11_CKR_OK; 856 } 857 858 static enum pkcs11_rc set_pin(struct pkcs11_session *session, 859 uint8_t *new_pin, size_t new_pin_size, 860 enum pkcs11_user_type user_type) 861 { 862 enum pkcs11_rc rc = PKCS11_CKR_OK; 863 uint32_t flags_clear = 0; 864 uint32_t flags_set = 0; 865 866 if (session->token->db_main->flags & PKCS11_CKFT_WRITE_PROTECTED) 867 return PKCS11_CKR_TOKEN_WRITE_PROTECTED; 868 869 if (!pkcs11_session_is_read_write(session)) 870 return PKCS11_CKR_SESSION_READ_ONLY; 871 872 if (new_pin_size < PKCS11_TOKEN_PIN_SIZE_MIN || 873 new_pin_size > PKCS11_TOKEN_PIN_SIZE_MAX) 874 return PKCS11_CKR_PIN_LEN_RANGE; 875 876 switch (user_type) { 877 case PKCS11_CKU_SO: 878 rc = hash_pin(user_type, new_pin, new_pin_size, 879 &session->token->db_main->so_pin_salt, 880 session->token->db_main->so_pin_hash); 881 if (rc) 882 return rc; 883 session->token->db_main->so_pin_count = 0; 884 flags_clear = PKCS11_CKFT_SO_PIN_COUNT_LOW | 885 PKCS11_CKFT_SO_PIN_FINAL_TRY | 886 PKCS11_CKFT_SO_PIN_LOCKED | 887 PKCS11_CKFT_SO_PIN_TO_BE_CHANGED; 888 break; 889 case PKCS11_CKU_USER: 890 rc = hash_pin(user_type, new_pin, new_pin_size, 891 &session->token->db_main->user_pin_salt, 892 session->token->db_main->user_pin_hash); 893 if (rc) 894 return rc; 895 session->token->db_main->user_pin_count = 0; 896 flags_clear = PKCS11_CKFT_USER_PIN_COUNT_LOW | 897 PKCS11_CKFT_USER_PIN_FINAL_TRY | 898 PKCS11_CKFT_USER_PIN_LOCKED | 899 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED; 900 flags_set = PKCS11_CKFT_USER_PIN_INITIALIZED; 901 break; 902 default: 903 return PKCS11_CKR_FUNCTION_FAILED; 904 } 905 906 session->token->db_main->flags &= ~flags_clear; 907 session->token->db_main->flags |= flags_set; 908 909 update_persistent_db(session->token); 910 911 return PKCS11_CKR_OK; 912 } 913 914 uint32_t entry_ck_init_pin(struct pkcs11_client *client, 915 uint32_t ptypes, TEE_Param *params) 916 { 917 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 918 TEE_PARAM_TYPE_NONE, 919 TEE_PARAM_TYPE_NONE, 920 TEE_PARAM_TYPE_NONE); 921 struct pkcs11_session *session = NULL; 922 enum pkcs11_rc rc = PKCS11_CKR_OK; 923 struct serialargs ctrlargs = { }; 924 uint32_t session_handle = 0; 925 TEE_Param *ctrl = params; 926 uint32_t pin_size = 0; 927 void *pin = NULL; 928 929 if (!client || ptypes != exp_pt) 930 return PKCS11_CKR_ARGUMENTS_BAD; 931 932 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 933 934 rc = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t)); 935 if (rc) 936 return rc; 937 938 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 939 if (rc) 940 return rc; 941 942 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 943 if (rc) 944 return rc; 945 946 if (serialargs_remaining_bytes(&ctrlargs)) 947 return PKCS11_CKR_ARGUMENTS_BAD; 948 949 session = pkcs11_handle2session(session_handle, client); 950 if (!session) 951 return PKCS11_CKR_SESSION_HANDLE_INVALID; 952 953 if (!pkcs11_session_is_so(session)) 954 return PKCS11_CKR_USER_NOT_LOGGED_IN; 955 956 assert(session->token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED); 957 958 IMSG("PKCS11 session %"PRIu32": init PIN", session_handle); 959 960 return set_pin(session, pin, pin_size, PKCS11_CKU_USER); 961 } 962 963 static uint32_t check_so_pin(struct pkcs11_session *session, 964 uint8_t *pin, size_t pin_size) 965 { 966 struct ck_token *token = session->token; 967 enum pkcs11_rc rc = PKCS11_CKR_OK; 968 969 assert(token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED); 970 971 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) 972 return PKCS11_CKR_PIN_LOCKED; 973 974 rc = verify_pin(PKCS11_CKU_SO, pin, pin_size, 975 token->db_main->so_pin_salt, 976 token->db_main->so_pin_hash); 977 if (rc) { 978 unsigned int pin_count = 0; 979 980 if (rc != PKCS11_CKR_PIN_INCORRECT) 981 return rc; 982 983 token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW; 984 token->db_main->so_pin_count++; 985 986 pin_count = token->db_main->so_pin_count; 987 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1) 988 token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY; 989 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX) 990 token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED; 991 992 update_persistent_db(token); 993 994 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) 995 return PKCS11_CKR_PIN_LOCKED; 996 997 return PKCS11_CKR_PIN_INCORRECT; 998 } 999 1000 if (token->db_main->so_pin_count) { 1001 token->db_main->so_pin_count = 0; 1002 1003 update_persistent_db(token); 1004 } 1005 1006 if (token->db_main->flags & (PKCS11_CKFT_SO_PIN_COUNT_LOW | 1007 PKCS11_CKFT_SO_PIN_FINAL_TRY)) { 1008 token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW | 1009 PKCS11_CKFT_SO_PIN_FINAL_TRY); 1010 1011 update_persistent_db(token); 1012 } 1013 1014 return PKCS11_CKR_OK; 1015 } 1016 1017 static uint32_t check_user_pin(struct pkcs11_session *session, 1018 uint8_t *pin, size_t pin_size) 1019 { 1020 struct ck_token *token = session->token; 1021 enum pkcs11_rc rc = PKCS11_CKR_OK; 1022 1023 if (!token->db_main->user_pin_salt) 1024 return PKCS11_CKR_USER_PIN_NOT_INITIALIZED; 1025 1026 if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED) 1027 return PKCS11_CKR_PIN_LOCKED; 1028 1029 rc = verify_pin(PKCS11_CKU_USER, pin, pin_size, 1030 token->db_main->user_pin_salt, 1031 token->db_main->user_pin_hash); 1032 if (rc) { 1033 unsigned int pin_count = 0; 1034 1035 if (rc != PKCS11_CKR_PIN_INCORRECT) 1036 return rc; 1037 1038 token->db_main->flags |= PKCS11_CKFT_USER_PIN_COUNT_LOW; 1039 token->db_main->user_pin_count++; 1040 1041 pin_count = token->db_main->user_pin_count; 1042 if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX - 1) 1043 token->db_main->flags |= PKCS11_CKFT_USER_PIN_FINAL_TRY; 1044 if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX) 1045 token->db_main->flags |= PKCS11_CKFT_USER_PIN_LOCKED; 1046 1047 update_persistent_db(token); 1048 1049 if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED) 1050 return PKCS11_CKR_PIN_LOCKED; 1051 1052 return PKCS11_CKR_PIN_INCORRECT; 1053 } 1054 1055 if (token->db_main->user_pin_count) { 1056 token->db_main->user_pin_count = 0; 1057 1058 update_persistent_db(token); 1059 } 1060 1061 if (token->db_main->flags & (PKCS11_CKFT_USER_PIN_COUNT_LOW | 1062 PKCS11_CKFT_USER_PIN_FINAL_TRY)) { 1063 token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_COUNT_LOW | 1064 PKCS11_CKFT_USER_PIN_FINAL_TRY); 1065 1066 update_persistent_db(token); 1067 } 1068 1069 return PKCS11_CKR_OK; 1070 } 1071 1072 uint32_t entry_ck_set_pin(struct pkcs11_client *client, 1073 uint32_t ptypes, TEE_Param *params) 1074 { 1075 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1076 TEE_PARAM_TYPE_NONE, 1077 TEE_PARAM_TYPE_NONE, 1078 TEE_PARAM_TYPE_NONE); 1079 struct pkcs11_session *session = NULL; 1080 enum pkcs11_rc rc = PKCS11_CKR_OK; 1081 struct serialargs ctrlargs = { }; 1082 uint32_t session_handle = 0; 1083 uint32_t old_pin_size = 0; 1084 TEE_Param *ctrl = params; 1085 uint32_t pin_size = 0; 1086 void *old_pin = NULL; 1087 void *pin = NULL; 1088 1089 if (!client || ptypes != exp_pt) 1090 return PKCS11_CKR_ARGUMENTS_BAD; 1091 1092 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1093 1094 rc = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t)); 1095 if (rc) 1096 return rc; 1097 1098 rc = serialargs_get(&ctrlargs, &old_pin_size, sizeof(uint32_t)); 1099 if (rc) 1100 return rc; 1101 1102 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 1103 if (rc) 1104 return rc; 1105 1106 rc = serialargs_get_ptr(&ctrlargs, &old_pin, old_pin_size); 1107 if (rc) 1108 return rc; 1109 1110 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 1111 if (rc) 1112 return rc; 1113 1114 if (serialargs_remaining_bytes(&ctrlargs)) 1115 return PKCS11_CKR_ARGUMENTS_BAD; 1116 1117 session = pkcs11_handle2session(session_handle, client); 1118 if (!session) 1119 return PKCS11_CKR_SESSION_HANDLE_INVALID; 1120 1121 if (!pkcs11_session_is_read_write(session)) 1122 return PKCS11_CKR_SESSION_READ_ONLY; 1123 1124 if (pkcs11_session_is_so(session)) { 1125 if (!(session->token->db_main->flags & 1126 PKCS11_CKFT_TOKEN_INITIALIZED)) 1127 return PKCS11_CKR_GENERAL_ERROR; 1128 1129 rc = check_so_pin(session, old_pin, old_pin_size); 1130 if (rc) 1131 return rc; 1132 1133 IMSG("PKCS11 session %"PRIu32": set PIN", session_handle); 1134 1135 return set_pin(session, pin, pin_size, PKCS11_CKU_SO); 1136 } 1137 1138 if (!(session->token->db_main->flags & 1139 PKCS11_CKFT_USER_PIN_INITIALIZED)) 1140 return PKCS11_CKR_GENERAL_ERROR; 1141 1142 rc = check_user_pin(session, old_pin, old_pin_size); 1143 if (rc) 1144 return rc; 1145 1146 IMSG("PKCS11 session %"PRIu32": set PIN", session_handle); 1147 1148 return set_pin(session, pin, pin_size, PKCS11_CKU_USER); 1149 } 1150 1151 static void session_login_user(struct pkcs11_session *session) 1152 { 1153 struct pkcs11_client *client = session->client; 1154 struct pkcs11_session *sess = NULL; 1155 1156 TAILQ_FOREACH(sess, &client->session_list, link) { 1157 if (sess->token != session->token) 1158 continue; 1159 1160 if (pkcs11_session_is_read_write(sess)) 1161 sess->state = PKCS11_CKS_RW_USER_FUNCTIONS; 1162 else 1163 sess->state = PKCS11_CKS_RO_USER_FUNCTIONS; 1164 } 1165 } 1166 1167 static void session_login_so(struct pkcs11_session *session) 1168 { 1169 struct pkcs11_client *client = session->client; 1170 struct pkcs11_session *sess = NULL; 1171 1172 TAILQ_FOREACH(sess, &client->session_list, link) { 1173 if (sess->token != session->token) 1174 continue; 1175 1176 if (pkcs11_session_is_read_write(sess)) 1177 sess->state = PKCS11_CKS_RW_SO_FUNCTIONS; 1178 else 1179 TEE_Panic(0); 1180 } 1181 } 1182 1183 static void session_logout(struct pkcs11_session *session) 1184 { 1185 struct pkcs11_client *client = session->client; 1186 struct pkcs11_session *sess = NULL; 1187 1188 TAILQ_FOREACH(sess, &client->session_list, link) { 1189 if (sess->token != session->token) 1190 continue; 1191 1192 if (pkcs11_session_is_read_write(sess)) 1193 sess->state = PKCS11_CKS_RW_PUBLIC_SESSION; 1194 else 1195 sess->state = PKCS11_CKS_RO_PUBLIC_SESSION; 1196 } 1197 } 1198 1199 uint32_t entry_ck_login(struct pkcs11_client *client, 1200 uint32_t ptypes, TEE_Param *params) 1201 { 1202 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1203 TEE_PARAM_TYPE_NONE, 1204 TEE_PARAM_TYPE_NONE, 1205 TEE_PARAM_TYPE_NONE); 1206 struct pkcs11_session *session = NULL; 1207 struct pkcs11_session *sess = NULL; 1208 enum pkcs11_rc rc = PKCS11_CKR_OK; 1209 struct serialargs ctrlargs = { }; 1210 uint32_t session_handle = 0; 1211 TEE_Param *ctrl = params; 1212 uint32_t user_type = 0; 1213 uint32_t pin_size = 0; 1214 void *pin = NULL; 1215 1216 if (!client || ptypes != exp_pt) 1217 return PKCS11_CKR_ARGUMENTS_BAD; 1218 1219 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1220 1221 rc = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t)); 1222 if (rc) 1223 return rc; 1224 1225 rc = serialargs_get(&ctrlargs, &user_type, sizeof(uint32_t)); 1226 if (rc) 1227 return rc; 1228 1229 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 1230 if (rc) 1231 return rc; 1232 1233 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 1234 if (rc) 1235 return rc; 1236 1237 if (serialargs_remaining_bytes(&ctrlargs)) 1238 return PKCS11_CKR_ARGUMENTS_BAD; 1239 1240 session = pkcs11_handle2session(session_handle, client); 1241 if (!session) 1242 return PKCS11_CKR_SESSION_HANDLE_INVALID; 1243 1244 switch (user_type) { 1245 case PKCS11_CKU_SO: 1246 if (pkcs11_session_is_so(session)) 1247 return PKCS11_CKR_USER_ALREADY_LOGGED_IN; 1248 1249 if (pkcs11_session_is_user(session)) 1250 return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN; 1251 1252 TAILQ_FOREACH(sess, &client->session_list, link) 1253 if (sess->token == session->token && 1254 !pkcs11_session_is_read_write(sess)) 1255 return PKCS11_CKR_SESSION_READ_ONLY_EXISTS; 1256 1257 /* 1258 * This is the point where we could check if another client 1259 * has another user or SO logged in. 1260 * 1261 * The spec says: 1262 * CKR_USER_TOO_MANY_TYPES: An attempt was made to have 1263 * more distinct users simultaneously logged into the token 1264 * than the token and/or library permits. For example, if 1265 * some application has an open SO session, and another 1266 * application attempts to log the normal user into a 1267 * session, the attempt may return this error. It is not 1268 * required to, however. Only if the simultaneous distinct 1269 * users cannot be supported does C_Login have to return 1270 * this value. Note that this error code generalizes to 1271 * true multi-user tokens. 1272 * 1273 * So it's permitted to have another user or SO logged in 1274 * from another client. 1275 */ 1276 1277 rc = check_so_pin(session, pin, pin_size); 1278 if (!rc) 1279 session_login_so(session); 1280 1281 break; 1282 1283 case PKCS11_CKU_USER: 1284 if (pkcs11_session_is_so(session)) 1285 return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN; 1286 1287 if (pkcs11_session_is_user(session)) 1288 return PKCS11_CKR_USER_ALREADY_LOGGED_IN; 1289 1290 /* 1291 * This is the point where we could check if another client 1292 * has another user or SO logged in. 1293 * See comment on CKR_USER_TOO_MANY_TYPES above. 1294 */ 1295 1296 rc = check_user_pin(session, pin, pin_size); 1297 if (!rc) 1298 session_login_user(session); 1299 1300 break; 1301 1302 case PKCS11_CKU_CONTEXT_SPECIFIC: 1303 return PKCS11_CKR_OPERATION_NOT_INITIALIZED; 1304 1305 default: 1306 return PKCS11_CKR_USER_TYPE_INVALID; 1307 } 1308 1309 if (!rc) 1310 IMSG("PKCS11 session %"PRIu32": login", session_handle); 1311 1312 return rc; 1313 } 1314 1315 uint32_t entry_ck_logout(struct pkcs11_client *client, 1316 uint32_t ptypes, TEE_Param *params) 1317 { 1318 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1319 TEE_PARAM_TYPE_NONE, 1320 TEE_PARAM_TYPE_NONE, 1321 TEE_PARAM_TYPE_NONE); 1322 struct pkcs11_session *session = NULL; 1323 enum pkcs11_rc rc = PKCS11_CKR_OK; 1324 struct serialargs ctrlargs = { }; 1325 uint32_t session_handle = 0; 1326 TEE_Param *ctrl = params; 1327 1328 if (!client || ptypes != exp_pt) 1329 return PKCS11_CKR_ARGUMENTS_BAD; 1330 1331 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1332 1333 rc = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t)); 1334 if (rc) 1335 return rc; 1336 1337 if (serialargs_remaining_bytes(&ctrlargs)) 1338 return PKCS11_CKR_ARGUMENTS_BAD; 1339 1340 session = pkcs11_handle2session(session_handle, client); 1341 if (!session) 1342 return PKCS11_CKR_SESSION_HANDLE_INVALID; 1343 1344 if (pkcs11_session_is_public(session)) 1345 return PKCS11_CKR_USER_NOT_LOGGED_IN; 1346 1347 session_logout(session); 1348 1349 IMSG("PKCS11 session %"PRIu32": logout", session_handle); 1350 1351 return PKCS11_CKR_OK; 1352 } 1353