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