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