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