1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2018-2020, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <compiler.h> 8 #include <pkcs11_ta.h> 9 #include <tee_internal_api.h> 10 #include <tee_internal_api_extensions.h> 11 #include <util.h> 12 13 #include "object.h" 14 #include "pkcs11_helpers.h" 15 #include "pkcs11_token.h" 16 #include "processing.h" 17 18 TEE_Result TA_CreateEntryPoint(void) 19 { 20 return pkcs11_init(); 21 } 22 23 void TA_DestroyEntryPoint(void) 24 { 25 pkcs11_deinit(); 26 } 27 28 TEE_Result TA_OpenSessionEntryPoint(uint32_t __unused param_types, 29 TEE_Param __unused params[4], 30 void **tee_session) 31 { 32 struct pkcs11_client *client = register_client(); 33 34 if (!client) 35 return TEE_ERROR_OUT_OF_MEMORY; 36 37 *tee_session = client; 38 39 return TEE_SUCCESS; 40 } 41 42 void TA_CloseSessionEntryPoint(void *tee_session) 43 { 44 struct pkcs11_client *client = tee_session2client(tee_session); 45 46 unregister_client(client); 47 } 48 49 /* 50 * Entry point for invocation command PKCS11_CMD_PING 51 * 52 * Return a PKCS11_CKR_* value which is also loaded into the output param#0 53 */ 54 static enum pkcs11_rc entry_ping(uint32_t ptypes, TEE_Param *params) 55 { 56 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 57 TEE_PARAM_TYPE_NONE, 58 TEE_PARAM_TYPE_MEMREF_OUTPUT, 59 TEE_PARAM_TYPE_NONE); 60 TEE_Param *out = params + 2; 61 const uint32_t ver[] = { 62 PKCS11_TA_VERSION_MAJOR, 63 PKCS11_TA_VERSION_MINOR, 64 PKCS11_TA_VERSION_PATCH, 65 }; 66 67 if (ptypes != exp_pt || 68 params[0].memref.size != TEE_PARAM0_SIZE_MIN || 69 out->memref.size != sizeof(ver)) 70 return PKCS11_CKR_ARGUMENTS_BAD; 71 72 TEE_MemMove(out->memref.buffer, ver, sizeof(ver)); 73 74 return PKCS11_CKR_OK; 75 } 76 77 static bool __maybe_unused param_is_none(uint32_t ptypes, unsigned int index) 78 { 79 return TEE_PARAM_TYPE_GET(ptypes, index) == 80 TEE_PARAM_TYPE_NONE; 81 } 82 83 static bool __maybe_unused param_is_memref(uint32_t ptypes, unsigned int index) 84 { 85 switch (TEE_PARAM_TYPE_GET(ptypes, index)) { 86 case TEE_PARAM_TYPE_MEMREF_INPUT: 87 case TEE_PARAM_TYPE_MEMREF_OUTPUT: 88 case TEE_PARAM_TYPE_MEMREF_INOUT: 89 return true; 90 default: 91 return false; 92 } 93 } 94 95 static bool __maybe_unused param_is_input(uint32_t ptypes, unsigned int index) 96 { 97 return TEE_PARAM_TYPE_GET(ptypes, index) == 98 TEE_PARAM_TYPE_MEMREF_INPUT; 99 } 100 101 static bool __maybe_unused param_is_output(uint32_t ptypes, unsigned int index) 102 { 103 return TEE_PARAM_TYPE_GET(ptypes, index) == 104 TEE_PARAM_TYPE_MEMREF_OUTPUT; 105 } 106 107 /* 108 * Entry point for PKCS11 TA commands 109 * 110 * Param#0 (ctrl) is an output or an in/out buffer. Input data are serialized 111 * arguments for the invoked command while the output data is used to send 112 * back to the client a PKCS11 finer status ID than the GPD TEE result codes 113 * Client shall check the status ID from the parameter #0 output buffer together 114 * with the GPD TEE result code. 115 */ 116 TEE_Result TA_InvokeCommandEntryPoint(void *tee_session, uint32_t cmd, 117 uint32_t ptypes, 118 TEE_Param params[TEE_NUM_PARAMS]) 119 { 120 struct pkcs11_client *client = tee_session2client(tee_session); 121 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 122 123 if (!client) 124 return TEE_ERROR_SECURITY; 125 126 /* All command handlers will check only against 4 parameters */ 127 COMPILE_TIME_ASSERT(TEE_NUM_PARAMS == 4); 128 129 /* 130 * Param#0 must be either an output or an inout memref as used to 131 * store the output return value for the invoked command. 132 */ 133 switch (TEE_PARAM_TYPE_GET(ptypes, 0)) { 134 case TEE_PARAM_TYPE_MEMREF_OUTPUT: 135 case TEE_PARAM_TYPE_MEMREF_INOUT: 136 if (params[0].memref.size < sizeof(rc)) 137 return TEE_ERROR_BAD_PARAMETERS; 138 break; 139 default: 140 return TEE_ERROR_BAD_PARAMETERS; 141 } 142 143 DMSG("%s p#0 %zu@%p, p#1 %s %zu@%p, p#2 %s %zu@%p", 144 id2str_ta_cmd(cmd), 145 params[0].memref.size, params[0].memref.buffer, 146 param_is_input(ptypes, 1) ? "in" : 147 param_is_output(ptypes, 1) ? "out" : "---", 148 param_is_memref(ptypes, 1) ? params[1].memref.size : 0, 149 param_is_memref(ptypes, 1) ? params[1].memref.buffer : NULL, 150 param_is_input(ptypes, 2) ? "in" : 151 param_is_output(ptypes, 2) ? "out" : "---", 152 param_is_memref(ptypes, 2) ? params[2].memref.size : 0, 153 param_is_memref(ptypes, 2) ? params[2].memref.buffer : NULL); 154 155 switch (cmd) { 156 case PKCS11_CMD_PING: 157 rc = entry_ping(ptypes, params); 158 break; 159 160 case PKCS11_CMD_SLOT_LIST: 161 rc = entry_ck_slot_list(ptypes, params); 162 break; 163 case PKCS11_CMD_SLOT_INFO: 164 rc = entry_ck_slot_info(ptypes, params); 165 break; 166 case PKCS11_CMD_TOKEN_INFO: 167 rc = entry_ck_token_info(ptypes, params); 168 break; 169 case PKCS11_CMD_MECHANISM_IDS: 170 rc = entry_ck_token_mecha_ids(ptypes, params); 171 break; 172 case PKCS11_CMD_MECHANISM_INFO: 173 rc = entry_ck_token_mecha_info(ptypes, params); 174 break; 175 176 case PKCS11_CMD_OPEN_SESSION: 177 rc = entry_ck_open_session(client, ptypes, params); 178 break; 179 case PKCS11_CMD_CLOSE_SESSION: 180 rc = entry_ck_close_session(client, ptypes, params); 181 break; 182 case PKCS11_CMD_CLOSE_ALL_SESSIONS: 183 rc = entry_ck_close_all_sessions(client, ptypes, params); 184 break; 185 case PKCS11_CMD_SESSION_INFO: 186 rc = entry_ck_session_info(client, ptypes, params); 187 break; 188 189 case PKCS11_CMD_INIT_TOKEN: 190 rc = entry_ck_token_initialize(ptypes, params); 191 break; 192 case PKCS11_CMD_INIT_PIN: 193 rc = entry_ck_init_pin(client, ptypes, params); 194 break; 195 case PKCS11_CMD_SET_PIN: 196 rc = entry_ck_set_pin(client, ptypes, params); 197 break; 198 case PKCS11_CMD_LOGIN: 199 rc = entry_ck_login(client, ptypes, params); 200 break; 201 case PKCS11_CMD_LOGOUT: 202 rc = entry_ck_logout(client, ptypes, params); 203 break; 204 205 case PKCS11_CMD_CREATE_OBJECT: 206 rc = entry_create_object(client, ptypes, params); 207 break; 208 case PKCS11_CMD_DESTROY_OBJECT: 209 rc = entry_destroy_object(client, ptypes, params); 210 break; 211 212 case PKCS11_CMD_ENCRYPT_INIT: 213 rc = entry_processing_init(client, ptypes, params, 214 PKCS11_FUNCTION_ENCRYPT); 215 break; 216 case PKCS11_CMD_DECRYPT_INIT: 217 rc = entry_processing_init(client, ptypes, params, 218 PKCS11_FUNCTION_DECRYPT); 219 break; 220 case PKCS11_CMD_ENCRYPT_UPDATE: 221 rc = entry_processing_step(client, ptypes, params, 222 PKCS11_FUNCTION_ENCRYPT, 223 PKCS11_FUNC_STEP_UPDATE); 224 break; 225 case PKCS11_CMD_DECRYPT_UPDATE: 226 rc = entry_processing_step(client, ptypes, params, 227 PKCS11_FUNCTION_DECRYPT, 228 PKCS11_FUNC_STEP_UPDATE); 229 break; 230 case PKCS11_CMD_ENCRYPT_ONESHOT: 231 rc = entry_processing_step(client, ptypes, params, 232 PKCS11_FUNCTION_ENCRYPT, 233 PKCS11_FUNC_STEP_ONESHOT); 234 break; 235 case PKCS11_CMD_DECRYPT_ONESHOT: 236 rc = entry_processing_step(client, ptypes, params, 237 PKCS11_FUNCTION_DECRYPT, 238 PKCS11_FUNC_STEP_ONESHOT); 239 break; 240 case PKCS11_CMD_ENCRYPT_FINAL: 241 rc = entry_processing_step(client, ptypes, params, 242 PKCS11_FUNCTION_ENCRYPT, 243 PKCS11_FUNC_STEP_FINAL); 244 break; 245 case PKCS11_CMD_DECRYPT_FINAL: 246 rc = entry_processing_step(client, ptypes, params, 247 PKCS11_FUNCTION_DECRYPT, 248 PKCS11_FUNC_STEP_FINAL); 249 break; 250 case PKCS11_CMD_SIGN_INIT: 251 rc = entry_processing_init(client, ptypes, params, 252 PKCS11_FUNCTION_SIGN); 253 break; 254 case PKCS11_CMD_VERIFY_INIT: 255 rc = entry_processing_init(client, ptypes, params, 256 PKCS11_FUNCTION_VERIFY); 257 break; 258 case PKCS11_CMD_SIGN_ONESHOT: 259 rc = entry_processing_step(client, ptypes, params, 260 PKCS11_FUNCTION_SIGN, 261 PKCS11_FUNC_STEP_ONESHOT); 262 break; 263 case PKCS11_CMD_VERIFY_ONESHOT: 264 rc = entry_processing_step(client, ptypes, params, 265 PKCS11_FUNCTION_VERIFY, 266 PKCS11_FUNC_STEP_ONESHOT); 267 break; 268 case PKCS11_CMD_SIGN_UPDATE: 269 rc = entry_processing_step(client, ptypes, params, 270 PKCS11_FUNCTION_SIGN, 271 PKCS11_FUNC_STEP_UPDATE); 272 break; 273 case PKCS11_CMD_VERIFY_UPDATE: 274 rc = entry_processing_step(client, ptypes, params, 275 PKCS11_FUNCTION_VERIFY, 276 PKCS11_FUNC_STEP_UPDATE); 277 break; 278 case PKCS11_CMD_SIGN_FINAL: 279 rc = entry_processing_step(client, ptypes, params, 280 PKCS11_FUNCTION_SIGN, 281 PKCS11_FUNC_STEP_FINAL); 282 break; 283 case PKCS11_CMD_VERIFY_FINAL: 284 rc = entry_processing_step(client, ptypes, params, 285 PKCS11_FUNCTION_VERIFY, 286 PKCS11_FUNC_STEP_FINAL); 287 break; 288 case PKCS11_CMD_GENERATE_KEY: 289 rc = entry_generate_secret(client, ptypes, params); 290 break; 291 case PKCS11_CMD_FIND_OBJECTS_INIT: 292 rc = entry_find_objects_init(client, ptypes, params); 293 break; 294 case PKCS11_CMD_FIND_OBJECTS: 295 rc = entry_find_objects(client, ptypes, params); 296 break; 297 case PKCS11_CMD_FIND_OBJECTS_FINAL: 298 rc = entry_find_objects_final(client, ptypes, params); 299 break; 300 case PKCS11_CMD_GET_ATTRIBUTE_VALUE: 301 rc = entry_get_attribute_value(client, ptypes, params); 302 break; 303 case PKCS11_CMD_GET_OBJECT_SIZE: 304 rc = entry_get_object_size(client, ptypes, params); 305 break; 306 case PKCS11_CMD_SET_ATTRIBUTE_VALUE: 307 rc = entry_set_attribute_value(client, ptypes, params); 308 break; 309 case PKCS11_CMD_COPY_OBJECT: 310 rc = entry_copy_object(client, ptypes, params); 311 break; 312 case PKCS11_CMD_SEED_RANDOM: 313 rc = entry_ck_seed_random(client, ptypes, params); 314 break; 315 case PKCS11_CMD_GENERATE_RANDOM: 316 rc = entry_ck_generate_random(client, ptypes, params); 317 break; 318 case PKCS11_CMD_DERIVE_KEY: 319 rc = entry_processing_key(client, ptypes, params, 320 PKCS11_FUNCTION_DERIVE); 321 break; 322 case PKCS11_CMD_RELEASE_ACTIVE_PROCESSING: 323 rc = entry_release_active_processing(client, ptypes, params); 324 break; 325 case PKCS11_CMD_DIGEST_INIT: 326 rc = entry_processing_init(client, ptypes, params, 327 PKCS11_FUNCTION_DIGEST); 328 break; 329 case PKCS11_CMD_DIGEST_UPDATE: 330 rc = entry_processing_step(client, ptypes, params, 331 PKCS11_FUNCTION_DIGEST, 332 PKCS11_FUNC_STEP_UPDATE); 333 break; 334 case PKCS11_CMD_DIGEST_KEY: 335 rc = entry_processing_step(client, ptypes, params, 336 PKCS11_FUNCTION_DIGEST, 337 PKCS11_FUNC_STEP_UPDATE_KEY); 338 break; 339 case PKCS11_CMD_DIGEST_ONESHOT: 340 rc = entry_processing_step(client, ptypes, params, 341 PKCS11_FUNCTION_DIGEST, 342 PKCS11_FUNC_STEP_ONESHOT); 343 break; 344 case PKCS11_CMD_DIGEST_FINAL: 345 rc = entry_processing_step(client, ptypes, params, 346 PKCS11_FUNCTION_DIGEST, 347 PKCS11_FUNC_STEP_FINAL); 348 break; 349 case PKCS11_CMD_GENERATE_KEY_PAIR: 350 rc = entry_generate_key_pair(client, ptypes, params); 351 break; 352 case PKCS11_CMD_WRAP_KEY: 353 rc = entry_wrap_key(client, ptypes, params); 354 break; 355 case PKCS11_CMD_UNWRAP_KEY: 356 rc = entry_processing_key(client, ptypes, params, 357 PKCS11_FUNCTION_UNWRAP); 358 break; 359 default: 360 EMSG("Command %#"PRIx32" is not supported", cmd); 361 return TEE_ERROR_NOT_SUPPORTED; 362 } 363 364 DMSG("%s rc %#"PRIx32"/%s", id2str_ta_cmd(cmd), rc, id2str_rc(rc)); 365 366 TEE_MemMove(params[0].memref.buffer, &rc, sizeof(rc)); 367 params[0].memref.size = sizeof(rc); 368 369 if (rc == PKCS11_CKR_BUFFER_TOO_SMALL) 370 return TEE_ERROR_SHORT_BUFFER; 371 else 372 return TEE_SUCCESS; 373 } 374