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 goto inited; 859 } 860 861 rc = verify_pin(PKCS11_CKU_SO, pin, pin_size, 862 token->db_main->so_pin_salt, 863 token->db_main->so_pin_hash); 864 if (rc) { 865 unsigned int pin_count = 0; 866 867 if (rc != PKCS11_CKR_PIN_INCORRECT) 868 return rc; 869 870 token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW; 871 token->db_main->so_pin_count++; 872 873 pin_count = token->db_main->so_pin_count; 874 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1) 875 token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY; 876 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX) 877 token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED; 878 879 update_persistent_db(token); 880 881 return PKCS11_CKR_PIN_INCORRECT; 882 } 883 884 inited: 885 /* Make sure SO PIN counters are zeroed */ 886 token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW | 887 PKCS11_CKFT_SO_PIN_FINAL_TRY | 888 PKCS11_CKFT_SO_PIN_LOCKED | 889 PKCS11_CKFT_SO_PIN_TO_BE_CHANGED); 890 token->db_main->so_pin_count = 0; 891 892 TEE_MemMove(token->db_main->label, label, PKCS11_TOKEN_LABEL_SIZE); 893 token->db_main->flags |= PKCS11_CKFT_TOKEN_INITIALIZED; 894 /* Reset user PIN */ 895 token->db_main->user_pin_salt = 0; 896 token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_INITIALIZED | 897 PKCS11_CKFT_USER_PIN_COUNT_LOW | 898 PKCS11_CKFT_USER_PIN_FINAL_TRY | 899 PKCS11_CKFT_USER_PIN_LOCKED | 900 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED); 901 902 update_persistent_db(token); 903 904 IMSG("PKCS11 token %"PRIu32": initialized", token_id); 905 906 return PKCS11_CKR_OK; 907 } 908 909 static enum pkcs11_rc set_pin(struct pkcs11_session *session, 910 uint8_t *new_pin, size_t new_pin_size, 911 enum pkcs11_user_type user_type) 912 { 913 enum pkcs11_rc rc = PKCS11_CKR_OK; 914 uint32_t flags_clear = 0; 915 uint32_t flags_set = 0; 916 917 if (session->token->db_main->flags & PKCS11_CKFT_WRITE_PROTECTED) 918 return PKCS11_CKR_TOKEN_WRITE_PROTECTED; 919 920 if (!pkcs11_session_is_read_write(session)) 921 return PKCS11_CKR_SESSION_READ_ONLY; 922 923 if (new_pin_size < PKCS11_TOKEN_PIN_SIZE_MIN || 924 new_pin_size > PKCS11_TOKEN_PIN_SIZE_MAX) 925 return PKCS11_CKR_PIN_LEN_RANGE; 926 927 switch (user_type) { 928 case PKCS11_CKU_SO: 929 rc = hash_pin(user_type, new_pin, new_pin_size, 930 &session->token->db_main->so_pin_salt, 931 session->token->db_main->so_pin_hash); 932 if (rc) 933 return rc; 934 session->token->db_main->so_pin_count = 0; 935 flags_clear = PKCS11_CKFT_SO_PIN_COUNT_LOW | 936 PKCS11_CKFT_SO_PIN_FINAL_TRY | 937 PKCS11_CKFT_SO_PIN_LOCKED | 938 PKCS11_CKFT_SO_PIN_TO_BE_CHANGED; 939 break; 940 case PKCS11_CKU_USER: 941 rc = hash_pin(user_type, new_pin, new_pin_size, 942 &session->token->db_main->user_pin_salt, 943 session->token->db_main->user_pin_hash); 944 if (rc) 945 return rc; 946 session->token->db_main->user_pin_count = 0; 947 flags_clear = PKCS11_CKFT_USER_PIN_COUNT_LOW | 948 PKCS11_CKFT_USER_PIN_FINAL_TRY | 949 PKCS11_CKFT_USER_PIN_LOCKED | 950 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED; 951 flags_set = PKCS11_CKFT_USER_PIN_INITIALIZED; 952 break; 953 default: 954 return PKCS11_CKR_FUNCTION_FAILED; 955 } 956 957 session->token->db_main->flags &= ~flags_clear; 958 session->token->db_main->flags |= flags_set; 959 960 update_persistent_db(session->token); 961 962 return PKCS11_CKR_OK; 963 } 964 965 enum pkcs11_rc entry_ck_init_pin(struct pkcs11_client *client, 966 uint32_t ptypes, TEE_Param *params) 967 { 968 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 969 TEE_PARAM_TYPE_NONE, 970 TEE_PARAM_TYPE_NONE, 971 TEE_PARAM_TYPE_NONE); 972 struct pkcs11_session *session = NULL; 973 enum pkcs11_rc rc = PKCS11_CKR_OK; 974 struct serialargs ctrlargs = { }; 975 TEE_Param *ctrl = params; 976 uint32_t pin_size = 0; 977 void *pin = NULL; 978 979 if (!client || ptypes != exp_pt) 980 return PKCS11_CKR_ARGUMENTS_BAD; 981 982 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 983 984 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 985 if (rc) 986 return rc; 987 988 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 989 if (rc) 990 return rc; 991 992 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 993 if (rc) 994 return rc; 995 996 if (serialargs_remaining_bytes(&ctrlargs)) 997 return PKCS11_CKR_ARGUMENTS_BAD; 998 999 if (!pkcs11_session_is_so(session)) 1000 return PKCS11_CKR_USER_NOT_LOGGED_IN; 1001 1002 assert(session->token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED); 1003 1004 IMSG("PKCS11 session %"PRIu32": init PIN", session->handle); 1005 1006 return set_pin(session, pin, pin_size, PKCS11_CKU_USER); 1007 } 1008 1009 static enum pkcs11_rc check_so_pin(struct pkcs11_session *session, 1010 uint8_t *pin, size_t pin_size) 1011 { 1012 struct ck_token *token = session->token; 1013 enum pkcs11_rc rc = PKCS11_CKR_OK; 1014 1015 assert(token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED); 1016 1017 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) 1018 return PKCS11_CKR_PIN_LOCKED; 1019 1020 rc = verify_pin(PKCS11_CKU_SO, pin, pin_size, 1021 token->db_main->so_pin_salt, 1022 token->db_main->so_pin_hash); 1023 if (rc) { 1024 unsigned int pin_count = 0; 1025 1026 if (rc != PKCS11_CKR_PIN_INCORRECT) 1027 return rc; 1028 1029 token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW; 1030 token->db_main->so_pin_count++; 1031 1032 pin_count = token->db_main->so_pin_count; 1033 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1) 1034 token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY; 1035 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX) 1036 token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED; 1037 1038 update_persistent_db(token); 1039 1040 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) 1041 return PKCS11_CKR_PIN_LOCKED; 1042 1043 return PKCS11_CKR_PIN_INCORRECT; 1044 } 1045 1046 if (token->db_main->so_pin_count) { 1047 token->db_main->so_pin_count = 0; 1048 1049 update_persistent_db(token); 1050 } 1051 1052 if (token->db_main->flags & (PKCS11_CKFT_SO_PIN_COUNT_LOW | 1053 PKCS11_CKFT_SO_PIN_FINAL_TRY)) { 1054 token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW | 1055 PKCS11_CKFT_SO_PIN_FINAL_TRY); 1056 1057 update_persistent_db(token); 1058 } 1059 1060 return PKCS11_CKR_OK; 1061 } 1062 1063 static enum pkcs11_rc check_user_pin(struct pkcs11_session *session, 1064 uint8_t *pin, size_t pin_size) 1065 { 1066 struct ck_token *token = session->token; 1067 enum pkcs11_rc rc = PKCS11_CKR_OK; 1068 1069 if (!token->db_main->user_pin_salt) 1070 return PKCS11_CKR_USER_PIN_NOT_INITIALIZED; 1071 1072 if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED) 1073 return PKCS11_CKR_PIN_LOCKED; 1074 1075 rc = verify_pin(PKCS11_CKU_USER, pin, pin_size, 1076 token->db_main->user_pin_salt, 1077 token->db_main->user_pin_hash); 1078 if (rc) { 1079 unsigned int pin_count = 0; 1080 1081 if (rc != PKCS11_CKR_PIN_INCORRECT) 1082 return rc; 1083 1084 token->db_main->flags |= PKCS11_CKFT_USER_PIN_COUNT_LOW; 1085 token->db_main->user_pin_count++; 1086 1087 pin_count = token->db_main->user_pin_count; 1088 if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX - 1) 1089 token->db_main->flags |= PKCS11_CKFT_USER_PIN_FINAL_TRY; 1090 if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX) 1091 token->db_main->flags |= PKCS11_CKFT_USER_PIN_LOCKED; 1092 1093 update_persistent_db(token); 1094 1095 if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED) 1096 return PKCS11_CKR_PIN_LOCKED; 1097 1098 return PKCS11_CKR_PIN_INCORRECT; 1099 } 1100 1101 if (token->db_main->user_pin_count) { 1102 token->db_main->user_pin_count = 0; 1103 1104 update_persistent_db(token); 1105 } 1106 1107 if (token->db_main->flags & (PKCS11_CKFT_USER_PIN_COUNT_LOW | 1108 PKCS11_CKFT_USER_PIN_FINAL_TRY)) { 1109 token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_COUNT_LOW | 1110 PKCS11_CKFT_USER_PIN_FINAL_TRY); 1111 1112 update_persistent_db(token); 1113 } 1114 1115 return PKCS11_CKR_OK; 1116 } 1117 1118 enum pkcs11_rc entry_ck_set_pin(struct pkcs11_client *client, 1119 uint32_t ptypes, TEE_Param *params) 1120 { 1121 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1122 TEE_PARAM_TYPE_NONE, 1123 TEE_PARAM_TYPE_NONE, 1124 TEE_PARAM_TYPE_NONE); 1125 struct pkcs11_session *session = NULL; 1126 enum pkcs11_rc rc = PKCS11_CKR_OK; 1127 struct serialargs ctrlargs = { }; 1128 uint32_t old_pin_size = 0; 1129 TEE_Param *ctrl = params; 1130 uint32_t pin_size = 0; 1131 void *old_pin = NULL; 1132 void *pin = NULL; 1133 1134 if (!client || ptypes != exp_pt) 1135 return PKCS11_CKR_ARGUMENTS_BAD; 1136 1137 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1138 1139 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1140 if (rc) 1141 return rc; 1142 1143 rc = serialargs_get(&ctrlargs, &old_pin_size, sizeof(uint32_t)); 1144 if (rc) 1145 return rc; 1146 1147 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 1148 if (rc) 1149 return rc; 1150 1151 rc = serialargs_get_ptr(&ctrlargs, &old_pin, old_pin_size); 1152 if (rc) 1153 return rc; 1154 1155 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 1156 if (rc) 1157 return rc; 1158 1159 if (serialargs_remaining_bytes(&ctrlargs)) 1160 return PKCS11_CKR_ARGUMENTS_BAD; 1161 1162 if (!pkcs11_session_is_read_write(session)) 1163 return PKCS11_CKR_SESSION_READ_ONLY; 1164 1165 if (pkcs11_session_is_so(session)) { 1166 if (!(session->token->db_main->flags & 1167 PKCS11_CKFT_TOKEN_INITIALIZED)) 1168 return PKCS11_CKR_GENERAL_ERROR; 1169 1170 rc = check_so_pin(session, old_pin, old_pin_size); 1171 if (rc) 1172 return rc; 1173 1174 IMSG("PKCS11 session %"PRIu32": set PIN", session->handle); 1175 1176 return set_pin(session, pin, pin_size, PKCS11_CKU_SO); 1177 } 1178 1179 if (!(session->token->db_main->flags & 1180 PKCS11_CKFT_USER_PIN_INITIALIZED)) 1181 return PKCS11_CKR_GENERAL_ERROR; 1182 1183 rc = check_user_pin(session, old_pin, old_pin_size); 1184 if (rc) 1185 return rc; 1186 1187 IMSG("PKCS11 session %"PRIu32": set PIN", session->handle); 1188 1189 return set_pin(session, pin, pin_size, PKCS11_CKU_USER); 1190 } 1191 1192 static void session_login_user(struct pkcs11_session *session) 1193 { 1194 struct pkcs11_client *client = session->client; 1195 struct pkcs11_session *sess = NULL; 1196 1197 TAILQ_FOREACH(sess, &client->session_list, link) { 1198 if (sess->token != session->token) 1199 continue; 1200 1201 if (pkcs11_session_is_read_write(sess)) 1202 sess->state = PKCS11_CKS_RW_USER_FUNCTIONS; 1203 else 1204 sess->state = PKCS11_CKS_RO_USER_FUNCTIONS; 1205 } 1206 } 1207 1208 static void session_login_so(struct pkcs11_session *session) 1209 { 1210 struct pkcs11_client *client = session->client; 1211 struct pkcs11_session *sess = NULL; 1212 1213 TAILQ_FOREACH(sess, &client->session_list, link) { 1214 if (sess->token != session->token) 1215 continue; 1216 1217 if (pkcs11_session_is_read_write(sess)) 1218 sess->state = PKCS11_CKS_RW_SO_FUNCTIONS; 1219 else 1220 TEE_Panic(0); 1221 } 1222 } 1223 1224 static void session_logout(struct pkcs11_session *session) 1225 { 1226 struct pkcs11_client *client = session->client; 1227 struct pkcs11_session *sess = NULL; 1228 1229 TAILQ_FOREACH(sess, &client->session_list, link) { 1230 if (sess->token != session->token) 1231 continue; 1232 1233 if (pkcs11_session_is_read_write(sess)) 1234 sess->state = PKCS11_CKS_RW_PUBLIC_SESSION; 1235 else 1236 sess->state = PKCS11_CKS_RO_PUBLIC_SESSION; 1237 } 1238 } 1239 1240 enum pkcs11_rc entry_ck_login(struct pkcs11_client *client, 1241 uint32_t ptypes, TEE_Param *params) 1242 { 1243 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1244 TEE_PARAM_TYPE_NONE, 1245 TEE_PARAM_TYPE_NONE, 1246 TEE_PARAM_TYPE_NONE); 1247 struct pkcs11_session *session = NULL; 1248 struct pkcs11_session *sess = NULL; 1249 enum pkcs11_rc rc = PKCS11_CKR_OK; 1250 struct serialargs ctrlargs = { }; 1251 TEE_Param *ctrl = params; 1252 uint32_t user_type = 0; 1253 uint32_t pin_size = 0; 1254 void *pin = NULL; 1255 1256 if (!client || ptypes != exp_pt) 1257 return PKCS11_CKR_ARGUMENTS_BAD; 1258 1259 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1260 1261 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1262 if (rc) 1263 return rc; 1264 1265 rc = serialargs_get(&ctrlargs, &user_type, sizeof(uint32_t)); 1266 if (rc) 1267 return rc; 1268 1269 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 1270 if (rc) 1271 return rc; 1272 1273 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 1274 if (rc) 1275 return rc; 1276 1277 if (serialargs_remaining_bytes(&ctrlargs)) 1278 return PKCS11_CKR_ARGUMENTS_BAD; 1279 1280 switch (user_type) { 1281 case PKCS11_CKU_SO: 1282 if (pkcs11_session_is_so(session)) 1283 return PKCS11_CKR_USER_ALREADY_LOGGED_IN; 1284 1285 if (pkcs11_session_is_user(session)) 1286 return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN; 1287 1288 TAILQ_FOREACH(sess, &client->session_list, link) 1289 if (sess->token == session->token && 1290 !pkcs11_session_is_read_write(sess)) 1291 return PKCS11_CKR_SESSION_READ_ONLY_EXISTS; 1292 1293 /* 1294 * This is the point where we could check if another client 1295 * has another user or SO logged in. 1296 * 1297 * The spec says: 1298 * CKR_USER_TOO_MANY_TYPES: An attempt was made to have 1299 * more distinct users simultaneously logged into the token 1300 * than the token and/or library permits. For example, if 1301 * some application has an open SO session, and another 1302 * application attempts to log the normal user into a 1303 * session, the attempt may return this error. It is not 1304 * required to, however. Only if the simultaneous distinct 1305 * users cannot be supported does C_Login have to return 1306 * this value. Note that this error code generalizes to 1307 * true multi-user tokens. 1308 * 1309 * So it's permitted to have another user or SO logged in 1310 * from another client. 1311 */ 1312 1313 rc = check_so_pin(session, pin, pin_size); 1314 if (!rc) 1315 session_login_so(session); 1316 1317 break; 1318 1319 case PKCS11_CKU_USER: 1320 if (pkcs11_session_is_so(session)) 1321 return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN; 1322 1323 if (pkcs11_session_is_user(session)) 1324 return PKCS11_CKR_USER_ALREADY_LOGGED_IN; 1325 1326 /* 1327 * This is the point where we could check if another client 1328 * has another user or SO logged in. 1329 * See comment on CKR_USER_TOO_MANY_TYPES above. 1330 */ 1331 1332 rc = check_user_pin(session, pin, pin_size); 1333 if (!rc) 1334 session_login_user(session); 1335 1336 break; 1337 1338 case PKCS11_CKU_CONTEXT_SPECIFIC: 1339 return PKCS11_CKR_OPERATION_NOT_INITIALIZED; 1340 1341 default: 1342 return PKCS11_CKR_USER_TYPE_INVALID; 1343 } 1344 1345 if (!rc) 1346 IMSG("PKCS11 session %"PRIu32": login", session->handle); 1347 1348 return rc; 1349 } 1350 1351 enum pkcs11_rc entry_ck_logout(struct pkcs11_client *client, 1352 uint32_t ptypes, TEE_Param *params) 1353 { 1354 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1355 TEE_PARAM_TYPE_NONE, 1356 TEE_PARAM_TYPE_NONE, 1357 TEE_PARAM_TYPE_NONE); 1358 struct pkcs11_session *session = NULL; 1359 enum pkcs11_rc rc = PKCS11_CKR_OK; 1360 struct serialargs ctrlargs = { }; 1361 TEE_Param *ctrl = params; 1362 1363 if (!client || ptypes != exp_pt) 1364 return PKCS11_CKR_ARGUMENTS_BAD; 1365 1366 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1367 1368 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1369 if (rc) 1370 return rc; 1371 1372 if (serialargs_remaining_bytes(&ctrlargs)) 1373 return PKCS11_CKR_ARGUMENTS_BAD; 1374 1375 if (pkcs11_session_is_public(session)) 1376 return PKCS11_CKR_USER_NOT_LOGGED_IN; 1377 1378 session_logout(session); 1379 1380 IMSG("PKCS11 session %"PRIu32": logout", session->handle); 1381 1382 return PKCS11_CKR_OK; 1383 } 1384