diff --git a/ocall/host/main.c b/ocall/host/main.c index 9911558..b881629 100644 --- a/ocall/host/main.c +++ b/ocall/host/main.c @@ -58,6 +58,29 @@ TEEC_Result ocall_handler(TEEC_UUID *taUUID, uint32_t commandId, printf("\n"); switch (commandId) { + case CA_OCALL_CMD_REPLY_SESSION_OPEN: + expected_pt = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, + TEEC_NONE, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT); + if (paramTypes != expected_pt) { + fprintf(stderr, "Bad parameter types\n"); + return TEEC_ERROR_BAD_PARAMETERS; + } + if (!params[3].tmpref.buffer) { + fprintf(stderr, "No buffer\n"); + return TEEC_ERROR_BAD_PARAMETERS; + } + + /* Print out the OCALL's INPUT/INOUT parameters */ + printf("Input values: 0x%x, 0x%x\n", params[0].value.a, + params[0].value.b); + printf("Input string: %s\n", (char *)params[3].tmpref.buffer); + + /* Set the OCALL's INOUT parameters */ + params[0].value.a = 0xCDDC1001; + params[0].value.b = 0xFFFFCAFE; + break; case CA_OCALL_CMD_REPLY_TA: expected_pt = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INOUT, @@ -94,13 +117,13 @@ TEEC_Result ocall_handler(TEEC_UUID *taUUID, uint32_t commandId, params[3].tmpref.size = strlen(msg) + 1; memcpy(params[3].tmpref.buffer, msg, params[3].tmpref.size); - - printf("OCALL handled\n"); break; default: fprintf(stderr, "Bad function ID\n"); return TEEC_ERROR_BAD_PARAMETERS; } + + printf("OCALL handled\n"); return TEEC_SUCCESS; } @@ -109,24 +132,26 @@ int main(int argc, char* argv[]) TEEC_Context ctx; TEEC_Session sess; TEEC_UUID uuid = TA_OCALL_UUID; - TEEC_Operation op = { 0 }; + TEEC_Operation op; TEEC_Result res; uint32_t err_origin; char buf[128]; + char buf2[128]; char *msg1 = "This string was sent by the CA"; const char *msg2 = "The CA thinks this is a fun riddle"; /* - * The TEE context OCALL setting allows setting the callback handler for - * when an OCALL arrives from the TA. This handler is effectively the - * equivalent of TA_InvokeCommandEntryPoint. Additionally, one may set - * an arbitrary pointer that will be passed to the OCALL handler when - * invoked. + * The TEE context OCALL setting allows specifying the callback handler + * for when an OCALL arrives from the TA. This handler is effectively + * the equivalent of TA_InvokeCommandEntryPoint, but on the CA side. + * Additionally, one may set an arbitrary pointer that will be passed + * to the OCALL handler when invoked. * * NOTE: You must pass this setting to the TEE context initialization - * routine to receive OCALLs. + * routine to receive OCALLs; otherwise, all OCALLs will return + * a failure code. */ TEEC_ContextSettingOcall ocall_setting = { .handler = ocall_handler, @@ -145,8 +170,8 @@ int main(int argc, char* argv[]) errx(1, "TEEC_InitializeContext failed with code 0x%x", res); /* - * The session data settings allows attaching an arbitrary pointer to - * the session. This pointer will be passed to the OCALL handler when + * The session data setting allows attaching an arbitrary pointer to the + * session. This pointer will be passed to the OCALL handler when * invoked. * * NOTE: This is optional; you can use TEEC_OpenSession as well even if @@ -162,13 +187,32 @@ int main(int argc, char* argv[]) .u.data = &data_setting, }; - /* Open a session with settings */ + /* Set up the parameters for the TA's session open handler */ + memset(&op, 0, sizeof(op)); + op.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_MEMREF_TEMP_INPUT, + TEEC_NONE, + TEEC_NONE); + + op.params[0].value.a = 0x0000CAFE; + op.params[0].value.b = 0xCAFE0000; + + op.params[1].tmpref.buffer = (void *)msg2; + op.params[1].tmpref.size = strlen(msg2) + 1; + + /* Open a session with settings; the sample TA will issue an OCALL */ res = TEEC_OpenSession2(&ctx, &sess, &uuid, TEEC_LOGIN_PUBLIC, NULL, - NULL, &err_origin, &session_settings, 1); + &op, &err_origin, &session_settings, 1); if (res != TEEC_SUCCESS) errx(1, "TEEC_OpenSessionEx failed with code 0x%x origin 0x%x", res, err_origin); + /* + * The code below executes after the OCALL has been handled in the + * callback at the top of this file. + */ + /* * Set up the parameters for the function invocation. These are just to * show that the CA can pass parameters to the TA and that during the @@ -177,6 +221,7 @@ int main(int argc, char* argv[]) * parameters passed from the CA to the TA do not interfere with those * passed from the TA to the CA, and vice-versa. */ + memset(&op, 0, sizeof(op)); op.paramTypes = TEEC_PARAM_TYPES( TEEC_VALUE_INPUT, TEEC_VALUE_INOUT, @@ -203,8 +248,8 @@ int main(int argc, char* argv[]) res, err_origin); /* - * The code below executes after the OCALL has been handled in the - * callback at the top of this file. + * The code below once again executes after the OCALL has been handled + * in the callback at the top of this file. */ /* diff --git a/ocall/ta/include/ocall_ta.h b/ocall/ta/include/ocall_ta.h index d7b38b6..8a3b0cb 100644 --- a/ocall/ta/include/ocall_ta.h +++ b/ocall/ta/include/ocall_ta.h @@ -15,6 +15,7 @@ #define TA_OCALL_CMD_CALL_CA 0 -#define CA_OCALL_CMD_REPLY_TA 100 +#define CA_OCALL_CMD_REPLY_SESSION_OPEN 99 +#define CA_OCALL_CMD_REPLY_TA 100 #endif /*TA_OCALL_H*/ diff --git a/ocall/ta/ocall_ta.c b/ocall/ta/ocall_ta.c index e255576..48cf54f 100644 --- a/ocall/ta/ocall_ta.c +++ b/ocall/ta/ocall_ta.c @@ -9,7 +9,8 @@ #include #include #include - +#pragma GCC push_options +#pragma GCC optimize ("-O0") static TEE_Result call_ca(uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { @@ -31,7 +32,7 @@ static TEE_Result call_ca(uint32_t param_types, TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_MEMREF_INOUT); - /* Parameter types for the OCALL (could be different from the above) */ + /* Parameter types for the OCALL (can be different from the above) */ const uint32_t ocall_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_VALUE_INOUT, @@ -49,6 +50,7 @@ static TEE_Result call_ca(uint32_t param_types, if (params[3].memref.size < strlen(msg2) + 1) return TEE_ERROR_BAD_PARAMETERS; + /* Print the invocation's INPUT/INOUT parameters */ DMSG("Input values: %u, %u", params[0].value.a, params[0].value.b); DMSG("Inout values: %u, %u", params[1].value.a, params[1].value.b); @@ -94,6 +96,7 @@ static TEE_Result call_ca(uint32_t param_types, return TEE_ERROR_BAD_PARAMETERS; } + /* Print the OCALL's INOUT parameters */ DMSG("Output values: %u, %u", ocall_params[1].value.a, ocall_params[1].value.b); DMSG("Output string: \"%s\"", (char *)ocall_params[3].memref.buffer); @@ -112,10 +115,64 @@ void TA_DestroyEntryPoint(void) /* NOTHING */ } -TEE_Result TA_OpenSessionEntryPoint(uint32_t param_types __unused, +TEE_Result TA_OpenSessionEntryPoint(uint32_t param_types, TEE_Param params[4] __unused, void **sess_ctx __unused) { + const char *msg = "The TA says hello during session open"; + + TEE_Param ocall_params[TEE_NUM_PARAMS]; + + TEE_Result res = TEE_SUCCESS; + uint32_t eorig = TEE_ORIGIN_TRUSTED_APP; + + /* Expected parameter types for the function invocation */ + const uint32_t expected_pt = + TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, + TEE_PARAM_TYPE_MEMREF_INPUT, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE); + + /* Parameter types for the OCALL (can be different from the above) */ + const uint32_t ocall_param_types = + TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INOUT, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_MEMREF_INPUT); + + if (param_types != expected_pt) + return TEE_ERROR_BAD_PARAMETERS; + + if (!params[1].memref.buffer) { + EMSG("No buffer"); + return TEE_ERROR_BAD_PARAMETERS; + } + + /* Print the invocation's INPUT parameters */ + DMSG("Input values: 0x%x, 0x%x", params[0].value.a, params[0].value.b); + DMSG("Input string: %s", (char *)params[1].memref.buffer); + DMSG("Input size: %u", params[1].memref.size); + + /* Set the OCALL's parameters */ + ocall_params[0].value.a = 0xFCFAFFFE; + ocall_params[0].value.b = 0x10CDDC01; + + ocall_params[3].memref.buffer = (void *)msg; + ocall_params[3].memref.size = strlen(msg) + 1; + + res = TEE_InvokeCACommand(TEE_TIMEOUT_INFINITE, + CA_OCALL_CMD_REPLY_SESSION_OPEN, + ocall_param_types, ocall_params, &eorig); + if (res != TEE_SUCCESS) { + EMSG("TEE_InvokeCACommand failed with code 0x%x origin 0x%x", + res, eorig); + return res; + } + + /* Print the OCALL's INOUT parameters */ + DMSG("Output values: 0x%x, 0x%x", ocall_params[0].value.a, + ocall_params[0].value.b); + return TEE_SUCCESS; } @@ -135,3 +192,4 @@ TEE_Result TA_InvokeCommandEntryPoint(void *sess_ctx __unused, uint32_t cmd_id, return TEE_ERROR_BAD_PARAMETERS; } } +#pragma GCC pop_options \ No newline at end of file