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