1c84ccd0aSEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause 2c84ccd0aSEtienne Carriere /* 3c84ccd0aSEtienne Carriere * Copyright (c) 2017-2020, Linaro Limited 4c84ccd0aSEtienne Carriere */ 5c84ccd0aSEtienne Carriere 6c84ccd0aSEtienne Carriere #include <assert.h> 7d38f9635SEtienne Carriere #include <confine_array_index.h> 8c84ccd0aSEtienne Carriere #include <pkcs11_ta.h> 9c84ccd0aSEtienne Carriere #include <string.h> 10c84ccd0aSEtienne Carriere #include <string_ext.h> 11c84ccd0aSEtienne Carriere #include <sys/queue.h> 12c84ccd0aSEtienne Carriere #include <tee_api_types.h> 13c84ccd0aSEtienne Carriere #include <tee_internal_api_extensions.h> 14c84ccd0aSEtienne Carriere #include <util.h> 15c84ccd0aSEtienne Carriere 16c84ccd0aSEtienne Carriere #include "pkcs11_token.h" 17c84ccd0aSEtienne Carriere #include "pkcs11_helpers.h" 1822ac6984SEtienne Carriere #include "serializer.h" 19c84ccd0aSEtienne Carriere 20c84ccd0aSEtienne Carriere /* Provide 3 slots/tokens, ID is token index */ 21c84ccd0aSEtienne Carriere #ifndef CFG_PKCS11_TA_TOKEN_COUNT 22c84ccd0aSEtienne Carriere #define TOKEN_COUNT 3 23c84ccd0aSEtienne Carriere #else 24c84ccd0aSEtienne Carriere #define TOKEN_COUNT CFG_PKCS11_TA_TOKEN_COUNT 25c84ccd0aSEtienne Carriere #endif 26c84ccd0aSEtienne Carriere 27e084583eSEtienne Carriere /* 28e084583eSEtienne Carriere * Structure tracking client applications 29e084583eSEtienne Carriere * 30e084583eSEtienne Carriere * @link - chained list of registered client applications 31e084583eSEtienne Carriere * @sessions - list of the PKCS11 sessions opened by the client application 32e084583eSEtienne Carriere */ 33e084583eSEtienne Carriere struct pkcs11_client { 34e084583eSEtienne Carriere TAILQ_ENTRY(pkcs11_client) link; 35e084583eSEtienne Carriere struct session_list session_list; 36e084583eSEtienne Carriere struct handle_db session_handle_db; 37e084583eSEtienne Carriere }; 38e084583eSEtienne Carriere 39c84ccd0aSEtienne Carriere /* Static allocation of tokens runtime instances (reset to 0 at load) */ 40c84ccd0aSEtienne Carriere struct ck_token ck_token[TOKEN_COUNT]; 41c84ccd0aSEtienne Carriere 42e084583eSEtienne Carriere static struct client_list pkcs11_client_list = 43e084583eSEtienne Carriere TAILQ_HEAD_INITIALIZER(pkcs11_client_list); 44e084583eSEtienne Carriere 45*6e4f8f17SEtienne Carriere static void close_ck_session(struct pkcs11_session *session); 46*6e4f8f17SEtienne Carriere 47c84ccd0aSEtienne Carriere struct ck_token *get_token(unsigned int token_id) 48c84ccd0aSEtienne Carriere { 49d38f9635SEtienne Carriere if (token_id < TOKEN_COUNT) 50d38f9635SEtienne Carriere return &ck_token[confine_array_index(token_id, TOKEN_COUNT)]; 51c84ccd0aSEtienne Carriere 52d38f9635SEtienne Carriere return NULL; 53c84ccd0aSEtienne Carriere } 54c84ccd0aSEtienne Carriere 55c84ccd0aSEtienne Carriere unsigned int get_token_id(struct ck_token *token) 56c84ccd0aSEtienne Carriere { 57c84ccd0aSEtienne Carriere ptrdiff_t id = token - ck_token; 58c84ccd0aSEtienne Carriere 59c84ccd0aSEtienne Carriere assert(id >= 0 && id < TOKEN_COUNT); 60c84ccd0aSEtienne Carriere return id; 61c84ccd0aSEtienne Carriere } 62c84ccd0aSEtienne Carriere 63e084583eSEtienne Carriere struct pkcs11_client *tee_session2client(void *tee_session) 64e084583eSEtienne Carriere { 65e084583eSEtienne Carriere struct pkcs11_client *client = NULL; 66e084583eSEtienne Carriere 67e084583eSEtienne Carriere TAILQ_FOREACH(client, &pkcs11_client_list, link) 68e084583eSEtienne Carriere if (client == tee_session) 69e084583eSEtienne Carriere break; 70e084583eSEtienne Carriere 71e084583eSEtienne Carriere return client; 72e084583eSEtienne Carriere } 73e084583eSEtienne Carriere 74*6e4f8f17SEtienne Carriere struct pkcs11_session *pkcs11_handle2session(uint32_t handle, 75*6e4f8f17SEtienne Carriere struct pkcs11_client *client) 76*6e4f8f17SEtienne Carriere { 77*6e4f8f17SEtienne Carriere return handle_lookup(&client->session_handle_db, handle); 78*6e4f8f17SEtienne Carriere } 79*6e4f8f17SEtienne Carriere 80e084583eSEtienne Carriere struct pkcs11_client *register_client(void) 81e084583eSEtienne Carriere { 82e084583eSEtienne Carriere struct pkcs11_client *client = NULL; 83e084583eSEtienne Carriere 84e084583eSEtienne Carriere client = TEE_Malloc(sizeof(*client), TEE_MALLOC_FILL_ZERO); 85e084583eSEtienne Carriere if (!client) 86e084583eSEtienne Carriere return NULL; 87e084583eSEtienne Carriere 88e084583eSEtienne Carriere TAILQ_INSERT_HEAD(&pkcs11_client_list, client, link); 89e084583eSEtienne Carriere TAILQ_INIT(&client->session_list); 90e084583eSEtienne Carriere handle_db_init(&client->session_handle_db); 91e084583eSEtienne Carriere 92e084583eSEtienne Carriere return client; 93e084583eSEtienne Carriere } 94e084583eSEtienne Carriere 95e084583eSEtienne Carriere void unregister_client(struct pkcs11_client *client) 96e084583eSEtienne Carriere { 97*6e4f8f17SEtienne Carriere struct pkcs11_session *session = NULL; 98*6e4f8f17SEtienne Carriere struct pkcs11_session *next = NULL; 99*6e4f8f17SEtienne Carriere 100e084583eSEtienne Carriere if (!client) { 101e084583eSEtienne Carriere EMSG("Invalid TEE session handle"); 102e084583eSEtienne Carriere return; 103e084583eSEtienne Carriere } 104e084583eSEtienne Carriere 105*6e4f8f17SEtienne Carriere TAILQ_FOREACH_SAFE(session, &client->session_list, link, next) 106*6e4f8f17SEtienne Carriere close_ck_session(session); 107*6e4f8f17SEtienne Carriere 108e084583eSEtienne Carriere TAILQ_REMOVE(&pkcs11_client_list, client, link); 109e084583eSEtienne Carriere handle_db_destroy(&client->session_handle_db); 110e084583eSEtienne Carriere TEE_Free(client); 111e084583eSEtienne Carriere } 112e084583eSEtienne Carriere 113c84ccd0aSEtienne Carriere static TEE_Result pkcs11_token_init(unsigned int id) 114c84ccd0aSEtienne Carriere { 115c84ccd0aSEtienne Carriere struct ck_token *token = init_persistent_db(id); 116c84ccd0aSEtienne Carriere 117c84ccd0aSEtienne Carriere if (!token) 118c84ccd0aSEtienne Carriere return TEE_ERROR_SECURITY; 119c84ccd0aSEtienne Carriere 120c84ccd0aSEtienne Carriere if (token->state == PKCS11_TOKEN_RESET) { 121c84ccd0aSEtienne Carriere /* As per PKCS#11 spec, token resets to read/write state */ 122c84ccd0aSEtienne Carriere token->state = PKCS11_TOKEN_READ_WRITE; 123c84ccd0aSEtienne Carriere token->session_count = 0; 124c84ccd0aSEtienne Carriere token->rw_session_count = 0; 125c84ccd0aSEtienne Carriere } 126c84ccd0aSEtienne Carriere 127c84ccd0aSEtienne Carriere return TEE_SUCCESS; 128c84ccd0aSEtienne Carriere } 129c84ccd0aSEtienne Carriere 130c84ccd0aSEtienne Carriere TEE_Result pkcs11_init(void) 131c84ccd0aSEtienne Carriere { 132c84ccd0aSEtienne Carriere unsigned int id = 0; 133c84ccd0aSEtienne Carriere TEE_Result ret = TEE_ERROR_GENERIC; 134c84ccd0aSEtienne Carriere 135c84ccd0aSEtienne Carriere for (id = 0; id < TOKEN_COUNT; id++) { 136c84ccd0aSEtienne Carriere ret = pkcs11_token_init(id); 137c84ccd0aSEtienne Carriere if (ret) 138e084583eSEtienne Carriere break; 139c84ccd0aSEtienne Carriere } 140c84ccd0aSEtienne Carriere 141c84ccd0aSEtienne Carriere return ret; 142c84ccd0aSEtienne Carriere } 143c84ccd0aSEtienne Carriere 144c84ccd0aSEtienne Carriere void pkcs11_deinit(void) 145c84ccd0aSEtienne Carriere { 146c84ccd0aSEtienne Carriere unsigned int id = 0; 147c84ccd0aSEtienne Carriere 148c84ccd0aSEtienne Carriere for (id = 0; id < TOKEN_COUNT; id++) 149c84ccd0aSEtienne Carriere close_persistent_db(get_token(id)); 150c84ccd0aSEtienne Carriere } 15122ac6984SEtienne Carriere 15222ac6984SEtienne Carriere uint32_t entry_ck_slot_list(uint32_t ptypes, TEE_Param *params) 15322ac6984SEtienne Carriere { 15422ac6984SEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 15522ac6984SEtienne Carriere TEE_PARAM_TYPE_NONE, 15622ac6984SEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 15722ac6984SEtienne Carriere TEE_PARAM_TYPE_NONE); 15822ac6984SEtienne Carriere TEE_Param *out = ¶ms[2]; 15922ac6984SEtienne Carriere uint32_t token_id = 0; 16022ac6984SEtienne Carriere const size_t out_size = sizeof(token_id) * TOKEN_COUNT; 16122ac6984SEtienne Carriere uint8_t *id = NULL; 16222ac6984SEtienne Carriere 16322ac6984SEtienne Carriere if (ptypes != exp_pt || 16422ac6984SEtienne Carriere params[0].memref.size != TEE_PARAM0_SIZE_MIN) 16522ac6984SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 16622ac6984SEtienne Carriere 16722ac6984SEtienne Carriere if (out->memref.size < out_size) { 16822ac6984SEtienne Carriere out->memref.size = out_size; 16922ac6984SEtienne Carriere 17022ac6984SEtienne Carriere if (out->memref.buffer) 17122ac6984SEtienne Carriere return PKCS11_CKR_BUFFER_TOO_SMALL; 17222ac6984SEtienne Carriere else 17322ac6984SEtienne Carriere return PKCS11_CKR_OK; 17422ac6984SEtienne Carriere } 17522ac6984SEtienne Carriere 17622ac6984SEtienne Carriere for (token_id = 0, id = out->memref.buffer; token_id < TOKEN_COUNT; 17722ac6984SEtienne Carriere token_id++, id += sizeof(token_id)) 17822ac6984SEtienne Carriere TEE_MemMove(id, &token_id, sizeof(token_id)); 17922ac6984SEtienne Carriere 18022ac6984SEtienne Carriere out->memref.size = out_size; 18122ac6984SEtienne Carriere 18222ac6984SEtienne Carriere return PKCS11_CKR_OK; 18322ac6984SEtienne Carriere } 184ce94efefSEtienne Carriere 185b3ac5035SEtienne Carriere static void pad_str(uint8_t *str, size_t size) 186b3ac5035SEtienne Carriere { 187b3ac5035SEtienne Carriere int n = strnlen((char *)str, size); 188b3ac5035SEtienne Carriere 189b3ac5035SEtienne Carriere TEE_MemFill(str + n, ' ', size - n); 190b3ac5035SEtienne Carriere } 191b3ac5035SEtienne Carriere 192ce94efefSEtienne Carriere uint32_t entry_ck_slot_info(uint32_t ptypes, TEE_Param *params) 193ce94efefSEtienne Carriere { 194ce94efefSEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 195ce94efefSEtienne Carriere TEE_PARAM_TYPE_NONE, 196ce94efefSEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 197ce94efefSEtienne Carriere TEE_PARAM_TYPE_NONE); 198ce94efefSEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 199ce94efefSEtienne Carriere TEE_Param *out = ¶ms[2]; 200ce94efefSEtienne Carriere uint32_t rv = 0; 201ce94efefSEtienne Carriere struct serialargs ctrlargs = { }; 202ce94efefSEtienne Carriere uint32_t token_id = 0; 203ce94efefSEtienne Carriere struct ck_token *token = NULL; 204ce94efefSEtienne Carriere struct pkcs11_slot_info info = { 205ce94efefSEtienne Carriere .slot_description = PKCS11_SLOT_DESCRIPTION, 206ce94efefSEtienne Carriere .manufacturer_id = PKCS11_SLOT_MANUFACTURER, 207ce94efefSEtienne Carriere .flags = PKCS11_CKFS_TOKEN_PRESENT, 208ce94efefSEtienne Carriere .hardware_version = PKCS11_SLOT_HW_VERSION, 209ce94efefSEtienne Carriere .firmware_version = PKCS11_SLOT_FW_VERSION, 210ce94efefSEtienne Carriere }; 211ce94efefSEtienne Carriere 212ce94efefSEtienne Carriere COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_DESCRIPTION) <= 213ce94efefSEtienne Carriere sizeof(info.slot_description)); 214ce94efefSEtienne Carriere COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_MANUFACTURER) <= 215ce94efefSEtienne Carriere sizeof(info.manufacturer_id)); 216ce94efefSEtienne Carriere 217ce94efefSEtienne Carriere if (ptypes != exp_pt || out->memref.size != sizeof(info)) 218ce94efefSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 219ce94efefSEtienne Carriere 220ce94efefSEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 221ce94efefSEtienne Carriere 222ce94efefSEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 223ce94efefSEtienne Carriere if (rv) 224ce94efefSEtienne Carriere return rv; 225ce94efefSEtienne Carriere 226ce94efefSEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 227ce94efefSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 228ce94efefSEtienne Carriere 229ce94efefSEtienne Carriere token = get_token(token_id); 230ce94efefSEtienne Carriere if (!token) 231ce94efefSEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 232ce94efefSEtienne Carriere 233b3ac5035SEtienne Carriere pad_str(info.slot_description, sizeof(info.slot_description)); 234b3ac5035SEtienne Carriere pad_str(info.manufacturer_id, sizeof(info.manufacturer_id)); 235ce94efefSEtienne Carriere 236ce94efefSEtienne Carriere out->memref.size = sizeof(info); 237ce94efefSEtienne Carriere TEE_MemMove(out->memref.buffer, &info, out->memref.size); 238ce94efefSEtienne Carriere 239ce94efefSEtienne Carriere return PKCS11_CKR_OK; 240ce94efefSEtienne Carriere } 241030e7392SEtienne Carriere 242030e7392SEtienne Carriere uint32_t entry_ck_token_info(uint32_t ptypes, TEE_Param *params) 243030e7392SEtienne Carriere { 244030e7392SEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 245030e7392SEtienne Carriere TEE_PARAM_TYPE_NONE, 246030e7392SEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 247030e7392SEtienne Carriere TEE_PARAM_TYPE_NONE); 248030e7392SEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 249030e7392SEtienne Carriere TEE_Param *out = ¶ms[2]; 250030e7392SEtienne Carriere uint32_t rv = 0; 251030e7392SEtienne Carriere struct serialargs ctrlargs = { }; 252030e7392SEtienne Carriere uint32_t token_id = 0; 253030e7392SEtienne Carriere struct ck_token *token = NULL; 254030e7392SEtienne Carriere struct pkcs11_token_info info = { 255030e7392SEtienne Carriere .manufacturer_id = PKCS11_TOKEN_MANUFACTURER, 256030e7392SEtienne Carriere .model = PKCS11_TOKEN_MODEL, 257030e7392SEtienne Carriere .serial_number = PKCS11_TOKEN_SERIAL_NUMBER, 258030e7392SEtienne Carriere .max_session_count = UINT32_MAX, 259030e7392SEtienne Carriere .max_rw_session_count = UINT32_MAX, 260030e7392SEtienne Carriere .max_pin_len = PKCS11_TOKEN_PIN_SIZE_MAX, 261030e7392SEtienne Carriere .min_pin_len = PKCS11_TOKEN_PIN_SIZE_MIN, 262030e7392SEtienne Carriere .total_public_memory = UINT32_MAX, 263030e7392SEtienne Carriere .free_public_memory = UINT32_MAX, 264030e7392SEtienne Carriere .total_private_memory = UINT32_MAX, 265030e7392SEtienne Carriere .free_private_memory = UINT32_MAX, 266030e7392SEtienne Carriere .hardware_version = PKCS11_TOKEN_HW_VERSION, 267030e7392SEtienne Carriere .firmware_version = PKCS11_TOKEN_FW_VERSION, 268030e7392SEtienne Carriere }; 269030e7392SEtienne Carriere 270030e7392SEtienne Carriere if (ptypes != exp_pt || out->memref.size != sizeof(info)) 271030e7392SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 272030e7392SEtienne Carriere 273030e7392SEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 274030e7392SEtienne Carriere 275030e7392SEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 276030e7392SEtienne Carriere if (rv) 277030e7392SEtienne Carriere return rv; 278030e7392SEtienne Carriere 279030e7392SEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 280030e7392SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 281030e7392SEtienne Carriere 282030e7392SEtienne Carriere token = get_token(token_id); 283030e7392SEtienne Carriere if (!token) 284030e7392SEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 285030e7392SEtienne Carriere 286030e7392SEtienne Carriere pad_str(info.manufacturer_id, sizeof(info.manufacturer_id)); 287030e7392SEtienne Carriere pad_str(info.model, sizeof(info.model)); 288030e7392SEtienne Carriere pad_str(info.serial_number, sizeof(info.serial_number)); 289030e7392SEtienne Carriere 290030e7392SEtienne Carriere TEE_MemMove(info.label, token->db_main->label, sizeof(info.label)); 291030e7392SEtienne Carriere 292030e7392SEtienne Carriere info.flags = token->db_main->flags; 293030e7392SEtienne Carriere info.session_count = token->session_count; 294030e7392SEtienne Carriere info.rw_session_count = token->rw_session_count; 295030e7392SEtienne Carriere 296030e7392SEtienne Carriere TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 297030e7392SEtienne Carriere 298030e7392SEtienne Carriere return PKCS11_CKR_OK; 299030e7392SEtienne Carriere } 3006f74919dSEtienne Carriere 3016f74919dSEtienne Carriere static void dmsg_print_supported_mechanism(unsigned int token_id __maybe_unused, 3026f74919dSEtienne Carriere uint32_t *array __maybe_unused, 3036f74919dSEtienne Carriere size_t count __maybe_unused) 3046f74919dSEtienne Carriere { 3056f74919dSEtienne Carriere size_t __maybe_unused n = 0; 3066f74919dSEtienne Carriere 3076f74919dSEtienne Carriere if (TRACE_LEVEL < TRACE_DEBUG) 3086f74919dSEtienne Carriere return; 3096f74919dSEtienne Carriere 3106f74919dSEtienne Carriere for (n = 0; n < count; n++) 3116f74919dSEtienne Carriere DMSG("PKCS11 token %"PRIu32": mechanism 0x%04"PRIx32": %s", 3126f74919dSEtienne Carriere token_id, array[n], id2str_mechanism(array[n])); 3136f74919dSEtienne Carriere } 3146f74919dSEtienne Carriere 3156f74919dSEtienne Carriere uint32_t entry_ck_token_mecha_ids(uint32_t ptypes, TEE_Param *params) 3166f74919dSEtienne Carriere { 3176f74919dSEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 3186f74919dSEtienne Carriere TEE_PARAM_TYPE_NONE, 3196f74919dSEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 3206f74919dSEtienne Carriere TEE_PARAM_TYPE_NONE); 3216f74919dSEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 3226f74919dSEtienne Carriere TEE_Param *out = ¶ms[2]; 3236f74919dSEtienne Carriere uint32_t rv = 0; 3246f74919dSEtienne Carriere struct serialargs ctrlargs = { }; 3256f74919dSEtienne Carriere uint32_t token_id = 0; 3266f74919dSEtienne Carriere struct ck_token __maybe_unused *token = NULL; 3276f74919dSEtienne Carriere size_t count = 0; 3286f74919dSEtienne Carriere uint32_t *array = NULL; 3296f74919dSEtienne Carriere 3306f74919dSEtienne Carriere if (ptypes != exp_pt) 3316f74919dSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 3326f74919dSEtienne Carriere 3336f74919dSEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 3346f74919dSEtienne Carriere 3356f74919dSEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 3366f74919dSEtienne Carriere if (rv) 3376f74919dSEtienne Carriere return rv; 3386f74919dSEtienne Carriere 3396f74919dSEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 3406f74919dSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 3416f74919dSEtienne Carriere 3426f74919dSEtienne Carriere token = get_token(token_id); 3436f74919dSEtienne Carriere if (!token) 3446f74919dSEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 3456f74919dSEtienne Carriere 3466f74919dSEtienne Carriere count = out->memref.size / sizeof(*array); 3476f74919dSEtienne Carriere array = tee_malloc_mechanism_list(&count); 3486f74919dSEtienne Carriere 3496f74919dSEtienne Carriere if (out->memref.size < count * sizeof(*array)) { 3506f74919dSEtienne Carriere assert(!array); 3516f74919dSEtienne Carriere out->memref.size = count * sizeof(*array); 3526f74919dSEtienne Carriere return PKCS11_CKR_BUFFER_TOO_SMALL; 3536f74919dSEtienne Carriere } 3546f74919dSEtienne Carriere 3556f74919dSEtienne Carriere if (!array) 3566f74919dSEtienne Carriere return PKCS11_CKR_DEVICE_MEMORY; 3576f74919dSEtienne Carriere 3586f74919dSEtienne Carriere dmsg_print_supported_mechanism(token_id, array, count); 3596f74919dSEtienne Carriere 3606f74919dSEtienne Carriere out->memref.size = count * sizeof(*array); 3616f74919dSEtienne Carriere TEE_MemMove(out->memref.buffer, array, out->memref.size); 3626f74919dSEtienne Carriere 3636f74919dSEtienne Carriere TEE_Free(array); 3646f74919dSEtienne Carriere 3656f74919dSEtienne Carriere return rv; 3666f74919dSEtienne Carriere } 3671d3ebedbSEtienne Carriere 3681d3ebedbSEtienne Carriere static void supported_mechanism_key_size(uint32_t proc_id, 3691d3ebedbSEtienne Carriere uint32_t *max_key_size, 3701d3ebedbSEtienne Carriere uint32_t *min_key_size) 3711d3ebedbSEtienne Carriere { 3721d3ebedbSEtienne Carriere switch (proc_id) { 3731d3ebedbSEtienne Carriere /* Will be filled once TA supports mechanisms */ 3741d3ebedbSEtienne Carriere default: 3751d3ebedbSEtienne Carriere *min_key_size = 0; 3761d3ebedbSEtienne Carriere *max_key_size = 0; 3771d3ebedbSEtienne Carriere break; 3781d3ebedbSEtienne Carriere } 3791d3ebedbSEtienne Carriere } 3801d3ebedbSEtienne Carriere 3811d3ebedbSEtienne Carriere uint32_t entry_ck_token_mecha_info(uint32_t ptypes, TEE_Param *params) 3821d3ebedbSEtienne Carriere { 3831d3ebedbSEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 3841d3ebedbSEtienne Carriere TEE_PARAM_TYPE_NONE, 3851d3ebedbSEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 3861d3ebedbSEtienne Carriere TEE_PARAM_TYPE_NONE); 3871d3ebedbSEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 3881d3ebedbSEtienne Carriere TEE_Param *out = ¶ms[2]; 3891d3ebedbSEtienne Carriere uint32_t rv = 0; 3901d3ebedbSEtienne Carriere struct serialargs ctrlargs = { }; 3911d3ebedbSEtienne Carriere uint32_t token_id = 0; 3921d3ebedbSEtienne Carriere uint32_t type = 0; 3931d3ebedbSEtienne Carriere struct ck_token *token = NULL; 3941d3ebedbSEtienne Carriere struct pkcs11_mechanism_info info = { }; 3951d3ebedbSEtienne Carriere 3961d3ebedbSEtienne Carriere if (ptypes != exp_pt || out->memref.size != sizeof(info)) 3971d3ebedbSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 3981d3ebedbSEtienne Carriere 3991d3ebedbSEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 4001d3ebedbSEtienne Carriere 4011d3ebedbSEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 4021d3ebedbSEtienne Carriere if (rv) 4031d3ebedbSEtienne Carriere return rv; 4041d3ebedbSEtienne Carriere 4051d3ebedbSEtienne Carriere rv = serialargs_get(&ctrlargs, &type, sizeof(uint32_t)); 4061d3ebedbSEtienne Carriere if (rv) 4071d3ebedbSEtienne Carriere return rv; 4081d3ebedbSEtienne Carriere 4091d3ebedbSEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 4101d3ebedbSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 4111d3ebedbSEtienne Carriere 4121d3ebedbSEtienne Carriere token = get_token(token_id); 4131d3ebedbSEtienne Carriere if (!token) 4141d3ebedbSEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 4151d3ebedbSEtienne Carriere 4161d3ebedbSEtienne Carriere if (!mechanism_is_valid(type)) 4171d3ebedbSEtienne Carriere return PKCS11_CKR_MECHANISM_INVALID; 4181d3ebedbSEtienne Carriere 4191d3ebedbSEtienne Carriere info.flags = mechanism_supported_flags(type); 4201d3ebedbSEtienne Carriere 4211d3ebedbSEtienne Carriere supported_mechanism_key_size(type, &info.min_key_size, 4221d3ebedbSEtienne Carriere &info.max_key_size); 4231d3ebedbSEtienne Carriere 4241d3ebedbSEtienne Carriere TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 4251d3ebedbSEtienne Carriere 4261d3ebedbSEtienne Carriere DMSG("PKCS11 token %"PRIu32": mechanism 0x%"PRIx32" info", 4271d3ebedbSEtienne Carriere token_id, type); 4281d3ebedbSEtienne Carriere 4291d3ebedbSEtienne Carriere return PKCS11_CKR_OK; 4301d3ebedbSEtienne Carriere } 431*6e4f8f17SEtienne Carriere 432*6e4f8f17SEtienne Carriere /* Select the ReadOnly or ReadWrite state for session login state */ 433*6e4f8f17SEtienne Carriere static void set_session_state(struct pkcs11_client *client, 434*6e4f8f17SEtienne Carriere struct pkcs11_session *session, bool readonly) 435*6e4f8f17SEtienne Carriere { 436*6e4f8f17SEtienne Carriere struct pkcs11_session *sess = NULL; 437*6e4f8f17SEtienne Carriere enum pkcs11_session_state state = PKCS11_CKS_RO_PUBLIC_SESSION; 438*6e4f8f17SEtienne Carriere 439*6e4f8f17SEtienne Carriere /* Default to public session if no session already registered */ 440*6e4f8f17SEtienne Carriere if (readonly) 441*6e4f8f17SEtienne Carriere state = PKCS11_CKS_RO_PUBLIC_SESSION; 442*6e4f8f17SEtienne Carriere else 443*6e4f8f17SEtienne Carriere state = PKCS11_CKS_RW_PUBLIC_SESSION; 444*6e4f8f17SEtienne Carriere 445*6e4f8f17SEtienne Carriere /* 446*6e4f8f17SEtienne Carriere * No need to check all client sessions, the first found in 447*6e4f8f17SEtienne Carriere * target token gives client login configuration. 448*6e4f8f17SEtienne Carriere */ 449*6e4f8f17SEtienne Carriere TAILQ_FOREACH(sess, &client->session_list, link) { 450*6e4f8f17SEtienne Carriere assert(sess != session); 451*6e4f8f17SEtienne Carriere 452*6e4f8f17SEtienne Carriere if (sess->token == session->token) { 453*6e4f8f17SEtienne Carriere switch (sess->state) { 454*6e4f8f17SEtienne Carriere case PKCS11_CKS_RW_PUBLIC_SESSION: 455*6e4f8f17SEtienne Carriere case PKCS11_CKS_RO_PUBLIC_SESSION: 456*6e4f8f17SEtienne Carriere if (readonly) 457*6e4f8f17SEtienne Carriere state = PKCS11_CKS_RO_PUBLIC_SESSION; 458*6e4f8f17SEtienne Carriere else 459*6e4f8f17SEtienne Carriere state = PKCS11_CKS_RW_PUBLIC_SESSION; 460*6e4f8f17SEtienne Carriere break; 461*6e4f8f17SEtienne Carriere case PKCS11_CKS_RO_USER_FUNCTIONS: 462*6e4f8f17SEtienne Carriere case PKCS11_CKS_RW_USER_FUNCTIONS: 463*6e4f8f17SEtienne Carriere if (readonly) 464*6e4f8f17SEtienne Carriere state = PKCS11_CKS_RO_USER_FUNCTIONS; 465*6e4f8f17SEtienne Carriere else 466*6e4f8f17SEtienne Carriere state = PKCS11_CKS_RW_USER_FUNCTIONS; 467*6e4f8f17SEtienne Carriere break; 468*6e4f8f17SEtienne Carriere case PKCS11_CKS_RW_SO_FUNCTIONS: 469*6e4f8f17SEtienne Carriere if (readonly) 470*6e4f8f17SEtienne Carriere TEE_Panic(0); 471*6e4f8f17SEtienne Carriere else 472*6e4f8f17SEtienne Carriere state = PKCS11_CKS_RW_SO_FUNCTIONS; 473*6e4f8f17SEtienne Carriere break; 474*6e4f8f17SEtienne Carriere default: 475*6e4f8f17SEtienne Carriere TEE_Panic(0); 476*6e4f8f17SEtienne Carriere } 477*6e4f8f17SEtienne Carriere break; 478*6e4f8f17SEtienne Carriere } 479*6e4f8f17SEtienne Carriere } 480*6e4f8f17SEtienne Carriere 481*6e4f8f17SEtienne Carriere session->state = state; 482*6e4f8f17SEtienne Carriere } 483*6e4f8f17SEtienne Carriere 484*6e4f8f17SEtienne Carriere uint32_t entry_ck_open_session(struct pkcs11_client *client, 485*6e4f8f17SEtienne Carriere uint32_t ptypes, TEE_Param *params) 486*6e4f8f17SEtienne Carriere { 487*6e4f8f17SEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 488*6e4f8f17SEtienne Carriere TEE_PARAM_TYPE_NONE, 489*6e4f8f17SEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 490*6e4f8f17SEtienne Carriere TEE_PARAM_TYPE_NONE); 491*6e4f8f17SEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 492*6e4f8f17SEtienne Carriere TEE_Param *out = ¶ms[2]; 493*6e4f8f17SEtienne Carriere uint32_t rv = 0; 494*6e4f8f17SEtienne Carriere struct serialargs ctrlargs = { }; 495*6e4f8f17SEtienne Carriere uint32_t token_id = 0; 496*6e4f8f17SEtienne Carriere uint32_t flags = 0; 497*6e4f8f17SEtienne Carriere struct ck_token *token = NULL; 498*6e4f8f17SEtienne Carriere struct pkcs11_session *session = NULL; 499*6e4f8f17SEtienne Carriere bool readonly = false; 500*6e4f8f17SEtienne Carriere 501*6e4f8f17SEtienne Carriere if (!client || ptypes != exp_pt || 502*6e4f8f17SEtienne Carriere out->memref.size != sizeof(session->handle)) 503*6e4f8f17SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 504*6e4f8f17SEtienne Carriere 505*6e4f8f17SEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 506*6e4f8f17SEtienne Carriere 507*6e4f8f17SEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 508*6e4f8f17SEtienne Carriere if (rv) 509*6e4f8f17SEtienne Carriere return rv; 510*6e4f8f17SEtienne Carriere 511*6e4f8f17SEtienne Carriere rv = serialargs_get(&ctrlargs, &flags, sizeof(flags)); 512*6e4f8f17SEtienne Carriere if (rv) 513*6e4f8f17SEtienne Carriere return rv; 514*6e4f8f17SEtienne Carriere 515*6e4f8f17SEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 516*6e4f8f17SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 517*6e4f8f17SEtienne Carriere 518*6e4f8f17SEtienne Carriere token = get_token(token_id); 519*6e4f8f17SEtienne Carriere if (!token) 520*6e4f8f17SEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 521*6e4f8f17SEtienne Carriere 522*6e4f8f17SEtienne Carriere /* Sanitize session flags */ 523*6e4f8f17SEtienne Carriere if (!(flags & PKCS11_CKFSS_SERIAL_SESSION) || 524*6e4f8f17SEtienne Carriere (flags & ~(PKCS11_CKFSS_RW_SESSION | 525*6e4f8f17SEtienne Carriere PKCS11_CKFSS_SERIAL_SESSION))) 526*6e4f8f17SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 527*6e4f8f17SEtienne Carriere 528*6e4f8f17SEtienne Carriere readonly = !(flags & PKCS11_CKFSS_RW_SESSION); 529*6e4f8f17SEtienne Carriere 530*6e4f8f17SEtienne Carriere if (!readonly && token->state == PKCS11_TOKEN_READ_ONLY) 531*6e4f8f17SEtienne Carriere return PKCS11_CKR_TOKEN_WRITE_PROTECTED; 532*6e4f8f17SEtienne Carriere 533*6e4f8f17SEtienne Carriere if (readonly) { 534*6e4f8f17SEtienne Carriere /* Specifically reject read-only session under SO login */ 535*6e4f8f17SEtienne Carriere TAILQ_FOREACH(session, &client->session_list, link) 536*6e4f8f17SEtienne Carriere if (pkcs11_session_is_so(session)) 537*6e4f8f17SEtienne Carriere return PKCS11_CKR_SESSION_READ_WRITE_SO_EXISTS; 538*6e4f8f17SEtienne Carriere } 539*6e4f8f17SEtienne Carriere 540*6e4f8f17SEtienne Carriere session = TEE_Malloc(sizeof(*session), TEE_MALLOC_FILL_ZERO); 541*6e4f8f17SEtienne Carriere if (!session) 542*6e4f8f17SEtienne Carriere return PKCS11_CKR_DEVICE_MEMORY; 543*6e4f8f17SEtienne Carriere 544*6e4f8f17SEtienne Carriere session->handle = handle_get(&client->session_handle_db, session); 545*6e4f8f17SEtienne Carriere if (!session->handle) { 546*6e4f8f17SEtienne Carriere TEE_Free(session); 547*6e4f8f17SEtienne Carriere return PKCS11_CKR_DEVICE_MEMORY; 548*6e4f8f17SEtienne Carriere } 549*6e4f8f17SEtienne Carriere 550*6e4f8f17SEtienne Carriere session->token = token; 551*6e4f8f17SEtienne Carriere session->client = client; 552*6e4f8f17SEtienne Carriere 553*6e4f8f17SEtienne Carriere set_session_state(client, session, readonly); 554*6e4f8f17SEtienne Carriere 555*6e4f8f17SEtienne Carriere TAILQ_INSERT_HEAD(&client->session_list, session, link); 556*6e4f8f17SEtienne Carriere 557*6e4f8f17SEtienne Carriere session->token->session_count++; 558*6e4f8f17SEtienne Carriere if (!readonly) 559*6e4f8f17SEtienne Carriere session->token->rw_session_count++; 560*6e4f8f17SEtienne Carriere 561*6e4f8f17SEtienne Carriere TEE_MemMove(out->memref.buffer, &session->handle, 562*6e4f8f17SEtienne Carriere sizeof(session->handle)); 563*6e4f8f17SEtienne Carriere 564*6e4f8f17SEtienne Carriere DMSG("Open PKCS11 session %"PRIu32, session->handle); 565*6e4f8f17SEtienne Carriere 566*6e4f8f17SEtienne Carriere return PKCS11_CKR_OK; 567*6e4f8f17SEtienne Carriere } 568*6e4f8f17SEtienne Carriere 569*6e4f8f17SEtienne Carriere static void close_ck_session(struct pkcs11_session *session) 570*6e4f8f17SEtienne Carriere { 571*6e4f8f17SEtienne Carriere TAILQ_REMOVE(&session->client->session_list, session, link); 572*6e4f8f17SEtienne Carriere handle_put(&session->client->session_handle_db, session->handle); 573*6e4f8f17SEtienne Carriere 574*6e4f8f17SEtienne Carriere session->token->session_count--; 575*6e4f8f17SEtienne Carriere if (pkcs11_session_is_read_write(session)) 576*6e4f8f17SEtienne Carriere session->token->rw_session_count--; 577*6e4f8f17SEtienne Carriere 578*6e4f8f17SEtienne Carriere TEE_Free(session); 579*6e4f8f17SEtienne Carriere 580*6e4f8f17SEtienne Carriere DMSG("Close PKCS11 session %"PRIu32, session->handle); 581*6e4f8f17SEtienne Carriere } 582*6e4f8f17SEtienne Carriere 583*6e4f8f17SEtienne Carriere uint32_t entry_ck_close_session(struct pkcs11_client *client, 584*6e4f8f17SEtienne Carriere uint32_t ptypes, TEE_Param *params) 585*6e4f8f17SEtienne Carriere { 586*6e4f8f17SEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 587*6e4f8f17SEtienne Carriere TEE_PARAM_TYPE_NONE, 588*6e4f8f17SEtienne Carriere TEE_PARAM_TYPE_NONE, 589*6e4f8f17SEtienne Carriere TEE_PARAM_TYPE_NONE); 590*6e4f8f17SEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 591*6e4f8f17SEtienne Carriere uint32_t rv = 0; 592*6e4f8f17SEtienne Carriere struct serialargs ctrlargs = { }; 593*6e4f8f17SEtienne Carriere uint32_t session_handle = 0; 594*6e4f8f17SEtienne Carriere struct pkcs11_session *session = NULL; 595*6e4f8f17SEtienne Carriere 596*6e4f8f17SEtienne Carriere if (!client || ptypes != exp_pt) 597*6e4f8f17SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 598*6e4f8f17SEtienne Carriere 599*6e4f8f17SEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 600*6e4f8f17SEtienne Carriere 601*6e4f8f17SEtienne Carriere rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t)); 602*6e4f8f17SEtienne Carriere if (rv) 603*6e4f8f17SEtienne Carriere return rv; 604*6e4f8f17SEtienne Carriere 605*6e4f8f17SEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 606*6e4f8f17SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 607*6e4f8f17SEtienne Carriere 608*6e4f8f17SEtienne Carriere session = pkcs11_handle2session(session_handle, client); 609*6e4f8f17SEtienne Carriere if (!session) 610*6e4f8f17SEtienne Carriere return PKCS11_CKR_SESSION_HANDLE_INVALID; 611*6e4f8f17SEtienne Carriere 612*6e4f8f17SEtienne Carriere close_ck_session(session); 613*6e4f8f17SEtienne Carriere 614*6e4f8f17SEtienne Carriere return PKCS11_CKR_OK; 615*6e4f8f17SEtienne Carriere } 616*6e4f8f17SEtienne Carriere 617*6e4f8f17SEtienne Carriere uint32_t entry_ck_close_all_sessions(struct pkcs11_client *client, 618*6e4f8f17SEtienne Carriere uint32_t ptypes, TEE_Param *params) 619*6e4f8f17SEtienne Carriere { 620*6e4f8f17SEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 621*6e4f8f17SEtienne Carriere TEE_PARAM_TYPE_NONE, 622*6e4f8f17SEtienne Carriere TEE_PARAM_TYPE_NONE, 623*6e4f8f17SEtienne Carriere TEE_PARAM_TYPE_NONE); 624*6e4f8f17SEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 625*6e4f8f17SEtienne Carriere uint32_t rv = 0; 626*6e4f8f17SEtienne Carriere struct serialargs ctrlargs = { }; 627*6e4f8f17SEtienne Carriere uint32_t token_id = 0; 628*6e4f8f17SEtienne Carriere struct ck_token *token = NULL; 629*6e4f8f17SEtienne Carriere struct pkcs11_session *session = NULL; 630*6e4f8f17SEtienne Carriere struct pkcs11_session *next = NULL; 631*6e4f8f17SEtienne Carriere 632*6e4f8f17SEtienne Carriere if (!client || ptypes != exp_pt) 633*6e4f8f17SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 634*6e4f8f17SEtienne Carriere 635*6e4f8f17SEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 636*6e4f8f17SEtienne Carriere 637*6e4f8f17SEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 638*6e4f8f17SEtienne Carriere if (rv) 639*6e4f8f17SEtienne Carriere return rv; 640*6e4f8f17SEtienne Carriere 641*6e4f8f17SEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 642*6e4f8f17SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 643*6e4f8f17SEtienne Carriere 644*6e4f8f17SEtienne Carriere token = get_token(token_id); 645*6e4f8f17SEtienne Carriere if (!token) 646*6e4f8f17SEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 647*6e4f8f17SEtienne Carriere 648*6e4f8f17SEtienne Carriere DMSG("Close all sessions for PKCS11 token %"PRIu32, token_id); 649*6e4f8f17SEtienne Carriere 650*6e4f8f17SEtienne Carriere TAILQ_FOREACH_SAFE(session, &client->session_list, link, next) 651*6e4f8f17SEtienne Carriere if (session->token == token) 652*6e4f8f17SEtienne Carriere close_ck_session(session); 653*6e4f8f17SEtienne Carriere 654*6e4f8f17SEtienne Carriere return PKCS11_CKR_OK; 655*6e4f8f17SEtienne Carriere } 656*6e4f8f17SEtienne Carriere 657*6e4f8f17SEtienne Carriere uint32_t entry_ck_session_info(struct pkcs11_client *client, 658*6e4f8f17SEtienne Carriere uint32_t ptypes, TEE_Param *params) 659*6e4f8f17SEtienne Carriere { 660*6e4f8f17SEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 661*6e4f8f17SEtienne Carriere TEE_PARAM_TYPE_NONE, 662*6e4f8f17SEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 663*6e4f8f17SEtienne Carriere TEE_PARAM_TYPE_NONE); 664*6e4f8f17SEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 665*6e4f8f17SEtienne Carriere TEE_Param *out = ¶ms[2]; 666*6e4f8f17SEtienne Carriere uint32_t rv = 0; 667*6e4f8f17SEtienne Carriere struct serialargs ctrlargs = { }; 668*6e4f8f17SEtienne Carriere uint32_t session_handle = 0; 669*6e4f8f17SEtienne Carriere struct pkcs11_session *session = NULL; 670*6e4f8f17SEtienne Carriere struct pkcs11_session_info info = { 671*6e4f8f17SEtienne Carriere .flags = PKCS11_CKFSS_SERIAL_SESSION, 672*6e4f8f17SEtienne Carriere }; 673*6e4f8f17SEtienne Carriere 674*6e4f8f17SEtienne Carriere if (!client || ptypes != exp_pt || out->memref.size != sizeof(info)) 675*6e4f8f17SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 676*6e4f8f17SEtienne Carriere 677*6e4f8f17SEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 678*6e4f8f17SEtienne Carriere 679*6e4f8f17SEtienne Carriere rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t)); 680*6e4f8f17SEtienne Carriere if (rv) 681*6e4f8f17SEtienne Carriere return rv; 682*6e4f8f17SEtienne Carriere 683*6e4f8f17SEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 684*6e4f8f17SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 685*6e4f8f17SEtienne Carriere 686*6e4f8f17SEtienne Carriere session = pkcs11_handle2session(session_handle, client); 687*6e4f8f17SEtienne Carriere if (!session) 688*6e4f8f17SEtienne Carriere return PKCS11_CKR_SESSION_HANDLE_INVALID; 689*6e4f8f17SEtienne Carriere 690*6e4f8f17SEtienne Carriere info.slot_id = get_token_id(session->token); 691*6e4f8f17SEtienne Carriere info.state = session->state; 692*6e4f8f17SEtienne Carriere if (pkcs11_session_is_read_write(session)) 693*6e4f8f17SEtienne Carriere info.flags |= PKCS11_CKFSS_RW_SESSION; 694*6e4f8f17SEtienne Carriere 695*6e4f8f17SEtienne Carriere TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 696*6e4f8f17SEtienne Carriere 697*6e4f8f17SEtienne Carriere DMSG("Get find on PKCS11 session %"PRIu32, session->handle); 698*6e4f8f17SEtienne Carriere 699*6e4f8f17SEtienne Carriere return PKCS11_CKR_OK; 700*6e4f8f17SEtienne Carriere } 701