1f8a3a2c4SEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause 2f8a3a2c4SEtienne Carriere /* 3f8a3a2c4SEtienne Carriere * Copyright (c) 2018-2020, Linaro Limited 4f8a3a2c4SEtienne Carriere */ 5f8a3a2c4SEtienne Carriere 6*208dec38SEtienne Carriere #include <assert.h> 7f8a3a2c4SEtienne Carriere #include <compiler.h> 86ea5aa6cSEtienne Carriere #include <pkcs11_ta.h> 9f8a3a2c4SEtienne Carriere #include <tee_internal_api.h> 1060290f69SEtienne Carriere #include <tee_internal_api_extensions.h> 11d34f3266SEtienne Carriere #include <util.h> 1260290f69SEtienne Carriere 1360290f69SEtienne Carriere #include "pkcs11_helpers.h" 14f8a3a2c4SEtienne Carriere 15f8a3a2c4SEtienne Carriere TEE_Result TA_CreateEntryPoint(void) 16f8a3a2c4SEtienne Carriere { 17f8a3a2c4SEtienne Carriere return TEE_SUCCESS; 18f8a3a2c4SEtienne Carriere } 19f8a3a2c4SEtienne Carriere 20f8a3a2c4SEtienne Carriere void TA_DestroyEntryPoint(void) 21f8a3a2c4SEtienne Carriere { 22f8a3a2c4SEtienne Carriere } 23f8a3a2c4SEtienne Carriere 24f8a3a2c4SEtienne Carriere TEE_Result TA_OpenSessionEntryPoint(uint32_t __unused param_types, 25f8a3a2c4SEtienne Carriere TEE_Param __unused params[4], 26f8a3a2c4SEtienne Carriere void **session) 27f8a3a2c4SEtienne Carriere { 28f8a3a2c4SEtienne Carriere *session = NULL; 29f8a3a2c4SEtienne Carriere 30f8a3a2c4SEtienne Carriere return TEE_SUCCESS; 31f8a3a2c4SEtienne Carriere } 32f8a3a2c4SEtienne Carriere 33f8a3a2c4SEtienne Carriere void TA_CloseSessionEntryPoint(void *session __unused) 34f8a3a2c4SEtienne Carriere { 35f8a3a2c4SEtienne Carriere } 36f8a3a2c4SEtienne Carriere 37f8a3a2c4SEtienne Carriere /* 386ea5aa6cSEtienne Carriere * Entry point for invocation command PKCS11_CMD_PING 396ea5aa6cSEtienne Carriere * 40*208dec38SEtienne Carriere * Return a PKCS11_CKR_* value which is also loaded into the output param#0 416ea5aa6cSEtienne Carriere */ 42*208dec38SEtienne Carriere static uint32_t entry_ping(uint32_t ptypes, TEE_Param *params) 436ea5aa6cSEtienne Carriere { 44*208dec38SEtienne Carriere const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 45*208dec38SEtienne Carriere TEE_PARAM_TYPE_NONE, 46*208dec38SEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT, 47*208dec38SEtienne Carriere TEE_PARAM_TYPE_NONE); 48*208dec38SEtienne Carriere TEE_Param *out = ¶ms[2]; 496ea5aa6cSEtienne Carriere const uint32_t ver[] = { 506ea5aa6cSEtienne Carriere PKCS11_TA_VERSION_MAJOR, 516ea5aa6cSEtienne Carriere PKCS11_TA_VERSION_MINOR, 526ea5aa6cSEtienne Carriere PKCS11_TA_VERSION_PATCH, 536ea5aa6cSEtienne Carriere }; 546ea5aa6cSEtienne Carriere 55*208dec38SEtienne Carriere if (ptypes != exp_pt || 56*208dec38SEtienne Carriere params[0].memref.size != TEE_PARAM0_SIZE_MIN || 57*208dec38SEtienne Carriere out->memref.size != sizeof(ver)) 58*208dec38SEtienne Carriere return PKCS11_CKR_ARGUMENTS_BAD; 596ea5aa6cSEtienne Carriere 606ea5aa6cSEtienne Carriere TEE_MemMove(out->memref.buffer, ver, sizeof(ver)); 616ea5aa6cSEtienne Carriere 62d34f3266SEtienne Carriere return PKCS11_CKR_OK; 636ea5aa6cSEtienne Carriere } 646ea5aa6cSEtienne Carriere 65*208dec38SEtienne Carriere static bool __maybe_unused param_is_none(uint32_t ptypes, unsigned int index) 66*208dec38SEtienne Carriere { 67*208dec38SEtienne Carriere return TEE_PARAM_TYPE_GET(ptypes, index) == 68*208dec38SEtienne Carriere TEE_PARAM_TYPE_NONE; 69*208dec38SEtienne Carriere } 70*208dec38SEtienne Carriere 71*208dec38SEtienne Carriere static bool __maybe_unused param_is_memref(uint32_t ptypes, unsigned int index) 72*208dec38SEtienne Carriere { 73*208dec38SEtienne Carriere switch (TEE_PARAM_TYPE_GET(ptypes, index)) { 74*208dec38SEtienne Carriere case TEE_PARAM_TYPE_MEMREF_INPUT: 75*208dec38SEtienne Carriere case TEE_PARAM_TYPE_MEMREF_OUTPUT: 76*208dec38SEtienne Carriere case TEE_PARAM_TYPE_MEMREF_INOUT: 77*208dec38SEtienne Carriere return true; 78*208dec38SEtienne Carriere default: 79*208dec38SEtienne Carriere return false; 80*208dec38SEtienne Carriere } 81*208dec38SEtienne Carriere } 82*208dec38SEtienne Carriere 83*208dec38SEtienne Carriere static bool __maybe_unused param_is_input(uint32_t ptypes, unsigned int index) 84*208dec38SEtienne Carriere { 85*208dec38SEtienne Carriere return TEE_PARAM_TYPE_GET(ptypes, index) == 86*208dec38SEtienne Carriere TEE_PARAM_TYPE_MEMREF_INPUT; 87*208dec38SEtienne Carriere } 88*208dec38SEtienne Carriere 89*208dec38SEtienne Carriere static bool __maybe_unused param_is_output(uint32_t ptypes, unsigned int index) 90*208dec38SEtienne Carriere { 91*208dec38SEtienne Carriere return TEE_PARAM_TYPE_GET(ptypes, index) == 92*208dec38SEtienne Carriere TEE_PARAM_TYPE_MEMREF_OUTPUT; 93*208dec38SEtienne Carriere } 94*208dec38SEtienne Carriere 956ea5aa6cSEtienne Carriere /* 96f8a3a2c4SEtienne Carriere * Entry point for PKCS11 TA commands 97*208dec38SEtienne Carriere * 98*208dec38SEtienne Carriere * Param#0 (ctrl) is an output or an in/out buffer. Input data are serialized 99*208dec38SEtienne Carriere * arguments for the invoked command while the output data is used to send 100*208dec38SEtienne Carriere * back to the client a PKCS11 finer status ID than the GPD TEE result codes 101*208dec38SEtienne Carriere * Client shall check the status ID from the parameter #0 output buffer together 102*208dec38SEtienne Carriere * with the GPD TEE result code. 103f8a3a2c4SEtienne Carriere */ 104f8a3a2c4SEtienne Carriere TEE_Result TA_InvokeCommandEntryPoint(void *tee_session __unused, uint32_t cmd, 1056ea5aa6cSEtienne Carriere uint32_t ptypes, 1066ea5aa6cSEtienne Carriere TEE_Param params[TEE_NUM_PARAMS]) 107f8a3a2c4SEtienne Carriere { 108d34f3266SEtienne Carriere uint32_t rc = 0; 109f8a3a2c4SEtienne Carriere 110*208dec38SEtienne Carriere /* All command handlers will check only against 4 parameters */ 111*208dec38SEtienne Carriere COMPILE_TIME_ASSERT(TEE_NUM_PARAMS == 4); 112*208dec38SEtienne Carriere 113*208dec38SEtienne Carriere /* 114*208dec38SEtienne Carriere * Param#0 must be either an output or an inout memref as used to 115*208dec38SEtienne Carriere * store the output return value for the invoked command. 116*208dec38SEtienne Carriere */ 1176ea5aa6cSEtienne Carriere switch (TEE_PARAM_TYPE_GET(ptypes, 0)) { 1186ea5aa6cSEtienne Carriere case TEE_PARAM_TYPE_MEMREF_OUTPUT: 119*208dec38SEtienne Carriere case TEE_PARAM_TYPE_MEMREF_INOUT: 120*208dec38SEtienne Carriere if (params[0].memref.size < sizeof(uint32_t)) 121*208dec38SEtienne Carriere return TEE_ERROR_BAD_PARAMETERS; 1226ea5aa6cSEtienne Carriere break; 1236ea5aa6cSEtienne Carriere default: 1246ea5aa6cSEtienne Carriere return TEE_ERROR_BAD_PARAMETERS; 1256ea5aa6cSEtienne Carriere } 1266ea5aa6cSEtienne Carriere 127*208dec38SEtienne Carriere DMSG("%s p#0 %"PRIu32"@%p, p#1 %s %"PRIu32"@%p, p#2 %s %"PRIu32"@%p", 12860290f69SEtienne Carriere id2str_ta_cmd(cmd), 129*208dec38SEtienne Carriere params[0].memref.size, params[0].memref.buffer, 130*208dec38SEtienne Carriere param_is_input(ptypes, 1) ? "in" : 131*208dec38SEtienne Carriere param_is_output(ptypes, 1) ? "out" : "---", 132*208dec38SEtienne Carriere param_is_memref(ptypes, 1) ? params[1].memref.size : 0, 133*208dec38SEtienne Carriere param_is_memref(ptypes, 1) ? params[1].memref.buffer : NULL, 134*208dec38SEtienne Carriere param_is_input(ptypes, 2) ? "in" : 135*208dec38SEtienne Carriere param_is_output(ptypes, 2) ? "out" : "---", 136*208dec38SEtienne Carriere param_is_memref(ptypes, 2) ? params[2].memref.size : 0, 137*208dec38SEtienne Carriere param_is_memref(ptypes, 2) ? params[2].memref.buffer : NULL); 13860290f69SEtienne Carriere 1396ea5aa6cSEtienne Carriere switch (cmd) { 1406ea5aa6cSEtienne Carriere case PKCS11_CMD_PING: 141*208dec38SEtienne Carriere rc = entry_ping(ptypes, params); 1426ea5aa6cSEtienne Carriere break; 1436ea5aa6cSEtienne Carriere 1446ea5aa6cSEtienne Carriere default: 1456ea5aa6cSEtienne Carriere EMSG("Command 0x%"PRIx32" is not supported", cmd); 146f8a3a2c4SEtienne Carriere return TEE_ERROR_NOT_SUPPORTED; 147f8a3a2c4SEtienne Carriere } 1486ea5aa6cSEtienne Carriere 149*208dec38SEtienne Carriere DMSG("%s rc 0x%08"PRIx32"/%s", id2str_ta_cmd(cmd), rc, id2str_rc(rc)); 1506ea5aa6cSEtienne Carriere 151*208dec38SEtienne Carriere TEE_MemMove(params[0].memref.buffer, &rc, sizeof(rc)); 152*208dec38SEtienne Carriere params[0].memref.size = sizeof(rc); 153d34f3266SEtienne Carriere 154*208dec38SEtienne Carriere if (rc == PKCS11_CKR_BUFFER_TOO_SMALL) 155*208dec38SEtienne Carriere return TEE_ERROR_SHORT_BUFFER; 156*208dec38SEtienne Carriere else 157*208dec38SEtienne Carriere return TEE_SUCCESS; 1586ea5aa6cSEtienne Carriere } 159