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