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 27c84ccd0aSEtienne Carriere /* Static allocation of tokens runtime instances (reset to 0 at load) */ 28c84ccd0aSEtienne Carriere struct ck_token ck_token[TOKEN_COUNT]; 29c84ccd0aSEtienne Carriere 30c84ccd0aSEtienne Carriere struct ck_token *get_token(unsigned int token_id) 31c84ccd0aSEtienne Carriere { 32d38f9635SEtienne Carriere if (token_id < TOKEN_COUNT) 33d38f9635SEtienne Carriere return &ck_token[confine_array_index(token_id, TOKEN_COUNT)]; 34c84ccd0aSEtienne Carriere 35d38f9635SEtienne Carriere return NULL; 36c84ccd0aSEtienne Carriere } 37c84ccd0aSEtienne Carriere 38c84ccd0aSEtienne Carriere unsigned int get_token_id(struct ck_token *token) 39c84ccd0aSEtienne Carriere { 40c84ccd0aSEtienne Carriere ptrdiff_t id = token - ck_token; 41c84ccd0aSEtienne Carriere 42c84ccd0aSEtienne Carriere assert(id >= 0 && id < TOKEN_COUNT); 43c84ccd0aSEtienne Carriere return id; 44c84ccd0aSEtienne Carriere } 45c84ccd0aSEtienne Carriere 46c84ccd0aSEtienne Carriere static TEE_Result pkcs11_token_init(unsigned int id) 47c84ccd0aSEtienne Carriere { 48c84ccd0aSEtienne Carriere struct ck_token *token = init_persistent_db(id); 49c84ccd0aSEtienne Carriere 50c84ccd0aSEtienne Carriere if (!token) 51c84ccd0aSEtienne Carriere return TEE_ERROR_SECURITY; 52c84ccd0aSEtienne Carriere 53c84ccd0aSEtienne Carriere if (token->state == PKCS11_TOKEN_RESET) { 54c84ccd0aSEtienne Carriere /* As per PKCS#11 spec, token resets to read/write state */ 55c84ccd0aSEtienne Carriere token->state = PKCS11_TOKEN_READ_WRITE; 56c84ccd0aSEtienne Carriere token->session_count = 0; 57c84ccd0aSEtienne Carriere token->rw_session_count = 0; 58c84ccd0aSEtienne Carriere } 59c84ccd0aSEtienne Carriere 60c84ccd0aSEtienne Carriere return TEE_SUCCESS; 61c84ccd0aSEtienne Carriere } 62c84ccd0aSEtienne Carriere 63c84ccd0aSEtienne Carriere TEE_Result pkcs11_init(void) 64c84ccd0aSEtienne Carriere { 65c84ccd0aSEtienne Carriere unsigned int id = 0; 66c84ccd0aSEtienne Carriere TEE_Result ret = TEE_ERROR_GENERIC; 67c84ccd0aSEtienne Carriere 68c84ccd0aSEtienne Carriere for (id = 0; id < TOKEN_COUNT; id++) { 69c84ccd0aSEtienne Carriere ret = pkcs11_token_init(id); 70c84ccd0aSEtienne Carriere if (ret) 71c84ccd0aSEtienne Carriere return ret; 72c84ccd0aSEtienne Carriere } 73c84ccd0aSEtienne Carriere 74c84ccd0aSEtienne Carriere return ret; 75c84ccd0aSEtienne Carriere } 76c84ccd0aSEtienne Carriere 77c84ccd0aSEtienne Carriere void pkcs11_deinit(void) 78c84ccd0aSEtienne Carriere { 79c84ccd0aSEtienne Carriere unsigned int id = 0; 80c84ccd0aSEtienne Carriere 81c84ccd0aSEtienne Carriere for (id = 0; id < TOKEN_COUNT; id++) 82c84ccd0aSEtienne Carriere close_persistent_db(get_token(id)); 83c84ccd0aSEtienne Carriere } 8422ac6984SEtienne Carriere 8522ac6984SEtienne Carriere uint32_t entry_ck_slot_list(uint32_t ptypes, TEE_Param *params) 8622ac6984SEtienne Carriere { 8722ac6984SEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 8822ac6984SEtienne Carriere TEE_PARAM_TYPE_NONE, 8922ac6984SEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 9022ac6984SEtienne Carriere TEE_PARAM_TYPE_NONE); 9122ac6984SEtienne Carriere TEE_Param *out = ¶ms[2]; 9222ac6984SEtienne Carriere uint32_t token_id = 0; 9322ac6984SEtienne Carriere const size_t out_size = sizeof(token_id) * TOKEN_COUNT; 9422ac6984SEtienne Carriere uint8_t *id = NULL; 9522ac6984SEtienne Carriere 9622ac6984SEtienne Carriere if (ptypes != exp_pt || 9722ac6984SEtienne Carriere params[0].memref.size != TEE_PARAM0_SIZE_MIN) 9822ac6984SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 9922ac6984SEtienne Carriere 10022ac6984SEtienne Carriere if (out->memref.size < out_size) { 10122ac6984SEtienne Carriere out->memref.size = out_size; 10222ac6984SEtienne Carriere 10322ac6984SEtienne Carriere if (out->memref.buffer) 10422ac6984SEtienne Carriere return PKCS11_CKR_BUFFER_TOO_SMALL; 10522ac6984SEtienne Carriere else 10622ac6984SEtienne Carriere return PKCS11_CKR_OK; 10722ac6984SEtienne Carriere } 10822ac6984SEtienne Carriere 10922ac6984SEtienne Carriere for (token_id = 0, id = out->memref.buffer; token_id < TOKEN_COUNT; 11022ac6984SEtienne Carriere token_id++, id += sizeof(token_id)) 11122ac6984SEtienne Carriere TEE_MemMove(id, &token_id, sizeof(token_id)); 11222ac6984SEtienne Carriere 11322ac6984SEtienne Carriere out->memref.size = out_size; 11422ac6984SEtienne Carriere 11522ac6984SEtienne Carriere return PKCS11_CKR_OK; 11622ac6984SEtienne Carriere } 117ce94efefSEtienne Carriere 118b3ac5035SEtienne Carriere static void pad_str(uint8_t *str, size_t size) 119b3ac5035SEtienne Carriere { 120b3ac5035SEtienne Carriere int n = strnlen((char *)str, size); 121b3ac5035SEtienne Carriere 122b3ac5035SEtienne Carriere TEE_MemFill(str + n, ' ', size - n); 123b3ac5035SEtienne Carriere } 124b3ac5035SEtienne Carriere 125ce94efefSEtienne Carriere uint32_t entry_ck_slot_info(uint32_t ptypes, TEE_Param *params) 126ce94efefSEtienne Carriere { 127ce94efefSEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 128ce94efefSEtienne Carriere TEE_PARAM_TYPE_NONE, 129ce94efefSEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 130ce94efefSEtienne Carriere TEE_PARAM_TYPE_NONE); 131ce94efefSEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 132ce94efefSEtienne Carriere TEE_Param *out = ¶ms[2]; 133ce94efefSEtienne Carriere uint32_t rv = 0; 134ce94efefSEtienne Carriere struct serialargs ctrlargs = { }; 135ce94efefSEtienne Carriere uint32_t token_id = 0; 136ce94efefSEtienne Carriere struct ck_token *token = NULL; 137ce94efefSEtienne Carriere struct pkcs11_slot_info info = { 138ce94efefSEtienne Carriere .slot_description = PKCS11_SLOT_DESCRIPTION, 139ce94efefSEtienne Carriere .manufacturer_id = PKCS11_SLOT_MANUFACTURER, 140ce94efefSEtienne Carriere .flags = PKCS11_CKFS_TOKEN_PRESENT, 141ce94efefSEtienne Carriere .hardware_version = PKCS11_SLOT_HW_VERSION, 142ce94efefSEtienne Carriere .firmware_version = PKCS11_SLOT_FW_VERSION, 143ce94efefSEtienne Carriere }; 144ce94efefSEtienne Carriere 145ce94efefSEtienne Carriere COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_DESCRIPTION) <= 146ce94efefSEtienne Carriere sizeof(info.slot_description)); 147ce94efefSEtienne Carriere COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_MANUFACTURER) <= 148ce94efefSEtienne Carriere sizeof(info.manufacturer_id)); 149ce94efefSEtienne Carriere 150ce94efefSEtienne Carriere if (ptypes != exp_pt || out->memref.size != sizeof(info)) 151ce94efefSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 152ce94efefSEtienne Carriere 153ce94efefSEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 154ce94efefSEtienne Carriere 155ce94efefSEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 156ce94efefSEtienne Carriere if (rv) 157ce94efefSEtienne Carriere return rv; 158ce94efefSEtienne Carriere 159ce94efefSEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 160ce94efefSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 161ce94efefSEtienne Carriere 162ce94efefSEtienne Carriere token = get_token(token_id); 163ce94efefSEtienne Carriere if (!token) 164ce94efefSEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 165ce94efefSEtienne Carriere 166b3ac5035SEtienne Carriere pad_str(info.slot_description, sizeof(info.slot_description)); 167b3ac5035SEtienne Carriere pad_str(info.manufacturer_id, sizeof(info.manufacturer_id)); 168ce94efefSEtienne Carriere 169ce94efefSEtienne Carriere out->memref.size = sizeof(info); 170ce94efefSEtienne Carriere TEE_MemMove(out->memref.buffer, &info, out->memref.size); 171ce94efefSEtienne Carriere 172ce94efefSEtienne Carriere return PKCS11_CKR_OK; 173ce94efefSEtienne Carriere } 174030e7392SEtienne Carriere 175030e7392SEtienne Carriere uint32_t entry_ck_token_info(uint32_t ptypes, TEE_Param *params) 176030e7392SEtienne Carriere { 177030e7392SEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 178030e7392SEtienne Carriere TEE_PARAM_TYPE_NONE, 179030e7392SEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 180030e7392SEtienne Carriere TEE_PARAM_TYPE_NONE); 181030e7392SEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 182030e7392SEtienne Carriere TEE_Param *out = ¶ms[2]; 183030e7392SEtienne Carriere uint32_t rv = 0; 184030e7392SEtienne Carriere struct serialargs ctrlargs = { }; 185030e7392SEtienne Carriere uint32_t token_id = 0; 186030e7392SEtienne Carriere struct ck_token *token = NULL; 187030e7392SEtienne Carriere struct pkcs11_token_info info = { 188030e7392SEtienne Carriere .manufacturer_id = PKCS11_TOKEN_MANUFACTURER, 189030e7392SEtienne Carriere .model = PKCS11_TOKEN_MODEL, 190030e7392SEtienne Carriere .serial_number = PKCS11_TOKEN_SERIAL_NUMBER, 191030e7392SEtienne Carriere .max_session_count = UINT32_MAX, 192030e7392SEtienne Carriere .max_rw_session_count = UINT32_MAX, 193030e7392SEtienne Carriere .max_pin_len = PKCS11_TOKEN_PIN_SIZE_MAX, 194030e7392SEtienne Carriere .min_pin_len = PKCS11_TOKEN_PIN_SIZE_MIN, 195030e7392SEtienne Carriere .total_public_memory = UINT32_MAX, 196030e7392SEtienne Carriere .free_public_memory = UINT32_MAX, 197030e7392SEtienne Carriere .total_private_memory = UINT32_MAX, 198030e7392SEtienne Carriere .free_private_memory = UINT32_MAX, 199030e7392SEtienne Carriere .hardware_version = PKCS11_TOKEN_HW_VERSION, 200030e7392SEtienne Carriere .firmware_version = PKCS11_TOKEN_FW_VERSION, 201030e7392SEtienne Carriere }; 202030e7392SEtienne Carriere 203030e7392SEtienne Carriere if (ptypes != exp_pt || out->memref.size != sizeof(info)) 204030e7392SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 205030e7392SEtienne Carriere 206030e7392SEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 207030e7392SEtienne Carriere 208030e7392SEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 209030e7392SEtienne Carriere if (rv) 210030e7392SEtienne Carriere return rv; 211030e7392SEtienne Carriere 212030e7392SEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 213030e7392SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 214030e7392SEtienne Carriere 215030e7392SEtienne Carriere token = get_token(token_id); 216030e7392SEtienne Carriere if (!token) 217030e7392SEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 218030e7392SEtienne Carriere 219030e7392SEtienne Carriere pad_str(info.manufacturer_id, sizeof(info.manufacturer_id)); 220030e7392SEtienne Carriere pad_str(info.model, sizeof(info.model)); 221030e7392SEtienne Carriere pad_str(info.serial_number, sizeof(info.serial_number)); 222030e7392SEtienne Carriere 223030e7392SEtienne Carriere TEE_MemMove(info.label, token->db_main->label, sizeof(info.label)); 224030e7392SEtienne Carriere 225030e7392SEtienne Carriere info.flags = token->db_main->flags; 226030e7392SEtienne Carriere info.session_count = token->session_count; 227030e7392SEtienne Carriere info.rw_session_count = token->rw_session_count; 228030e7392SEtienne Carriere 229030e7392SEtienne Carriere TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 230030e7392SEtienne Carriere 231030e7392SEtienne Carriere return PKCS11_CKR_OK; 232030e7392SEtienne Carriere } 2336f74919dSEtienne Carriere 2346f74919dSEtienne Carriere static void dmsg_print_supported_mechanism(unsigned int token_id __maybe_unused, 2356f74919dSEtienne Carriere uint32_t *array __maybe_unused, 2366f74919dSEtienne Carriere size_t count __maybe_unused) 2376f74919dSEtienne Carriere { 2386f74919dSEtienne Carriere size_t __maybe_unused n = 0; 2396f74919dSEtienne Carriere 2406f74919dSEtienne Carriere if (TRACE_LEVEL < TRACE_DEBUG) 2416f74919dSEtienne Carriere return; 2426f74919dSEtienne Carriere 2436f74919dSEtienne Carriere for (n = 0; n < count; n++) 2446f74919dSEtienne Carriere DMSG("PKCS11 token %"PRIu32": mechanism 0x%04"PRIx32": %s", 2456f74919dSEtienne Carriere token_id, array[n], id2str_mechanism(array[n])); 2466f74919dSEtienne Carriere } 2476f74919dSEtienne Carriere 2486f74919dSEtienne Carriere uint32_t entry_ck_token_mecha_ids(uint32_t ptypes, TEE_Param *params) 2496f74919dSEtienne Carriere { 2506f74919dSEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 2516f74919dSEtienne Carriere TEE_PARAM_TYPE_NONE, 2526f74919dSEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 2536f74919dSEtienne Carriere TEE_PARAM_TYPE_NONE); 2546f74919dSEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 2556f74919dSEtienne Carriere TEE_Param *out = ¶ms[2]; 2566f74919dSEtienne Carriere uint32_t rv = 0; 2576f74919dSEtienne Carriere struct serialargs ctrlargs = { }; 2586f74919dSEtienne Carriere uint32_t token_id = 0; 2596f74919dSEtienne Carriere struct ck_token __maybe_unused *token = NULL; 2606f74919dSEtienne Carriere size_t count = 0; 2616f74919dSEtienne Carriere uint32_t *array = NULL; 2626f74919dSEtienne Carriere 2636f74919dSEtienne Carriere if (ptypes != exp_pt) 2646f74919dSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 2656f74919dSEtienne Carriere 2666f74919dSEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 2676f74919dSEtienne Carriere 2686f74919dSEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 2696f74919dSEtienne Carriere if (rv) 2706f74919dSEtienne Carriere return rv; 2716f74919dSEtienne Carriere 2726f74919dSEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 2736f74919dSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 2746f74919dSEtienne Carriere 2756f74919dSEtienne Carriere token = get_token(token_id); 2766f74919dSEtienne Carriere if (!token) 2776f74919dSEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 2786f74919dSEtienne Carriere 2796f74919dSEtienne Carriere count = out->memref.size / sizeof(*array); 2806f74919dSEtienne Carriere array = tee_malloc_mechanism_list(&count); 2816f74919dSEtienne Carriere 2826f74919dSEtienne Carriere if (out->memref.size < count * sizeof(*array)) { 2836f74919dSEtienne Carriere assert(!array); 2846f74919dSEtienne Carriere out->memref.size = count * sizeof(*array); 2856f74919dSEtienne Carriere return PKCS11_CKR_BUFFER_TOO_SMALL; 2866f74919dSEtienne Carriere } 2876f74919dSEtienne Carriere 2886f74919dSEtienne Carriere if (!array) 2896f74919dSEtienne Carriere return PKCS11_CKR_DEVICE_MEMORY; 2906f74919dSEtienne Carriere 2916f74919dSEtienne Carriere dmsg_print_supported_mechanism(token_id, array, count); 2926f74919dSEtienne Carriere 2936f74919dSEtienne Carriere out->memref.size = count * sizeof(*array); 2946f74919dSEtienne Carriere TEE_MemMove(out->memref.buffer, array, out->memref.size); 2956f74919dSEtienne Carriere 2966f74919dSEtienne Carriere TEE_Free(array); 2976f74919dSEtienne Carriere 2986f74919dSEtienne Carriere return rv; 2996f74919dSEtienne Carriere } 300*1d3ebedbSEtienne Carriere 301*1d3ebedbSEtienne Carriere static void supported_mechanism_key_size(uint32_t proc_id, 302*1d3ebedbSEtienne Carriere uint32_t *max_key_size, 303*1d3ebedbSEtienne Carriere uint32_t *min_key_size) 304*1d3ebedbSEtienne Carriere { 305*1d3ebedbSEtienne Carriere switch (proc_id) { 306*1d3ebedbSEtienne Carriere /* Will be filled once TA supports mechanisms */ 307*1d3ebedbSEtienne Carriere default: 308*1d3ebedbSEtienne Carriere *min_key_size = 0; 309*1d3ebedbSEtienne Carriere *max_key_size = 0; 310*1d3ebedbSEtienne Carriere break; 311*1d3ebedbSEtienne Carriere } 312*1d3ebedbSEtienne Carriere } 313*1d3ebedbSEtienne Carriere 314*1d3ebedbSEtienne Carriere uint32_t entry_ck_token_mecha_info(uint32_t ptypes, TEE_Param *params) 315*1d3ebedbSEtienne Carriere { 316*1d3ebedbSEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 317*1d3ebedbSEtienne Carriere TEE_PARAM_TYPE_NONE, 318*1d3ebedbSEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 319*1d3ebedbSEtienne Carriere TEE_PARAM_TYPE_NONE); 320*1d3ebedbSEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 321*1d3ebedbSEtienne Carriere TEE_Param *out = ¶ms[2]; 322*1d3ebedbSEtienne Carriere uint32_t rv = 0; 323*1d3ebedbSEtienne Carriere struct serialargs ctrlargs = { }; 324*1d3ebedbSEtienne Carriere uint32_t token_id = 0; 325*1d3ebedbSEtienne Carriere uint32_t type = 0; 326*1d3ebedbSEtienne Carriere struct ck_token *token = NULL; 327*1d3ebedbSEtienne Carriere struct pkcs11_mechanism_info info = { }; 328*1d3ebedbSEtienne Carriere 329*1d3ebedbSEtienne Carriere if (ptypes != exp_pt || out->memref.size != sizeof(info)) 330*1d3ebedbSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 331*1d3ebedbSEtienne Carriere 332*1d3ebedbSEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 333*1d3ebedbSEtienne Carriere 334*1d3ebedbSEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t)); 335*1d3ebedbSEtienne Carriere if (rv) 336*1d3ebedbSEtienne Carriere return rv; 337*1d3ebedbSEtienne Carriere 338*1d3ebedbSEtienne Carriere rv = serialargs_get(&ctrlargs, &type, sizeof(uint32_t)); 339*1d3ebedbSEtienne Carriere if (rv) 340*1d3ebedbSEtienne Carriere return rv; 341*1d3ebedbSEtienne Carriere 342*1d3ebedbSEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 343*1d3ebedbSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 344*1d3ebedbSEtienne Carriere 345*1d3ebedbSEtienne Carriere token = get_token(token_id); 346*1d3ebedbSEtienne Carriere if (!token) 347*1d3ebedbSEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 348*1d3ebedbSEtienne Carriere 349*1d3ebedbSEtienne Carriere if (!mechanism_is_valid(type)) 350*1d3ebedbSEtienne Carriere return PKCS11_CKR_MECHANISM_INVALID; 351*1d3ebedbSEtienne Carriere 352*1d3ebedbSEtienne Carriere info.flags = mechanism_supported_flags(type); 353*1d3ebedbSEtienne Carriere 354*1d3ebedbSEtienne Carriere supported_mechanism_key_size(type, &info.min_key_size, 355*1d3ebedbSEtienne Carriere &info.max_key_size); 356*1d3ebedbSEtienne Carriere 357*1d3ebedbSEtienne Carriere TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 358*1d3ebedbSEtienne Carriere 359*1d3ebedbSEtienne Carriere DMSG("PKCS11 token %"PRIu32": mechanism 0x%"PRIx32" info", 360*1d3ebedbSEtienne Carriere token_id, type); 361*1d3ebedbSEtienne Carriere 362*1d3ebedbSEtienne Carriere return PKCS11_CKR_OK; 363*1d3ebedbSEtienne Carriere } 364