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 /* Verify authentication if token is already initialized */ 863 if (token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED) { 864 unsigned int pin_count = 0; 865 866 if (IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) && 867 (token->db_main->flags & 868 PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH)) { 869 /* Check TEE Identity based authentication if enabled */ 870 rc = verify_identity_auth(token, PKCS11_CKU_SO); 871 if (rc) 872 return rc; 873 874 goto inited; 875 } 876 877 /* Check PIN based authentication */ 878 rc = verify_pin(PKCS11_CKU_SO, pin, pin_size, 879 token->db_main->so_pin_salt, 880 token->db_main->so_pin_hash); 881 if (!rc) 882 goto inited; 883 884 if (rc != PKCS11_CKR_PIN_INCORRECT) 885 return rc; 886 887 token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW; 888 token->db_main->so_pin_count++; 889 890 pin_count = token->db_main->so_pin_count; 891 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1) 892 token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY; 893 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX) 894 token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED; 895 896 update_persistent_db(token); 897 898 return PKCS11_CKR_PIN_INCORRECT; 899 } 900 901 /* Initialize SO's authentication */ 902 if (IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) && !pin) { 903 rc = setup_so_identity_auth_from_client(token); 904 if (rc) 905 return rc; 906 } else { 907 /* 908 * The spec doesn't permit returning 909 * PKCS11_CKR_PIN_LEN_RANGE for this function, take another 910 * error code. 911 */ 912 if (pin_size < PKCS11_TOKEN_PIN_SIZE_MIN || 913 pin_size > PKCS11_TOKEN_PIN_SIZE_MAX) 914 return PKCS11_CKR_ARGUMENTS_BAD; 915 916 rc = hash_pin(PKCS11_CKU_SO, pin, pin_size, 917 &token->db_main->so_pin_salt, 918 token->db_main->so_pin_hash); 919 if (rc) 920 return rc; 921 } 922 923 inited: 924 /* Make sure SO PIN counters are zeroed */ 925 token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW | 926 PKCS11_CKFT_SO_PIN_FINAL_TRY | 927 PKCS11_CKFT_SO_PIN_LOCKED | 928 PKCS11_CKFT_SO_PIN_TO_BE_CHANGED); 929 token->db_main->so_pin_count = 0; 930 931 TEE_MemMove(token->db_main->label, label, PKCS11_TOKEN_LABEL_SIZE); 932 token->db_main->flags |= PKCS11_CKFT_TOKEN_INITIALIZED; 933 /* Reset user PIN */ 934 token->db_main->user_pin_salt = 0; 935 token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_INITIALIZED | 936 PKCS11_CKFT_USER_PIN_COUNT_LOW | 937 PKCS11_CKFT_USER_PIN_FINAL_TRY | 938 PKCS11_CKFT_USER_PIN_LOCKED | 939 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED); 940 941 update_persistent_db(token); 942 943 /* Remove all persistent objects */ 944 while (!LIST_EMPTY(&token->object_list)) { 945 obj = LIST_FIRST(&token->object_list); 946 947 /* Try twice otherwise panic! */ 948 if (unregister_persistent_object(token, obj->uuid) && 949 unregister_persistent_object(token, obj->uuid)) 950 TEE_Panic(0); 951 952 cleanup_persistent_object(obj, token); 953 } 954 955 IMSG("PKCS11 token %"PRIu32": initialized", token_id); 956 957 return PKCS11_CKR_OK; 958 } 959 960 static enum pkcs11_rc set_pin(struct pkcs11_session *session, 961 uint8_t *new_pin, size_t new_pin_size, 962 enum pkcs11_user_type user_type) 963 { 964 struct ck_token *token = session->token; 965 enum pkcs11_rc rc = PKCS11_CKR_OK; 966 uint32_t flags_clear = 0; 967 uint32_t flags_set = 0; 968 969 if (token->db_main->flags & PKCS11_CKFT_WRITE_PROTECTED) 970 return PKCS11_CKR_TOKEN_WRITE_PROTECTED; 971 972 if (!pkcs11_session_is_read_write(session)) 973 return PKCS11_CKR_SESSION_READ_ONLY; 974 975 if (IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) && 976 token->db_main->flags & PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH) { 977 rc = setup_identity_auth_from_pin(token, user_type, new_pin, 978 new_pin_size); 979 if (rc) 980 return rc; 981 982 goto update_db; 983 } 984 985 if (new_pin_size < PKCS11_TOKEN_PIN_SIZE_MIN || 986 new_pin_size > PKCS11_TOKEN_PIN_SIZE_MAX) 987 return PKCS11_CKR_PIN_LEN_RANGE; 988 989 switch (user_type) { 990 case PKCS11_CKU_SO: 991 rc = hash_pin(user_type, new_pin, new_pin_size, 992 &token->db_main->so_pin_salt, 993 token->db_main->so_pin_hash); 994 if (rc) 995 return rc; 996 token->db_main->so_pin_count = 0; 997 flags_clear = PKCS11_CKFT_SO_PIN_COUNT_LOW | 998 PKCS11_CKFT_SO_PIN_FINAL_TRY | 999 PKCS11_CKFT_SO_PIN_LOCKED | 1000 PKCS11_CKFT_SO_PIN_TO_BE_CHANGED; 1001 break; 1002 case PKCS11_CKU_USER: 1003 rc = hash_pin(user_type, new_pin, new_pin_size, 1004 &token->db_main->user_pin_salt, 1005 token->db_main->user_pin_hash); 1006 if (rc) 1007 return rc; 1008 token->db_main->user_pin_count = 0; 1009 flags_clear = PKCS11_CKFT_USER_PIN_COUNT_LOW | 1010 PKCS11_CKFT_USER_PIN_FINAL_TRY | 1011 PKCS11_CKFT_USER_PIN_LOCKED | 1012 PKCS11_CKFT_USER_PIN_TO_BE_CHANGED; 1013 flags_set = PKCS11_CKFT_USER_PIN_INITIALIZED; 1014 break; 1015 default: 1016 return PKCS11_CKR_FUNCTION_FAILED; 1017 } 1018 1019 update_db: 1020 token->db_main->flags &= ~flags_clear; 1021 token->db_main->flags |= flags_set; 1022 1023 update_persistent_db(token); 1024 1025 return PKCS11_CKR_OK; 1026 } 1027 1028 enum pkcs11_rc entry_ck_init_pin(struct pkcs11_client *client, 1029 uint32_t ptypes, TEE_Param *params) 1030 { 1031 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1032 TEE_PARAM_TYPE_NONE, 1033 TEE_PARAM_TYPE_NONE, 1034 TEE_PARAM_TYPE_NONE); 1035 struct pkcs11_session *session = NULL; 1036 enum pkcs11_rc rc = PKCS11_CKR_OK; 1037 struct serialargs ctrlargs = { }; 1038 TEE_Param *ctrl = params; 1039 uint32_t pin_size = 0; 1040 void *pin = NULL; 1041 1042 if (!client || ptypes != exp_pt) 1043 return PKCS11_CKR_ARGUMENTS_BAD; 1044 1045 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1046 1047 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1048 if (rc) 1049 return rc; 1050 1051 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 1052 if (rc) 1053 return rc; 1054 1055 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 1056 if (rc) 1057 return rc; 1058 1059 if (serialargs_remaining_bytes(&ctrlargs)) 1060 return PKCS11_CKR_ARGUMENTS_BAD; 1061 1062 if (!pkcs11_session_is_so(session)) 1063 return PKCS11_CKR_USER_NOT_LOGGED_IN; 1064 1065 assert(session->token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED); 1066 1067 IMSG("PKCS11 session %"PRIu32": init PIN", session->handle); 1068 1069 return set_pin(session, pin, pin_size, PKCS11_CKU_USER); 1070 } 1071 1072 static enum pkcs11_rc check_so_pin(struct pkcs11_session *session, 1073 uint8_t *pin, size_t pin_size) 1074 { 1075 struct ck_token *token = session->token; 1076 enum pkcs11_rc rc = PKCS11_CKR_OK; 1077 1078 assert(token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED); 1079 1080 if (IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) && 1081 token->db_main->flags & PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH) 1082 return verify_identity_auth(token, PKCS11_CKU_SO); 1083 1084 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) 1085 return PKCS11_CKR_PIN_LOCKED; 1086 1087 rc = verify_pin(PKCS11_CKU_SO, pin, pin_size, 1088 token->db_main->so_pin_salt, 1089 token->db_main->so_pin_hash); 1090 if (rc) { 1091 unsigned int pin_count = 0; 1092 1093 if (rc != PKCS11_CKR_PIN_INCORRECT) 1094 return rc; 1095 1096 token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW; 1097 token->db_main->so_pin_count++; 1098 1099 pin_count = token->db_main->so_pin_count; 1100 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1) 1101 token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY; 1102 if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX) 1103 token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED; 1104 1105 update_persistent_db(token); 1106 1107 if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) 1108 return PKCS11_CKR_PIN_LOCKED; 1109 1110 return PKCS11_CKR_PIN_INCORRECT; 1111 } 1112 1113 if (token->db_main->so_pin_count) { 1114 token->db_main->so_pin_count = 0; 1115 1116 update_persistent_db(token); 1117 } 1118 1119 if (token->db_main->flags & (PKCS11_CKFT_SO_PIN_COUNT_LOW | 1120 PKCS11_CKFT_SO_PIN_FINAL_TRY)) { 1121 token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW | 1122 PKCS11_CKFT_SO_PIN_FINAL_TRY); 1123 1124 update_persistent_db(token); 1125 } 1126 1127 return PKCS11_CKR_OK; 1128 } 1129 1130 static enum pkcs11_rc check_user_pin(struct pkcs11_session *session, 1131 uint8_t *pin, size_t pin_size) 1132 { 1133 struct ck_token *token = session->token; 1134 enum pkcs11_rc rc = PKCS11_CKR_OK; 1135 1136 if (IS_ENABLED(CFG_PKCS11_TA_AUTH_TEE_IDENTITY) && 1137 token->db_main->flags & PKCS11_CKFT_PROTECTED_AUTHENTICATION_PATH) 1138 return verify_identity_auth(token, PKCS11_CKU_USER); 1139 1140 if (!token->db_main->user_pin_salt) 1141 return PKCS11_CKR_USER_PIN_NOT_INITIALIZED; 1142 1143 if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED) 1144 return PKCS11_CKR_PIN_LOCKED; 1145 1146 rc = verify_pin(PKCS11_CKU_USER, pin, pin_size, 1147 token->db_main->user_pin_salt, 1148 token->db_main->user_pin_hash); 1149 if (rc) { 1150 unsigned int pin_count = 0; 1151 1152 if (rc != PKCS11_CKR_PIN_INCORRECT) 1153 return rc; 1154 1155 token->db_main->flags |= PKCS11_CKFT_USER_PIN_COUNT_LOW; 1156 token->db_main->user_pin_count++; 1157 1158 pin_count = token->db_main->user_pin_count; 1159 if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX - 1) 1160 token->db_main->flags |= PKCS11_CKFT_USER_PIN_FINAL_TRY; 1161 if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX) 1162 token->db_main->flags |= PKCS11_CKFT_USER_PIN_LOCKED; 1163 1164 update_persistent_db(token); 1165 1166 if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED) 1167 return PKCS11_CKR_PIN_LOCKED; 1168 1169 return PKCS11_CKR_PIN_INCORRECT; 1170 } 1171 1172 if (token->db_main->user_pin_count) { 1173 token->db_main->user_pin_count = 0; 1174 1175 update_persistent_db(token); 1176 } 1177 1178 if (token->db_main->flags & (PKCS11_CKFT_USER_PIN_COUNT_LOW | 1179 PKCS11_CKFT_USER_PIN_FINAL_TRY)) { 1180 token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_COUNT_LOW | 1181 PKCS11_CKFT_USER_PIN_FINAL_TRY); 1182 1183 update_persistent_db(token); 1184 } 1185 1186 return PKCS11_CKR_OK; 1187 } 1188 1189 enum pkcs11_rc entry_ck_set_pin(struct pkcs11_client *client, 1190 uint32_t ptypes, TEE_Param *params) 1191 { 1192 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1193 TEE_PARAM_TYPE_NONE, 1194 TEE_PARAM_TYPE_NONE, 1195 TEE_PARAM_TYPE_NONE); 1196 struct pkcs11_session *session = NULL; 1197 enum pkcs11_rc rc = PKCS11_CKR_OK; 1198 struct serialargs ctrlargs = { }; 1199 uint32_t old_pin_size = 0; 1200 TEE_Param *ctrl = params; 1201 uint32_t pin_size = 0; 1202 void *old_pin = NULL; 1203 void *pin = NULL; 1204 1205 if (!client || ptypes != exp_pt) 1206 return PKCS11_CKR_ARGUMENTS_BAD; 1207 1208 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1209 1210 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1211 if (rc) 1212 return rc; 1213 1214 rc = serialargs_get(&ctrlargs, &old_pin_size, sizeof(uint32_t)); 1215 if (rc) 1216 return rc; 1217 1218 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 1219 if (rc) 1220 return rc; 1221 1222 rc = serialargs_get_ptr(&ctrlargs, &old_pin, old_pin_size); 1223 if (rc) 1224 return rc; 1225 1226 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 1227 if (rc) 1228 return rc; 1229 1230 if (serialargs_remaining_bytes(&ctrlargs)) 1231 return PKCS11_CKR_ARGUMENTS_BAD; 1232 1233 if (!pkcs11_session_is_read_write(session)) 1234 return PKCS11_CKR_SESSION_READ_ONLY; 1235 1236 if (pkcs11_session_is_so(session)) { 1237 if (!(session->token->db_main->flags & 1238 PKCS11_CKFT_TOKEN_INITIALIZED)) 1239 return PKCS11_CKR_GENERAL_ERROR; 1240 1241 rc = check_so_pin(session, old_pin, old_pin_size); 1242 if (rc) 1243 return rc; 1244 1245 IMSG("PKCS11 session %"PRIu32": set PIN", session->handle); 1246 1247 return set_pin(session, pin, pin_size, PKCS11_CKU_SO); 1248 } 1249 1250 if (!(session->token->db_main->flags & 1251 PKCS11_CKFT_USER_PIN_INITIALIZED)) 1252 return PKCS11_CKR_GENERAL_ERROR; 1253 1254 rc = check_user_pin(session, old_pin, old_pin_size); 1255 if (rc) 1256 return rc; 1257 1258 IMSG("PKCS11 session %"PRIu32": set PIN", session->handle); 1259 1260 return set_pin(session, pin, pin_size, PKCS11_CKU_USER); 1261 } 1262 1263 static void session_login_user(struct pkcs11_session *session) 1264 { 1265 struct pkcs11_client *client = session->client; 1266 struct pkcs11_session *sess = NULL; 1267 1268 TAILQ_FOREACH(sess, &client->session_list, link) { 1269 if (sess->token != session->token) 1270 continue; 1271 1272 if (pkcs11_session_is_read_write(sess)) 1273 sess->state = PKCS11_CKS_RW_USER_FUNCTIONS; 1274 else 1275 sess->state = PKCS11_CKS_RO_USER_FUNCTIONS; 1276 } 1277 } 1278 1279 static void session_login_so(struct pkcs11_session *session) 1280 { 1281 struct pkcs11_client *client = session->client; 1282 struct pkcs11_session *sess = NULL; 1283 1284 TAILQ_FOREACH(sess, &client->session_list, link) { 1285 if (sess->token != session->token) 1286 continue; 1287 1288 if (pkcs11_session_is_read_write(sess)) 1289 sess->state = PKCS11_CKS_RW_SO_FUNCTIONS; 1290 else 1291 TEE_Panic(0); 1292 } 1293 } 1294 1295 static void session_logout(struct pkcs11_session *session) 1296 { 1297 struct pkcs11_client *client = session->client; 1298 struct pkcs11_session *sess = NULL; 1299 1300 TAILQ_FOREACH(sess, &client->session_list, link) { 1301 struct pkcs11_object *obj = NULL; 1302 struct pkcs11_object *tobj = NULL; 1303 uint32_t handle = 0; 1304 1305 if (sess->token != session->token) 1306 continue; 1307 1308 release_active_processing(session); 1309 1310 /* Destroy private session objects */ 1311 LIST_FOREACH_SAFE(obj, &sess->object_list, link, tobj) { 1312 if (object_is_private(obj->attributes)) 1313 destroy_object(sess, obj, true); 1314 } 1315 1316 /* 1317 * Remove handle of token private objects from 1318 * sessions object_handle_db 1319 */ 1320 LIST_FOREACH(obj, &session->token->object_list, link) { 1321 handle = pkcs11_object2handle(obj, session); 1322 1323 if (handle && object_is_private(obj->attributes)) 1324 handle_put(get_object_handle_db(sess), handle); 1325 } 1326 1327 release_session_find_obj_context(session); 1328 1329 if (pkcs11_session_is_read_write(sess)) 1330 sess->state = PKCS11_CKS_RW_PUBLIC_SESSION; 1331 else 1332 sess->state = PKCS11_CKS_RO_PUBLIC_SESSION; 1333 } 1334 } 1335 1336 enum pkcs11_rc entry_ck_login(struct pkcs11_client *client, 1337 uint32_t ptypes, TEE_Param *params) 1338 { 1339 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1340 TEE_PARAM_TYPE_NONE, 1341 TEE_PARAM_TYPE_NONE, 1342 TEE_PARAM_TYPE_NONE); 1343 struct pkcs11_session *session = NULL; 1344 struct pkcs11_session *sess = NULL; 1345 enum pkcs11_rc rc = PKCS11_CKR_OK; 1346 struct serialargs ctrlargs = { }; 1347 TEE_Param *ctrl = params; 1348 uint32_t user_type = 0; 1349 uint32_t pin_size = 0; 1350 void *pin = NULL; 1351 1352 if (!client || ptypes != exp_pt) 1353 return PKCS11_CKR_ARGUMENTS_BAD; 1354 1355 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1356 1357 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1358 if (rc) 1359 return rc; 1360 1361 rc = serialargs_get(&ctrlargs, &user_type, sizeof(uint32_t)); 1362 if (rc) 1363 return rc; 1364 1365 rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t)); 1366 if (rc) 1367 return rc; 1368 1369 rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size); 1370 if (rc) 1371 return rc; 1372 1373 if (serialargs_remaining_bytes(&ctrlargs)) 1374 return PKCS11_CKR_ARGUMENTS_BAD; 1375 1376 switch (user_type) { 1377 case PKCS11_CKU_SO: 1378 if (pkcs11_session_is_so(session)) 1379 return PKCS11_CKR_USER_ALREADY_LOGGED_IN; 1380 1381 if (pkcs11_session_is_user(session)) 1382 return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN; 1383 1384 TAILQ_FOREACH(sess, &client->session_list, link) 1385 if (sess->token == session->token && 1386 !pkcs11_session_is_read_write(sess)) 1387 return PKCS11_CKR_SESSION_READ_ONLY_EXISTS; 1388 1389 /* 1390 * This is the point where we could check if another client 1391 * has another user or SO logged in. 1392 * 1393 * The spec says: 1394 * CKR_USER_TOO_MANY_TYPES: An attempt was made to have 1395 * more distinct users simultaneously logged into the token 1396 * than the token and/or library permits. For example, if 1397 * some application has an open SO session, and another 1398 * application attempts to log the normal user into a 1399 * session, the attempt may return this error. It is not 1400 * required to, however. Only if the simultaneous distinct 1401 * users cannot be supported does C_Login have to return 1402 * this value. Note that this error code generalizes to 1403 * true multi-user tokens. 1404 * 1405 * So it's permitted to have another user or SO logged in 1406 * from another client. 1407 */ 1408 1409 rc = check_so_pin(session, pin, pin_size); 1410 if (!rc) 1411 session_login_so(session); 1412 1413 break; 1414 1415 case PKCS11_CKU_USER: 1416 if (pkcs11_session_is_so(session)) 1417 return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN; 1418 1419 if (pkcs11_session_is_user(session)) 1420 return PKCS11_CKR_USER_ALREADY_LOGGED_IN; 1421 1422 /* 1423 * This is the point where we could check if another client 1424 * has another user or SO logged in. 1425 * See comment on CKR_USER_TOO_MANY_TYPES above. 1426 */ 1427 1428 rc = check_user_pin(session, pin, pin_size); 1429 if (!rc) 1430 session_login_user(session); 1431 1432 break; 1433 1434 case PKCS11_CKU_CONTEXT_SPECIFIC: 1435 return PKCS11_CKR_OPERATION_NOT_INITIALIZED; 1436 1437 default: 1438 return PKCS11_CKR_USER_TYPE_INVALID; 1439 } 1440 1441 if (!rc) 1442 IMSG("PKCS11 session %"PRIu32": login", session->handle); 1443 1444 return rc; 1445 } 1446 1447 enum pkcs11_rc entry_ck_logout(struct pkcs11_client *client, 1448 uint32_t ptypes, TEE_Param *params) 1449 { 1450 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1451 TEE_PARAM_TYPE_NONE, 1452 TEE_PARAM_TYPE_NONE, 1453 TEE_PARAM_TYPE_NONE); 1454 struct pkcs11_session *session = NULL; 1455 enum pkcs11_rc rc = PKCS11_CKR_OK; 1456 struct serialargs ctrlargs = { }; 1457 TEE_Param *ctrl = params; 1458 1459 if (!client || ptypes != exp_pt) 1460 return PKCS11_CKR_ARGUMENTS_BAD; 1461 1462 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1463 1464 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1465 if (rc) 1466 return rc; 1467 1468 if (serialargs_remaining_bytes(&ctrlargs)) 1469 return PKCS11_CKR_ARGUMENTS_BAD; 1470 1471 if (pkcs11_session_is_public(session)) 1472 return PKCS11_CKR_USER_NOT_LOGGED_IN; 1473 1474 session_logout(session); 1475 1476 IMSG("PKCS11 session %"PRIu32": logout", session->handle); 1477 1478 return PKCS11_CKR_OK; 1479 } 1480 1481 static TEE_Result seed_rng_pool(void *seed, size_t length) 1482 { 1483 static const TEE_UUID system_uuid = PTA_SYSTEM_UUID; 1484 uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 1485 TEE_PARAM_TYPE_NONE, 1486 TEE_PARAM_TYPE_NONE, 1487 TEE_PARAM_TYPE_NONE); 1488 TEE_Param params[TEE_NUM_PARAMS] = { }; 1489 TEE_TASessionHandle sess = TEE_HANDLE_NULL; 1490 TEE_Result res = TEE_ERROR_GENERIC; 1491 uint32_t ret_orig = 0; 1492 1493 params[0].memref.buffer = seed; 1494 params[0].memref.size = (uint32_t)length; 1495 1496 res = TEE_OpenTASession(&system_uuid, TEE_TIMEOUT_INFINITE, 0, NULL, 1497 &sess, &ret_orig); 1498 if (res != TEE_SUCCESS) { 1499 EMSG("Can't open session to system PTA"); 1500 return res; 1501 } 1502 1503 res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE, 1504 PTA_SYSTEM_ADD_RNG_ENTROPY, 1505 param_types, params, &ret_orig); 1506 if (res != TEE_SUCCESS) 1507 EMSG("Can't invoke system PTA"); 1508 1509 TEE_CloseTASession(sess); 1510 return res; 1511 } 1512 1513 enum pkcs11_rc entry_ck_seed_random(struct pkcs11_client *client, 1514 uint32_t ptypes, TEE_Param *params) 1515 { 1516 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1517 TEE_PARAM_TYPE_MEMREF_INPUT, 1518 TEE_PARAM_TYPE_NONE, 1519 TEE_PARAM_TYPE_NONE); 1520 TEE_Param *ctrl = params; 1521 TEE_Param *in = params + 1; 1522 enum pkcs11_rc rc = PKCS11_CKR_OK; 1523 struct serialargs ctrlargs = { }; 1524 struct pkcs11_session *session = NULL; 1525 TEE_Result res = TEE_SUCCESS; 1526 1527 if (!client || ptypes != exp_pt) 1528 return PKCS11_CKR_ARGUMENTS_BAD; 1529 1530 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1531 1532 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1533 if (rc) 1534 return rc; 1535 1536 if (serialargs_remaining_bytes(&ctrlargs)) 1537 return PKCS11_CKR_ARGUMENTS_BAD; 1538 1539 if (in->memref.size && !in->memref.buffer) 1540 return PKCS11_CKR_ARGUMENTS_BAD; 1541 1542 if (!in->memref.size) 1543 return PKCS11_CKR_OK; 1544 1545 res = seed_rng_pool(in->memref.buffer, in->memref.size); 1546 if (res != TEE_SUCCESS) 1547 return PKCS11_CKR_FUNCTION_FAILED; 1548 1549 DMSG("PKCS11 session %"PRIu32": seed random", session->handle); 1550 1551 return PKCS11_CKR_OK; 1552 } 1553 1554 enum pkcs11_rc entry_ck_generate_random(struct pkcs11_client *client, 1555 uint32_t ptypes, TEE_Param *params) 1556 { 1557 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 1558 TEE_PARAM_TYPE_NONE, 1559 TEE_PARAM_TYPE_MEMREF_OUTPUT, 1560 TEE_PARAM_TYPE_NONE); 1561 TEE_Param *ctrl = params; 1562 TEE_Param *out = params + 2; 1563 enum pkcs11_rc rc = PKCS11_CKR_OK; 1564 struct serialargs ctrlargs = { }; 1565 struct pkcs11_session *session = NULL; 1566 void *buffer = NULL; 1567 size_t buffer_size = 0; 1568 uint8_t *data = NULL; 1569 size_t left = 0; 1570 1571 if (!client || ptypes != exp_pt) 1572 return PKCS11_CKR_ARGUMENTS_BAD; 1573 1574 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 1575 1576 rc = serialargs_get_session_from_handle(&ctrlargs, client, &session); 1577 if (rc) 1578 return rc; 1579 1580 if (serialargs_remaining_bytes(&ctrlargs)) 1581 return PKCS11_CKR_ARGUMENTS_BAD; 1582 1583 if (out->memref.size && !out->memref.buffer) 1584 return PKCS11_CKR_ARGUMENTS_BAD; 1585 1586 if (!out->memref.size) 1587 return PKCS11_CKR_OK; 1588 1589 buffer_size = MIN(out->memref.size, RNG_CHUNK_SIZE); 1590 buffer = TEE_Malloc(buffer_size, TEE_MALLOC_FILL_ZERO); 1591 if (!buffer) 1592 return PKCS11_CKR_DEVICE_MEMORY; 1593 1594 data = out->memref.buffer; 1595 left = out->memref.size; 1596 1597 while (left) { 1598 size_t count = MIN(left, buffer_size); 1599 1600 TEE_GenerateRandom(buffer, count); 1601 TEE_MemMove(data, buffer, count); 1602 1603 data += count; 1604 left -= count; 1605 } 1606 1607 DMSG("PKCS11 session %"PRIu32": generate random", session->handle); 1608 1609 TEE_Free(buffer); 1610 1611 return PKCS11_CKR_OK; 1612 } 1613