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