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 } 117*ce94efefSEtienne Carriere 118*ce94efefSEtienne Carriere uint32_t entry_ck_slot_info(uint32_t ptypes, TEE_Param *params) 119*ce94efefSEtienne Carriere { 120*ce94efefSEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 121*ce94efefSEtienne Carriere TEE_PARAM_TYPE_NONE, 122*ce94efefSEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 123*ce94efefSEtienne Carriere TEE_PARAM_TYPE_NONE); 124*ce94efefSEtienne Carriere TEE_Param *ctrl = ¶ms[0]; 125*ce94efefSEtienne Carriere TEE_Param *out = ¶ms[2]; 126*ce94efefSEtienne Carriere uint32_t rv = 0; 127*ce94efefSEtienne Carriere struct serialargs ctrlargs = { }; 128*ce94efefSEtienne Carriere uint32_t token_id = 0; 129*ce94efefSEtienne Carriere struct ck_token *token = NULL; 130*ce94efefSEtienne Carriere struct pkcs11_slot_info info = { 131*ce94efefSEtienne Carriere .slot_description = PKCS11_SLOT_DESCRIPTION, 132*ce94efefSEtienne Carriere .manufacturer_id = PKCS11_SLOT_MANUFACTURER, 133*ce94efefSEtienne Carriere .flags = PKCS11_CKFS_TOKEN_PRESENT, 134*ce94efefSEtienne Carriere .hardware_version = PKCS11_SLOT_HW_VERSION, 135*ce94efefSEtienne Carriere .firmware_version = PKCS11_SLOT_FW_VERSION, 136*ce94efefSEtienne Carriere }; 137*ce94efefSEtienne Carriere int n = 0; 138*ce94efefSEtienne Carriere 139*ce94efefSEtienne Carriere COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_DESCRIPTION) <= 140*ce94efefSEtienne Carriere sizeof(info.slot_description)); 141*ce94efefSEtienne Carriere COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_MANUFACTURER) <= 142*ce94efefSEtienne Carriere sizeof(info.manufacturer_id)); 143*ce94efefSEtienne Carriere 144*ce94efefSEtienne Carriere if (ptypes != exp_pt || out->memref.size != sizeof(info)) 145*ce94efefSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 146*ce94efefSEtienne Carriere 147*ce94efefSEtienne Carriere serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 148*ce94efefSEtienne Carriere 149*ce94efefSEtienne Carriere rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 150*ce94efefSEtienne Carriere if (rv) 151*ce94efefSEtienne Carriere return rv; 152*ce94efefSEtienne Carriere 153*ce94efefSEtienne Carriere if (serialargs_remaining_bytes(&ctrlargs)) 154*ce94efefSEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 155*ce94efefSEtienne Carriere 156*ce94efefSEtienne Carriere token = get_token(token_id); 157*ce94efefSEtienne Carriere if (!token) 158*ce94efefSEtienne Carriere return PKCS11_CKR_SLOT_ID_INVALID; 159*ce94efefSEtienne Carriere 160*ce94efefSEtienne Carriere /* Pad string identifiers with blank characters */ 161*ce94efefSEtienne Carriere n = strnlen((char *)info.slot_description, 162*ce94efefSEtienne Carriere sizeof(info.slot_description)); 163*ce94efefSEtienne Carriere TEE_MemFill(&info.slot_description[n], ' ', 164*ce94efefSEtienne Carriere sizeof(info.slot_description) - n); 165*ce94efefSEtienne Carriere 166*ce94efefSEtienne Carriere n = strnlen((char *)info.manufacturer_id, 167*ce94efefSEtienne Carriere sizeof(info.manufacturer_id)); 168*ce94efefSEtienne Carriere TEE_MemFill(&info.manufacturer_id[n], ' ', 169*ce94efefSEtienne Carriere sizeof(info.manufacturer_id) - n); 170*ce94efefSEtienne Carriere 171*ce94efefSEtienne Carriere out->memref.size = sizeof(info); 172*ce94efefSEtienne Carriere TEE_MemMove(out->memref.buffer, &info, out->memref.size); 173*ce94efefSEtienne Carriere 174*ce94efefSEtienne Carriere return PKCS11_CKR_OK; 175*ce94efefSEtienne Carriere } 176