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> 7*d38f9635SEtienne 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 { 32*d38f9635SEtienne Carriere if (token_id < TOKEN_COUNT) 33*d38f9635SEtienne Carriere return &ck_token[confine_array_index(token_id, TOKEN_COUNT)]; 34c84ccd0aSEtienne Carriere 35*d38f9635SEtienne 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