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