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