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 return PKCS11_CKR_BUFFER_TOO_SMALL; 353 } 354 355 if (!array) 356 return PKCS11_CKR_DEVICE_MEMORY; 357 358 dmsg_print_supported_mechanism(token_id, array, count); 359 360 out->memref.size = count * sizeof(*array); 361 TEE_MemMove(out->memref.buffer, array, out->memref.size); 362 363 TEE_Free(array); 364 365 return rv; 366 } 367 368 static void supported_mechanism_key_size(uint32_t proc_id, 369 uint32_t *max_key_size, 370 uint32_t *min_key_size) 371 { 372 switch (proc_id) { 373 /* Will be filled once TA supports mechanisms */ 374 default: 375 *min_key_size = 0; 376 *max_key_size = 0; 377 break; 378 } 379 } 380 381 uint32_t entry_ck_token_mecha_info(uint32_t ptypes, TEE_Param *params) 382 { 383 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 384 TEE_PARAM_TYPE_NONE, 385 TEE_PARAM_TYPE_MEMREF_OUTPUT, 386 TEE_PARAM_TYPE_NONE); 387 TEE_Param *ctrl = ¶ms[0]; 388 TEE_Param *out = ¶ms[2]; 389 uint32_t rv = 0; 390 struct serialargs ctrlargs = { }; 391 uint32_t token_id = 0; 392 uint32_t type = 0; 393 struct ck_token *token = NULL; 394 struct pkcs11_mechanism_info info = { }; 395 396 if (ptypes != exp_pt || out->memref.size != sizeof(info)) 397 return PKCS11_CKR_ARGUMENTS_BAD; 398 399 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 400 401 rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 402 if (rv) 403 return rv; 404 405 rv = serialargs_get(&ctrlargs, &type, sizeof(uint32_t)); 406 if (rv) 407 return rv; 408 409 if (serialargs_remaining_bytes(&ctrlargs)) 410 return PKCS11_CKR_ARGUMENTS_BAD; 411 412 token = get_token(token_id); 413 if (!token) 414 return PKCS11_CKR_SLOT_ID_INVALID; 415 416 if (!mechanism_is_valid(type)) 417 return PKCS11_CKR_MECHANISM_INVALID; 418 419 info.flags = mechanism_supported_flags(type); 420 421 supported_mechanism_key_size(type, &info.min_key_size, 422 &info.max_key_size); 423 424 TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 425 426 DMSG("PKCS11 token %"PRIu32": mechanism 0x%"PRIx32" info", 427 token_id, type); 428 429 return PKCS11_CKR_OK; 430 } 431 432 /* Select the ReadOnly or ReadWrite state for session login state */ 433 static void set_session_state(struct pkcs11_client *client, 434 struct pkcs11_session *session, bool readonly) 435 { 436 struct pkcs11_session *sess = NULL; 437 enum pkcs11_session_state state = PKCS11_CKS_RO_PUBLIC_SESSION; 438 439 /* Default to public session if no session already registered */ 440 if (readonly) 441 state = PKCS11_CKS_RO_PUBLIC_SESSION; 442 else 443 state = PKCS11_CKS_RW_PUBLIC_SESSION; 444 445 /* 446 * No need to check all client sessions, the first found in 447 * target token gives client login configuration. 448 */ 449 TAILQ_FOREACH(sess, &client->session_list, link) { 450 assert(sess != session); 451 452 if (sess->token == session->token) { 453 switch (sess->state) { 454 case PKCS11_CKS_RW_PUBLIC_SESSION: 455 case PKCS11_CKS_RO_PUBLIC_SESSION: 456 if (readonly) 457 state = PKCS11_CKS_RO_PUBLIC_SESSION; 458 else 459 state = PKCS11_CKS_RW_PUBLIC_SESSION; 460 break; 461 case PKCS11_CKS_RO_USER_FUNCTIONS: 462 case PKCS11_CKS_RW_USER_FUNCTIONS: 463 if (readonly) 464 state = PKCS11_CKS_RO_USER_FUNCTIONS; 465 else 466 state = PKCS11_CKS_RW_USER_FUNCTIONS; 467 break; 468 case PKCS11_CKS_RW_SO_FUNCTIONS: 469 if (readonly) 470 TEE_Panic(0); 471 else 472 state = PKCS11_CKS_RW_SO_FUNCTIONS; 473 break; 474 default: 475 TEE_Panic(0); 476 } 477 break; 478 } 479 } 480 481 session->state = state; 482 } 483 484 uint32_t entry_ck_open_session(struct pkcs11_client *client, 485 uint32_t ptypes, TEE_Param *params) 486 { 487 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 488 TEE_PARAM_TYPE_NONE, 489 TEE_PARAM_TYPE_MEMREF_OUTPUT, 490 TEE_PARAM_TYPE_NONE); 491 TEE_Param *ctrl = ¶ms[0]; 492 TEE_Param *out = ¶ms[2]; 493 uint32_t rv = 0; 494 struct serialargs ctrlargs = { }; 495 uint32_t token_id = 0; 496 uint32_t flags = 0; 497 struct ck_token *token = NULL; 498 struct pkcs11_session *session = NULL; 499 bool readonly = false; 500 501 if (!client || ptypes != exp_pt || 502 out->memref.size != sizeof(session->handle)) 503 return PKCS11_CKR_ARGUMENTS_BAD; 504 505 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 506 507 rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 508 if (rv) 509 return rv; 510 511 rv = serialargs_get(&ctrlargs, &flags, sizeof(flags)); 512 if (rv) 513 return rv; 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 /* Sanitize session flags */ 523 if (!(flags & PKCS11_CKFSS_SERIAL_SESSION) || 524 (flags & ~(PKCS11_CKFSS_RW_SESSION | 525 PKCS11_CKFSS_SERIAL_SESSION))) 526 return PKCS11_CKR_ARGUMENTS_BAD; 527 528 readonly = !(flags & PKCS11_CKFSS_RW_SESSION); 529 530 if (!readonly && token->state == PKCS11_TOKEN_READ_ONLY) 531 return PKCS11_CKR_TOKEN_WRITE_PROTECTED; 532 533 if (readonly) { 534 /* Specifically reject read-only session under SO login */ 535 TAILQ_FOREACH(session, &client->session_list, link) 536 if (pkcs11_session_is_so(session)) 537 return PKCS11_CKR_SESSION_READ_WRITE_SO_EXISTS; 538 } 539 540 session = TEE_Malloc(sizeof(*session), TEE_MALLOC_FILL_ZERO); 541 if (!session) 542 return PKCS11_CKR_DEVICE_MEMORY; 543 544 session->handle = handle_get(&client->session_handle_db, session); 545 if (!session->handle) { 546 TEE_Free(session); 547 return PKCS11_CKR_DEVICE_MEMORY; 548 } 549 550 session->token = token; 551 session->client = client; 552 553 set_session_state(client, session, readonly); 554 555 TAILQ_INSERT_HEAD(&client->session_list, session, link); 556 557 session->token->session_count++; 558 if (!readonly) 559 session->token->rw_session_count++; 560 561 TEE_MemMove(out->memref.buffer, &session->handle, 562 sizeof(session->handle)); 563 564 DMSG("Open PKCS11 session %"PRIu32, session->handle); 565 566 return PKCS11_CKR_OK; 567 } 568 569 static void close_ck_session(struct pkcs11_session *session) 570 { 571 TAILQ_REMOVE(&session->client->session_list, session, link); 572 handle_put(&session->client->session_handle_db, session->handle); 573 574 session->token->session_count--; 575 if (pkcs11_session_is_read_write(session)) 576 session->token->rw_session_count--; 577 578 TEE_Free(session); 579 580 DMSG("Close PKCS11 session %"PRIu32, session->handle); 581 } 582 583 uint32_t entry_ck_close_session(struct pkcs11_client *client, 584 uint32_t ptypes, TEE_Param *params) 585 { 586 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 587 TEE_PARAM_TYPE_NONE, 588 TEE_PARAM_TYPE_NONE, 589 TEE_PARAM_TYPE_NONE); 590 TEE_Param *ctrl = ¶ms[0]; 591 uint32_t rv = 0; 592 struct serialargs ctrlargs = { }; 593 uint32_t session_handle = 0; 594 struct pkcs11_session *session = NULL; 595 596 if (!client || ptypes != exp_pt) 597 return PKCS11_CKR_ARGUMENTS_BAD; 598 599 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 600 601 rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t)); 602 if (rv) 603 return rv; 604 605 if (serialargs_remaining_bytes(&ctrlargs)) 606 return PKCS11_CKR_ARGUMENTS_BAD; 607 608 session = pkcs11_handle2session(session_handle, client); 609 if (!session) 610 return PKCS11_CKR_SESSION_HANDLE_INVALID; 611 612 close_ck_session(session); 613 614 return PKCS11_CKR_OK; 615 } 616 617 uint32_t entry_ck_close_all_sessions(struct pkcs11_client *client, 618 uint32_t ptypes, TEE_Param *params) 619 { 620 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 621 TEE_PARAM_TYPE_NONE, 622 TEE_PARAM_TYPE_NONE, 623 TEE_PARAM_TYPE_NONE); 624 TEE_Param *ctrl = ¶ms[0]; 625 uint32_t rv = 0; 626 struct serialargs ctrlargs = { }; 627 uint32_t token_id = 0; 628 struct ck_token *token = NULL; 629 struct pkcs11_session *session = NULL; 630 struct pkcs11_session *next = NULL; 631 632 if (!client || ptypes != exp_pt) 633 return PKCS11_CKR_ARGUMENTS_BAD; 634 635 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 636 637 rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 638 if (rv) 639 return rv; 640 641 if (serialargs_remaining_bytes(&ctrlargs)) 642 return PKCS11_CKR_ARGUMENTS_BAD; 643 644 token = get_token(token_id); 645 if (!token) 646 return PKCS11_CKR_SLOT_ID_INVALID; 647 648 DMSG("Close all sessions for PKCS11 token %"PRIu32, token_id); 649 650 TAILQ_FOREACH_SAFE(session, &client->session_list, link, next) 651 if (session->token == token) 652 close_ck_session(session); 653 654 return PKCS11_CKR_OK; 655 } 656 657 uint32_t entry_ck_session_info(struct pkcs11_client *client, 658 uint32_t ptypes, TEE_Param *params) 659 { 660 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 661 TEE_PARAM_TYPE_NONE, 662 TEE_PARAM_TYPE_MEMREF_OUTPUT, 663 TEE_PARAM_TYPE_NONE); 664 TEE_Param *ctrl = ¶ms[0]; 665 TEE_Param *out = ¶ms[2]; 666 uint32_t rv = 0; 667 struct serialargs ctrlargs = { }; 668 uint32_t session_handle = 0; 669 struct pkcs11_session *session = NULL; 670 struct pkcs11_session_info info = { 671 .flags = PKCS11_CKFSS_SERIAL_SESSION, 672 }; 673 674 if (!client || ptypes != exp_pt || out->memref.size != sizeof(info)) 675 return PKCS11_CKR_ARGUMENTS_BAD; 676 677 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 678 679 rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t)); 680 if (rv) 681 return rv; 682 683 if (serialargs_remaining_bytes(&ctrlargs)) 684 return PKCS11_CKR_ARGUMENTS_BAD; 685 686 session = pkcs11_handle2session(session_handle, client); 687 if (!session) 688 return PKCS11_CKR_SESSION_HANDLE_INVALID; 689 690 info.slot_id = get_token_id(session->token); 691 info.state = session->state; 692 if (pkcs11_session_is_read_write(session)) 693 info.flags |= PKCS11_CKFSS_RW_SESSION; 694 695 TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 696 697 DMSG("Get find on PKCS11 session %"PRIu32, session->handle); 698 699 return PKCS11_CKR_OK; 700 } 701