-
Notifications
You must be signed in to change notification settings - Fork 154
ocall: add an example to show how to use OCALLs #64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
HernanGatta
wants to merge
1
commit into
linaro-swg:master
from
HernanGatta:optee-generic-rpc-support
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
###################### optee-hello-world ###################### | ||
LOCAL_PATH := $(call my-dir) | ||
|
||
OPTEE_CLIENT_EXPORT = $(LOCAL_PATH)/../../optee_client/out/export | ||
|
||
include $(CLEAR_VARS) | ||
LOCAL_CFLAGS += -DANDROID_BUILD | ||
LOCAL_CFLAGS += -Wall | ||
|
||
LOCAL_SRC_FILES += host/main.c | ||
|
||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/ta/include \ | ||
$(OPTEE_CLIENT_EXPORT)/include \ | ||
|
||
LOCAL_SHARED_LIBRARIES := libteec | ||
LOCAL_MODULE := optee_example_ocall | ||
LOCAL_VENDOR_MODULE := true | ||
LOCAL_MODULE_TAGS := optional | ||
include $(BUILD_EXECUTABLE) | ||
|
||
include $(LOCAL_PATH)/ta/Android.mk |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
project (optee_example_ocall C) | ||
|
||
set (SRC host/main.c) | ||
|
||
add_executable (${PROJECT_NAME} ${SRC}) | ||
|
||
target_include_directories(${PROJECT_NAME} | ||
PRIVATE ta/include | ||
PRIVATE include) | ||
|
||
target_link_libraries (${PROJECT_NAME} PRIVATE teec) | ||
|
||
install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export V?=0 | ||
|
||
# If _HOST or _TA specific compilers are not specified, then use CROSS_COMPILE | ||
HOST_CROSS_COMPILE ?= $(CROSS_COMPILE) | ||
TA_CROSS_COMPILE ?= $(CROSS_COMPILE) | ||
|
||
.PHONY: all | ||
all: | ||
$(MAKE) -C host CROSS_COMPILE="$(HOST_CROSS_COMPILE)" --no-builtin-variables | ||
$(MAKE) -C ta CROSS_COMPILE="$(TA_CROSS_COMPILE)" LDFLAGS="" | ||
|
||
.PHONY: clean | ||
clean: | ||
$(MAKE) -C host clean | ||
$(MAKE) -C ta clean |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
CC ?= $(CROSS_COMPILE)gcc | ||
LD ?= $(CROSS_COMPILE)ld | ||
AR ?= $(CROSS_COMPILE)ar | ||
NM ?= $(CROSS_COMPILE)nm | ||
OBJCOPY ?= $(CROSS_COMPILE)objcopy | ||
OBJDUMP ?= $(CROSS_COMPILE)objdump | ||
READELF ?= $(CROSS_COMPILE)readelf | ||
|
||
OBJS = main.o | ||
|
||
CFLAGS += -Wall -I../ta/include -I$(TEEC_EXPORT)/include -I./include | ||
#Add/link other required libraries here | ||
LDADD += -lteec -L$(TEEC_EXPORT)/lib | ||
|
||
BINARY = optee_example_hello_world | ||
|
||
.PHONY: all | ||
all: $(BINARY) | ||
|
||
$(BINARY): $(OBJS) | ||
$(CC) -o $@ $< $(LDADD) | ||
|
||
.PHONY: clean | ||
clean: | ||
rm -f $(OBJS) $(BINARY) | ||
|
||
%.o: %.c | ||
$(CC) $(CFLAGS) -c $< -o $@ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,272 @@ | ||
/* | ||
* Copyright (c) 2020, Microsoft Corporation | ||
* All rights reserved. | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
||
#include <err.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
#include <tee_client_api.h> | ||
#include <tee_client_api_extensions.h> | ||
|
||
#include <ocall_ta.h> | ||
|
||
static void print_uuid(TEEC_UUID *uuid) | ||
{ | ||
printf("%x-%x-%x-%x%x-%x%x%x%x%x%x", | ||
uuid->timeLow, | ||
uuid->timeMid, | ||
uuid->timeHiAndVersion, | ||
uuid->clockSeqAndNode[0], | ||
uuid->clockSeqAndNode[1], | ||
uuid->clockSeqAndNode[2], | ||
uuid->clockSeqAndNode[3], | ||
uuid->clockSeqAndNode[4], | ||
uuid->clockSeqAndNode[5], | ||
uuid->clockSeqAndNode[6], | ||
uuid->clockSeqAndNode[7]); | ||
} | ||
|
||
/* | ||
* This function is called by the TEE Client API whenever an OCALL arrives from | ||
* the TA. | ||
* | ||
* The 'taUUID' parameter carries the UUID of the TA that sent the OCALL. Since | ||
* a TA can open a session to another TA, it is possible to receive OCALLs from | ||
* other TAs that your TA calls into, if any. | ||
* | ||
* The 'commandId' indicates which function the TA wishes the CA to run. | ||
* | ||
* 'ctxData' is the arbitrary pointer that was set via the TEE context OCALL | ||
* setting, if any. Similarly, 'sessionData' is the arbitrary pointer set via | ||
* the session data setting, if it was supplied, or NULL. | ||
*/ | ||
TEEC_Result ocall_handler(TEEC_UUID *taUUID, uint32_t commandId, | ||
uint32_t paramTypes, | ||
TEEC_Parameter params[TEEC_CONFIG_PAYLOAD_REF_COUNT], | ||
void *ctxData, void *sessionData) | ||
{ | ||
const char *msg = "This string was sent by the CA"; | ||
uint32_t expected_pt; | ||
|
||
printf("Received an OCALL for Command Id: %u\n", commandId); | ||
printf("The TA that sent it is: "); | ||
print_uuid(taUUID); | ||
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, | ||
TEEC_MEMREF_TEMP_INPUT, | ||
TEEC_MEMREF_TEMP_INOUT); | ||
if (paramTypes != expected_pt) { | ||
fprintf(stderr, "Bad parameter types\n"); | ||
return TEEC_ERROR_BAD_PARAMETERS; | ||
} | ||
if (!params[2].tmpref.buffer || !params[3].tmpref.buffer) { | ||
fprintf(stderr, "No buffer(s)\n"); | ||
return TEEC_ERROR_BAD_PARAMETERS; | ||
} | ||
if (params[3].tmpref.size < strlen(msg) + 1) { | ||
fprintf(stderr, "Bad parameters\n"); | ||
return TEEC_ERROR_BAD_PARAMETERS; | ||
} | ||
|
||
/* Print out the OCALL's INPUT/INOUT parameters */ | ||
printf("Input values: %u, %u\n", params[0].value.a, | ||
params[0].value.b); | ||
printf("Inout values: %u, %u\n", params[1].value.a, | ||
params[1].value.b); | ||
|
||
printf("Input string: %s\n", (char *)params[2].tmpref.buffer); | ||
printf("Input size: %zu\n", params[2].tmpref.size); | ||
|
||
printf("Inout string: %s\n", (char *)params[3].tmpref.buffer); | ||
printf("Inout size: %zu\n", params[3].tmpref.size); | ||
|
||
/* Set the OCALL's INOUT parameters */ | ||
params[1].value.a = 0x3; | ||
params[1].value.b = 0x4; | ||
|
||
params[3].tmpref.size = strlen(msg) + 1; | ||
memcpy(params[3].tmpref.buffer, msg, params[3].tmpref.size); | ||
break; | ||
default: | ||
fprintf(stderr, "Bad function ID\n"); | ||
return TEEC_ERROR_BAD_PARAMETERS; | ||
} | ||
|
||
printf("OCALL handled\n"); | ||
return TEEC_SUCCESS; | ||
} | ||
|
||
int main(int argc, char* argv[]) | ||
{ | ||
TEEC_Context ctx; | ||
TEEC_Session sess; | ||
TEEC_UUID uuid = TA_OCALL_UUID; | ||
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 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; otherwise, all OCALLs will return | ||
* a failure code. | ||
*/ | ||
TEEC_ContextSettingOCall ocall_setting = { | ||
.handler = ocall_handler, | ||
.data = &ctx, | ||
}; | ||
|
||
/* Array of TEE context settings */ | ||
TEEC_ContextSetting ctx_settings = { | ||
.type = TEEC_CONTEXT_SETTING_OCALL, | ||
.u.ocall = &ocall_setting, | ||
}; | ||
|
||
/* Initialize a TEE context with settings */ | ||
res = TEEC_InitializeContext2(NULL, &ctx, &ctx_settings, 1); | ||
if (res != TEEC_SUCCESS) | ||
errx(1, "TEEC_InitializeContext failed with code 0x%x", res); | ||
|
||
/* | ||
* 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 | ||
* you expect OCALLs. | ||
*/ | ||
TEEC_SessionSettingData data_setting = { | ||
.data = &sess | ||
}; | ||
|
||
/* Array of session settings */ | ||
TEEC_SessionSetting session_settings = { | ||
.type = TEEC_SESSION_SETTING_DATA, | ||
.u.data = &data_setting, | ||
}; | ||
|
||
/* 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, | ||
&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 | ||
* function invocation that carries those parameters to the TA, the TA | ||
* can make an OCALL with parameters of its own choosing. That is, the | ||
* 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, | ||
TEEC_MEMREF_TEMP_INPUT, | ||
TEEC_MEMREF_TEMP_INOUT); | ||
|
||
op.params[0].value.a = 0x3; | ||
op.params[0].value.b = 0x4; | ||
|
||
op.params[1].value.a = 0x5; | ||
op.params[1].value.b = 0x6; | ||
|
||
op.params[2].tmpref.buffer = msg1; | ||
op.params[2].tmpref.size = strlen(msg1) + 1; | ||
|
||
op.params[3].tmpref.buffer = buf; | ||
op.params[3].tmpref.size = sizeof(buf); | ||
memcpy(buf, msg2, strlen(msg2) + 1); | ||
|
||
/* Ask the TA to call us back */ | ||
res = TEEC_InvokeCommand(&sess, TA_OCALL_CMD_CALL_CA, &op, &err_origin); | ||
if (res != TEEC_SUCCESS) | ||
errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x", | ||
res, err_origin); | ||
|
||
/* | ||
* The code below once again executes after the OCALL has been handled | ||
* in the callback at the top of this file. | ||
*/ | ||
|
||
/* | ||
* Print out the values of the INOUT parameters of the original function | ||
* invocation that we got from the TA.. | ||
*/ | ||
printf("INOUT parameters from the original function invocation:\n"); | ||
printf("Inout values: %u, %u\n", op.params[1].value.a, | ||
op.params[1].value.b); | ||
|
||
printf("Inout string: %s\n", (char *)op.params[3].tmpref.buffer); | ||
printf("Inout size: %zu\n", op.params[3].tmpref.size); | ||
|
||
/* All done */ | ||
TEEC_CloseSession(&sess); | ||
|
||
TEEC_FinalizeContext(&ctx); | ||
|
||
return 0; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
LOCAL_PATH := $(call my-dir) | ||
|
||
local_module := 9b2c0652-3b9b-4d83-971e-e56c40512793.ta | ||
include $(BUILD_OPTEE_MK) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
CFG_TEE_TA_LOG_LEVEL ?= 4 | ||
CPPFLAGS += -DCFG_TEE_TA_LOG_LEVEL=$(CFG_TEE_TA_LOG_LEVEL) | ||
|
||
# The UUID for the Trusted Application | ||
BINARY=9b2c0652-3b9b-4d83-971e-e56c40512793 | ||
|
||
-include $(TA_DEV_KIT_DIR)/mk/ta_dev_kit.mk | ||
|
||
ifeq ($(wildcard $(TA_DEV_KIT_DIR)/mk/ta_dev_kit.mk), ) | ||
clean: | ||
@echo 'Note: $$(TA_DEV_KIT_DIR)/mk/ta_dev_kit.mk not found, cannot clean TA' | ||
@echo 'Note: TA_DEV_KIT_DIR=$(TA_DEV_KIT_DIR)' | ||
endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Copyright (c) 2020, Microsoft Corporation | ||
* All rights reserved. | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
||
#ifndef TA_OCALL_H | ||
#define TA_OCALL_H | ||
|
||
/* 9b2c0652-3b9b-4d83-971e-e56c40512793 */ | ||
#define TA_OCALL_UUID \ | ||
{ 0x9b2c0652, 0x3b9b, 0x4d83, \ | ||
{ 0x97, 0x1e, 0xe5, 0x6c, 0x40, 0x51, 0x27, 0x93 } } | ||
|
||
#define TA_OCALL_CMD_CALL_CA 0 | ||
|
||
#define CA_OCALL_CMD_REPLY_SESSION_OPEN 99 | ||
#define CA_OCALL_CMD_REPLY_TA 100 | ||
|
||
#endif /*TA_OCALL_H*/ |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto