1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2017-2020, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <confine_array_index.h> 8 #include <pkcs11_ta.h> 9 #include <string.h> 10 #include <string_ext.h> 11 #include <sys/queue.h> 12 #include <tee_api_types.h> 13 #include <tee_internal_api_extensions.h> 14 #include <util.h> 15 16 #include "pkcs11_helpers.h" 17 #include "pkcs11_token.h" 18 #include "serializer.h" 19 20 /* Provide 3 slots/tokens, ID is token index */ 21 #ifndef CFG_PKCS11_TA_TOKEN_COUNT 22 #define TOKEN_COUNT 3 23 #else 24 #define TOKEN_COUNT CFG_PKCS11_TA_TOKEN_COUNT 25 #endif 26 27 /* 28 * Structure tracking client applications 29 * 30 * @link - chained list of registered client applications 31 * @sessions - list of the PKCS11 sessions opened by the client application 32 */ 33 struct pkcs11_client { 34 TAILQ_ENTRY(pkcs11_client) link; 35 struct session_list session_list; 36 struct handle_db session_handle_db; 37 }; 38 39 /* Static allocation of tokens runtime instances (reset to 0 at load) */ 40 struct ck_token ck_token[TOKEN_COUNT]; 41 42 static struct client_list pkcs11_client_list = 43 TAILQ_HEAD_INITIALIZER(pkcs11_client_list); 44 45 static void close_ck_session(struct pkcs11_session *session); 46 47 struct ck_token *get_token(unsigned int token_id) 48 { 49 if (token_id < TOKEN_COUNT) 50 return &ck_token[confine_array_index(token_id, TOKEN_COUNT)]; 51 52 return NULL; 53 } 54 55 unsigned int get_token_id(struct ck_token *token) 56 { 57 ptrdiff_t id = token - ck_token; 58 59 assert(id >= 0 && id < TOKEN_COUNT); 60 return id; 61 } 62 63 struct pkcs11_client *tee_session2client(void *tee_session) 64 { 65 struct pkcs11_client *client = NULL; 66 67 TAILQ_FOREACH(client, &pkcs11_client_list, link) 68 if (client == tee_session) 69 break; 70 71 return client; 72 } 73 74 struct pkcs11_session *pkcs11_handle2session(uint32_t handle, 75 struct pkcs11_client *client) 76 { 77 return handle_lookup(&client->session_handle_db, handle); 78 } 79 80 struct pkcs11_client *register_client(void) 81 { 82 struct pkcs11_client *client = NULL; 83 84 client = TEE_Malloc(sizeof(*client), TEE_MALLOC_FILL_ZERO); 85 if (!client) 86 return NULL; 87 88 TAILQ_INSERT_HEAD(&pkcs11_client_list, client, link); 89 TAILQ_INIT(&client->session_list); 90 handle_db_init(&client->session_handle_db); 91 92 return client; 93 } 94 95 void unregister_client(struct pkcs11_client *client) 96 { 97 struct pkcs11_session *session = NULL; 98 struct pkcs11_session *next = NULL; 99 100 if (!client) { 101 EMSG("Invalid TEE session handle"); 102 return; 103 } 104 105 TAILQ_FOREACH_SAFE(session, &client->session_list, link, next) 106 close_ck_session(session); 107 108 TAILQ_REMOVE(&pkcs11_client_list, client, link); 109 handle_db_destroy(&client->session_handle_db); 110 TEE_Free(client); 111 } 112 113 static TEE_Result pkcs11_token_init(unsigned int id) 114 { 115 struct ck_token *token = init_persistent_db(id); 116 117 if (!token) 118 return TEE_ERROR_SECURITY; 119 120 if (token->state == PKCS11_TOKEN_RESET) { 121 /* As per PKCS#11 spec, token resets to read/write state */ 122 token->state = PKCS11_TOKEN_READ_WRITE; 123 token->session_count = 0; 124 token->rw_session_count = 0; 125 } 126 127 return TEE_SUCCESS; 128 } 129 130 TEE_Result pkcs11_init(void) 131 { 132 unsigned int id = 0; 133 TEE_Result ret = TEE_ERROR_GENERIC; 134 135 for (id = 0; id < TOKEN_COUNT; id++) { 136 ret = pkcs11_token_init(id); 137 if (ret) 138 break; 139 } 140 141 return ret; 142 } 143 144 void pkcs11_deinit(void) 145 { 146 unsigned int id = 0; 147 148 for (id = 0; id < TOKEN_COUNT; id++) 149 close_persistent_db(get_token(id)); 150 } 151 152 uint32_t entry_ck_slot_list(uint32_t ptypes, TEE_Param *params) 153 { 154 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 155 TEE_PARAM_TYPE_NONE, 156 TEE_PARAM_TYPE_MEMREF_OUTPUT, 157 TEE_PARAM_TYPE_NONE); 158 TEE_Param *out = ¶ms[2]; 159 uint32_t token_id = 0; 160 const size_t out_size = sizeof(token_id) * TOKEN_COUNT; 161 uint8_t *id = NULL; 162 163 if (ptypes != exp_pt || 164 params[0].memref.size != TEE_PARAM0_SIZE_MIN) 165 return PKCS11_CKR_ARGUMENTS_BAD; 166 167 if (out->memref.size < out_size) { 168 out->memref.size = out_size; 169 170 if (out->memref.buffer) 171 return PKCS11_CKR_BUFFER_TOO_SMALL; 172 else 173 return PKCS11_CKR_OK; 174 } 175 176 for (token_id = 0, id = out->memref.buffer; token_id < TOKEN_COUNT; 177 token_id++, id += sizeof(token_id)) 178 TEE_MemMove(id, &token_id, sizeof(token_id)); 179 180 out->memref.size = out_size; 181 182 return PKCS11_CKR_OK; 183 } 184 185 static void pad_str(uint8_t *str, size_t size) 186 { 187 int n = strnlen((char *)str, size); 188 189 TEE_MemFill(str + n, ' ', size - n); 190 } 191 192 uint32_t entry_ck_slot_info(uint32_t ptypes, TEE_Param *params) 193 { 194 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 195 TEE_PARAM_TYPE_NONE, 196 TEE_PARAM_TYPE_MEMREF_OUTPUT, 197 TEE_PARAM_TYPE_NONE); 198 TEE_Param *ctrl = ¶ms[0]; 199 TEE_Param *out = ¶ms[2]; 200 uint32_t rv = 0; 201 struct serialargs ctrlargs = { }; 202 uint32_t token_id = 0; 203 struct ck_token *token = NULL; 204 struct pkcs11_slot_info info = { 205 .slot_description = PKCS11_SLOT_DESCRIPTION, 206 .manufacturer_id = PKCS11_SLOT_MANUFACTURER, 207 .flags = PKCS11_CKFS_TOKEN_PRESENT, 208 .hardware_version = PKCS11_SLOT_HW_VERSION, 209 .firmware_version = PKCS11_SLOT_FW_VERSION, 210 }; 211 212 COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_DESCRIPTION) <= 213 sizeof(info.slot_description)); 214 COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_MANUFACTURER) <= 215 sizeof(info.manufacturer_id)); 216 217 if (ptypes != exp_pt || out->memref.size != sizeof(info)) 218 return PKCS11_CKR_ARGUMENTS_BAD; 219 220 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 221 222 rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 223 if (rv) 224 return rv; 225 226 if (serialargs_remaining_bytes(&ctrlargs)) 227 return PKCS11_CKR_ARGUMENTS_BAD; 228 229 token = get_token(token_id); 230 if (!token) 231 return PKCS11_CKR_SLOT_ID_INVALID; 232 233 pad_str(info.slot_description, sizeof(info.slot_description)); 234 pad_str(info.manufacturer_id, sizeof(info.manufacturer_id)); 235 236 out->memref.size = sizeof(info); 237 TEE_MemMove(out->memref.buffer, &info, out->memref.size); 238 239 return PKCS11_CKR_OK; 240 } 241 242 uint32_t entry_ck_token_info(uint32_t ptypes, TEE_Param *params) 243 { 244 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 245 TEE_PARAM_TYPE_NONE, 246 TEE_PARAM_TYPE_MEMREF_OUTPUT, 247 TEE_PARAM_TYPE_NONE); 248 TEE_Param *ctrl = ¶ms[0]; 249 TEE_Param *out = ¶ms[2]; 250 uint32_t rv = 0; 251 struct serialargs ctrlargs = { }; 252 uint32_t token_id = 0; 253 struct ck_token *token = NULL; 254 struct pkcs11_token_info info = { 255 .manufacturer_id = PKCS11_TOKEN_MANUFACTURER, 256 .model = PKCS11_TOKEN_MODEL, 257 .serial_number = PKCS11_TOKEN_SERIAL_NUMBER, 258 .max_session_count = UINT32_MAX, 259 .max_rw_session_count = UINT32_MAX, 260 .max_pin_len = PKCS11_TOKEN_PIN_SIZE_MAX, 261 .min_pin_len = PKCS11_TOKEN_PIN_SIZE_MIN, 262 .total_public_memory = UINT32_MAX, 263 .free_public_memory = UINT32_MAX, 264 .total_private_memory = UINT32_MAX, 265 .free_private_memory = UINT32_MAX, 266 .hardware_version = PKCS11_TOKEN_HW_VERSION, 267 .firmware_version = PKCS11_TOKEN_FW_VERSION, 268 }; 269 270 if (ptypes != exp_pt || out->memref.size != sizeof(info)) 271 return PKCS11_CKR_ARGUMENTS_BAD; 272 273 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 274 275 rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 276 if (rv) 277 return rv; 278 279 if (serialargs_remaining_bytes(&ctrlargs)) 280 return PKCS11_CKR_ARGUMENTS_BAD; 281 282 token = get_token(token_id); 283 if (!token) 284 return PKCS11_CKR_SLOT_ID_INVALID; 285 286 pad_str(info.manufacturer_id, sizeof(info.manufacturer_id)); 287 pad_str(info.model, sizeof(info.model)); 288 pad_str(info.serial_number, sizeof(info.serial_number)); 289 290 TEE_MemMove(info.label, token->db_main->label, sizeof(info.label)); 291 292 info.flags = token->db_main->flags; 293 info.session_count = token->session_count; 294 info.rw_session_count = token->rw_session_count; 295 296 TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 297 298 return PKCS11_CKR_OK; 299 } 300 301 static void dmsg_print_supported_mechanism(unsigned int token_id __maybe_unused, 302 uint32_t *array __maybe_unused, 303 size_t count __maybe_unused) 304 { 305 size_t __maybe_unused n = 0; 306 307 if (TRACE_LEVEL < TRACE_DEBUG) 308 return; 309 310 for (n = 0; n < count; n++) 311 DMSG("PKCS11 token %"PRIu32": mechanism 0x%04"PRIx32": %s", 312 token_id, array[n], id2str_mechanism(array[n])); 313 } 314 315 uint32_t entry_ck_token_mecha_ids(uint32_t ptypes, TEE_Param *params) 316 { 317 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 318 TEE_PARAM_TYPE_NONE, 319 TEE_PARAM_TYPE_MEMREF_OUTPUT, 320 TEE_PARAM_TYPE_NONE); 321 TEE_Param *ctrl = ¶ms[0]; 322 TEE_Param *out = ¶ms[2]; 323 uint32_t rv = 0; 324 struct serialargs ctrlargs = { }; 325 uint32_t token_id = 0; 326 struct ck_token __maybe_unused *token = NULL; 327 size_t count = 0; 328 uint32_t *array = NULL; 329 330 if (ptypes != exp_pt) 331 return PKCS11_CKR_ARGUMENTS_BAD; 332 333 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 334 335 rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 336 if (rv) 337 return rv; 338 339 if (serialargs_remaining_bytes(&ctrlargs)) 340 return PKCS11_CKR_ARGUMENTS_BAD; 341 342 token = get_token(token_id); 343 if (!token) 344 return PKCS11_CKR_SLOT_ID_INVALID; 345 346 count = out->memref.size / sizeof(*array); 347 array = tee_malloc_mechanism_list(&count); 348 349 if (out->memref.size < count * sizeof(*array)) { 350 assert(!array); 351 out->memref.size = count * sizeof(*array); 352 if (out->memref.buffer) 353 return PKCS11_CKR_BUFFER_TOO_SMALL; 354 else 355 return PKCS11_CKR_OK; 356 } 357 358 if (!array) 359 return PKCS11_CKR_DEVICE_MEMORY; 360 361 dmsg_print_supported_mechanism(token_id, array, count); 362 363 out->memref.size = count * sizeof(*array); 364 TEE_MemMove(out->memref.buffer, array, out->memref.size); 365 366 TEE_Free(array); 367 368 return rv; 369 } 370 371 static void supported_mechanism_key_size(uint32_t proc_id, 372 uint32_t *max_key_size, 373 uint32_t *min_key_size) 374 { 375 switch (proc_id) { 376 /* Will be filled once TA supports mechanisms */ 377 default: 378 *min_key_size = 0; 379 *max_key_size = 0; 380 break; 381 } 382 } 383 384 uint32_t entry_ck_token_mecha_info(uint32_t ptypes, TEE_Param *params) 385 { 386 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 387 TEE_PARAM_TYPE_NONE, 388 TEE_PARAM_TYPE_MEMREF_OUTPUT, 389 TEE_PARAM_TYPE_NONE); 390 TEE_Param *ctrl = ¶ms[0]; 391 TEE_Param *out = ¶ms[2]; 392 uint32_t rv = 0; 393 struct serialargs ctrlargs = { }; 394 uint32_t token_id = 0; 395 uint32_t type = 0; 396 struct ck_token *token = NULL; 397 struct pkcs11_mechanism_info info = { }; 398 399 if (ptypes != exp_pt || out->memref.size != sizeof(info)) 400 return PKCS11_CKR_ARGUMENTS_BAD; 401 402 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 403 404 rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 405 if (rv) 406 return rv; 407 408 rv = serialargs_get(&ctrlargs, &type, sizeof(uint32_t)); 409 if (rv) 410 return rv; 411 412 if (serialargs_remaining_bytes(&ctrlargs)) 413 return PKCS11_CKR_ARGUMENTS_BAD; 414 415 token = get_token(token_id); 416 if (!token) 417 return PKCS11_CKR_SLOT_ID_INVALID; 418 419 if (!mechanism_is_valid(type)) 420 return PKCS11_CKR_MECHANISM_INVALID; 421 422 info.flags = mechanism_supported_flags(type); 423 424 supported_mechanism_key_size(type, &info.min_key_size, 425 &info.max_key_size); 426 427 TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 428 429 DMSG("PKCS11 token %"PRIu32": mechanism 0x%"PRIx32" info", 430 token_id, type); 431 432 return PKCS11_CKR_OK; 433 } 434 435 /* Select the ReadOnly or ReadWrite state for session login state */ 436 static void set_session_state(struct pkcs11_client *client, 437 struct pkcs11_session *session, bool readonly) 438 { 439 struct pkcs11_session *sess = NULL; 440 enum pkcs11_session_state state = PKCS11_CKS_RO_PUBLIC_SESSION; 441 442 /* Default to public session if no session already registered */ 443 if (readonly) 444 state = PKCS11_CKS_RO_PUBLIC_SESSION; 445 else 446 state = PKCS11_CKS_RW_PUBLIC_SESSION; 447 448 /* 449 * No need to check all client sessions, the first found in 450 * target token gives client login configuration. 451 */ 452 TAILQ_FOREACH(sess, &client->session_list, link) { 453 assert(sess != session); 454 455 if (sess->token == session->token) { 456 switch (sess->state) { 457 case PKCS11_CKS_RW_PUBLIC_SESSION: 458 case PKCS11_CKS_RO_PUBLIC_SESSION: 459 if (readonly) 460 state = PKCS11_CKS_RO_PUBLIC_SESSION; 461 else 462 state = PKCS11_CKS_RW_PUBLIC_SESSION; 463 break; 464 case PKCS11_CKS_RO_USER_FUNCTIONS: 465 case PKCS11_CKS_RW_USER_FUNCTIONS: 466 if (readonly) 467 state = PKCS11_CKS_RO_USER_FUNCTIONS; 468 else 469 state = PKCS11_CKS_RW_USER_FUNCTIONS; 470 break; 471 case PKCS11_CKS_RW_SO_FUNCTIONS: 472 if (readonly) 473 TEE_Panic(0); 474 else 475 state = PKCS11_CKS_RW_SO_FUNCTIONS; 476 break; 477 default: 478 TEE_Panic(0); 479 } 480 break; 481 } 482 } 483 484 session->state = state; 485 } 486 487 uint32_t entry_ck_open_session(struct pkcs11_client *client, 488 uint32_t ptypes, TEE_Param *params) 489 { 490 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 491 TEE_PARAM_TYPE_NONE, 492 TEE_PARAM_TYPE_MEMREF_OUTPUT, 493 TEE_PARAM_TYPE_NONE); 494 TEE_Param *ctrl = ¶ms[0]; 495 TEE_Param *out = ¶ms[2]; 496 uint32_t rv = 0; 497 struct serialargs ctrlargs = { }; 498 uint32_t token_id = 0; 499 uint32_t flags = 0; 500 struct ck_token *token = NULL; 501 struct pkcs11_session *session = NULL; 502 bool readonly = false; 503 504 if (!client || ptypes != exp_pt || 505 out->memref.size != sizeof(session->handle)) 506 return PKCS11_CKR_ARGUMENTS_BAD; 507 508 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 509 510 rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 511 if (rv) 512 return rv; 513 514 rv = serialargs_get(&ctrlargs, &flags, sizeof(flags)); 515 if (rv) 516 return rv; 517 518 if (serialargs_remaining_bytes(&ctrlargs)) 519 return PKCS11_CKR_ARGUMENTS_BAD; 520 521 token = get_token(token_id); 522 if (!token) 523 return PKCS11_CKR_SLOT_ID_INVALID; 524 525 /* Sanitize session flags */ 526 if (!(flags & PKCS11_CKFSS_SERIAL_SESSION) || 527 (flags & ~(PKCS11_CKFSS_RW_SESSION | 528 PKCS11_CKFSS_SERIAL_SESSION))) 529 return PKCS11_CKR_ARGUMENTS_BAD; 530 531 readonly = !(flags & PKCS11_CKFSS_RW_SESSION); 532 533 if (!readonly && token->state == PKCS11_TOKEN_READ_ONLY) 534 return PKCS11_CKR_TOKEN_WRITE_PROTECTED; 535 536 if (readonly) { 537 /* Specifically reject read-only session under SO login */ 538 TAILQ_FOREACH(session, &client->session_list, link) 539 if (pkcs11_session_is_so(session)) 540 return PKCS11_CKR_SESSION_READ_WRITE_SO_EXISTS; 541 } 542 543 session = TEE_Malloc(sizeof(*session), TEE_MALLOC_FILL_ZERO); 544 if (!session) 545 return PKCS11_CKR_DEVICE_MEMORY; 546 547 session->handle = handle_get(&client->session_handle_db, session); 548 if (!session->handle) { 549 TEE_Free(session); 550 return PKCS11_CKR_DEVICE_MEMORY; 551 } 552 553 session->token = token; 554 session->client = client; 555 556 set_session_state(client, session, readonly); 557 558 TAILQ_INSERT_HEAD(&client->session_list, session, link); 559 560 session->token->session_count++; 561 if (!readonly) 562 session->token->rw_session_count++; 563 564 TEE_MemMove(out->memref.buffer, &session->handle, 565 sizeof(session->handle)); 566 567 DMSG("Open PKCS11 session %"PRIu32, session->handle); 568 569 return PKCS11_CKR_OK; 570 } 571 572 static void close_ck_session(struct pkcs11_session *session) 573 { 574 TAILQ_REMOVE(&session->client->session_list, session, link); 575 handle_put(&session->client->session_handle_db, session->handle); 576 577 session->token->session_count--; 578 if (pkcs11_session_is_read_write(session)) 579 session->token->rw_session_count--; 580 581 TEE_Free(session); 582 583 DMSG("Close PKCS11 session %"PRIu32, session->handle); 584 } 585 586 uint32_t entry_ck_close_session(struct pkcs11_client *client, 587 uint32_t ptypes, TEE_Param *params) 588 { 589 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 590 TEE_PARAM_TYPE_NONE, 591 TEE_PARAM_TYPE_NONE, 592 TEE_PARAM_TYPE_NONE); 593 TEE_Param *ctrl = ¶ms[0]; 594 uint32_t rv = 0; 595 struct serialargs ctrlargs = { }; 596 uint32_t session_handle = 0; 597 struct pkcs11_session *session = NULL; 598 599 if (!client || ptypes != exp_pt) 600 return PKCS11_CKR_ARGUMENTS_BAD; 601 602 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 603 604 rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t)); 605 if (rv) 606 return rv; 607 608 if (serialargs_remaining_bytes(&ctrlargs)) 609 return PKCS11_CKR_ARGUMENTS_BAD; 610 611 session = pkcs11_handle2session(session_handle, client); 612 if (!session) 613 return PKCS11_CKR_SESSION_HANDLE_INVALID; 614 615 close_ck_session(session); 616 617 return PKCS11_CKR_OK; 618 } 619 620 uint32_t entry_ck_close_all_sessions(struct pkcs11_client *client, 621 uint32_t ptypes, TEE_Param *params) 622 { 623 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 624 TEE_PARAM_TYPE_NONE, 625 TEE_PARAM_TYPE_NONE, 626 TEE_PARAM_TYPE_NONE); 627 TEE_Param *ctrl = ¶ms[0]; 628 uint32_t rv = 0; 629 struct serialargs ctrlargs = { }; 630 uint32_t token_id = 0; 631 struct ck_token *token = NULL; 632 struct pkcs11_session *session = NULL; 633 struct pkcs11_session *next = NULL; 634 635 if (!client || ptypes != exp_pt) 636 return PKCS11_CKR_ARGUMENTS_BAD; 637 638 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 639 640 rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 641 if (rv) 642 return rv; 643 644 if (serialargs_remaining_bytes(&ctrlargs)) 645 return PKCS11_CKR_ARGUMENTS_BAD; 646 647 token = get_token(token_id); 648 if (!token) 649 return PKCS11_CKR_SLOT_ID_INVALID; 650 651 DMSG("Close all sessions for PKCS11 token %"PRIu32, token_id); 652 653 TAILQ_FOREACH_SAFE(session, &client->session_list, link, next) 654 if (session->token == token) 655 close_ck_session(session); 656 657 return PKCS11_CKR_OK; 658 } 659 660 uint32_t entry_ck_session_info(struct pkcs11_client *client, 661 uint32_t ptypes, TEE_Param *params) 662 { 663 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 664 TEE_PARAM_TYPE_NONE, 665 TEE_PARAM_TYPE_MEMREF_OUTPUT, 666 TEE_PARAM_TYPE_NONE); 667 TEE_Param *ctrl = ¶ms[0]; 668 TEE_Param *out = ¶ms[2]; 669 uint32_t rv = 0; 670 struct serialargs ctrlargs = { }; 671 uint32_t session_handle = 0; 672 struct pkcs11_session *session = NULL; 673 struct pkcs11_session_info info = { 674 .flags = PKCS11_CKFSS_SERIAL_SESSION, 675 }; 676 677 if (!client || ptypes != exp_pt || out->memref.size != sizeof(info)) 678 return PKCS11_CKR_ARGUMENTS_BAD; 679 680 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 681 682 rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t)); 683 if (rv) 684 return rv; 685 686 if (serialargs_remaining_bytes(&ctrlargs)) 687 return PKCS11_CKR_ARGUMENTS_BAD; 688 689 session = pkcs11_handle2session(session_handle, client); 690 if (!session) 691 return PKCS11_CKR_SESSION_HANDLE_INVALID; 692 693 info.slot_id = get_token_id(session->token); 694 info.state = session->state; 695 if (pkcs11_session_is_read_write(session)) 696 info.flags |= PKCS11_CKFSS_RW_SESSION; 697 698 TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 699 700 DMSG("Get find on PKCS11 session %"PRIu32, session->handle); 701 702 return PKCS11_CKR_OK; 703 } 704