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