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