1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2017-2020, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <confine_array_index.h> 8 #include <pkcs11_ta.h> 9 #include <string.h> 10 #include <string_ext.h> 11 #include <sys/queue.h> 12 #include <tee_api_types.h> 13 #include <tee_internal_api_extensions.h> 14 #include <util.h> 15 16 #include "pkcs11_token.h" 17 #include "pkcs11_helpers.h" 18 #include "serializer.h" 19 20 /* Provide 3 slots/tokens, ID is token index */ 21 #ifndef CFG_PKCS11_TA_TOKEN_COUNT 22 #define TOKEN_COUNT 3 23 #else 24 #define TOKEN_COUNT CFG_PKCS11_TA_TOKEN_COUNT 25 #endif 26 27 /* Static allocation of tokens runtime instances (reset to 0 at load) */ 28 struct ck_token ck_token[TOKEN_COUNT]; 29 30 struct ck_token *get_token(unsigned int token_id) 31 { 32 if (token_id < TOKEN_COUNT) 33 return &ck_token[confine_array_index(token_id, TOKEN_COUNT)]; 34 35 return NULL; 36 } 37 38 unsigned int get_token_id(struct ck_token *token) 39 { 40 ptrdiff_t id = token - ck_token; 41 42 assert(id >= 0 && id < TOKEN_COUNT); 43 return id; 44 } 45 46 static TEE_Result pkcs11_token_init(unsigned int id) 47 { 48 struct ck_token *token = init_persistent_db(id); 49 50 if (!token) 51 return TEE_ERROR_SECURITY; 52 53 if (token->state == PKCS11_TOKEN_RESET) { 54 /* As per PKCS#11 spec, token resets to read/write state */ 55 token->state = PKCS11_TOKEN_READ_WRITE; 56 token->session_count = 0; 57 token->rw_session_count = 0; 58 } 59 60 return TEE_SUCCESS; 61 } 62 63 TEE_Result pkcs11_init(void) 64 { 65 unsigned int id = 0; 66 TEE_Result ret = TEE_ERROR_GENERIC; 67 68 for (id = 0; id < TOKEN_COUNT; id++) { 69 ret = pkcs11_token_init(id); 70 if (ret) 71 return ret; 72 } 73 74 return ret; 75 } 76 77 void pkcs11_deinit(void) 78 { 79 unsigned int id = 0; 80 81 for (id = 0; id < TOKEN_COUNT; id++) 82 close_persistent_db(get_token(id)); 83 } 84 85 uint32_t entry_ck_slot_list(uint32_t ptypes, TEE_Param *params) 86 { 87 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 88 TEE_PARAM_TYPE_NONE, 89 TEE_PARAM_TYPE_MEMREF_OUTPUT, 90 TEE_PARAM_TYPE_NONE); 91 TEE_Param *out = ¶ms[2]; 92 uint32_t token_id = 0; 93 const size_t out_size = sizeof(token_id) * TOKEN_COUNT; 94 uint8_t *id = NULL; 95 96 if (ptypes != exp_pt || 97 params[0].memref.size != TEE_PARAM0_SIZE_MIN) 98 return PKCS11_CKR_ARGUMENTS_BAD; 99 100 if (out->memref.size < out_size) { 101 out->memref.size = out_size; 102 103 if (out->memref.buffer) 104 return PKCS11_CKR_BUFFER_TOO_SMALL; 105 else 106 return PKCS11_CKR_OK; 107 } 108 109 for (token_id = 0, id = out->memref.buffer; token_id < TOKEN_COUNT; 110 token_id++, id += sizeof(token_id)) 111 TEE_MemMove(id, &token_id, sizeof(token_id)); 112 113 out->memref.size = out_size; 114 115 return PKCS11_CKR_OK; 116 } 117 118 static void pad_str(uint8_t *str, size_t size) 119 { 120 int n = strnlen((char *)str, size); 121 122 TEE_MemFill(str + n, ' ', size - n); 123 } 124 125 uint32_t entry_ck_slot_info(uint32_t ptypes, TEE_Param *params) 126 { 127 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 128 TEE_PARAM_TYPE_NONE, 129 TEE_PARAM_TYPE_MEMREF_OUTPUT, 130 TEE_PARAM_TYPE_NONE); 131 TEE_Param *ctrl = ¶ms[0]; 132 TEE_Param *out = ¶ms[2]; 133 uint32_t rv = 0; 134 struct serialargs ctrlargs = { }; 135 uint32_t token_id = 0; 136 struct ck_token *token = NULL; 137 struct pkcs11_slot_info info = { 138 .slot_description = PKCS11_SLOT_DESCRIPTION, 139 .manufacturer_id = PKCS11_SLOT_MANUFACTURER, 140 .flags = PKCS11_CKFS_TOKEN_PRESENT, 141 .hardware_version = PKCS11_SLOT_HW_VERSION, 142 .firmware_version = PKCS11_SLOT_FW_VERSION, 143 }; 144 145 COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_DESCRIPTION) <= 146 sizeof(info.slot_description)); 147 COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_MANUFACTURER) <= 148 sizeof(info.manufacturer_id)); 149 150 if (ptypes != exp_pt || out->memref.size != sizeof(info)) 151 return PKCS11_CKR_ARGUMENTS_BAD; 152 153 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 154 155 rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 156 if (rv) 157 return rv; 158 159 if (serialargs_remaining_bytes(&ctrlargs)) 160 return PKCS11_CKR_ARGUMENTS_BAD; 161 162 token = get_token(token_id); 163 if (!token) 164 return PKCS11_CKR_SLOT_ID_INVALID; 165 166 pad_str(info.slot_description, sizeof(info.slot_description)); 167 pad_str(info.manufacturer_id, sizeof(info.manufacturer_id)); 168 169 out->memref.size = sizeof(info); 170 TEE_MemMove(out->memref.buffer, &info, out->memref.size); 171 172 return PKCS11_CKR_OK; 173 } 174 175 uint32_t entry_ck_token_info(uint32_t ptypes, TEE_Param *params) 176 { 177 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 178 TEE_PARAM_TYPE_NONE, 179 TEE_PARAM_TYPE_MEMREF_OUTPUT, 180 TEE_PARAM_TYPE_NONE); 181 TEE_Param *ctrl = ¶ms[0]; 182 TEE_Param *out = ¶ms[2]; 183 uint32_t rv = 0; 184 struct serialargs ctrlargs = { }; 185 uint32_t token_id = 0; 186 struct ck_token *token = NULL; 187 struct pkcs11_token_info info = { 188 .manufacturer_id = PKCS11_TOKEN_MANUFACTURER, 189 .model = PKCS11_TOKEN_MODEL, 190 .serial_number = PKCS11_TOKEN_SERIAL_NUMBER, 191 .max_session_count = UINT32_MAX, 192 .max_rw_session_count = UINT32_MAX, 193 .max_pin_len = PKCS11_TOKEN_PIN_SIZE_MAX, 194 .min_pin_len = PKCS11_TOKEN_PIN_SIZE_MIN, 195 .total_public_memory = UINT32_MAX, 196 .free_public_memory = UINT32_MAX, 197 .total_private_memory = UINT32_MAX, 198 .free_private_memory = UINT32_MAX, 199 .hardware_version = PKCS11_TOKEN_HW_VERSION, 200 .firmware_version = PKCS11_TOKEN_FW_VERSION, 201 }; 202 203 if (ptypes != exp_pt || out->memref.size != sizeof(info)) 204 return PKCS11_CKR_ARGUMENTS_BAD; 205 206 serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 207 208 rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id)); 209 if (rv) 210 return rv; 211 212 if (serialargs_remaining_bytes(&ctrlargs)) 213 return PKCS11_CKR_ARGUMENTS_BAD; 214 215 token = get_token(token_id); 216 if (!token) 217 return PKCS11_CKR_SLOT_ID_INVALID; 218 219 pad_str(info.manufacturer_id, sizeof(info.manufacturer_id)); 220 pad_str(info.model, sizeof(info.model)); 221 pad_str(info.serial_number, sizeof(info.serial_number)); 222 223 TEE_MemMove(info.label, token->db_main->label, sizeof(info.label)); 224 225 info.flags = token->db_main->flags; 226 info.session_count = token->session_count; 227 info.rw_session_count = token->rw_session_count; 228 229 TEE_MemMove(out->memref.buffer, &info, sizeof(info)); 230 231 return PKCS11_CKR_OK; 232 } 233