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 27*e084583eSEtienne Carriere /* 28*e084583eSEtienne Carriere * Structure tracking client applications 29*e084583eSEtienne Carriere * 30*e084583eSEtienne Carriere * @link - chained list of registered client applications 31*e084583eSEtienne Carriere * @sessions - list of the PKCS11 sessions opened by the client application 32*e084583eSEtienne Carriere */ 33*e084583eSEtienne Carriere struct pkcs11_client { 34*e084583eSEtienne Carriere TAILQ_ENTRY(pkcs11_client) link; 35*e084583eSEtienne Carriere struct session_list session_list; 36*e084583eSEtienne Carriere struct handle_db session_handle_db; 37*e084583eSEtienne Carriere }; 38*e084583eSEtienne 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 42*e084583eSEtienne Carriere static struct client_list pkcs11_client_list = 43*e084583eSEtienne Carriere TAILQ_HEAD_INITIALIZER(pkcs11_client_list); 44*e084583eSEtienne Carriere 45c84ccd0aSEtienne Carriere struct ck_token *get_token(unsigned int token_id) 46c84ccd0aSEtienne Carriere { 47d38f9635SEtienne Carriere if (token_id < TOKEN_COUNT) 48d38f9635SEtienne Carriere return &ck_token[confine_array_index(token_id, TOKEN_COUNT)]; 49c84ccd0aSEtienne Carriere 50d38f9635SEtienne Carriere return NULL; 51c84ccd0aSEtienne Carriere } 52c84ccd0aSEtienne Carriere 53c84ccd0aSEtienne Carriere unsigned int get_token_id(struct ck_token *token) 54c84ccd0aSEtienne Carriere { 55c84ccd0aSEtienne Carriere ptrdiff_t id = token - ck_token; 56c84ccd0aSEtienne Carriere 57c84ccd0aSEtienne Carriere assert(id >= 0 && id < TOKEN_COUNT); 58c84ccd0aSEtienne Carriere return id; 59c84ccd0aSEtienne Carriere } 60c84ccd0aSEtienne Carriere 61*e084583eSEtienne Carriere struct pkcs11_client *tee_session2client(void *tee_session) 62*e084583eSEtienne Carriere { 63*e084583eSEtienne Carriere struct pkcs11_client *client = NULL; 64*e084583eSEtienne Carriere 65*e084583eSEtienne Carriere TAILQ_FOREACH(client, &pkcs11_client_list, link) 66*e084583eSEtienne Carriere if (client == tee_session) 67*e084583eSEtienne Carriere break; 68*e084583eSEtienne Carriere 69*e084583eSEtienne Carriere return client; 70*e084583eSEtienne Carriere } 71*e084583eSEtienne Carriere 72*e084583eSEtienne Carriere struct pkcs11_client *register_client(void) 73*e084583eSEtienne Carriere { 74*e084583eSEtienne Carriere struct pkcs11_client *client = NULL; 75*e084583eSEtienne Carriere 76*e084583eSEtienne Carriere client = TEE_Malloc(sizeof(*client), TEE_MALLOC_FILL_ZERO); 77*e084583eSEtienne Carriere if (!client) 78*e084583eSEtienne Carriere return NULL; 79*e084583eSEtienne Carriere 80*e084583eSEtienne Carriere TAILQ_INSERT_HEAD(&pkcs11_client_list, client, link); 81*e084583eSEtienne Carriere TAILQ_INIT(&client->session_list); 82*e084583eSEtienne Carriere handle_db_init(&client->session_handle_db); 83*e084583eSEtienne Carriere 84*e084583eSEtienne Carriere return client; 85*e084583eSEtienne Carriere } 86*e084583eSEtienne Carriere 87*e084583eSEtienne Carriere void unregister_client(struct pkcs11_client *client) 88*e084583eSEtienne Carriere { 89*e084583eSEtienne Carriere if (!client) { 90*e084583eSEtienne Carriere EMSG("Invalid TEE session handle"); 91*e084583eSEtienne Carriere return; 92*e084583eSEtienne Carriere } 93*e084583eSEtienne Carriere 94*e084583eSEtienne Carriere TAILQ_REMOVE(&pkcs11_client_list, client, link); 95*e084583eSEtienne Carriere handle_db_destroy(&client->session_handle_db); 96*e084583eSEtienne Carriere TEE_Free(client); 97*e084583eSEtienne Carriere } 98*e084583eSEtienne Carriere 99c84ccd0aSEtienne Carriere static TEE_Result pkcs11_token_init(unsigned int id) 100c84ccd0aSEtienne Carriere { 101c84ccd0aSEtienne Carriere struct ck_token *token = init_persistent_db(id); 102c84ccd0aSEtienne Carriere 103c84ccd0aSEtienne Carriere if (!token) 104c84ccd0aSEtienne Carriere return TEE_ERROR_SECURITY; 105c84ccd0aSEtienne Carriere 106c84ccd0aSEtienne Carriere if (token->state == PKCS11_TOKEN_RESET) { 107c84ccd0aSEtienne Carriere /* As per PKCS#11 spec, token resets to read/write state */ 108c84ccd0aSEtienne Carriere token->state = PKCS11_TOKEN_READ_WRITE; 109c84ccd0aSEtienne Carriere token->session_count = 0; 110c84ccd0aSEtienne Carriere token->rw_session_count = 0; 111c84ccd0aSEtienne Carriere } 112c84ccd0aSEtienne Carriere 113c84ccd0aSEtienne Carriere return TEE_SUCCESS; 114c84ccd0aSEtienne Carriere } 115c84ccd0aSEtienne Carriere 116c84ccd0aSEtienne Carriere TEE_Result pkcs11_init(void) 117c84ccd0aSEtienne Carriere { 118c84ccd0aSEtienne Carriere unsigned int id = 0; 119c84ccd0aSEtienne Carriere TEE_Result ret = TEE_ERROR_GENERIC; 120c84ccd0aSEtienne Carriere 121c84ccd0aSEtienne Carriere for (id = 0; id < TOKEN_COUNT; id++) { 122c84ccd0aSEtienne Carriere ret = pkcs11_token_init(id); 123c84ccd0aSEtienne Carriere if (ret) 124*e084583eSEtienne Carriere break; 125c84ccd0aSEtienne Carriere } 126c84ccd0aSEtienne Carriere 127c84ccd0aSEtienne Carriere return ret; 128c84ccd0aSEtienne Carriere } 129c84ccd0aSEtienne Carriere 130c84ccd0aSEtienne Carriere void pkcs11_deinit(void) 131c84ccd0aSEtienne Carriere { 132c84ccd0aSEtienne Carriere unsigned int id = 0; 133c84ccd0aSEtienne Carriere 134c84ccd0aSEtienne Carriere for (id = 0; id < TOKEN_COUNT; id++) 135c84ccd0aSEtienne Carriere close_persistent_db(get_token(id)); 136c84ccd0aSEtienne Carriere } 13722ac6984SEtienne Carriere 13822ac6984SEtienne Carriere uint32_t entry_ck_slot_list(uint32_t ptypes, TEE_Param *params) 13922ac6984SEtienne Carriere { 14022ac6984SEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 14122ac6984SEtienne Carriere TEE_PARAM_TYPE_NONE, 14222ac6984SEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 14322ac6984SEtienne Carriere TEE_PARAM_TYPE_NONE); 14422ac6984SEtienne Carriere TEE_Param *out = ¶ms[2]; 14522ac6984SEtienne Carriere uint32_t token_id = 0; 14622ac6984SEtienne Carriere const size_t out_size = sizeof(token_id) * TOKEN_COUNT; 14722ac6984SEtienne Carriere uint8_t *id = NULL; 14822ac6984SEtienne Carriere 14922ac6984SEtienne Carriere if (ptypes != exp_pt || 15022ac6984SEtienne Carriere params[0].memref.size != TEE_PARAM0_SIZE_MIN) 15122ac6984SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 15222ac6984SEtienne Carriere 15322ac6984SEtienne Carriere if (out->memref.size < out_size) { 15422ac6984SEtienne Carriere out->memref.size = out_size; 15522ac6984SEtienne Carriere 15622ac6984SEtienne Carriere if (out->memref.buffer) 15722ac6984SEtienne Carriere return PKCS11_CKR_BUFFER_TOO_SMALL; 15822ac6984SEtienne Carriere else 15922ac6984SEtienne Carriere return PKCS11_CKR_OK; 16022ac6984SEtienne Carriere } 16122ac6984SEtienne Carriere 16222ac6984SEtienne Carriere for (token_id = 0, id = out->memref.buffer; token_id < TOKEN_COUNT; 16322ac6984SEtienne Carriere token_id++, id += sizeof(token_id)) 16422ac6984SEtienne Carriere TEE_MemMove(id, &token_id, sizeof(token_id)); 16522ac6984SEtienne Carriere 16622ac6984SEtienne Carriere out->memref.size = out_size; 16722ac6984SEtienne Carriere 16822ac6984SEtienne Carriere return PKCS11_CKR_OK; 16922ac6984SEtienne Carriere } 170ce94efefSEtienne Carriere 171b3ac5035SEtienne Carriere static void pad_str(uint8_t *str, size_t size) 172b3ac5035SEtienne Carriere { 173b3ac5035SEtienne Carriere int n = strnlen((char *)str, size); 174b3ac5035SEtienne Carriere 175b3ac5035SEtienne Carriere TEE_MemFill(str + n, ' ', size - n); 176b3ac5035SEtienne Carriere } 177b3ac5035SEtienne Carriere 178ce94efefSEtienne Carriere uint32_t entry_ck_slot_info(uint32_t ptypes, TEE_Param *params) 179ce94efefSEtienne Carriere { 180ce94efefSEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 181ce94efefSEtienne Carriere TEE_PARAM_TYPE_NONE, 182ce94efefSEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 183ce94efefSEtienne Carriere TEE_PARAM_TYPE_NONE); 184ce94efefSEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 185ce94efefSEtienne Carriere TEE_Param *out = ¶ms[2]; 186ce94efefSEtienne Carriere uint32_t rv = 0; 187ce94efefSEtienne Carriere struct serialargs ctrlargs = { }; 188ce94efefSEtienne Carriere uint32_t token_id = 0; 189ce94efefSEtienne Carriere struct ck_token *token = NULL; 190ce94efefSEtienne Carriere struct pkcs11_slot_info info = { 191ce94efefSEtienne Carriere .slot_description = PKCS11_SLOT_DESCRIPTION, 192ce94efefSEtienne Carriere .manufacturer_id = PKCS11_SLOT_MANUFACTURER, 193ce94efefSEtienne Carriere .flags = PKCS11_CKFS_TOKEN_PRESENT, 194ce94efefSEtienne Carriere .hardware_version = PKCS11_SLOT_HW_VERSION, 195ce94efefSEtienne Carriere .firmware_version = PKCS11_SLOT_FW_VERSION, 196ce94efefSEtienne Carriere }; 197ce94efefSEtienne Carriere 198ce94efefSEtienne Carriere COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_DESCRIPTION) <= 199ce94efefSEtienne Carriere sizeof(info.slot_description)); 200ce94efefSEtienne Carriere COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_MANUFACTURER) <= 201ce94efefSEtienne Carriere sizeof(info.manufacturer_id)); 202ce94efefSEtienne Carriere 203ce94efefSEtienne Carriere if (ptypes != exp_pt || out->memref.size != sizeof(info)) 204ce94efefSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 205ce94efefSEtienne Carriere 206ce94efefSEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 207ce94efefSEtienne Carriere 208ce94efefSEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 209ce94efefSEtienne Carriere if (rv) 210ce94efefSEtienne Carriere return rv; 211ce94efefSEtienne Carriere 212ce94efefSEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 213ce94efefSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 214ce94efefSEtienne Carriere 215ce94efefSEtienne Carriere token = get_token(token_id); 216ce94efefSEtienne Carriere if (!token) 217ce94efefSEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 218ce94efefSEtienne Carriere 219b3ac5035SEtienne Carriere pad_str(info.slot_description, sizeof(info.slot_description)); 220b3ac5035SEtienne Carriere pad_str(info.manufacturer_id, sizeof(info.manufacturer_id)); 221ce94efefSEtienne Carriere 222ce94efefSEtienne Carriere out->memref.size = sizeof(info); 223ce94efefSEtienne Carriere TEE_MemMove(out->memref.buffer, &info, out->memref.size); 224ce94efefSEtienne Carriere 225ce94efefSEtienne Carriere return PKCS11_CKR_OK; 226ce94efefSEtienne Carriere } 227030e7392SEtienne Carriere 228030e7392SEtienne Carriere uint32_t entry_ck_token_info(uint32_t ptypes, TEE_Param *params) 229030e7392SEtienne Carriere { 230030e7392SEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 231030e7392SEtienne Carriere TEE_PARAM_TYPE_NONE, 232030e7392SEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 233030e7392SEtienne Carriere TEE_PARAM_TYPE_NONE); 234030e7392SEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 235030e7392SEtienne Carriere TEE_Param *out = ¶ms[2]; 236030e7392SEtienne Carriere uint32_t rv = 0; 237030e7392SEtienne Carriere struct serialargs ctrlargs = { }; 238030e7392SEtienne Carriere uint32_t token_id = 0; 239030e7392SEtienne Carriere struct ck_token *token = NULL; 240030e7392SEtienne Carriere struct pkcs11_token_info info = { 241030e7392SEtienne Carriere .manufacturer_id = PKCS11_TOKEN_MANUFACTURER, 242030e7392SEtienne Carriere .model = PKCS11_TOKEN_MODEL, 243030e7392SEtienne Carriere .serial_number = PKCS11_TOKEN_SERIAL_NUMBER, 244030e7392SEtienne Carriere .max_session_count = UINT32_MAX, 245030e7392SEtienne Carriere .max_rw_session_count = UINT32_MAX, 246030e7392SEtienne Carriere .max_pin_len = PKCS11_TOKEN_PIN_SIZE_MAX, 247030e7392SEtienne Carriere .min_pin_len = PKCS11_TOKEN_PIN_SIZE_MIN, 248030e7392SEtienne Carriere .total_public_memory = UINT32_MAX, 249030e7392SEtienne Carriere .free_public_memory = UINT32_MAX, 250030e7392SEtienne Carriere .total_private_memory = UINT32_MAX, 251030e7392SEtienne Carriere .free_private_memory = UINT32_MAX, 252030e7392SEtienne Carriere .hardware_version = PKCS11_TOKEN_HW_VERSION, 253030e7392SEtienne Carriere .firmware_version = PKCS11_TOKEN_FW_VERSION, 254030e7392SEtienne Carriere }; 255030e7392SEtienne Carriere 256030e7392SEtienne Carriere if (ptypes != exp_pt || out->memref.size != sizeof(info)) 257030e7392SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 258030e7392SEtienne Carriere 259030e7392SEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 260030e7392SEtienne Carriere 261030e7392SEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 262030e7392SEtienne Carriere if (rv) 263030e7392SEtienne Carriere return rv; 264030e7392SEtienne Carriere 265030e7392SEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 266030e7392SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 267030e7392SEtienne Carriere 268030e7392SEtienne Carriere token = get_token(token_id); 269030e7392SEtienne Carriere if (!token) 270030e7392SEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 271030e7392SEtienne Carriere 272030e7392SEtienne Carriere pad_str(info.manufacturer_id, sizeof(info.manufacturer_id)); 273030e7392SEtienne Carriere pad_str(info.model, sizeof(info.model)); 274030e7392SEtienne Carriere pad_str(info.serial_number, sizeof(info.serial_number)); 275030e7392SEtienne Carriere 276030e7392SEtienne Carriere TEE_MemMove(info.label, token->db_main->label, sizeof(info.label)); 277030e7392SEtienne Carriere 278030e7392SEtienne Carriere info.flags = token->db_main->flags; 279030e7392SEtienne Carriere info.session_count = token->session_count; 280030e7392SEtienne Carriere info.rw_session_count = token->rw_session_count; 281030e7392SEtienne Carriere 282030e7392SEtienne Carriere TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 283030e7392SEtienne Carriere 284030e7392SEtienne Carriere return PKCS11_CKR_OK; 285030e7392SEtienne Carriere } 2866f74919dSEtienne Carriere 2876f74919dSEtienne Carriere static void dmsg_print_supported_mechanism(unsigned int token_id __maybe_unused, 2886f74919dSEtienne Carriere uint32_t *array __maybe_unused, 2896f74919dSEtienne Carriere size_t count __maybe_unused) 2906f74919dSEtienne Carriere { 2916f74919dSEtienne Carriere size_t __maybe_unused n = 0; 2926f74919dSEtienne Carriere 2936f74919dSEtienne Carriere if (TRACE_LEVEL < TRACE_DEBUG) 2946f74919dSEtienne Carriere return; 2956f74919dSEtienne Carriere 2966f74919dSEtienne Carriere for (n = 0; n < count; n++) 2976f74919dSEtienne Carriere DMSG("PKCS11 token %"PRIu32": mechanism 0x%04"PRIx32": %s", 2986f74919dSEtienne Carriere token_id, array[n], id2str_mechanism(array[n])); 2996f74919dSEtienne Carriere } 3006f74919dSEtienne Carriere 3016f74919dSEtienne Carriere uint32_t entry_ck_token_mecha_ids(uint32_t ptypes, TEE_Param *params) 3026f74919dSEtienne Carriere { 3036f74919dSEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 3046f74919dSEtienne Carriere TEE_PARAM_TYPE_NONE, 3056f74919dSEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 3066f74919dSEtienne Carriere TEE_PARAM_TYPE_NONE); 3076f74919dSEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 3086f74919dSEtienne Carriere TEE_Param *out = ¶ms[2]; 3096f74919dSEtienne Carriere uint32_t rv = 0; 3106f74919dSEtienne Carriere struct serialargs ctrlargs = { }; 3116f74919dSEtienne Carriere uint32_t token_id = 0; 3126f74919dSEtienne Carriere struct ck_token __maybe_unused *token = NULL; 3136f74919dSEtienne Carriere size_t count = 0; 3146f74919dSEtienne Carriere uint32_t *array = NULL; 3156f74919dSEtienne Carriere 3166f74919dSEtienne Carriere if (ptypes != exp_pt) 3176f74919dSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 3186f74919dSEtienne Carriere 3196f74919dSEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 3206f74919dSEtienne Carriere 3216f74919dSEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 3226f74919dSEtienne Carriere if (rv) 3236f74919dSEtienne Carriere return rv; 3246f74919dSEtienne Carriere 3256f74919dSEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 3266f74919dSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 3276f74919dSEtienne Carriere 3286f74919dSEtienne Carriere token = get_token(token_id); 3296f74919dSEtienne Carriere if (!token) 3306f74919dSEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 3316f74919dSEtienne Carriere 3326f74919dSEtienne Carriere count = out->memref.size / sizeof(*array); 3336f74919dSEtienne Carriere array = tee_malloc_mechanism_list(&count); 3346f74919dSEtienne Carriere 3356f74919dSEtienne Carriere if (out->memref.size < count * sizeof(*array)) { 3366f74919dSEtienne Carriere assert(!array); 3376f74919dSEtienne Carriere out->memref.size = count * sizeof(*array); 3386f74919dSEtienne Carriere return PKCS11_CKR_BUFFER_TOO_SMALL; 3396f74919dSEtienne Carriere } 3406f74919dSEtienne Carriere 3416f74919dSEtienne Carriere if (!array) 3426f74919dSEtienne Carriere return PKCS11_CKR_DEVICE_MEMORY; 3436f74919dSEtienne Carriere 3446f74919dSEtienne Carriere dmsg_print_supported_mechanism(token_id, array, count); 3456f74919dSEtienne Carriere 3466f74919dSEtienne Carriere out->memref.size = count * sizeof(*array); 3476f74919dSEtienne Carriere TEE_MemMove(out->memref.buffer, array, out->memref.size); 3486f74919dSEtienne Carriere 3496f74919dSEtienne Carriere TEE_Free(array); 3506f74919dSEtienne Carriere 3516f74919dSEtienne Carriere return rv; 3526f74919dSEtienne Carriere } 3531d3ebedbSEtienne Carriere 3541d3ebedbSEtienne Carriere static void supported_mechanism_key_size(uint32_t proc_id, 3551d3ebedbSEtienne Carriere uint32_t *max_key_size, 3561d3ebedbSEtienne Carriere uint32_t *min_key_size) 3571d3ebedbSEtienne Carriere { 3581d3ebedbSEtienne Carriere switch (proc_id) { 3591d3ebedbSEtienne Carriere /* Will be filled once TA supports mechanisms */ 3601d3ebedbSEtienne Carriere default: 3611d3ebedbSEtienne Carriere *min_key_size = 0; 3621d3ebedbSEtienne Carriere *max_key_size = 0; 3631d3ebedbSEtienne Carriere break; 3641d3ebedbSEtienne Carriere } 3651d3ebedbSEtienne Carriere } 3661d3ebedbSEtienne Carriere 3671d3ebedbSEtienne Carriere uint32_t entry_ck_token_mecha_info(uint32_t ptypes, TEE_Param *params) 3681d3ebedbSEtienne Carriere { 3691d3ebedbSEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 3701d3ebedbSEtienne Carriere TEE_PARAM_TYPE_NONE, 3711d3ebedbSEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 3721d3ebedbSEtienne Carriere TEE_PARAM_TYPE_NONE); 3731d3ebedbSEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 3741d3ebedbSEtienne Carriere TEE_Param *out = ¶ms[2]; 3751d3ebedbSEtienne Carriere uint32_t rv = 0; 3761d3ebedbSEtienne Carriere struct serialargs ctrlargs = { }; 3771d3ebedbSEtienne Carriere uint32_t token_id = 0; 3781d3ebedbSEtienne Carriere uint32_t type = 0; 3791d3ebedbSEtienne Carriere struct ck_token *token = NULL; 3801d3ebedbSEtienne Carriere struct pkcs11_mechanism_info info = { }; 3811d3ebedbSEtienne Carriere 3821d3ebedbSEtienne Carriere if (ptypes != exp_pt || out->memref.size != sizeof(info)) 3831d3ebedbSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 3841d3ebedbSEtienne Carriere 3851d3ebedbSEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 3861d3ebedbSEtienne Carriere 3871d3ebedbSEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 3881d3ebedbSEtienne Carriere if (rv) 3891d3ebedbSEtienne Carriere return rv; 3901d3ebedbSEtienne Carriere 3911d3ebedbSEtienne Carriere rv = serialargs_get(&ctrlargs, &type, sizeof(uint32_t)); 3921d3ebedbSEtienne Carriere if (rv) 3931d3ebedbSEtienne Carriere return rv; 3941d3ebedbSEtienne Carriere 3951d3ebedbSEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 3961d3ebedbSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 3971d3ebedbSEtienne Carriere 3981d3ebedbSEtienne Carriere token = get_token(token_id); 3991d3ebedbSEtienne Carriere if (!token) 4001d3ebedbSEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 4011d3ebedbSEtienne Carriere 4021d3ebedbSEtienne Carriere if (!mechanism_is_valid(type)) 4031d3ebedbSEtienne Carriere return PKCS11_CKR_MECHANISM_INVALID; 4041d3ebedbSEtienne Carriere 4051d3ebedbSEtienne Carriere info.flags = mechanism_supported_flags(type); 4061d3ebedbSEtienne Carriere 4071d3ebedbSEtienne Carriere supported_mechanism_key_size(type, &info.min_key_size, 4081d3ebedbSEtienne Carriere &info.max_key_size); 4091d3ebedbSEtienne Carriere 4101d3ebedbSEtienne Carriere TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 4111d3ebedbSEtienne Carriere 4121d3ebedbSEtienne Carriere DMSG("PKCS11 token %"PRIu32": mechanism 0x%"PRIx32" info", 4131d3ebedbSEtienne Carriere token_id, type); 4141d3ebedbSEtienne Carriere 4151d3ebedbSEtienne Carriere return PKCS11_CKR_OK; 4161d3ebedbSEtienne Carriere } 417