-
Notifications
You must be signed in to change notification settings - Fork 140
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Example a raw access to the secure storage
Secure_storage example provides basics for creating, reading and deleting a object in a TA secure storage. A TA command allows to create an object in the TA secure storage. A TA command allows to read an object in the TA secure storage. A TA command allows to delete an object from the TA secur storage. This example does not cover all the possibilities of secure storage API provided to TAs: seeking into a object data stream, manipulating key material objects instead of raw data objects, etc. Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
- Loading branch information
1 parent
16c8af5
commit ea22eff
Showing
13 changed files
with
676 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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,19 @@ | ||
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_secure_storage | ||
LOCAL_MODULE_TAGS := optional | ||
include $(BUILD_EXECUTABLE) | ||
|
||
include $(LOCAL_PATH)/ta/Android.mk |
This file contains 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)" | ||
$(MAKE) -C ta CROSS_COMPILE="$(TA_CROSS_COMPILE)" | ||
|
||
.PHONY: clean | ||
clean: | ||
$(MAKE) -C host clean | ||
$(MAKE) -C ta clean |
This file contains 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,25 @@ | ||
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./include | ||
CFLAGS += -I$(TEEC_EXPORT)/include | ||
LDADD += -lteec -L$(TEEC_EXPORT)/lib | ||
|
||
BINARY = optee_example_secure_storage | ||
|
||
.PHONY: all | ||
all: $(BINARY) | ||
|
||
$(BINARY): $(OBJS) | ||
$(CC) -o $@ $< $(LDADD) | ||
|
||
.PHONY: clean | ||
clean: | ||
rm -f $(OBJS) $(BINARY) |
This file contains 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,241 @@ | ||
/* | ||
* Copyright (c) 2017, Linaro Limited | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright notice, | ||
* this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright notice, | ||
* this list of conditions and the following disclaimer in the documentation | ||
* and/or other materials provided with the distribution. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
* POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
|
||
#include <err.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
/* OP-TEE TEE client API (built by optee_client) */ | ||
#include <tee_client_api.h> | ||
|
||
/* To the the UUID (found the the TA's h-file(s)) */ | ||
#include <optee_example_secure_storage_ta.h> | ||
|
||
/* TEE resources */ | ||
struct test_ctx { | ||
TEEC_Context ctx; | ||
TEEC_Session sess; | ||
}; | ||
|
||
void prepare_tee_session(struct test_ctx *ctx) | ||
{ | ||
TEEC_UUID uuid = OPTEE_EXAMPLE_SECURE_STORAGE_UUID; | ||
uint32_t origin; | ||
TEEC_Result res; | ||
|
||
/* Initialize a context connecting us to the TEE */ | ||
res = TEEC_InitializeContext(NULL, &ctx->ctx); | ||
if (res != TEEC_SUCCESS) | ||
errx(1, "TEEC_InitializeContext failed with code 0x%x", res); | ||
|
||
/* Open a session with the TA */ | ||
res = TEEC_OpenSession(&ctx->ctx, &ctx->sess, &uuid, | ||
TEEC_LOGIN_PUBLIC, NULL, NULL, &origin); | ||
if (res != TEEC_SUCCESS) | ||
errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x", | ||
res, origin); | ||
} | ||
|
||
void terminate_tee_session(struct test_ctx *ctx) | ||
{ | ||
TEEC_CloseSession(&ctx->sess); | ||
TEEC_FinalizeContext(&ctx->ctx); | ||
} | ||
|
||
TEEC_Result read_secure_object(struct test_ctx *ctx, char *id, | ||
char *data, size_t data_len) | ||
{ | ||
TEEC_Operation op; | ||
uint32_t origin; | ||
TEEC_Result res; | ||
size_t id_len = strlen(id); | ||
|
||
memset(&op, 0, sizeof(op)); | ||
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, | ||
TEEC_MEMREF_TEMP_OUTPUT, | ||
TEEC_NONE, TEEC_NONE); | ||
|
||
op.params[0].tmpref.buffer = id; | ||
op.params[0].tmpref.size = id_len; | ||
|
||
op.params[1].tmpref.buffer = data; | ||
op.params[1].tmpref.size = data_len; | ||
|
||
res = TEEC_InvokeCommand(&ctx->sess, | ||
OPTEE_EXAMPLE_SECURE_STORAGE_CMD_READ_RAW, | ||
&op, &origin); | ||
switch (res) { | ||
case TEEC_SUCCESS: | ||
case TEEC_ERROR_SHORT_BUFFER: | ||
case TEEC_ERROR_ITEM_NOT_FOUND: | ||
break; | ||
default: | ||
printf("Command READ_RAW failed: 0x%x / %u\n", res, origin); | ||
} | ||
|
||
return res; | ||
} | ||
|
||
TEEC_Result write_secure_object(struct test_ctx *ctx, char *id, | ||
char *data, size_t data_len) | ||
{ | ||
TEEC_Operation op; | ||
uint32_t origin; | ||
TEEC_Result res; | ||
size_t id_len = strlen(id); | ||
|
||
memset(&op, 0, sizeof(op)); | ||
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, | ||
TEEC_MEMREF_TEMP_INPUT, | ||
TEEC_NONE, TEEC_NONE); | ||
|
||
op.params[0].tmpref.buffer = id; | ||
op.params[0].tmpref.size = id_len; | ||
|
||
op.params[1].tmpref.buffer = data; | ||
op.params[1].tmpref.size = data_len; | ||
|
||
res = TEEC_InvokeCommand(&ctx->sess, | ||
OPTEE_EXAMPLE_SECURE_STORAGE_CMD_WRITE_RAW, | ||
&op, &origin); | ||
if (res != TEEC_SUCCESS) | ||
printf("Command WRITE_RAW failed: 0x%x / %u\n", res, origin); | ||
|
||
switch (res) { | ||
case TEEC_SUCCESS: | ||
break; | ||
default: | ||
printf("Command WRITE_RAW failed: 0x%x / %u\n", res, origin); | ||
} | ||
|
||
return res; | ||
} | ||
|
||
TEEC_Result delete_secure_object(struct test_ctx *ctx, char *id) | ||
{ | ||
TEEC_Operation op; | ||
uint32_t origin; | ||
TEEC_Result res; | ||
size_t id_len = strlen(id); | ||
|
||
memset(&op, 0, sizeof(op)); | ||
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, | ||
TEEC_NONE, TEEC_NONE, TEEC_NONE); | ||
|
||
op.params[0].tmpref.buffer = id; | ||
op.params[0].tmpref.size = id_len; | ||
|
||
res = TEEC_InvokeCommand(&ctx->sess, | ||
OPTEE_EXAMPLE_SECURE_STORAGE_CMD_DELETE, | ||
&op, &origin); | ||
|
||
switch (res) { | ||
case TEEC_SUCCESS: | ||
case TEEC_ERROR_ITEM_NOT_FOUND: | ||
break; | ||
default: | ||
printf("Command DELETE failed: 0x%x / %u\n", res, origin); | ||
} | ||
|
||
return res; | ||
} | ||
|
||
#define TEST_OBJECT_SIZE 7000 | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
struct test_ctx ctx; | ||
char obj1_id[] = "object#1"; /* string identification for the object */ | ||
char obj2_id[] = "object#2"; /* string identification for the object */ | ||
char obj1_data[TEST_OBJECT_SIZE]; | ||
char read_data[TEST_OBJECT_SIZE]; | ||
TEEC_Result res; | ||
|
||
printf("Prepare session with the TA\n"); | ||
prepare_tee_session(&ctx); | ||
|
||
/* | ||
* Create object, read it, delete it. | ||
*/ | ||
printf("\nTest on object \"%s\"\n", obj1_id); | ||
|
||
printf("- Create and load object in the TA secure storage\n"); | ||
|
||
memset(obj1_data, 0xA1, sizeof(obj1_data)); | ||
|
||
res = write_secure_object(&ctx, obj1_id, | ||
obj1_data, sizeof(obj1_data)); | ||
if (res != TEEC_SUCCESS) | ||
errx(1, "Failed to create an object in the secure storage"); | ||
|
||
printf("- Read back the object\n"); | ||
|
||
res = read_secure_object(&ctx, obj1_id, | ||
read_data, sizeof(read_data)); | ||
if (res != TEEC_SUCCESS) | ||
errx(1, "Failed to read an object from the secure storage"); | ||
if (memcmp(obj1_data, read_data, sizeof(obj1_data))) | ||
errx(1, "Unexpected content found in secure storage"); | ||
|
||
printf("- Delete the object\n"); | ||
|
||
res = delete_secure_object(&ctx, obj1_id); | ||
if (res != TEEC_SUCCESS) | ||
errx(1, "Failed to delete the object: 0x%x", res); | ||
|
||
/* | ||
* Non volatile storage: create object2 if not found, delete it if found | ||
*/ | ||
printf("\nTest on object \"%s\"\n", obj2_id); | ||
|
||
res = read_secure_object(&ctx, obj2_id, | ||
read_data, sizeof(read_data)); | ||
if (res != TEEC_SUCCESS && res != TEEC_ERROR_ITEM_NOT_FOUND) | ||
errx(1, "Unexpected status when reading an object : 0x%x", res); | ||
|
||
if (res == TEEC_ERROR_ITEM_NOT_FOUND) { | ||
char data[] = "This is data stored in the secure storage.\n"; | ||
|
||
printf("- Object not found in TA secure storage, create it.\n"); | ||
|
||
res = write_secure_object(&ctx, obj2_id, | ||
data, sizeof(data)); | ||
if (res != TEEC_SUCCESS) | ||
errx(1, "Failed to create/load an object"); | ||
|
||
} else if (res == TEEC_SUCCESS) { | ||
printf("- Object found in TA secure storage, delete it.\n"); | ||
|
||
res = delete_secure_object(&ctx, obj2_id); | ||
if (res != TEEC_SUCCESS) | ||
errx(1, "Failed to delete an object"); | ||
} | ||
|
||
printf("\nWe're done, close and release TEE resources\n"); | ||
terminate_tee_session(&ctx); | ||
return 0; | ||
} |
This file contains 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 := f4e750bb-1437-4fbf-8785-8d3580c34994.ta | ||
include $(BUILD_OPTEE_MK) |
This file contains 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 ?= 2 | ||
CPPFLAGS += -DCFG_TEE_TA_LOG_LEVEL=$(CFG_TEE_TA_LOG_LEVEL) | ||
|
||
# The UUID for the Trusted Application | ||
BINARY=f4e750bb-1437-4fbf-8785-8d3580c34994 | ||
|
||
-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 |
Oops, something went wrong.