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