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