initial commit
This commit is contained in:
commit
0c1ec145aa
62
Dockerfile
Normal file
62
Dockerfile
Normal file
@ -0,0 +1,62 @@
|
||||
FROM ubuntu:22.04
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt update && apt upgrade -y
|
||||
RUN apt install -y \
|
||||
adb \
|
||||
acpica-tools \
|
||||
autoconf \
|
||||
automake \
|
||||
bc \
|
||||
bison \
|
||||
build-essential \
|
||||
ccache \
|
||||
cpio \
|
||||
cscope \
|
||||
curl \
|
||||
device-tree-compiler \
|
||||
e2tools \
|
||||
expect \
|
||||
fastboot \
|
||||
flex \
|
||||
ftp-upload \
|
||||
gdisk \
|
||||
git \
|
||||
libattr1-dev \
|
||||
libcap-ng-dev \
|
||||
libfdt-dev \
|
||||
libftdi-dev \
|
||||
libglib2.0-dev \
|
||||
libgmp3-dev \
|
||||
libhidapi-dev \
|
||||
libmpc-dev \
|
||||
libncurses5-dev \
|
||||
libpixman-1-dev \
|
||||
libslirp-dev \
|
||||
libssl-dev \
|
||||
libtool \
|
||||
libusb-1.0-0-dev \
|
||||
make \
|
||||
mtools \
|
||||
netcat \
|
||||
ninja-build \
|
||||
python3-cryptography \
|
||||
python3-pip \
|
||||
python3-pyelftools \
|
||||
python3-serial \
|
||||
python-is-python3 \
|
||||
rsync \
|
||||
swig \
|
||||
unzip \
|
||||
uuid-dev \
|
||||
wget \
|
||||
xdg-utils \
|
||||
xterm \
|
||||
xz-utils \
|
||||
zlib1g-dev
|
||||
RUN curl https://storage.googleapis.com/git-repo-downloads/repo > /bin/repo && chmod a+x /bin/repo
|
||||
RUN mkdir /optee
|
||||
WORKDIR /optee
|
||||
RUN repo init -u https://github.com/OP-TEE/manifest.git -m qemu_v8.xml && repo sync -j10
|
||||
WORKDIR /optee/build
|
||||
RUN make -j2 toolchains
|
||||
RUN make -j$(nproc) check
|
82
README.md
Normal file
82
README.md
Normal file
@ -0,0 +1,82 @@
|
||||
This project provides a simple PoC implementation of a Secure Storage on top of [OP-TEE](https://optee.readthedocs.io/en/latest/general/about.html) TrustZone based technology.
|
||||
|
||||
# Main functionality
|
||||
|
||||
The project consists of two modules: Trusted Application and Normal World client.
|
||||
|
||||
## Trusted Application
|
||||
|
||||
1. Generate RSA key pair.
|
||||
2. Serialize / Deserialize RSA key pair into Secure Storage for use across sessions. Access to multiple RSA key pairs is implemented with help of TAG identifiers.
|
||||
3. A special run-time provided PIN is used for further RSA key pair protection. Provided PIN is used by Trusted Application to derive SessionKey, which is used for encryption / decryption of RSA key pair matherial stored in Secure Storage.
|
||||
4. RSA key pair data is never exposed outside of Trusted Application.
|
||||
5. Assuming that correct PIN is known, Client Application can use RSA key pair TAG to encrypt / decrypt arbitrary data.
|
||||
|
||||
## Normal World client application
|
||||
|
||||
1. Provides functional demo for APIs exposed by Trusted Application.
|
||||
|
||||
# Build instructions
|
||||
|
||||
Usually, access to ARM TrustZone powered device is necessary to see GP-TEE based APIs in action. This project benefits heavily from virtualization techniques like Docker and Qemu.
|
||||
|
||||
## 1 Prepare build environment
|
||||
|
||||
Run `build-docker.sh` script.
|
||||
|
||||
This operation might take several hours to finish. It will create Ubuntu based container, will install all necessary build tools and dependancies. Lastly, it will `git clone` OP-TEE repository with ARMv8 build flavour. Check `Dockerfile` for actual list of performed actions.
|
||||
|
||||
## 2 Execute build environment
|
||||
|
||||
Use `run-docker.sh` script. The script will:
|
||||
- map src folder `bliq_storage` inside build environment
|
||||
- use X11 window forwarding technique, to map two `cli` named **Normal World** and **Secure World** from Docker container onto your host OS
|
||||
|
||||
If all went well, you will end up inside an instance of Ubuntu dev environment with `cli` interface similar to `root@80e6b6f27bef:/optee/build#`.
|
||||
|
||||
### X11 window forwarding
|
||||
|
||||
Use [XQuartz](https://www.xquartz.org/) to enable x11 window forwarding on [mac](https://gist.github.com/sorny/969fe55d85c9b0035b0109a31cbcb088).
|
||||
|
||||
> [!NOTE] Be ware
|
||||
> You will always have to run `xhost +` after a restart of X11 as this is not a persistent setting.
|
||||
|
||||
## 3 Build and run demo application
|
||||
|
||||
Typing `make run` in `/optee/build`. Will start build for Secure and Normal world parts of OP-TEE OS. After successful build `qemu` emulator will be executed. Press `c` to proceed with virtual device execution. On a first run you might need to type `boot` in **Normal World** console to start boot process.
|
||||
|
||||
After the boot finishes, use **Normal World** console window to login as `root`. Then simply type `bliq_storage` to execute demo app, which was build directly from sources.
|
||||
|
||||
Other OP-TEE [demo applications](https://github.com/linaro-swg/optee_examples) are also available. Use *tab-key* to assist with typing.
|
||||
|
||||
# Source code overview
|
||||
|
||||
## `bliq_storege\ta`
|
||||
|
||||
This folder contains sources for the Trusted Part of `Bliq Storage` application. Check header files to explore high level API exposed by project submodules.
|
||||
|
||||
### `bliq_storage_ta.c`
|
||||
|
||||
Main entry point for the Trusted Application. Provides high level implementation for the main commands:
|
||||
- Create Key
|
||||
- Delete Key
|
||||
- Check Key
|
||||
- Encrypt
|
||||
- Decrypt
|
||||
|
||||
It is also worth mentioning, that PIN-derived AES key (which is used for RSA key pair data encryption) lives in Session context, see `TA_OpenSessionEntryPoint()`
|
||||
|
||||
### `operations.c`
|
||||
|
||||
Handles AES PIN derivation API, as well as AES encryption / decryption functions for RSA key pair protection.
|
||||
|
||||
### `key_pair.c`
|
||||
|
||||
Incapsulates set of APIs of underlined GP-TEE APIs, necessary for RSA key pair creating and usage as a handy *trunsient* object. It also provides endpoints for RSA key-pair encryption and decryption of arbitrary data.
|
||||
|
||||
Two functions `kp_serialize()` and `kp_deserilize()` might be seen as the sole `hard` of an entire project. Since they are used for *storing / re-storing* RSA key pair data* into / from* a flat buffer. The whole application might be seen as a set of *derivative / supportive* operations build *around / on top of* these two functions.
|
||||
|
||||
## `bliq_storage/host/main.c`
|
||||
|
||||
A simple TZ client application, showcasing communication between Normal World and Trusted World applications. A particular use case implementation of APIs defined by `bliq_storage\ta\include\bliq_storage_ta.h`
|
||||
|
17
bliq_storage/Android.mk
Normal file
17
bliq_storage/Android.mk
Normal file
@ -0,0 +1,17 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_CFLAGS += -DANDROID_BUILD
|
||||
LOCAL_CFLAGS += -Wall
|
||||
|
||||
LOCAL_SRC_FILES += host/main.c
|
||||
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/ta/include
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libteec
|
||||
LOCAL_MODULE := bliq_storage
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(LOCAL_PATH)/ta/Android.mk
|
13
bliq_storage/CMakeLists.txt
Normal file
13
bliq_storage/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
project (bliq_storage 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})
|
15
bliq_storage/Makefile
Normal file
15
bliq_storage/Makefile
Normal file
@ -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
|
28
bliq_storage/host/Makefile
Normal file
28
bliq_storage/host/Makefile
Normal file
@ -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./include
|
||||
CFLAGS += -I$(TEEC_EXPORT)/include
|
||||
LDADD += -lteec -L$(TEEC_EXPORT)/lib
|
||||
|
||||
BINARY = bliq_storage
|
||||
|
||||
.PHONY: all
|
||||
all: $(BINARY)
|
||||
|
||||
$(BINARY): $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $< $(LDADD)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(OBJS) $(BINARY)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
346
bliq_storage/host/main.c
Normal file
346
bliq_storage/host/main.c
Normal file
@ -0,0 +1,346 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
/* TA API: UUID and command IDs */
|
||||
#include <bliq_storage_ta.h>
|
||||
|
||||
/* TEE resources */
|
||||
struct test_ctx {
|
||||
TEEC_Context ctx;
|
||||
TEEC_Session sess;
|
||||
};
|
||||
|
||||
void open_tee_session(
|
||||
struct test_ctx *ctx,
|
||||
char *pin, size_t pin_len)
|
||||
{
|
||||
TEEC_Operation op;
|
||||
TEEC_UUID uuid = TA_BLIQ_STORAGE_UUID;
|
||||
uint32_t origin;
|
||||
TEEC_Result res;
|
||||
|
||||
// Set session PIN
|
||||
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 = pin;
|
||||
op.params[0].tmpref.size = pin_len;
|
||||
|
||||
/* 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, &op, &origin);
|
||||
if (res != TEEC_SUCCESS)
|
||||
errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x",
|
||||
res, origin);
|
||||
}
|
||||
|
||||
void close_tee_session(struct test_ctx *ctx)
|
||||
{
|
||||
TEEC_CloseSession(&ctx->sess);
|
||||
TEEC_FinalizeContext(&ctx->ctx);
|
||||
}
|
||||
|
||||
TEEC_Result create_key(
|
||||
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,
|
||||
TA_BLIQ_STORAGE_CMD_CREATE_KEY,
|
||||
&op, &origin);
|
||||
|
||||
switch (res) {
|
||||
case TEEC_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
printf("Command TA_BLIQ_STORAGE_CMD_CREATE_KEY failed: 0x%x / %u\n", res, origin);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
TEEC_Result check_key(
|
||||
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,
|
||||
TA_BLIQ_STORAGE_CMD_CHECK_KEY,
|
||||
&op, &origin);
|
||||
|
||||
switch (res) {
|
||||
case TEEC_SUCCESS:
|
||||
case TEEC_ERROR_ITEM_NOT_FOUND:
|
||||
break;
|
||||
default:
|
||||
printf("Command TA_BLIQ_STORAGE_CMD_CHECK_KEY failed: 0x%x / %u\n", res, origin);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
TEEC_Result delete_key(
|
||||
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,
|
||||
TA_BLIQ_STORAGE_CMD_DELETE_KEY,
|
||||
&op, &origin);
|
||||
|
||||
switch (res) {
|
||||
case TEEC_SUCCESS:
|
||||
case TEEC_ERROR_ITEM_NOT_FOUND:
|
||||
break;
|
||||
default:
|
||||
printf("Command TA_BLIQ_STORAGE_CMD_DELETE_KEY failed: 0x%x / %u\n", res, origin);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
TEEC_Result encrypt(
|
||||
struct test_ctx *ctx,
|
||||
char *id,
|
||||
char *data, uint32_t data_len,
|
||||
char *encr, uint32_t *encr_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_MEMREF_TEMP_INOUT,
|
||||
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;
|
||||
|
||||
op.params[2].tmpref.buffer = encr;
|
||||
op.params[2].tmpref.size = *encr_len;
|
||||
|
||||
res = TEEC_InvokeCommand(&ctx->sess,
|
||||
TA_BLIQ_STORAGE_CMD_ENCRYPT,
|
||||
&op, &origin);
|
||||
|
||||
switch (res) {
|
||||
case TEEC_SUCCESS:
|
||||
*encr_len = op.params[2].tmpref.size;
|
||||
break;
|
||||
default:
|
||||
printf("Command TA_BLIQ_STORAGE_CMD_ENCRYPT failed: 0x%x / %u\n", res, origin);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
TEEC_Result decrypt(
|
||||
struct test_ctx *ctx,
|
||||
char *id,
|
||||
char *encr, uint32_t encr_len,
|
||||
char *decr, uint32_t *decr_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_MEMREF_TEMP_INOUT,
|
||||
TEEC_NONE);
|
||||
|
||||
op.params[0].tmpref.buffer = id;
|
||||
op.params[0].tmpref.size = id_len;
|
||||
|
||||
op.params[1].tmpref.buffer = encr;
|
||||
op.params[1].tmpref.size = encr_len;
|
||||
|
||||
op.params[2].tmpref.buffer = decr;
|
||||
op.params[2].tmpref.size = *decr_len;
|
||||
|
||||
res = TEEC_InvokeCommand(&ctx->sess,
|
||||
TA_BLIQ_STORAGE_CMD_DECRYPT,
|
||||
&op, &origin);
|
||||
|
||||
switch (res) {
|
||||
case TEEC_SUCCESS:
|
||||
*decr_len = op.params[2].tmpref.size;
|
||||
break;
|
||||
default:
|
||||
printf("Command TA_BLIQ_STORAGE_CMD_DECRYPT failed: 0x%x / %u\n", res, origin);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct test_ctx ctx;
|
||||
char key_id[] = "key#1";
|
||||
char pin[6] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; // used to encrypt/decrypt key
|
||||
|
||||
char data[] = "Test string for data encryption";
|
||||
|
||||
char encrypted_data[512];
|
||||
uint32_t encrypted_data_sz = sizeof(encrypted_data);
|
||||
|
||||
char decrypted_data[512];
|
||||
uint32_t decrypted_data_sz = sizeof(decrypted_data);
|
||||
|
||||
TEEC_Result res;
|
||||
|
||||
printf("Prepare session with the TA\n");
|
||||
open_tee_session(&ctx, pin, sizeof(pin));
|
||||
|
||||
/*
|
||||
* Check Create , read it, delete it.
|
||||
*/
|
||||
printf("\nCheck KeyID \"%s\"\n", key_id);
|
||||
res = check_key(
|
||||
&ctx,
|
||||
key_id);
|
||||
if (res == TEEC_ERROR_ITEM_NOT_FOUND) {
|
||||
printf(" - KeyId was not found in TA secure storage, create new one\n");
|
||||
|
||||
res = create_key(
|
||||
&ctx,
|
||||
key_id);
|
||||
if (res != TEEC_SUCCESS)
|
||||
errx(1, "Unexpected status when creating key: 0x%x", res);
|
||||
|
||||
printf(" - RSA keypair creation [OK]\n");
|
||||
printf(" - Run application one more time to test Encrypt / Decrypt APIs..\n");
|
||||
}
|
||||
else if (res == TEEC_SUCCESS) {
|
||||
printf(" - KeyId was found!\n");
|
||||
printf(" - Test Encrypt / Decrypt APIs..\n");
|
||||
|
||||
res = encrypt(
|
||||
&ctx,
|
||||
key_id,
|
||||
data, sizeof(data),
|
||||
encrypted_data, &encrypted_data_sz);
|
||||
if (res != TEEC_SUCCESS)
|
||||
errx(1, "Unexpected status during data encryption: 0x%x", res);
|
||||
|
||||
printf(" -- encr_data: [%u] first 4 bytes: %02x:%02x:%02x:%02x\n",
|
||||
encrypted_data_sz, encrypted_data[0], encrypted_data[1], encrypted_data[2], encrypted_data[3]);
|
||||
|
||||
res = decrypt(&ctx, key_id,
|
||||
encrypted_data, encrypted_data_sz,
|
||||
decrypted_data, &decrypted_data_sz);
|
||||
if (res != TEEC_SUCCESS)
|
||||
errx(1, "Unexpected status during data decryption: 0x%x", res);
|
||||
|
||||
printf(" -- orig_data: [%lu] '%s'\n -- decr_data: [%d] '%s'\n",
|
||||
sizeof(data), data,
|
||||
decrypted_data_sz, decrypted_data);
|
||||
|
||||
printf(" - Encrypt / Decrypt APIs test [ok]\n");
|
||||
printf(" - Delete RSA keypair from secure storage\n");
|
||||
|
||||
res = delete_key(
|
||||
&ctx,
|
||||
key_id);
|
||||
if (res != TEEC_SUCCESS)
|
||||
errx(1, "Unexpected status during key delition: 0x%x", res);
|
||||
}
|
||||
|
||||
close_tee_session(&ctx);
|
||||
return 0;
|
||||
}
|
4
bliq_storage/ta/Android.mk
Normal file
4
bliq_storage/ta/Android.mk
Normal file
@ -0,0 +1,4 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
local_module := 0651d840-a91b-4b3f-a222-b68cd195231c.ta
|
||||
include $(BUILD_OPTEE_MK)
|
13
bliq_storage/ta/Makefile
Normal file
13
bliq_storage/ta/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
CFG_TEE_TA_LOG_LEVEL ?= 2
|
||||
CFG_TA_OPTEE_CORE_API_COMPAT_1_1=y
|
||||
|
||||
# The UUID for the Trusted Application
|
||||
BINARY=0651d840-a91b-4b3f-a222-b68cd195231c
|
||||
|
||||
-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
|
560
bliq_storage/ta/bliq_storage_ta.c
Normal file
560
bliq_storage/ta/bliq_storage_ta.c
Normal file
@ -0,0 +1,560 @@
|
||||
#include <inttypes.h>
|
||||
#include <bliq_storage_ta.h>
|
||||
#include <tee_internal_api.h>
|
||||
#include <tee_internal_api_extensions.h>
|
||||
#include "operations.h"
|
||||
#include "key_pair.h"
|
||||
#include <string.h>
|
||||
|
||||
static TEE_Result ss_read_object(
|
||||
char *obj_id, uint32_t obj_id_sz,
|
||||
void *buff, uint32_t *buff_sz
|
||||
)
|
||||
{
|
||||
TEE_Result res;
|
||||
TEE_ObjectHandle object = NULL;
|
||||
TEE_ObjectInfo object_info;
|
||||
|
||||
res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
|
||||
obj_id, obj_id_sz,
|
||||
TEE_DATA_FLAG_ACCESS_READ |
|
||||
TEE_DATA_FLAG_SHARE_READ,
|
||||
&object);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] ss_read_object(): Failed to open persistent object, res=0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_GetObjectInfo1(
|
||||
object,
|
||||
&object_info);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] ss_read_object(): Failed to get persistent object ibfo, res=0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (object_info.dataSize > *buff_sz) {
|
||||
/*
|
||||
* Provided buffer is too short.
|
||||
* Return the expected size together with status "short buffer"
|
||||
*/
|
||||
*buff_sz = object_info.dataSize;
|
||||
res = TEE_ERROR_SHORT_BUFFER;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_ReadObjectData(
|
||||
object,
|
||||
buff, object_info.dataSize,
|
||||
buff_sz);
|
||||
|
||||
exit:
|
||||
if (object)
|
||||
TEE_CloseObject(object);
|
||||
return res;
|
||||
}
|
||||
|
||||
static TEE_Result get_key(
|
||||
Session *session,
|
||||
char *obj_id, uint32_t obj_id_sz,
|
||||
TEE_ObjectHandle *kp)
|
||||
{
|
||||
TEE_Result res;
|
||||
|
||||
char *kp_serialized_buff = NULL;
|
||||
uint32_t kp_serialized_buff_sz = 2048;
|
||||
|
||||
char *kp_decrypted_buff = NULL;
|
||||
uint32_t kp_decrypted_buff_sz = 2048;
|
||||
|
||||
kp_serialized_buff = TEE_Malloc(kp_serialized_buff_sz, 0);
|
||||
if (!kp_serialized_buff)
|
||||
return TEE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
res = ss_read_object(
|
||||
obj_id, obj_id_sz,
|
||||
kp_serialized_buff, &kp_serialized_buff_sz);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR]: get_key(%s): Unable to read data from sec store: 0x%x", obj_id, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
kp_decrypted_buff = TEE_Malloc(kp_decrypted_buff_sz, 0);
|
||||
if (!kp_decrypted_buff)
|
||||
return TEE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
res = so_decrypt(
|
||||
session,
|
||||
kp_serialized_buff, kp_serialized_buff_sz,
|
||||
kp_decrypted_buff, &kp_decrypted_buff_sz);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR]: get_key(%s): Unable to decrypt RSA key pair: 0x%x", obj_id, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = kp_deserialize(
|
||||
kp_decrypted_buff, kp_decrypted_buff_sz,
|
||||
kp);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR]: get_key(%s): Unable to deserialize RSA key pair: 0x%x", obj_id, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
TEE_Free(kp_serialized_buff);
|
||||
TEE_Free(kp_decrypted_buff);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* TA API implementation
|
||||
*/
|
||||
static TEE_Result create_key(
|
||||
Session *session,
|
||||
uint32_t param_types,
|
||||
TEE_Param params[4])
|
||||
{
|
||||
const uint32_t exp_param_types = TEE_PARAM_TYPES(
|
||||
TEE_PARAM_TYPE_MEMREF_INPUT,
|
||||
TEE_PARAM_TYPE_NONE,
|
||||
TEE_PARAM_TYPE_NONE,
|
||||
TEE_PARAM_TYPE_NONE);
|
||||
|
||||
TEE_ObjectHandle kp = NULL;
|
||||
TEE_ObjectHandle object;
|
||||
TEE_Result res;
|
||||
char *obj_id = NULL;
|
||||
size_t obj_id_sz;
|
||||
uint32_t obj_data_flag;
|
||||
|
||||
char *kp_serialized_buff = NULL;
|
||||
uint32_t kp_serialized_buff_sz = 2048;
|
||||
|
||||
char *kp_encrypted_buff = NULL;
|
||||
uint32_t kp_encrypted_buff_sz = 2048;
|
||||
|
||||
/*
|
||||
* Safely get the invocation parameters
|
||||
*/
|
||||
if (param_types != exp_param_types)
|
||||
return TEE_ERROR_BAD_PARAMETERS;
|
||||
|
||||
obj_id_sz = params[0].memref.size;
|
||||
obj_id = TEE_Malloc(obj_id_sz, 0);
|
||||
if (!obj_id)
|
||||
return TEE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
TEE_MemMove(obj_id, params[0].memref.buffer, obj_id_sz);
|
||||
|
||||
/*
|
||||
* Generate RSA KeyPair
|
||||
*/
|
||||
res = kp_create(&kp);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("Unable to create RSA key pair: 0x%08x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize RSA KeyPair into external buffer
|
||||
*/
|
||||
kp_serialized_buff = TEE_Malloc(kp_serialized_buff_sz, 0);
|
||||
if (!kp_serialized_buff)
|
||||
return TEE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
res = kp_serialize(
|
||||
kp,
|
||||
kp_serialized_buff, &kp_serialized_buff_sz);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("Unable to serialize RSA key pair: 0x%08x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encrypt serrialized RSA keypair buffer
|
||||
*/
|
||||
kp_encrypted_buff = TEE_Malloc(kp_encrypted_buff_sz, 0);
|
||||
if (!kp_encrypted_buff)
|
||||
return TEE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
res = so_encrypt(
|
||||
session,
|
||||
kp_serialized_buff, kp_serialized_buff_sz,
|
||||
kp_encrypted_buff, &kp_encrypted_buff_sz);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("Unable to encrypt RSA key pair: 0x%08x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create object in secure storage and fill it with encrypted RSA keypair
|
||||
*/
|
||||
obj_data_flag =
|
||||
TEE_DATA_FLAG_ACCESS_READ | /* we can later read the oject */
|
||||
TEE_DATA_FLAG_ACCESS_WRITE | /* we can later write into the object */
|
||||
TEE_DATA_FLAG_ACCESS_WRITE_META | /* we can later destroy or rename the object */
|
||||
TEE_DATA_FLAG_OVERWRITE; /* destroy existing object of same ID */
|
||||
|
||||
res = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE,
|
||||
obj_id, obj_id_sz,
|
||||
obj_data_flag,
|
||||
TEE_HANDLE_NULL,
|
||||
NULL, 0, /* we may not fill it right now */
|
||||
&object);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("TEE_CreatePersistentObject failed 0x%08x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_WriteObjectData(
|
||||
object,
|
||||
kp_encrypted_buff, kp_encrypted_buff_sz);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("TEE_WriteObjectData failed 0x%08x", res);
|
||||
TEE_CloseAndDeletePersistentObject1(object);
|
||||
} else {
|
||||
TEE_CloseObject(object);
|
||||
}
|
||||
|
||||
exit:
|
||||
TEE_Free(obj_id);
|
||||
TEE_Free(kp_serialized_buff);
|
||||
TEE_Free(kp_encrypted_buff);
|
||||
|
||||
if (kp)
|
||||
TEE_FreeTransientObject(kp);
|
||||
return res;
|
||||
}
|
||||
|
||||
static TEE_Result check_key(
|
||||
Session *session,
|
||||
uint32_t param_types,
|
||||
TEE_Param params[4])
|
||||
{
|
||||
const uint32_t exp_param_types = TEE_PARAM_TYPES(
|
||||
TEE_PARAM_TYPE_MEMREF_INPUT,
|
||||
TEE_PARAM_TYPE_NONE,
|
||||
TEE_PARAM_TYPE_NONE,
|
||||
TEE_PARAM_TYPE_NONE);
|
||||
|
||||
TEE_Result res;
|
||||
TEE_ObjectHandle kp = NULL;
|
||||
|
||||
char *obj_id;
|
||||
uint32_t obj_id_sz;
|
||||
|
||||
/*
|
||||
* Safely get the invocation parameters
|
||||
*/
|
||||
if (param_types != exp_param_types)
|
||||
return TEE_ERROR_BAD_PARAMETERS;
|
||||
|
||||
obj_id_sz = params[0].memref.size;
|
||||
obj_id = TEE_Malloc(obj_id_sz, 0);
|
||||
if (!obj_id)
|
||||
return TEE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
TEE_MemMove(obj_id, params[0].memref.buffer, obj_id_sz);
|
||||
EMSG("[DBG] check_key(): obj_id '%s'", obj_id);
|
||||
|
||||
res = get_key(
|
||||
session,
|
||||
obj_id, obj_id_sz,
|
||||
&kp);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] check_key(): Unable to obtain RSA keypair: 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
TEE_Free(obj_id);
|
||||
if (kp)
|
||||
TEE_FreeTransientObject(kp);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static TEE_Result delete_key(
|
||||
uint32_t param_types,
|
||||
TEE_Param params[4])
|
||||
{
|
||||
const uint32_t exp_param_types = TEE_PARAM_TYPES(
|
||||
TEE_PARAM_TYPE_MEMREF_INPUT,
|
||||
TEE_PARAM_TYPE_NONE,
|
||||
TEE_PARAM_TYPE_NONE,
|
||||
TEE_PARAM_TYPE_NONE);
|
||||
TEE_ObjectHandle object;
|
||||
TEE_Result res;
|
||||
char *obj_id;
|
||||
size_t obj_id_sz;
|
||||
|
||||
/*
|
||||
* Safely get the invocation parameters
|
||||
*/
|
||||
if (param_types != exp_param_types)
|
||||
return TEE_ERROR_BAD_PARAMETERS;
|
||||
|
||||
obj_id_sz = params[0].memref.size;
|
||||
obj_id = TEE_Malloc(obj_id_sz, 0);
|
||||
if (!obj_id)
|
||||
return TEE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
TEE_MemMove(obj_id, params[0].memref.buffer, obj_id_sz);
|
||||
|
||||
/*
|
||||
* Check object exists and delete it
|
||||
*/
|
||||
res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
|
||||
obj_id, obj_id_sz,
|
||||
TEE_DATA_FLAG_ACCESS_READ |
|
||||
TEE_DATA_FLAG_ACCESS_WRITE_META, /* we must be allowed to delete it */
|
||||
&object);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] Unable to open persistent object, res=0x%x", res);
|
||||
TEE_Free(obj_id);
|
||||
return res;
|
||||
}
|
||||
|
||||
TEE_CloseAndDeletePersistentObject1(object);
|
||||
TEE_Free(obj_id);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static TEE_Result encrypt_data(
|
||||
Session *session,
|
||||
uint32_t param_types,
|
||||
TEE_Param params[4])
|
||||
{
|
||||
const uint32_t exp_param_types = TEE_PARAM_TYPES(
|
||||
TEE_PARAM_TYPE_MEMREF_INPUT,
|
||||
TEE_PARAM_TYPE_MEMREF_INPUT,
|
||||
TEE_PARAM_TYPE_MEMREF_INOUT,
|
||||
TEE_PARAM_TYPE_NONE);
|
||||
|
||||
TEE_Result res;
|
||||
TEE_ObjectHandle kp = NULL;
|
||||
|
||||
char *obj_id;
|
||||
uint32_t obj_id_sz;
|
||||
|
||||
char *data;
|
||||
uint32_t data_sz;
|
||||
|
||||
char *enc_data;
|
||||
uint32_t enc_data_sz;
|
||||
|
||||
/*
|
||||
* Safely get the invocation parameters
|
||||
*/
|
||||
if (param_types != exp_param_types)
|
||||
return TEE_ERROR_BAD_PARAMETERS;
|
||||
|
||||
obj_id_sz = params[0].memref.size;
|
||||
obj_id = TEE_Malloc(obj_id_sz, 0);
|
||||
if (!obj_id)
|
||||
return TEE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
TEE_MemMove(obj_id, params[0].memref.buffer, obj_id_sz);
|
||||
EMSG("[DBG] encrypt_data: obj_id '%s'", obj_id);
|
||||
|
||||
data_sz = params[1].memref.size;
|
||||
data = TEE_Malloc(data_sz, 0);
|
||||
if (!data)
|
||||
return TEE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
TEE_MemMove(data, params[1].memref.buffer, data_sz);
|
||||
EMSG("[DBG] encrypt_data: plain_data '%s'", data);
|
||||
|
||||
res = get_key(
|
||||
session,
|
||||
obj_id, obj_id_sz,
|
||||
&kp);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] encrypt_data(): Unable to obtain RSA keypair: 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// const char msg[] = "hello from kp_encrypt";
|
||||
// EMSG("[DBG] encrypt_data(): Return hardcoded string");
|
||||
|
||||
// TEE_MemMove(params[2].memref.buffer, msg, sizeof(msg));
|
||||
// params[2].memref.size = sizeof(msg);
|
||||
// return res;
|
||||
|
||||
enc_data = params[2].memref.buffer;
|
||||
enc_data_sz = params[2].memref.size;
|
||||
|
||||
res = kp_encrypt(
|
||||
kp,
|
||||
data, data_sz,
|
||||
enc_data, &enc_data_sz);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] encrypt_data(): Unable to encryp data: 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Encryption [OK]
|
||||
// update output buffer size
|
||||
params[2].memref.size = enc_data_sz;
|
||||
|
||||
exit:
|
||||
TEE_Free(obj_id);
|
||||
TEE_Free(data);
|
||||
if (kp)
|
||||
TEE_FreeTransientObject(kp);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static TEE_Result decrypt_data(
|
||||
Session *session,
|
||||
uint32_t param_types,
|
||||
TEE_Param params[4])
|
||||
{
|
||||
const uint32_t exp_param_types = TEE_PARAM_TYPES(
|
||||
TEE_PARAM_TYPE_MEMREF_INPUT,
|
||||
TEE_PARAM_TYPE_MEMREF_INPUT,
|
||||
TEE_PARAM_TYPE_MEMREF_INOUT,
|
||||
TEE_PARAM_TYPE_NONE);
|
||||
|
||||
TEE_Result res;
|
||||
TEE_ObjectHandle kp = NULL;
|
||||
|
||||
char *obj_id;
|
||||
uint32_t obj_id_sz;
|
||||
|
||||
char *data;
|
||||
uint32_t data_sz;
|
||||
|
||||
char *dec_data;
|
||||
uint32_t dec_data_sz;
|
||||
|
||||
/*
|
||||
* Safely get the invocation parameters
|
||||
*/
|
||||
if (param_types != exp_param_types)
|
||||
return TEE_ERROR_BAD_PARAMETERS;
|
||||
|
||||
obj_id_sz = params[0].memref.size;
|
||||
obj_id = TEE_Malloc(obj_id_sz, 0);
|
||||
if (!obj_id)
|
||||
return TEE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
TEE_MemMove(obj_id, params[0].memref.buffer, obj_id_sz);
|
||||
EMSG("[DBG] decrypt_data: obj_id '%s'", obj_id);
|
||||
|
||||
data_sz = params[1].memref.size;
|
||||
data = TEE_Malloc(data_sz, 0);
|
||||
if (!data)
|
||||
return TEE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
TEE_MemMove(data, params[1].memref.buffer, data_sz);
|
||||
|
||||
res = get_key(
|
||||
session,
|
||||
obj_id, obj_id_sz,
|
||||
&kp);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] decrypt_data(): Unable to obtain RSA keypair: 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
dec_data = params[2].memref.buffer;
|
||||
dec_data_sz = params[2].memref.size;
|
||||
|
||||
res = kp_decrypt(
|
||||
kp,
|
||||
data, data_sz,
|
||||
dec_data, &dec_data_sz);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] decrypt_data(): Unable to decryp data: 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Decryption [OK]
|
||||
// update output buffer size
|
||||
params[2].memref.size = dec_data_sz;
|
||||
|
||||
exit:
|
||||
TEE_Free(obj_id);
|
||||
TEE_Free(data);
|
||||
if (kp)
|
||||
TEE_FreeTransientObject(kp);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
TEE_Result TA_CreateEntryPoint(void)
|
||||
{
|
||||
/* Nothing to do */
|
||||
return TEE_SUCCESS;
|
||||
}
|
||||
|
||||
void TA_DestroyEntryPoint(void)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
TEE_Result TA_OpenSessionEntryPoint(
|
||||
uint32_t param_types,
|
||||
TEE_Param params[4],
|
||||
void **ctx)
|
||||
{
|
||||
const uint32_t exp_param_types = TEE_PARAM_TYPES(
|
||||
TEE_PARAM_TYPE_MEMREF_INPUT,
|
||||
TEE_PARAM_TYPE_NONE,
|
||||
TEE_PARAM_TYPE_NONE,
|
||||
TEE_PARAM_TYPE_NONE);
|
||||
|
||||
/*
|
||||
* Safely get the invocation parameters
|
||||
*/
|
||||
if (param_types != exp_param_types)
|
||||
return TEE_ERROR_BAD_PARAMETERS;
|
||||
|
||||
Session *session = TEE_Malloc(sizeof (Session), 0);
|
||||
if (!session)
|
||||
return TEE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
char *pin = params[0].memref.buffer;
|
||||
size_t pin_sz = params[0].memref.size;
|
||||
|
||||
*ctx = session;
|
||||
|
||||
return so_init(pin, pin_sz, session);
|
||||
}
|
||||
|
||||
void TA_CloseSessionEntryPoint(void *ctx)
|
||||
{
|
||||
Session *session = ctx;
|
||||
if (session == NULL)
|
||||
return;
|
||||
|
||||
so_free(session);
|
||||
TEE_Free(ctx);
|
||||
}
|
||||
|
||||
TEE_Result TA_InvokeCommandEntryPoint(
|
||||
void *session,
|
||||
uint32_t command,
|
||||
uint32_t param_types,
|
||||
TEE_Param params[4])
|
||||
{
|
||||
switch (command) {
|
||||
case TA_BLIQ_STORAGE_CMD_CREATE_KEY:
|
||||
return create_key(session, param_types, params);
|
||||
case TA_BLIQ_STORAGE_CMD_CHECK_KEY:
|
||||
return check_key(session, param_types, params);
|
||||
case TA_BLIQ_STORAGE_CMD_DELETE_KEY:
|
||||
return delete_key(param_types, params);
|
||||
case TA_BLIQ_STORAGE_CMD_ENCRYPT:
|
||||
return encrypt_data(session, param_types, params);
|
||||
case TA_BLIQ_STORAGE_CMD_DECRYPT:
|
||||
return decrypt_data(session, param_types, params);
|
||||
default:
|
||||
EMSG("Command ID 0x%x is not supported", command);
|
||||
return TEE_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
59
bliq_storage/ta/include/bliq_storage_ta.h
Normal file
59
bliq_storage/ta/include/bliq_storage_ta.h
Normal file
@ -0,0 +1,59 @@
|
||||
|
||||
#ifndef __BLIQ_STORAGE_H__
|
||||
#define __BLIQ_STORAGE_H__
|
||||
|
||||
/* UUID of the trusted application */
|
||||
#define TA_BLIQ_STORAGE_UUID \
|
||||
{ 0x0651d840, 0xa91b, 0x4b3f, \
|
||||
{ 0xa2, 0x22, 0xb6, 0x8c, 0xd1, 0x95, 0x23, 0x1c } }
|
||||
|
||||
/*
|
||||
* TA_BLIQ_STORAGE_CMD_CREATE_KEY - Create RSA key and store it
|
||||
* in encrypted form (AES pin) inside secure storage file
|
||||
* param[0] (memref) ID used the identify RSA key
|
||||
* param[1] unused
|
||||
* param[2] unused
|
||||
* param[3] unused
|
||||
*/
|
||||
#define TA_BLIQ_STORAGE_CMD_CREATE_KEY 1
|
||||
|
||||
/*
|
||||
* TA_BLIQ_STORAGE_CMD_CHECK_KEY - Check if tagget RSA key pair
|
||||
* exists and is accessinbel
|
||||
* param[0] (memref) ID used the identify RSA key
|
||||
* param[1] unused
|
||||
* param[2] unused
|
||||
* param[3] unused
|
||||
*/
|
||||
#define TA_BLIQ_STORAGE_CMD_CHECK_KEY 2
|
||||
|
||||
/*
|
||||
* TA_BLIQ_STORAGE_CMD_DELETE - Delete tagget RSA key pair
|
||||
* param[0] (memref) ID used the identify the persistent object
|
||||
* param[1] unused
|
||||
* param[2] unused
|
||||
* param[3] unused
|
||||
*/
|
||||
#define TA_BLIQ_STORAGE_CMD_DELETE_KEY 3
|
||||
|
||||
/*
|
||||
* TA_BLIQ_STORAGE_CMD_ENCRYPT - Encrypt arbitrary string
|
||||
* with protected RSA KeyPair from secure storage
|
||||
* param[0] (memref) ID used the identify RSA key
|
||||
* param[1] (memref) plain data to encrypt
|
||||
* param[2] (memref) encrypted data
|
||||
* param[3] unused
|
||||
*/
|
||||
#define TA_BLIQ_STORAGE_CMD_ENCRYPT 4
|
||||
|
||||
/*
|
||||
* TA_BLIQ_STORAGE_CMD_DECRYPT - Decrypt previosly encrypted string
|
||||
* with protected RSA KeyPair from secure storage
|
||||
* param[0] (memref) ID used the identify RSA key
|
||||
* param[1] (memref) encrypted data
|
||||
* param[2] (memref) decrypted data
|
||||
* param[3] unused
|
||||
*/
|
||||
#define TA_BLIQ_STORAGE_CMD_DECRYPT 5
|
||||
|
||||
#endif /* __BLIQ_STORAGE_H__ */
|
263
bliq_storage/ta/key_pair.c
Normal file
263
bliq_storage/ta/key_pair.c
Normal file
@ -0,0 +1,263 @@
|
||||
#include <inttypes.h>
|
||||
#include "operations.h"
|
||||
#include "key_pair.h"
|
||||
|
||||
static char* storeNext(
|
||||
TEE_ObjectHandle kp,
|
||||
uint32_t attribute_id,
|
||||
char *curr, const char * const end)
|
||||
{
|
||||
TEE_Result res;
|
||||
uint32_t attribute_sz;
|
||||
|
||||
if (curr == NULL)
|
||||
return NULL;
|
||||
|
||||
TEE_GetObjectBufferAttribute(kp, attribute_id, NULL, &attribute_sz);
|
||||
if (curr + sizeof(uint32_t) + attribute_sz > end)
|
||||
return NULL;
|
||||
|
||||
EMSG("[INFO] -->> attr_size %u\n", attribute_sz);
|
||||
|
||||
// store attribute size
|
||||
curr[0] = attribute_sz & 0xFF;
|
||||
curr[1] = attribute_sz >> 8 & 0xFF;
|
||||
curr[2] = attribute_sz >> 16 & 0xFF;
|
||||
curr[3] = attribute_sz >> 24 & 0xFF;
|
||||
|
||||
curr += sizeof(uint32_t); // move pointer
|
||||
|
||||
res = TEE_GetObjectBufferAttribute(kp, attribute_id, curr, &attribute_sz);
|
||||
if (res != TEE_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
return curr + attribute_sz;
|
||||
}
|
||||
|
||||
static char* readNext(
|
||||
TEE_Attribute *key_attr,
|
||||
uint32_t attribute_id,
|
||||
char *curr, const char * const end)
|
||||
{
|
||||
if (curr > end || curr == NULL)
|
||||
return NULL;
|
||||
|
||||
uint32_t attribute_sz = curr[3] <<24 | curr[2] <<16 | curr[1] <<8 | curr[0];
|
||||
EMSG("[INFO] <<-- attr_size %u\n", attribute_sz);
|
||||
curr += sizeof(uint32_t); // move pointer
|
||||
|
||||
TEE_InitRefAttribute(key_attr, attribute_id, curr, attribute_sz);
|
||||
|
||||
return curr + attribute_sz;
|
||||
}
|
||||
|
||||
TEE_Result kp_create(
|
||||
TEE_ObjectHandle *kp)
|
||||
{
|
||||
const uint32_t key_type = TEE_TYPE_RSA_KEYPAIR;
|
||||
const uint32_t key_size = 1024; // fast calculations
|
||||
|
||||
TEE_Result res;
|
||||
TEE_ObjectHandle key = NULL;
|
||||
|
||||
res = TEE_AllocateTransientObject(
|
||||
key_type, key_size,
|
||||
&key);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] kp_create: TEE_AllocateTransientObject(%#" PRIx32 ", %" PRId32 "): %#" PRIx32, key_type, key_size, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_GenerateKey(
|
||||
key, key_size,
|
||||
NULL, 0);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] kp_create: TEE_GenerateKey(%" PRId32 "): %#" PRIx32, key_size, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*kp = key;
|
||||
key = NULL;
|
||||
|
||||
exit:
|
||||
if (key)
|
||||
TEE_FreeTransientObject(key);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
TEE_Result kp_serialize(
|
||||
TEE_ObjectHandle kp,
|
||||
char *serilized, uint32_t *serilized_sz)
|
||||
{
|
||||
char *curr = serilized;
|
||||
char *end = serilized + *serilized_sz;
|
||||
|
||||
curr = storeNext(kp, TEE_ATTR_RSA_MODULUS , curr, end);
|
||||
curr = storeNext(kp, TEE_ATTR_RSA_PUBLIC_EXPONENT , curr, end);
|
||||
curr = storeNext(kp, TEE_ATTR_RSA_PRIVATE_EXPONENT, curr, end);
|
||||
curr = storeNext(kp, TEE_ATTR_RSA_PRIME1 , curr, end);
|
||||
curr = storeNext(kp, TEE_ATTR_RSA_PRIME2 , curr, end);
|
||||
curr = storeNext(kp, TEE_ATTR_RSA_EXPONENT1 , curr, end);
|
||||
curr = storeNext(kp, TEE_ATTR_RSA_EXPONENT2 , curr, end);
|
||||
curr = storeNext(kp, TEE_ATTR_RSA_COEFFICIENT , curr, end);
|
||||
|
||||
if (curr == NULL)
|
||||
return TEE_ERROR_OVERFLOW;
|
||||
|
||||
*serilized_sz = curr - serilized;
|
||||
|
||||
return TEE_SUCCESS;
|
||||
}
|
||||
|
||||
TEE_Result kp_deserialize(
|
||||
char *serilized, uint32_t serilized_sz,
|
||||
TEE_ObjectHandle *kp)
|
||||
{
|
||||
TEE_Result res;
|
||||
TEE_Attribute key_attr[8];
|
||||
uint32_t key_attr_count = 8;
|
||||
|
||||
TEE_ObjectHandle transient_kp = NULL;
|
||||
const uint32_t key_type = TEE_TYPE_RSA_KEYPAIR;
|
||||
const uint32_t key_size = 1024; // fast calculations
|
||||
|
||||
char *curr = serilized;
|
||||
char *curr_end = serilized + serilized_sz;
|
||||
|
||||
curr = readNext(&key_attr[0], TEE_ATTR_RSA_MODULUS , curr, curr_end);
|
||||
curr = readNext(&key_attr[1], TEE_ATTR_RSA_PUBLIC_EXPONENT , curr, curr_end);
|
||||
curr = readNext(&key_attr[2], TEE_ATTR_RSA_PRIVATE_EXPONENT, curr, curr_end);
|
||||
curr = readNext(&key_attr[3], TEE_ATTR_RSA_PRIME1 , curr, curr_end);
|
||||
curr = readNext(&key_attr[4], TEE_ATTR_RSA_PRIME2 , curr, curr_end);
|
||||
curr = readNext(&key_attr[5], TEE_ATTR_RSA_EXPONENT1 , curr, curr_end);
|
||||
curr = readNext(&key_attr[6], TEE_ATTR_RSA_EXPONENT2 , curr, curr_end);
|
||||
curr = readNext(&key_attr[7], TEE_ATTR_RSA_COEFFICIENT , curr, curr_end);
|
||||
|
||||
if (curr == NULL) {
|
||||
res = TEE_ERROR_OVERFLOW;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_AllocateTransientObject(
|
||||
key_type, key_size,
|
||||
&transient_kp);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] kp_deserialize(): TEE_AllocateTransientObject(%#" PRIx32 ", %" PRId32 "): %#" PRIx32, key_type, key_size, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_PopulateTransientObject(
|
||||
transient_kp,
|
||||
key_attr, key_attr_count);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR]: kp_deserialize(): TEE_PopulateTransientObject: 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*kp = transient_kp;
|
||||
transient_kp = NULL;
|
||||
|
||||
exit:
|
||||
if (transient_kp)
|
||||
TEE_FreeTransientObject(transient_kp);
|
||||
return res;
|
||||
}
|
||||
|
||||
TEE_Result kp_encrypt(
|
||||
TEE_ObjectHandle kp,
|
||||
void *inbuf, uint32_t inbuf_sz,
|
||||
void *outbuf, uint32_t *outbuf_sz)
|
||||
{
|
||||
const uint32_t alg = TEE_ALG_RSAES_PKCS1_V1_5;
|
||||
|
||||
TEE_Result res;
|
||||
TEE_OperationHandle op = NULL;
|
||||
TEE_ObjectInfo key_info;
|
||||
|
||||
res = TEE_GetObjectInfo1(kp, &key_info);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] kp_encrypt: TEE_GetObjectInfo1: %#" PRIx32, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_AllocateOperation(
|
||||
&op,
|
||||
alg, TEE_MODE_ENCRYPT,
|
||||
key_info.keySize);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] kp_encrypt: TEE_AllocateOperation(TEE_MODE_ENCRYPT, %#" PRIx32 ", %" PRId32 "): %#" PRIx32, alg, key_info.keySize, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_SetOperationKey(op, kp);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] kp_encrypt: TEE_SetOperationKey: %#" PRIx32, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_AsymmetricEncrypt(
|
||||
op,
|
||||
NULL, 0,
|
||||
inbuf, inbuf_sz,
|
||||
outbuf, outbuf_sz);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] kp_encrypt: TEE_AsymmetricEncrypt(%u, %u): 0x%x", inbuf_sz, *outbuf_sz, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (op)
|
||||
TEE_FreeOperation(op);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
TEE_Result kp_decrypt(
|
||||
TEE_ObjectHandle kp,
|
||||
void *inbuf, uint32_t inbuf_sz,
|
||||
void *outbuf, uint32_t *outbuf_sz)
|
||||
{
|
||||
const uint32_t alg = TEE_ALG_RSAES_PKCS1_V1_5;
|
||||
|
||||
TEE_Result res;
|
||||
TEE_OperationHandle op = NULL;
|
||||
TEE_ObjectInfo key_info;
|
||||
|
||||
res = TEE_GetObjectInfo1(kp, &key_info);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] kp_encrypt: TEE_GetObjectInfo1: %#" PRIx32, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_AllocateOperation(
|
||||
&op,
|
||||
alg, TEE_MODE_DECRYPT,
|
||||
key_info.keySize);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] kp_encrypt: TEE_AllocateOperation(TEE_MODE_DECRYPT, %#" PRIx32 ", %" PRId32 "): %#" PRIx32, alg, key_info.keySize, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_SetOperationKey(op, kp);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] kp_encrypt: TEE_SetOperationKey: %#" PRIx32, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_AsymmetricDecrypt(
|
||||
op,
|
||||
NULL, 0,
|
||||
inbuf, inbuf_sz,
|
||||
outbuf, outbuf_sz);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR] kp_encrypt: TEE_AsymmetricEncrypt(%u, %u): 0x%x", inbuf_sz, *outbuf_sz, res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (op)
|
||||
TEE_FreeOperation(op);
|
||||
|
||||
return res;
|
||||
}
|
27
bliq_storage/ta/key_pair.h
Normal file
27
bliq_storage/ta/key_pair.h
Normal file
@ -0,0 +1,27 @@
|
||||
#include <tee_internal_api.h>
|
||||
|
||||
#ifndef KEY_PAIR_H
|
||||
#define KEY_PAIR_H
|
||||
|
||||
TEE_Result kp_create(
|
||||
TEE_ObjectHandle *kp);
|
||||
|
||||
TEE_Result kp_serialize(
|
||||
TEE_ObjectHandle kp,
|
||||
char *serilized, uint32_t *serilized_sz);
|
||||
|
||||
TEE_Result kp_deserialize(
|
||||
char *serilized, uint32_t serilized_sz,
|
||||
TEE_ObjectHandle *kp);
|
||||
|
||||
TEE_Result kp_encrypt(
|
||||
TEE_ObjectHandle kp,
|
||||
void *in, uint32_t in_sz,
|
||||
void *out, uint32_t *out_sz);
|
||||
|
||||
TEE_Result kp_decrypt(
|
||||
TEE_ObjectHandle kp,
|
||||
void *in, uint32_t in_sz,
|
||||
void *out, uint32_t *out_sz);
|
||||
|
||||
#endif /*KEY_PAIR_H*/
|
151
bliq_storage/ta/operations.c
Normal file
151
bliq_storage/ta/operations.c
Normal file
@ -0,0 +1,151 @@
|
||||
#include <inttypes.h>
|
||||
#include "operations.h"
|
||||
|
||||
char iv[] = {
|
||||
0x7D, 0x3F, 0x80, 0x6C, 0x35, 0x7E, 0x04, 0xC2,
|
||||
0x92, 0x4C, 0x67, 0x30, 0xBA, 0xFA, 0xE0, 0xF7};
|
||||
uint32_t iv_sz = sizeof(iv);
|
||||
|
||||
|
||||
static TEE_Result sha256(
|
||||
char *in, size_t in_sz,
|
||||
char *out, uint32_t *out_sz)
|
||||
{
|
||||
TEE_Result res;
|
||||
TEE_OperationHandle hDigest = NULL;
|
||||
|
||||
res = TEE_AllocateOperation(
|
||||
&hDigest,
|
||||
TEE_ALG_SHA256, TEE_MODE_DIGEST,
|
||||
0);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR]: TEE_AllocateOperation: 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_DigestDoFinal(
|
||||
hDigest,
|
||||
in, in_sz,
|
||||
out, out_sz);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR]: TEE_DigestDoFinal: 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (hDigest)
|
||||
TEE_FreeOperation(hDigest);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Session Operations
|
||||
*/
|
||||
TEE_Result so_init(
|
||||
char *pin, size_t pin_sz,
|
||||
Session *session)
|
||||
{
|
||||
TEE_Result res;
|
||||
TEE_ObjectHandle hSessionKey = NULL;
|
||||
TEE_Attribute key_attr = { 0 };
|
||||
uint32_t key_attr_count = 1;
|
||||
|
||||
char key[32]; // 256bit
|
||||
uint32_t key_sz = sizeof(key);
|
||||
|
||||
res = sha256(
|
||||
pin, pin_sz,
|
||||
key, &key_sz);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR]: sha256: %d", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_AllocateTransientObject(
|
||||
TEE_TYPE_AES, 256,
|
||||
&hSessionKey);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR]: SessionKey TEE_AllocateTransientObject: 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
TEE_InitRefAttribute(&key_attr, TEE_ATTR_SECRET_VALUE, key, key_sz);
|
||||
res = TEE_PopulateTransientObject(
|
||||
hSessionKey,
|
||||
&key_attr, key_attr_count);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR]: SessionKey TEE_PopulateTransientObject: 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_AllocateOperation(
|
||||
&session->hSK_encrypt,
|
||||
TEE_ALG_AES_CTR, TEE_MODE_ENCRYPT, 256);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR]: SessionKey hSK_encrypt: TEE_AllocateOperation: 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_SetOperationKey(
|
||||
session->hSK_encrypt,
|
||||
hSessionKey);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR]: SessionKey TEE_SetOperationKey(sk_encrypt): 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_AllocateOperation(
|
||||
&session->hSK_decrypt,
|
||||
TEE_ALG_AES_CTR, TEE_MODE_DECRYPT, 256);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR]: SessionKey hSK_decrypt: TEE_AllocateOperation: 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = TEE_SetOperationKey(
|
||||
session->hSK_decrypt,
|
||||
hSessionKey);
|
||||
if (res != TEE_SUCCESS) {
|
||||
EMSG("[ERR]: SessionKey TEE_SetOperationKey(sk_decrypt): 0x%x", res);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (hSessionKey)
|
||||
TEE_FreeTransientObject(hSessionKey);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void so_free(
|
||||
Session *session)
|
||||
{
|
||||
TEE_FreeOperation(session->hSK_encrypt);
|
||||
TEE_FreeOperation(session->hSK_decrypt);
|
||||
}
|
||||
|
||||
|
||||
TEE_Result so_encrypt(
|
||||
Session *session,
|
||||
void *in, uint32_t in_sz,
|
||||
void *out, uint32_t *out_sz)
|
||||
{
|
||||
TEE_CipherInit(session->hSK_encrypt, iv, iv_sz);
|
||||
|
||||
return TEE_CipherDoFinal(session->hSK_encrypt,
|
||||
in, in_sz, // src
|
||||
out, out_sz); // dest
|
||||
}
|
||||
|
||||
TEE_Result so_decrypt(
|
||||
Session *session,
|
||||
void *in, uint32_t in_sz,
|
||||
void *out, uint32_t *out_sz)
|
||||
{
|
||||
TEE_CipherInit(session->hSK_decrypt, iv, iv_sz);
|
||||
|
||||
return TEE_CipherDoFinal(session->hSK_decrypt,
|
||||
in, in_sz, // src
|
||||
out, out_sz); // dest
|
||||
}
|
28
bliq_storage/ta/operations.h
Normal file
28
bliq_storage/ta/operations.h
Normal file
@ -0,0 +1,28 @@
|
||||
#include <tee_internal_api.h>
|
||||
|
||||
#ifndef OPERATIONS_H
|
||||
#define OPERATIONS_H
|
||||
|
||||
typedef struct {
|
||||
TEE_OperationHandle hSK_encrypt;
|
||||
TEE_OperationHandle hSK_decrypt;
|
||||
} Session;
|
||||
|
||||
TEE_Result so_init(
|
||||
char *pin, size_t pin_sz,
|
||||
Session *session);
|
||||
|
||||
void so_free(
|
||||
Session *session);
|
||||
|
||||
TEE_Result so_encrypt(
|
||||
Session *session,
|
||||
void *inbuf, uint32_t inbuf_sz,
|
||||
void *outbuf, uint32_t *outbuf_sz);
|
||||
|
||||
TEE_Result so_decrypt(
|
||||
Session *session,
|
||||
void *inbuf, uint32_t inbuf_sz,
|
||||
void *outbuf, uint32_t *outbuf_sz);
|
||||
|
||||
#endif /*OPERATIONS_H*/
|
2
bliq_storage/ta/sub.mk
Normal file
2
bliq_storage/ta/sub.mk
Normal file
@ -0,0 +1,2 @@
|
||||
global-incdirs-y += include
|
||||
srcs-y += bliq_storage_ta.c operations.c key_pair.c
|
21
bliq_storage/ta/user_ta_header_defines.h
Normal file
21
bliq_storage/ta/user_ta_header_defines.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* The name of this file must not be modified
|
||||
*/
|
||||
|
||||
#ifndef USER_TA_HEADER_DEFINES_H
|
||||
#define USER_TA_HEADER_DEFINES_H
|
||||
|
||||
#include <bliq_storage_ta.h>
|
||||
|
||||
#define TA_UUID TA_BLIQ_STORAGE_UUID
|
||||
|
||||
#define TA_FLAGS (TA_FLAG_EXEC_DDR | TA_FLAG_SINGLE_INSTANCE)
|
||||
#define TA_STACK_SIZE (2 * 1024)
|
||||
#define TA_DATA_SIZE (32 * 1024)
|
||||
|
||||
#define TA_CURRENT_TA_EXT_PROPERTIES \
|
||||
{ "gp.ta.description", USER_TA_PROP_TYPE_STRING, \
|
||||
"A simple secure storage TA for BliQ" }, \
|
||||
{ "gp.ta.version", USER_TA_PROP_TYPE_U32, &(const uint32_t){ 0x0010 } }
|
||||
|
||||
#endif /*USER_TA_HEADER_DEFINES_H*/
|
4
build-docker.sh
Executable file
4
build-docker.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euxo pipefail
|
||||
|
||||
docker build -t op-tee-quemu:latest .
|
9
run-docker.sh
Executable file
9
run-docker.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euxo pipefail
|
||||
|
||||
docker run \
|
||||
--name op-tee-secstore \
|
||||
--rm \
|
||||
-v $(pwd)/bliq_storage:/optee/optee_examples/bliq_storage \
|
||||
-e DISPLAY=docker.for.mac.host.internal:0 \
|
||||
-it op-tee-quemu:latest
|
Binary file not shown.
BIN
spec/TEE_Client_API_Specification-V1.0.pdf
Normal file
BIN
spec/TEE_Client_API_Specification-V1.0.pdf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user