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