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