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