rel_1.6.0 init

This commit is contained in:
guocheng.kgc 2020-06-18 20:06:52 +08:00 committed by shengdong.dsd
commit 27b3e2883d
19359 changed files with 8093121 additions and 0 deletions

View file

@ -0,0 +1,241 @@
#!/bin/bash
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
TOP=..
SRV_PATH_LIST=./srv_path_list.log
OUT=$TOP/out
TEST_BED=$TOP/test/test_bed
PLAT_ARRAY=('csky_phobos' 'csky_ch2201')
ALIAS_ARRAY=('phobos' 'ch2201')
TEE_PLAT=
SCRIPT=$0
_chk_proj()
{
if [[ "" == "$1" ]]
then
echo "ERROR: invalid cmd fmt"
echo "INFO: $SCRIPT platform_name [test]"
echo "INFO: $SCRIPT platform_name [clean]"
echo " valid platform_name: "${ALIAS_ARRAY[@]}
exit
fi
idx=0
for i in ${ALIAS_ARRAY[@]}
do
if [[ "$i" == "$1" ]]
then
TEE_PLAT=${PLAT_ARRAY[$idx]}
echo "build tee platform "$TEE_PLAT
fi
idx=$idx+1
done
if [[ "" == "$TEE_PLAT" ]]
then
echo "ERROR: "$1 "platform not support!"
echo "INFO: $SCRIPT platform_name [test]"
echo "INFO: $SCRIPT platform_name [clean]"
echo " valid platform_name: "${ALIAS_ARRAY[@]}
exit
fi
}
# main flow
_chk_proj $@
if [ "$1" == "clean" ] || [ "$2" == "clean" ];
then
CLEAN="clean"
rm ../src/tw/tee/tw.sdk.o -fv
rm ../src/tw/tee/crypto.rsa.o -fv
rm ../src/tw/tee/crypto.aes.o -fv
rm ../src/tw/tee/crypto.sha.o -fv
rm ../src/tw/tee/crypto.rand.o -fv
rm ../src/ntw/drv/drv.sdk.o -fv
rm ../src/ntw/lpm/ntw.lpmapi.o -fv
rm ../src/ntw/stub/tst_stub/tststub.o -fv
rm ../src/app/id2/tw/built-in.o -fv
# rm ../tools/build_tw/build_tw -fv
rm -rf $OUT/tee_tw.bin
else
CLEAN=""
fi
echo "prepare $TEE_PLAT platform!"
sed -i "/^PLATFORM :=/ cPLATFORM := $TEE_PLAT" ../src/tw/tee.cfg
if [ "$2" = "test" ];
then
## link test object
echo "prepare TEST environment!"
sed -i "/^TEST :=/ cTEST := Y" ../src/tw/tee.cfg
sed -i '/VERSION/s/_.*//' ../src/tw/tee.cfg
sed -i '/VERSION/ s/$/_TEST/' ../src/tw/tee.cfg
ln -sf tw.sdk.test.o ../src/tw/tee/tw.sdk.o
ln -sf crypto.rsa.test.o ../src/tw/tee/crypto.rsa.o
ln -sf crypto.aes.test.o ../src/tw/tee/crypto.aes.o
ln -sf crypto.sha.test.o ../src/tw/tee/crypto.sha.o
ln -sf crypto.rand.test.o ../src/tw/tee/crypto.rand.o
ln -sf drv.sdk.test.o ../src/ntw/drv/drv.sdk.o
ln -sf ntw.lpmapi.test.o ../src/ntw/lpm/ntw.lpmapi.o
ln -sf tststub.test.o ../src/ntw/stub/tst_stub/tststub.o
ln -sf built-in.test.o ../src/app/id2/tw/built-in.o
else
## link release object
echo "prepare RELEASE environment!"
sed -i "/^TEST :=/ cTEST := N" ../src/tw/tee.cfg
sed -i '/VERSION/s/_.*//' ../src/tw/tee.cfg
sed -i '/VERSION/ s/$/_RELEASE/' ../src/tw/tee.cfg
ln -sf tw.sdk.rel.o ../src/tw/tee/tw.sdk.o
ln -sf crypto.rsa.rel.o ../src/tw/tee/crypto.rsa.o
ln -sf crypto.aes.rel.o ../src/tw/tee/crypto.aes.o
ln -sf crypto.sha.rel.o ../src/tw/tee/crypto.sha.o
ln -sf crypto.rand.rel.o ../src/tw/tee/crypto.rand.o
ln -sf drv.sdk.rel.o ../src/ntw/drv/drv.sdk.o
ln -sf ntw.lpmapi.rel.o ../src/ntw/lpm/ntw.lpmapi.o
ln -sf tststub.rel.o ../src/ntw/stub/tst_stub/tststub.o
ln -sf built-in.rel.o ../src/app/id2/tw/built-in.o
fi
################################################################################
# build trusted world
while IFS='' read -r line || [[ -n "$line" ]];
do
if [ ${line:0:1} == "#" ];
then
continue;
fi
pushd $line
make $CLEAN
popd
done < $SRV_PATH_LIST
## build apps
if [ "$CLEAN" == "clean" ];
then
pushd $TOP/src/app/id2/tw
rm -f built-in.bin built-in.elf built-in.lds
popd
fi
pushd $TOP/src/tw
make $CLEAN
popd
## read TEE TW flash and Sram size
flash_info=`grep "FLASH : ORIGIN" ../src/tw/sw.lds`
flash_sz=`echo ${flash_info##*LENGTH} | grep -Eo '0[xX][0-9a-fA-F]+'`
sram_info=`grep "ISRAM : ORIGIN" ../src/tw/sw.lds`
sram_sz=`echo ${sram_info##*LENGTH} | grep -Eo '0[xX][0-9a-fA-F]+'`
if [ "$CLEAN" == "" ];
then
if [ ! -e "$OUT" ];
then
mkdir $OUT
fi
rm -f $OUT/tee_tw.bin
cmd="$TOP/tools/build_tw/build_tw -s $TOP/src/tw/sw.elf -f $flash_sz -r $sram_sz"
### append the default apps here
cmd=$cmd" -a $TOP/src/app/id2/tw/built-in.o"
while IFS='' read -r line || [[ -n "$line" ]];
do
if [ ${line:0:1}. == "#". ];
then
continue;
fi
cmd=$cmd" -a "$line"/built-in.o"
done < $SRV_PATH_LIST
cmd=$cmd" -o $OUT/tee_tw.bin"
### DBG ### echo "integ-cmd = $cmd"
eval $cmd
fi
################################################################################
# build non-trusted world
pushd $TOP/src/ntw
make $CLEAN
popd
pushd $TOP/samples/xor/ntw
make $CLEAN
popd
# make link
pushd $TEST_BED
if [ "$CLEAN" == "clean" ];
then
rm ntw_drv/tee_ntw.o -rf
rm ntw_drv/ntw_lpmapi.o -rf
rm ntw_drv/tststub.o -rf
rm inc/tee_client_api.h -rf
rm inc/tee_os_dep.h -rf
rm inc/tee_types.h -rf
rm inc/tee_dbg.h -rf
rm inc/teec_lpm_api.h -rf
rm inc/tee_addr_map.h -rf
rm os_lib/$TEE_PLAT/inc/hal_memmap.h
rm test/xor_stub.o -rf
rm ntw_drv/tee_id2.c -rf
rm ntw_drv/tee_rsa.c -rf
rm ntw_app/tee_cipher.c -rf
rm ntw_drv/tee_id2_cmd.h -rf
rm ntw_drv/tee_id2.h -rf
rm ntw_drv/tee_rsa.h -rf
rm ntw_app/tee_sym.h -rf
rm test/test_stub.o -rf
else
# don't link tee_drv.o, because tee_drv.o has already contains printk/kmalloc/kfree
##ln -sf ../../../src/ntw/tee_drv.o ntw_drv/tee_ntw.o
ln -sfT ../../..//src/ntw/drv/drv.sdk.o ntw_drv/tee_ntw.o
ln -sfT ../../..//src/ntw/lpm/ntw.lpmapi.o ntw_drv/ntw.lpmapi.o
ln -sfT ../../..//src/ntw/stub/tst_stub/tststub..o ntw_drv/tststub.o
ln -sf ../../../src/ntw/inc/tee_client_api.h inc/tee_client_api.h
ln -sf ../../../src/ntw/inc/tee_client_api.h inc/tee_client_api.h
ln -sf ../../../src/ntw/inc/tee_os_dep.h inc/tee_os_dep.h
ln -sf ../../../src/ntw/inc/tee_types.h inc/tee_types.h
ln -sf ../../../src/ntw/inc/tee_dbg.h inc/tee_dbg.h
ln -sf ../../../src/ntw/inc/teec_lpm_api.h inc/teec_lpm_api.h
ln -sf ../../../src/tw/inc/tee_addr_map.h inc/tee_addr_map.h
ln -sf ../../../../../src/tw/platform/$TEE_PLAT/inc/hal_memmap.h os_lib/$TEE_PLAT/inc/hal_memmap.h
ln -sf ../../../samples/xor/ntw/xor_stub.o test/xor_stub.o
ln -sf ../../../src/app/id2/ntw/src/tee_id2.c ntw_app/tee_id2.c
ln -sf ../../../src/app/id2/ntw/src/tee_rsa.c ntw_app/tee_rsa.c
ln -sf ../../../src/app/id2/ntw/src/tee_cipher.c ntw_app/tee_cipher.c
ln -sf ../../../src/app/id2/ntw/include/tee_id2_cmd.h ntw_app/tee_id2_cmd.h
ln -sf ../../../src/app/id2/ntw/include/tee_id2.h ntw_app/tee_id2.h
ln -sf ../../../src/app/id2/ntw/include/tee_rsa.h ntw_app/tee_rsa.h
ln -sf ../../../src/app/id2/ntw/include/tee_sym.h ntw_app/tee_sym.h
ln -sf ../../../test/testcases/test_stub.o test/test_stub.o
fi
popd
pushd $TOP/test/testcases
make $CLEAN
popd
pushd $TEST_BED
make $CLEAN
cp test_bed.bin ../../out -f
popd

View file

@ -0,0 +1,7 @@
#../samples/xor/tw
#../test/testcases/mem/tw
#../test/testcases/hash/tw
#../test/testcases/rsa/tw
#../test/testcases/asc/tw
#../test/testcases/aes/tw
#../test/testcases/rng/tw

View file

@ -0,0 +1,54 @@
Alibaba TrustZone/TEE Software Development Kit For IoT Devices
Version 1.0
DESCRIPTION
The software package is the Software Development Kit (SDK) of Alibaba TrustZone/TEE solution. It is the development environment of YoC devices.
LAYOUT
$
├── build -- the build-related materials
│   ├── b -- the build script
│   └── srv_path_list.log -- the log to describe the services integrated to the TEE binary
├── docs -- the document set of the SDK
│   └── README -- this file
├── samples -- the sample code set
│   └── xor -- the sample code of building a Client Application (CA) and its Trusted Application (TA)
├── src -- the code and binary of the SDK
│   ├── app -- the application set (CA and TA) of Alibaba TEE solution
│   ├── ntw -- the non-secure code and its binary
│   └── tw -- the secure code and its binary
├── test -- the tese cases and sample test bed
│ ├── test_bed -- the sample non-secure test bed.
│ └── testcases -- the tee test cases, include CA/TA.
└── tools -- the toolkit
└── build_tw -- the tool to build secure binary
TOOLCHAIN
Alibaba TrustZone/TEE SDK is built according to the architecture that the SDK serves. Now it is for C-Sky and its toolchain version is "csky-abiv2-elf-tools-x86_64-minilibc-20151217".
SAMPLE
There is a sample code for developping a CA and its TA accordingly. You could find it in $/samples/xor.
BUILD
Go into $/build and run:
./b ---- for release version, TEST=N in tee.cfg
./b test ---- for test version, TEST=Y in tee.cfg
The outputs are:
1. non-secure world (or non-trusted world)
There are two object files for non-secure world: $/src/ntw/tee_drv.o and $/samples/xor/ntw/xor_stub.o
2. secure world (or trusted world)
There is one binary file for secure world: $/out/tee_tw.bin
3. test cases and test bed
There is one binary file of non-secure world which include tee_drv, test CAs and test beds :$/out/test_bed.bin
RUN
Use CDS to flash tee_tw.bin and test_bed.bin and run;
Copyright (C) 2016 The YunOS Project. All rights reserved.

View file

@ -0,0 +1,26 @@
v0.3.0:
1. Shrink TEE OS size, remove unused functions.
0.4.2:
1. rename c_sky to hal_platform.
2. separate crypto.o to crypto.rsa.o crypto.aes.o crypto.hash.o and crypto.rand.o.
3. support PHOBOS_GENERAL platform config.
0.4.3:
1. support test and release in one SDK.
{./b test} will set TEST=Y in tee.cfg and build test version tee.
{./b } will set TEST=N in tee.cfg and build releasve version tee.
0.4.4:
1. fix rand impl.
2. fix memref/tmpmem size not return.
0.4.5:
1. add ree lpm api.
2. fix sha drv bugs.
0.4.6:
1. add support TRNG for csky.
0.4.7:
1. support tst.
0.4.8:
1. fix memory leak in core module.
2. fix tst-stub mismatch between reading and writing.
0.4.9:
1. support multi platfrom.
2. ID2 support aes solution.

View file

@ -0,0 +1,17 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _XOR_H_
#define _XOR_H_
#define CMD_XOR (0x12345678)
#define XOR_SRV_UUID { \
0x78b97118, 0x998a, 0x1aca, \
{ 0x02, 0x8e, 0xb6, 0x01, 0xd5, 0x3e, 0xd5, 0x03 } \
}
extern int tee_xor_test(void);
#endif /* _XOR_H_ */

View file

@ -0,0 +1,26 @@
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
## Use Make.rulse in tee/tw folder
NTW_DRV_TOP := ../../../src/ntw/
TW_TOP := ../../../src/tw/
CURRENT_BUILD := NTW
include $(TW_TOP)/tee.cfg
include $(TW_TOP)/Make.rules
SRCS := $(wildcard *.c *.cxx)
OBJS := $(patsubst %.cxx,%.o,$(patsubst %.c,%.o,$(SRCS)))
CFLAGS += -I../inc -I$(NTW_DRV_TOP)/inc -I$(NTW_DRV_TOP)/drv/inc
LIBS := xor_stub.o
all: $(OBJS) $(LIBS)
$(LIBS): $(OBJS)
$(LD) -r -o $(LIBS) $(OBJS)
@ echo "Finish building $(LIBS)..."
clean:
@ echo "Cleaning $(LIBS)..."
rm -f $(OBJS) $(LIBS)

View file

@ -0,0 +1,50 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#include "tee_client_api.h"
#include "tee_dbg.h"
#include "xor.h"
static const TEEC_UUID _g_uuid = XOR_SRV_UUID;
/* c = a ^ b */
int tee_xor_test()
{
unsigned int a = 12345, b = 67890, c = 0;
TEEC_Context cntx;
TEEC_Session ss;
TEEC_Operation op;
TEEC_Result ret = TEEC_SUCCESS;
ret = TEEC_OpenSession(&ss, &_g_uuid, NULL);
if (ret != TEEC_SUCCESS) {
tee_dbg_print(ERR, "failed to call TEEC_OpenSession, 0x%08x\n", ret);
goto cleanup2;
}
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_VALUE_INPUT, TEEC_VALUE_INPUT,
TEEC_VALUE_OUTPUT, TEEC_NONE);
op.params[0].value.a = a;
op.params[1].value.a = b;
op.params[2].value.a = c;
ret = TEEC_InvokeCommand(&ss, CMD_XOR, &op);
if (ret != TEEC_SUCCESS) {
tee_dbg_print(ERR, "failed to call TEEC_InvokeCommand, 0x%08x\n", ret);
goto cleanup3;
}
c = op.params[2].value.a;
tee_dbg_print(INF, "a = %d; b = %d; c = a ^ b: %d\n", a, b, c);
if (c != (a ^ b)) {
ret = TEEC_ERROR_GENERIC;
tee_dbg_print(ERR, "XOR failed!\n");
goto cleanup3;
}
cleanup3:
TEEC_CloseSession(&ss);
cleanup2:
return ret;
}

View file

@ -0,0 +1,28 @@
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
CROSS_COMPILE ?= csky-abiv2-elf-
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
CFLAGS += -I. -I$(XOR_INC) -I$(TEE_INC) -mcpu=ck802t -g3 -Wall -c -Wa,-melrw
PWD := $(shell pwd)
TW_DIR = $(PWD)/../../../src/tw
XOR_INC = $(PWD)/../inc
TEE_INC = $(TW_DIR)/inc
CFLAGS += -I../../../src/common/inc -DCONFIG_DBG
SRCS := $(wildcard *.c *.cxx)
OBJS := $(patsubst %.cxx,%.o,$(patsubst %.c,%.o,$(SRCS)))
built-in.o: $(OBJS)
$(LD) -r $^ -o $@
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $*.o
clean:
rm -f *.o built-in.*

View file

@ -0,0 +1,76 @@
/* FILE GENERATED AUTOMATICALLY - DON'T CHANGE IT MANUALLY */
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
MEMORY
{
/* eXecuting-In-Place */
XIP_MEM : ORIGIN = 0x10009cb8, LENGTH = 0x00006348
/* RELocating */
REL_MEM : ORIGIN = 0x200027a4, LENGTH = 0x0000185c
}
SECTIONS
{
/* srv_head ********************************************************/
.srv.head : {
LONG(0x76527354); /* 0x00000000: magic */
LONG(0x00000001); /* 0x00000004: version */
LONG(0x00000000); /* 0x00000008: tee_fix */
LONG(__srv_data_start); /* 0x0000000C: data start */
LONG(__srv_data_end); /* 0x00000010: data end */
LONG(SIZEOF(.srv.head) +
SIZEOF(.srv.data) +
SIZEOF(.text) +
SIZEOF(.rodata)); /* 0x00000014: data offset */
LONG(__srv_bss_start); /* 0x00000018: bss start */
LONG(__srv_bss_end); /* 0x0000001C: bss end */
LONG(SIZEOF(.srv.head) +
SIZEOF(.srv.data) +
SIZEOF(.text) +
SIZEOF(.rodata) +
SIZEOF(.data)); /* 0x00000020: bss offset */
} > XIP_MEM
.srv.data : AT(ADDR(.srv.head) + SIZEOF(.srv.head)) {
KEEP(*(.srv.data)) /* 0x00000024: srv_data */
} > XIP_MEM
/* srv_head ********************************************************/
.text : AT(ADDR(.srv.data) + SIZEOF(.srv.data)) {
. = ALIGN(0x4);
__srv_text_start = .;
KEEP(*(.text))
KEEP(*(.text*))
. = ALIGN(0x4);
__srv_text_end = .;
} > XIP_MEM
.rodata : AT(ADDR(.text) + SIZEOF(.text)) {
. = ALIGN(0x4);
__srv_rodata_start = .;
KEEP(*(.rodata))
KEEP(*(.rodata*))
. = ALIGN(0x4);
__srv_rodata_end = .;
} > XIP_MEM
.data : AT(ADDR(.rodata) + SIZEOF(.rodata)) {
. = ALIGN(0x4);
__srv_data_start = .;
KEEP(*(.data))
KEEP(*(.data*))
. = ALIGN(0x4);
__srv_data_end = .;
} > REL_MEM
.bss : AT(ADDR(.data) + SIZEOF(.data)) {
. = ALIGN(0x4);
__srv_bss_start = .;
KEEP(*(.bss))
KEEP(*(.bss*))
. = ALIGN(0x4);
__srv_bss_end = .;
} > REL_MEM
}

View file

@ -0,0 +1,67 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#include "tee_tos.h"
#include "tee_srv.h"
#include "xor.h"
static TEE_Result _xor_CreateEntryPoint(void)
{
return TEE_SUCCESS;
}
static void _xor_DestroyEntryPoint(void)
{
return;
}
static TEE_Result _xor_OpenSessionEntryPoint(
uint32_t paramTypes,
TEE_Param params[4],
void **sessionContext)
{
return TEE_SUCCESS;
}
static void _xor_CloseSessionEntryPoint(void *sessionContext)
{
return;
}
static TEE_Result _xor_InvokeCommandEntryPoint(
void *sessionContext,
uint32_t commandID,
uint32_t paramTypes,
TEE_Param params[4])
{
if (paramTypes != TEE_PARAM_TYPES(
TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_VALUE_OUTPUT,
TEE_PARAM_TYPE_NONE)) {
return TEE_ERROR_BAD_PARAMETERS;
}
if (CMD_XOR != commandID) {
return TEE_ERROR_BAD_PARAMETERS;
}
params[2].value.a =
params[0].value.a ^ params[1].value.a;
return TEE_SUCCESS;
}
TEE_SRV_DATA_START(_xor_CreateEntryPoint,
_xor_DestroyEntryPoint,
_xor_OpenSessionEntryPoint,
_xor_CloseSessionEntryPoint,
_xor_InvokeCommandEntryPoint)
TEE_SRV_UUID_PROPERTY("gpd.ta.appID", XOR_SRV_UUID)
TEE_SRV_BOOL_PROPERTY("gpd.ta.singleInstance", true)
TEE_SRV_BOOL_PROPERTY("gpd.ta.multiSession", true)
TEE_SRV_BOOL_PROPERTY("gpd.ta.instanceKeepAlive", true)
TEE_SRV_INT_PROPERTY("gpd.ta.dataSize", 0x10000)
TEE_SRV_INT_PROPERTY("gpd.ta.stackSize", 0x1000)
TEE_SRV_DATA_END

View file

@ -0,0 +1,20 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef TEE_AES_H
#define TEE_AES_H
int32_t tee_aes_cbc_encrypt(const uint8_t *key,
const uint8_t *iv,
int32_t input_len,
const uint8_t *input,
uint8_t *output);
int32_t tee_aes_cbc_decrypt(const uint8_t *key,
const uint8_t *iv,
int32_t input_len,
const uint8_t *input,
uint8_t *output);
#endif

View file

@ -0,0 +1,21 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef TEE_AES_CMD_H
#define TEE_AES_CMD_H
#define TEE_AES_CBC_ENC (0x0)
#define TEE_AES_CBC_DEC (0x1)
#define AES_BLOCK_SIZE 16
#define AES_KEY_SIZE 16
#define AES_IV_SIZE 16
#define AES_SRV_UUID { \
0x7465655f, 0x6861, 0x7368, \
{ 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x74, 0x65, 0x73 } \
}
#endif

View file

@ -0,0 +1,100 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#include "tee_client_api.h"
#include "tee_dbg.h"
#include "tee_aes_cmd.h"
static const TEEC_UUID tee_aes_uuid = AES_SRV_UUID;
int32_t tee_aes_cbc_encrypt(const uint8_t *key,
const uint8_t *iv,
int32_t input_len,
const uint8_t *input,
uint8_t *output)
{
TEEC_Session ss;
TEEC_Operation op;
TEEC_Result ret = TEEC_SUCCESS;
if ((key == NULL) || (iv == NULL) || (input == NULL) || (output == NULL) || (input_len <= 0)) {
return TEEC_ERROR_BAD_PARAMETERS;
}
ret = TEEC_OpenSession(&ss, &tee_aes_uuid, NULL);
if (ret != TEEC_SUCCESS) {
tee_dbg_print(ERR, "fail(%08x) to open ss\n", ret);
goto cleanup2;
}
op.params[0].tmpref.buffer = (uint8_t *)key;
op.params[0].tmpref.size = AES_KEY_SIZE;
op.params[1].tmpref.buffer = (uint8_t *)iv;
op.params[1].tmpref.size = AES_IV_SIZE;
op.params[2].tmpref.buffer = (uint8_t *)input;
op.params[2].tmpref.size = input_len;
op.params[3].tmpref.buffer = output;
op.params[3].tmpref.size = input_len;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
TEEC_MEMREF_TEMP_INPUT,
TEEC_MEMREF_TEMP_INPUT,
TEEC_MEMREF_TEMP_OUTPUT);
ret = TEEC_InvokeCommand(&ss, TEE_AES_CBC_ENC, &op);
if (ret != TEEC_SUCCESS) {
tee_dbg_print(ERR, "fail(%08x) to inv cmd(%d)\n", ret, TEE_AES_CBC_ENC);
goto cleanup3;
} else {
tee_dbg_print(INF, "tee aes cbc enc success\n");
}
cleanup3:
TEEC_CloseSession(&ss);
cleanup2:
return ret;
}
int32_t tee_aes_cbc_decrypt(const uint8_t *key,
const uint8_t *iv,
int32_t input_len,
const uint8_t *input,
uint8_t *output)
{
TEEC_Session ss;
TEEC_Operation op;
TEEC_Result ret = TEEC_SUCCESS;
ret = TEEC_OpenSession(&ss, &tee_aes_uuid, NULL);
if (ret != TEEC_SUCCESS) {
tee_dbg_print(ERR, "fail(%08x) to open ss\n", ret);
goto cleanup2;
}
op.params[0].tmpref.buffer = (uint8_t *)key;
op.params[0].tmpref.size = AES_KEY_SIZE;
op.params[1].tmpref.buffer = (uint8_t *)iv;
op.params[1].tmpref.size = AES_IV_SIZE;
op.params[2].tmpref.buffer = (uint8_t *)input;
op.params[2].tmpref.size = input_len;
op.params[3].tmpref.buffer = output;
op.params[3].tmpref.size = input_len;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
TEEC_MEMREF_TEMP_INPUT,
TEEC_MEMREF_TEMP_INPUT,
TEEC_MEMREF_TEMP_OUTPUT);
ret = TEEC_InvokeCommand(&ss, TEE_AES_CBC_DEC, &op);
if (ret != TEEC_SUCCESS) {
tee_dbg_print(ERR, "fail(%08x) to inv cmd(%d)\n", ret, TEE_AES_CBC_DEC);
goto cleanup3;
} else {
tee_dbg_print(INF, "tee aes cbc dec success\n");
}
cleanup3:
TEEC_CloseSession(&ss);
cleanup2:
return ret;
}

View file

@ -0,0 +1,23 @@
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
TOP := $(PWD)/../../../../src/tw
CURRENT_BUILD := TW
include $(TOP)/tee.cfg
include $(TOP)/Make.rules
CFLAGS += -I../inc/ -I./ -I../ntw/include
SRCS := $(wildcard *.c *.cxx)
OBJS := $(patsubst %.cxx,%.o,$(patsubst %.c,%.o,$(SRCS)))
.PHONY: all clean
all: built-in.o
built-in.o: $(OBJS)
$(LD) -r $^ -o $@
clean:
rm -f *.o built-in.*

View file

@ -0,0 +1,130 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#include "tee_srv.h"
#include "tee_types.h"
#include "tee_dbg.h"
#include "tee_tos.h"
#include "tee_crypto.h"
#include "tee_aes_cmd.h"
#include "tee_aes.h"
#define AES_CONTEXT_SIZE 120
static TEE_Result _AES_Test_CreateEntryPoint(void)
{
return TEE_SUCCESS;
}
static void _AES_Test_DestroyEntryPoint(void)
{
return;
}
static TEE_Result _AES_Test_OpenSessionEntryPoint(
uint32_t paramTypes,
TEE_Param params[4],
void **sessionContext)
{
return TEE_SUCCESS;
}
static void _AES_Test_CloseSessionEntryPoint(void *sessionContext)
{
return;
}
static TEE_Result _AES_Test_InvokeCommandEntryPoint(
void *sessionContext,
uint32_t commandID,
uint32_t paramTypes,
TEE_Param params[4])
{
TEE_Result ret = TEE_SUCCESS;
uint8_t *key;
uint8_t *iv;
uint8_t *in;
uint8_t *out;
uint32_t len;
int32_t ctx_sz;
uint8_t ctx[AES_CONTEXT_SIZE];
bool enc;
if (commandID == TEE_AES_CBC_ENC) {
enc = true;
} else if (commandID == TEE_AES_CBC_DEC) {
enc = false;
} else {
return TEE_ERROR_BAD_PARAMETERS;
}
if (paramTypes != TEE_PARAM_TYPES(
TEE_PARAM_TYPE_MEMREF_INPUT,
TEE_PARAM_TYPE_MEMREF_INPUT,
TEE_PARAM_TYPE_MEMREF_INPUT,
TEE_PARAM_TYPE_MEMREF_OUTPUT)) {
return TEE_ERROR_BAD_PARAMETERS;
}
key = params[0].memref.buffer;
iv = params[1].memref.buffer;
in = params[2].memref.buffer;
out = params[3].memref.buffer;
if (params[2].memref.size != params[3].memref.size) {
return TEE_ERROR_BAD_PARAMETERS;
} else {
len = params[2].memref.size;
}
ret = tee_aes_get_ctx_size(AES_CBC, (size_t *)&ctx_sz);
if (ret != TEE_CRYPTO_SUCCESS) {
return -1;
}
if (ctx_sz > AES_CONTEXT_SIZE) {
return -1;
}
memset(ctx, 0, ctx_sz);
uart_print_string("aes init");
ret = tee_aes_init(AES_CBC, enc, key, NULL, AES_BLOCK_SIZE, iv, ctx);
if (ret != TEE_CRYPTO_SUCCESS) {
return -1;
}
ret = tee_aes_process(in, out, len, ctx);
if (ret != TEE_CRYPTO_SUCCESS) {
return -1;
}
ret = tee_aes_finish(NULL, 0, NULL, NULL, SYM_NOPAD, ctx);
if (ret != TEE_CRYPTO_SUCCESS) {
return -1;
}
/* update iv */
if (enc) {
if (((len % AES_BLOCK_SIZE) == 0) && (len != 0)) {
memcpy(iv, &out[len - AES_BLOCK_SIZE], AES_BLOCK_SIZE);
}
} else {
if (((len % AES_BLOCK_SIZE) == 0) && (len != 0)) {
memcpy(iv, &in[len - AES_BLOCK_SIZE], AES_BLOCK_SIZE);
}
}
return ret;
}
TEE_SRV_DATA_START(_AES_Test_CreateEntryPoint,
_AES_Test_DestroyEntryPoint,
_AES_Test_OpenSessionEntryPoint,
_AES_Test_CloseSessionEntryPoint,
_AES_Test_InvokeCommandEntryPoint)
TEE_SRV_UUID_PROPERTY("gpd.ta.appID", AES_SRV_UUID)
TEE_SRV_BOOL_PROPERTY("gpd.ta.singleInstance", true)
TEE_SRV_BOOL_PROPERTY("gpd.ta.multiSession", true)
TEE_SRV_BOOL_PROPERTY("gpd.ta.instanceKeepAlive", true)
TEE_SRV_INT_PROPERTY("gpd.ta.dataSize", 0x10000)
TEE_SRV_INT_PROPERTY("gpd.ta.stackSize", 0x1000)
TEE_SRV_DATA_END

View file

@ -0,0 +1,20 @@
/*
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_ID2_H
#define _TEE_ID2_H
#include "tee_types.h"
#ifdef __cplusplus
extern "C" {
#endif
int tee_get_ID2(uint8_t *id2, uint32_t *len);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,57 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_ID2_CMD_H_
#define _TEE_ID2_CMD_H_
#include "tee_dbg.h"
#define TEE_ID2_GET_ID (0x0)
#define TEE_ID2_RSA_SIGN (0x1)
#define TEE_ID2_RSA_VERIFY (0x2)
#define TEE_ID2_RSA_PUBK_ENC (0x3)
#define TEE_ID2_RSA_PRVK_DEC (0x4)
#define TEE_ID2_CIPHER (0x5)
#define ID_LEN (24)
#define SIGN_LEN (128)
#define ID2_SRV_UUID { \
0x5445455f, 0x4944, 0x325f, \
{ 0x53, 0x52, 0x56, 0x5f, 0x55, 0x55, 0x49, 0x44 } \
}
#define ID2_DBG_E(_f, _a ...) tee_dbg_print(ERR, _f, ##_a)
#define ID2_DBG_I(_f, _a ...) tee_dbg_print(INF, _f, ##_a)
#define ID2_DBG_E_STRING(_str) uart_print_string(_str)
#define ID2_DBG_I_STRING(_str) uart_print_string(_str)
#define ID2_DBG_E_DATA(_data) \
do { \
uart_print_uint32(_data); \
uart_print_string("\n"); \
} while (0)
#define ID2_DBG_I_DATA(_data) \
do { \
uart_print_uint32(_data); \
uart_print_string("\n"); \
} while (0)
#define ID2_DBG_I_DUMP_DATA8(_data, _cnt) \
do { \
{ \
int __tmp__i = 0; \
for (__tmp__i = 0; __tmp__i < (int)(_cnt); __tmp__i++) { \
uart_print_uint8(_data[__tmp__i]); \
uart_print_string(" "); \
if (7 == (__tmp__i & 7)) { \
uart_print_string("\n"); \
} \
} \
uart_print_string("\n"); \
} \
} while (0)
#endif /* _TEE_ID2_CMD_H_ */

View file

@ -0,0 +1,48 @@
/*
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_RSA_H
#define _TEE_RSA_H
#include "tee_types.h"
// KEY TYPE
#define KEY_512 0
#define KEY_1024 1
#define KEY_2048 2
// SIGN TYPE
#define ID2_MD5 0
#define ID2_SHA1 1
#define ID2_SHA256 2
// PADDING TYPE
#define No_PADDING 0X00
#define PKCS1_PADDING 0X01 // default
// KEY ID, 3~10:reserved
#define KEY_ID_0 0 // ID2
#define KEY_ID_1 1 // Alipay Barcode
#define KEY_ID_2 2 // Alipay Passwordless
#ifdef __cplusplus
extern "C" {
#endif
int tee_RSA_generate_key(uint8_t ID, uint8_t type);
int tee_RSA_get_pub_key(uint8_t ID, uint8_t *pub, uint32_t *len);
int tee_RSA_sign(uint8_t ID, const uint8_t *in, uint32_t in_len,
uint8_t *sign, uint32_t *sign_len, uint8_t type);
int tee_RSA_verify(uint8_t ID, const uint8_t *in, uint32_t in_len,
uint8_t *sign, uint32_t sign_len, uint8_t type);
int tee_RSA_public_encrypt(uint8_t ID, const uint8_t *in, uint32_t in_len,
uint8_t *out, uint32_t *out_len, uint8_t padding);
int tee_RSA_private_decrypt(uint8_t ID, uint8_t *in, uint32_t in_len,
uint8_t *out, uint32_t *out_len, uint8_t padding);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,50 @@
/*
* Copyright (C) 2017 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_SYM_H_
#define _TEE_SYM_H_
#include "tee_types.h"
/* BLOCK MODE */
#define ID2_ECB 0x00
#define ID2_CBC 0x01
#define ID2_CTR 0x02
#define No_PADDING 0X00
#define ID2_PKCS5 0x02
#define ID2_PKCS7 0x03
#define ID2_AES 0x01
#define ID2_DES 0x02
#define ID2_3DES 0x03
/* IS ENC */
#define ID2_DECRYPT 0x00
#define ID2_ENCRYPT 0x01
#define KEY_ID_18 18 //3DES ID2 key
#define KEY_ID_33 33 //AES ID2 key
typedef struct _cipher_param_t {
uint8_t cipher_type;
uint8_t block_mode;
uint8_t padding_type;
uint8_t is_enc;
} cipher_param_t;
#ifdef __cplusplus
extern "C" {
#endif
int tee_sym_cipher(uint8_t ID, cipher_param_t *cipher_param,
const uint8_t *iv, uint32_t iv_len,
const uint8_t *in, uint32_t in_len,
uint8_t *out, uint32_t *out_len);
#ifdef __cplusplus
}
#endif
#endif /* _TEE_SYM_H_ */

View file

@ -0,0 +1,210 @@
/*
* Copyright (C) 2017 The YunOS Project. All rights reserved.
*/
#include "tee_client_api.h"
#include "tee_sym.h"
#include "tee_id2_cmd.h"
#define AES_BLOCK_LEN 16
#define DES_BLOCK_LEN 8
static const TEEC_UUID id2_uuid = ID2_SRV_UUID;
static int _get_pkcs_padding(unsigned char *input, size_t input_len,
uint32_t *data_len)
{
uint32_t i, pad_idx;
uint8_t padding_len, bad = 0;
if(NULL == input || NULL == data_len) {
return -1;
}
padding_len = input[input_len - 1];
*data_len = input_len - padding_len;
/* Avoid logical || since it results in a branch */
bad |= padding_len > input_len;
bad |= padding_len == 0;
/* The number of bytes checked must be independent of padding_len,
** so pick input_len, which is usually 8 or 16 (one block) */
pad_idx = input_len - padding_len;
for(i = 0; i < input_len; i++) {
bad |= (input[i] ^ padding_len) * (i >= pad_idx);
}
if (bad != 0) {
ID2_DBG_E("bad pkcs padding\n");
return -1;
}
return 0;
}
int tee_sym_cipher(uint8_t ID, cipher_param_t *cipher_param,
const uint8_t *iv, uint32_t iv_len,
const uint8_t *in, uint32_t in_len,
uint8_t *out, uint32_t *out_len)
{
TEEC_UUID tee_uuid;
TEEC_Result result;
TEEC_Session ss;
TEEC_Operation op;
TEEC_SharedMemory shm;
cipher_param_t sym_param;
uint32_t src_len = 0; //for padding
uint32_t dest_len = 0;
uint32_t block_len = 0;
uint32_t padding_data = 0;
int ret = 0;
uint32_t dec_len = 0;
if (in == NULL || in_len <= 0 || out_len == NULL ||
(out == NULL && *out_len != 0)) {
ID2_DBG_E("tee_sym_cipher: invalid input args!\n");
return -1;
}
if (ID == KEY_ID_18 || ID == KEY_ID_33) {
tee_uuid = id2_uuid;
} else {
ID2_DBG_E("tee_sym_cipher: not support this ID(%d)\n", ID);
return -1;
}
if (ID2_AES == cipher_param->cipher_type) {
block_len = AES_BLOCK_LEN;
} else if (ID2_3DES != cipher_param->cipher_type ||
ID2_DES != cipher_param->cipher_type) {
block_len = DES_BLOCK_LEN;
} else {
ID2_DBG_E("tee_sym_cipher: not support cipher type %d\n",
cipher_param->cipher_type);
return -1;
}
if (ID2_ECB == cipher_param->block_mode) {
iv_len = 0;
} else if (ID2_CBC == cipher_param->block_mode ||
ID2_CTR == cipher_param->block_mode) {
if (iv_len < block_len) {
ID2_DBG_E("tee_sym_cipher: bad iv\n");
return -1;
} else {
iv_len = block_len;
}
} else {
ID2_DBG_E("tee_sym_cipher: not support block mode %d\n",
cipher_param->block_mode);
return -1;
}
if (ID2_PKCS5 == cipher_param->padding_type ||
ID2_PKCS7 == cipher_param->padding_type) {
if (cipher_param->is_enc) {
padding_data = block_len - in_len % block_len;
src_len = in_len + padding_data;
dest_len = src_len;
if (*out_len < dest_len) {
ID2_DBG_E("tee_sym_cipher: aes enc short buffer %d : %d\n", *out_len, dest_len);
*out_len = dest_len;
return -1;
}
} else {
src_len = in_len;
dest_len = src_len;
}
} else if (No_PADDING == cipher_param->padding_type) {
src_len = in_len;
dest_len = src_len;
if (*out_len < dest_len) {
ID2_DBG_E("tee_sym_cipher: aes enc short buffer %d : %d\n", *out_len, dest_len);
*out_len = dest_len;
return -1;
}
} else {
ID2_DBG_E("tee_sym_cipher: not support block mode %d\n", cipher_param->block_mode);
return -1;
}
result = TEEC_OpenSession(&ss, &tee_uuid, NULL);
if (result != TEEC_SUCCESS) {
ID2_DBG_E("tee_sym_cipher: open ss err(%08x)\n", result);
ret = -1;
goto cleanup2;
}
memcpy(&sym_param, cipher_param, sizeof(cipher_param_t));
//iv | src | dest
shm.size = iv_len + src_len + dest_len;
shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
result = TEEC_AllocateSharedMemory(&shm);
if (TEEC_SUCCESS != result) {
ID2_DBG_E("tee_sym_cipher: alloc shm err(%08x)\n", result);
ret = -1;
goto cleanup3;
}
if (iv_len) {
memcpy(shm.buffer, (uint8_t *)iv, iv_len);
}
memcpy(shm.buffer + iv_len, (uint8_t *)in, in_len);
if (padding_data) {
memset(shm.buffer + iv_len + in_len, padding_data, padding_data);
}
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_MEMREF_TEMP_INPUT,
TEEC_MEMREF_PARTIAL_INPUT,
TEEC_MEMREF_PARTIAL_OUTPUT,
TEEC_NONE);
op.params[0].tmpref.buffer = (uint8_t *)(&sym_param);
op.params[0].tmpref.size = sizeof(cipher_param_t);
op.params[1].memref.parent = &shm;
op.params[1].memref.offset = 0;
op.params[1].memref.size = iv_len + src_len;
op.params[2].memref.parent = &shm;
op.params[2].memref.offset = iv_len + src_len;
op.params[2].memref.size = dest_len;
result = TEEC_InvokeCommand(&ss, TEE_ID2_CIPHER, &op);
if (result != TEEC_SUCCESS) {
ID2_DBG_E("tee_sym_cipher: inv cmd err(%08x)\n", result);
ret = -1;
goto cleanup4;
}
//for ecb cbc decrypt
if (!cipher_param->is_enc &&
(ID2_PKCS5 == cipher_param->padding_type ||
ID2_PKCS7 == cipher_param->padding_type)) {
if (_get_pkcs_padding((uint8_t *)shm.buffer + iv_len + src_len, dest_len, &dec_len)) {
ID2_DBG_E("tee_sym_cipher: dec wrong pkcs padding\n");
ret = -1;
goto cleanup4;
} else {
if (*out_len < dec_len) {
ID2_DBG_E("tee_sym_cipher: short buffer %d : %d\n", *out_len, dec_len);
*out_len = dec_len;
ret = -1;
goto cleanup4;
}
*out_len = dec_len;
}
} else {
*out_len = op.params[2].memref.size;
}
memcpy(out, (uint8_t *)shm.buffer + src_len + iv_len, *out_len);
cleanup4:
TEEC_ReleaseSharedMemory(&shm);
cleanup3:
TEEC_CloseSession(&ss);
cleanup2:
return ret;
}

View file

@ -0,0 +1,55 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#include "tee_client_api.h"
#include "tee_id2.h"
#include "tee_id2_cmd.h"
static const TEEC_UUID tee_id2_uuid = ID2_SRV_UUID;
int tee_get_ID2(uint8_t *id2, uint32_t *len)
{
int ret = 0;
TEEC_Result result;
TEEC_Session ss;
TEEC_Operation op;
TEE_ASSERT(id2 || len);
if (id2 == NULL) {
*len = ID_LEN;
return 0;
}
result = TEEC_OpenSession(&ss, &tee_id2_uuid, NULL);
if (result != TEEC_SUCCESS) {
ID2_DBG_E("tee_get_ID2: open ss err(%08x)\n", result);
ret = -1;
goto cleanup2;
}
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_MEMREF_TEMP_OUTPUT,
TEEC_NONE,
TEEC_NONE,
TEEC_NONE);
op.params[0].tmpref.buffer = id2;
op.params[0].tmpref.size = ID_LEN;
result = TEEC_InvokeCommand(&ss, TEE_ID2_GET_ID, &op);
if (result != TEEC_SUCCESS) {
ID2_DBG_E("tee_get_ID2: inv cmd err(%08x)\n", result);
ret = -1;
goto cleanup3;
}
if (len) {
*len = ID_LEN;
}
cleanup3:
TEEC_CloseSession(&ss);
cleanup2:
return ret;
}

View file

@ -0,0 +1,324 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#include "tee_client_api.h"
#include "tee_rsa.h"
#include "tee_id2_cmd.h"
static const TEEC_UUID id2_uuid = ID2_SRV_UUID;
int tee_RSA_generate_key(uint8_t ID, uint8_t type)
{
ID2_DBG_I("tee_RSA_generate_key: not support!\n");
return -1;
}
int tee_RSA_get_pub_key(uint8_t ID, uint8_t *pub, uint32_t *in_len)
{
ID2_DBG_I("tee_RSA_get_pub_key: not support!\n");
return -1;
}
int tee_RSA_sign(uint8_t ID, const uint8_t *in, uint32_t in_len,
uint8_t *sign, uint32_t *sign_len, uint8_t type)
{
int ret = 0;
TEEC_UUID tee_uuid;
TEEC_Result result;
TEEC_Session ss;
TEEC_Operation op;
TEEC_SharedMemory shm;
if (in == NULL || in_len <= 0 ||
sign == NULL || sign_len == NULL) {
ID2_DBG_E("tee_RSA_sign: invalid input args!\n");
return -1;
}
if (ID == KEY_ID_0) {
tee_uuid = id2_uuid;
} else {
ID2_DBG_E("tee_RSA_sign: not support this ID(%d)\n", ID);
return -1;
}
if (*sign_len < SIGN_LEN) {
ID2_DBG_E("tee_RSA_sign: short buffer!\n");
*sign_len = SIGN_LEN;
return -1;
}
result = TEEC_OpenSession(&ss, &tee_uuid, NULL);
if (result != TEEC_SUCCESS) {
ID2_DBG_E("tee_RSA_sign: open ss err(%08x)\n", result);
ret = -1;
goto cleanup2;
}
shm.size = in_len + *sign_len;
shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
result = TEEC_AllocateSharedMemory(&shm);
if (TEEC_SUCCESS != result) {
ID2_DBG_E("tee_RSA_sign: alloc shm err(%08x)\n", result);
ret = -1;
goto cleanup3;
}
memcpy(shm.buffer, (uint8_t *)in, in_len);
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_VALUE_INPUT,
TEEC_MEMREF_PARTIAL_INPUT,
TEEC_MEMREF_PARTIAL_OUTPUT,
TEEC_NONE);
op.params[0].value.a = type;
op.params[1].memref.parent = &shm;
op.params[1].memref.offset = 0;
op.params[1].memref.size = in_len;
op.params[2].memref.parent = &shm;
op.params[2].memref.offset = in_len;
op.params[2].memref.size = *sign_len;
result = TEEC_InvokeCommand(&ss, TEE_ID2_RSA_SIGN, &op);
if (result != TEEC_SUCCESS) {
ID2_DBG_E("tee_RSA_sign: inv cmd err(%08x)\n", result);
ret = -1;
goto cleanup4;
}
*sign_len = op.params[2].memref.size;
memcpy(sign, (uint8_t *)shm.buffer + in_len, *sign_len);
cleanup4:
TEEC_ReleaseSharedMemory(&shm);
cleanup3:
TEEC_CloseSession(&ss);
cleanup2:
return ret;
}
int tee_RSA_verify(uint8_t ID, const uint8_t *in, uint32_t in_len,
uint8_t *sign, uint32_t sign_len, uint8_t type)
{
int ret = 0;
TEEC_UUID tee_uuid;
TEEC_Result result;
TEEC_Session ss;
TEEC_Operation op;
TEEC_SharedMemory shm;
if (in == NULL || in_len <= 0 ||
sign == NULL || sign_len <= 0) {
ID2_DBG_E("tee_RSA_verify: invalid input args!\n");
return -1;
}
if (ID == KEY_ID_0) {
tee_uuid = id2_uuid;
} else {
ID2_DBG_E("tee_RSA_verify: not support this ID(%d)\n", ID);
return -1;
}
result = TEEC_OpenSession(&ss, &tee_uuid, NULL);
if (result != TEEC_SUCCESS) {
ID2_DBG_E("tee_RSA_verify: open ss err(%08x)\n", result);
ret = -1;
goto cleanup2;
}
shm.size = in_len + sign_len;
shm.flags = TEEC_MEM_INPUT;
result = TEEC_AllocateSharedMemory(&shm);
if (TEEC_SUCCESS != result) {
ID2_DBG_E("tee_rsa_sign: alloc shm err(%08x)\n", result);
ret = -1;
goto cleanup3;
}
memcpy(shm.buffer, (uint8_t *)in, in_len);
memcpy((uint8_t *)shm.buffer + in_len, sign, sign_len);
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_VALUE_INPUT,
TEEC_MEMREF_PARTIAL_INPUT,
TEEC_MEMREF_PARTIAL_INPUT,
TEEC_NONE);
op.params[0].value.a = type;
op.params[1].memref.parent = &shm;
op.params[1].memref.offset = 0;
op.params[1].memref.size = in_len;
op.params[2].memref.parent = &shm;
op.params[2].memref.offset = in_len;
op.params[2].memref.size = sign_len;
result = TEEC_InvokeCommand(&ss, TEE_ID2_RSA_VERIFY, &op);
if (result != TEEC_SUCCESS) {
ID2_DBG_E("tee_RSA_verify: inv cmd err(%08x)\n", result);
ret = -1;
goto cleanup4;
}
cleanup4:
TEEC_ReleaseSharedMemory(&shm);
cleanup3:
TEEC_CloseSession(&ss);
cleanup2:
return ret;
}
int tee_RSA_public_encrypt(uint8_t ID, const uint8_t *in, uint32_t in_len,
uint8_t *out, uint32_t *out_len, uint8_t padding)
{
int ret = 0;
TEEC_UUID tee_uuid;
TEEC_Result result;
TEEC_Session ss;
TEEC_Operation op;
TEEC_SharedMemory shm;
if (in == NULL || in_len <= 0 ||
out == NULL || out_len == NULL) {
ID2_DBG_E("tee_RSA_public_encrypt: invalid input args!\n");
return -1;
}
if (ID == KEY_ID_0) {
tee_uuid = id2_uuid;
} else {
ID2_DBG_E("tee_RSA_public_encrypt: not support this ID(%d)\n", ID);
return -1;
}
if (*out_len < SIGN_LEN) {
*out_len = SIGN_LEN;
ID2_DBG_E("tee_rsa_public_encrypt: short buffer!\n");
return -1;
}
result = TEEC_OpenSession(&ss, &tee_uuid, NULL);
if (result != TEEC_SUCCESS) {
ID2_DBG_E("tee_rsa_public_encrypt: open ss err(%08x)\n", result);
ret = -1;
goto cleanup2;
}
shm.size = in_len + *out_len;
shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
result = TEEC_AllocateSharedMemory(&shm);
if (TEEC_SUCCESS != result) {
ID2_DBG_E("tee_rsa_public_encrypt: alloc shm err(%08x)\n", result);
ret = -1;
goto cleanup3;
}
memcpy(shm.buffer, (uint8_t *)in, in_len);
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_VALUE_INPUT,
TEEC_MEMREF_PARTIAL_INPUT,
TEEC_MEMREF_PARTIAL_OUTPUT,
TEEC_NONE);
op.params[0].value.a = padding;
op.params[1].memref.parent = &shm;
op.params[1].memref.offset = 0;
op.params[1].memref.size = in_len;
op.params[2].memref.parent = &shm;
op.params[2].memref.offset = in_len;
op.params[2].memref.size = *out_len;
result = TEEC_InvokeCommand(&ss, TEE_ID2_RSA_PUBK_ENC, &op);
if (result != TEEC_SUCCESS) {
ID2_DBG_E("tee_rsa_public_encrypt: inv cmd err(%08x)\n", result);
ret = -1;
goto cleanup4;
}
*out_len = op.params[2].memref.size;
memcpy(out, (uint8_t *)shm.buffer + in_len, *out_len);
cleanup4:
TEEC_ReleaseSharedMemory(&shm);
cleanup3:
TEEC_CloseSession(&ss);
cleanup2:
return ret;
}
int tee_RSA_private_decrypt(uint8_t ID, uint8_t *in, uint32_t in_len,
uint8_t *out, uint32_t *out_len, uint8_t padding)
{
int ret = 0;
TEEC_UUID tee_uuid;
TEEC_Result result;
TEEC_Session ss;
TEEC_Operation op;
TEEC_SharedMemory shm;
if (in == NULL || in_len <= 0 ||
out == NULL || out_len == NULL) {
ID2_DBG_E("tee_RSA_private_decrypt: invalid input args!\n");
return -1;
}
if (ID == KEY_ID_0) {
tee_uuid = id2_uuid;
} else {
ID2_DBG_E("tee_RSA_private_decrypt: not support this ID(%d)\n", ID);
return -1;
}
result = TEEC_OpenSession(&ss, &tee_uuid, NULL);
if (result != TEEC_SUCCESS) {
ID2_DBG_E("tee_RSA_private_decrypt: open ss err(%08x)\n", result);
ret = -1;
goto cleanup2;
}
shm.size = in_len + *out_len;
shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
result = TEEC_AllocateSharedMemory(&shm);
if (TEEC_SUCCESS != result) {
ID2_DBG_E("tee_RSA_private_decrypt: alloc shm err(%08x)\n", result);
ret = -1;
goto cleanup3;
}
memcpy(shm.buffer, in, in_len);
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_VALUE_INPUT,
TEEC_MEMREF_PARTIAL_INPUT,
TEEC_MEMREF_PARTIAL_OUTPUT,
TEEC_NONE);
op.params[0].value.a = padding;
op.params[1].memref.parent = &shm;
op.params[1].memref.offset = 0;
op.params[1].memref.size = in_len;
op.params[2].memref.parent = &shm;
op.params[2].memref.offset = in_len;
op.params[2].memref.size = *out_len;
result = TEEC_InvokeCommand(&ss, TEE_ID2_RSA_PRVK_DEC, &op);
if (result != TEEC_SUCCESS) {
ID2_DBG_E("tee_RSA_private_decrypt: inv cmd err(%08x)\n", result);
ret = -1;
goto cleanup4;
}
*out_len = op.params[2].memref.size;
memcpy(out, (uint8_t *)shm.buffer + in_len, *out_len);
cleanup4:
TEEC_ReleaseSharedMemory(&shm);
cleanup3:
TEEC_CloseSession(&ss);
cleanup2:
return ret;
}

View file

@ -0,0 +1 @@
built-in.rel.o

View file

@ -0,0 +1,18 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef TEE_RANDOM_H
#define TEE_RANDOM_H
#ifdef __cplusplus
extern "C" {
#endif
int tee_random_generate(uint8_t *buf, size_t len);
int tee_random_seed(uint32_t seed);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,16 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef TEE_RANDOM_CMD_H
#define TEE_RANDOM_CMD_H
#define TEE_RANDOM_SEED_SET (0x0)
#define TEE_RANDOM_DATA_GET (0x1)
#define RANDOM_SRV_UUID { \
0x5b174c2e, 0x1b37, 0x11e7, \
{ 0xb2, 0x7b, 0x00, 0x0c, 0x29, 0x7c, 0x3b, 0x37 } \
}
#endif

View file

@ -0,0 +1,80 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#include "tee_client_api.h"
#include "tee_dbg.h"
#include "tee_random_cmd.h"
static const TEEC_UUID tee_random_uuid = RANDOM_SRV_UUID;
int tee_random_seed(uint32_t seed)
{
TEEC_Session ss;
TEEC_Operation op;
TEEC_Result ret = TEEC_SUCCESS;
ret = TEEC_OpenSession(&ss, &tee_random_uuid, NULL);
if (ret != TEEC_SUCCESS) {
tee_dbg_print(ERR, "fail(%08x) to open ss\n", ret);
goto cleanup2;
}
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_NONE,
TEEC_NONE,
TEEC_NONE);
if (seed == 0) {
op.params[0].value.a = 0x1ab48fd5;
op.params[0].value.b = 0xbe836b2a;
} else {
op.params[0].value.a = seed * 0x1ab48fd5;
op.params[0].value.b = seed * 0xbe836b2a;
}
ret = TEEC_InvokeCommand(&ss, TEE_RANDOM_SEED_SET, &op);
if (ret != TEEC_SUCCESS) {
tee_dbg_print(ERR, "fail(%08x) to inv cmd(%d)\n", ret, TEE_RANDOM_SEED_SET);
goto cleanup3;
} else {
tee_dbg_print(INF, "tee random seed success\n");
}
cleanup3:
TEEC_CloseSession(&ss);
cleanup2:
return ret;
}
int tee_random_generate(uint8_t *buf, size_t len)
{
TEEC_Session ss;
TEEC_Operation op;
TEEC_Result ret = TEEC_SUCCESS;
ret = TEEC_OpenSession(&ss, &tee_random_uuid, NULL);
if (ret != TEEC_SUCCESS) {
tee_dbg_print(ERR, "fail(%08x) to open ss\n", ret);
goto cleanup2;
}
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT,
TEEC_NONE,
TEEC_NONE,
TEEC_NONE);
op.params[0].tmpref.buffer = buf;
op.params[0].tmpref.size = len;
ret = TEEC_InvokeCommand(&ss, TEE_RANDOM_DATA_GET, &op);
if (ret != TEEC_SUCCESS) {
tee_dbg_print(ERR, "fail(%08x) to inv cmd(%d)\n", ret, TEE_RANDOM_DATA_GET);
goto cleanup3;
} else {
tee_dbg_print(INF, "tee random generate success\n");
}
cleanup3:
TEEC_CloseSession(&ss);
cleanup2:
return ret;
}

View file

@ -0,0 +1,23 @@
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
TOP := $(PWD)/../../../../src/tw
CURRENT_BUILD := TW
include $(TOP)/tee.cfg
include $(TOP)/Make.rules
CFLAGS += -I../inc/ -I./ -I../ntw/include
SRCS := $(wildcard *.c *.cxx)
OBJS := $(patsubst %.cxx,%.o,$(patsubst %.c,%.o,$(SRCS)))
.PHONY: all clean
all: built-in.o
built-in.o: $(OBJS)
$(LD) -r $^ -o $@
clean:
rm -f *.o built-in.*

View file

@ -0,0 +1,100 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#include "tee_srv.h"
#include "tee_types.h"
#include "tee_dbg.h"
#include "tee_tos.h"
#include "tee_crypto.h"
#include "tee_random_cmd.h"
#include "tee_random.h"
static TEE_Result _RANDOM_Test_CreateEntryPoint(void)
{
return TEE_SUCCESS;
}
static void _RANDOM_Test_DestroyEntryPoint(void)
{
return;
}
static TEE_Result _RANDOM_Test_OpenSessionEntryPoint(
uint32_t paramTypes,
TEE_Param params[4],
void **sessionContext)
{
return TEE_SUCCESS;
}
static void _RANDOM_Test_CloseSessionEntryPoint(void *sessionContext)
{
return;
}
static TEE_Result _RANDOM_Test_InvokeCommandEntryPoint(
void *sessionContext,
uint32_t commandID,
uint32_t paramTypes,
TEE_Param params[4])
{
TEE_Result ret = TEE_SUCCESS;
uint8_t *data;
uint32_t len;
if (commandID == TEE_RANDOM_SEED_SET) {
if (paramTypes != TEE_PARAM_TYPES(
TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE)) {
return TEE_ERROR_BAD_PARAMETERS;
}
ret = TEE_SUCCESS;
} else if (commandID == TEE_RANDOM_DATA_GET){
if (paramTypes != TEE_PARAM_TYPES(
TEE_PARAM_TYPE_MEMREF_OUTPUT,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE)) {
return TEE_ERROR_BAD_PARAMETERS;
}
data = params[0].memref.buffer;
len = params[0].memref.size;
if (tee_rand_gen(data, len) != TEE_CRYPTO_SUCCESS) {
ret = TEE_CRYPTO_ERROR;
} else {
ret = TEE_SUCCESS;
}
{
int i;
if (ret == TEE_SUCCESS) {
for (i = 0; i < len; i++) {
tee_dbg_print(INF, "%x ", data[i]);
}
}
}
} else {
ret = TEE_ERROR_BAD_PARAMETERS;
}
return ret;
}
TEE_SRV_DATA_START(_RANDOM_Test_CreateEntryPoint,
_RANDOM_Test_DestroyEntryPoint,
_RANDOM_Test_OpenSessionEntryPoint,
_RANDOM_Test_CloseSessionEntryPoint,
_RANDOM_Test_InvokeCommandEntryPoint)
TEE_SRV_UUID_PROPERTY("gpd.ta.appID", RANDOM_SRV_UUID)
TEE_SRV_BOOL_PROPERTY("gpd.ta.singleInstance", true)
TEE_SRV_BOOL_PROPERTY("gpd.ta.multiSession", true)
TEE_SRV_BOOL_PROPERTY("gpd.ta.instanceKeepAlive", true)
TEE_SRV_INT_PROPERTY("gpd.ta.dataSize", 0x10000)
TEE_SRV_INT_PROPERTY("gpd.ta.stackSize", 0x1000)
TEE_SRV_DATA_END

View file

@ -0,0 +1,32 @@
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
TW_TOP := ../tw
CURRENT_BUILD := NTW
include $(TW_TOP)/tee.cfg
include $(TW_TOP)/Make.rules
CFLAGS += -I./inc -I./osa/inc
SRCS := $(wildcard ./osa/*.c) $(wildcard ./*.c)
OBJS := $(patsubst %.c,%.ntw.o,$(patsubst %.S,%.ntw.o,$(SRCS)))
DRV := tee_drv.o
DEP_OBJS := ./drv/drv.sdk.o ./lpm/ntw.lpmapi.o
ifeq ($(CONFIG_TST_STUB), Y)
DEP_OBJS += ./stub/tst_stub/tststub.o
endif
.PHONY: all clean
all: $(OBJS) $(DRV)
$(DRV): $(OBJS)
$(NOECHO)$(LD) -r -o $(DRV) $(OBJS) $(DEP_OBJS)
@echo "Finish building $@..."
clean:
@echo "Cleaning up ..."
$(NOECHO)rm -f $(OBJS) $(DRV)

View file

@ -0,0 +1 @@
drv.sdk.rel.o

View file

@ -0,0 +1,214 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_CLIENT_API_H_
#define _TEE_CLIENT_API_H_
#include "tee_types.h"
/*
* Constants
*/
#define TEEC_CONFIG_SHAREDMEM_MAX_SIZE (0x000A000) /* 40k */
/*
* API Error Codes
*/
#define TEEC_SUCCESS (0x00000000)
#define TEEC_ERROR_GENERIC (0xFFFF0000)
#define TEEC_ERROR_ACCESS_DENIED (0xFFFF0001)
#define TEEC_ERROR_CANCEL (0xFFFF0002)
#define TEEC_ERROR_ACCESS_CONFLICT (0xFFFF0003)
#define TEEC_ERROR_EXCESS_DATA (0xFFFF0004)
#define TEEC_ERROR_BAD_FORMAT (0xFFFF0005)
#define TEEC_ERROR_BAD_PARAMETERS (0xFFFF0006)
#define TEEC_ERROR_BAD_STATE (0xFFFF0007)
#define TEEC_ERROR_ITEM_NOT_FOUND (0xFFFF0008)
#define TEEC_ERROR_NOT_IMPLEMENTED (0xFFFF0009)
#define TEEC_ERROR_NOT_SUPPORTED (0xFFFF000A)
#define TEEC_ERROR_NO_DATA (0xFFFF000B)
#define TEEC_ERROR_OUT_OF_MEMORY (0xFFFF000C)
#define TEEC_ERROR_BUSY (0xFFFF000D)
#define TEEC_ERROR_COMMUNICATION (0xFFFF000E)
#define TEEC_ERROR_SECURITY (0xFFFF000F)
#define TEEC_ERROR_SHORT_BUFFER (0xFFFF0010)
#define TEEC_ERROR_TARGET_DEAD (0xFFFF3024)
/*
* Return Code for returnOrigins
*/
#define TEEC_ORIGIN_API (0x00000001)
#define TEEC_ORIGIN_COMMS (0x00000002)
#define TEEC_ORIGIN_TEE (0x00000003)
#define TEEC_ORIGIN_TRUSTED_APP (0x00000004)
/*
* Parameter Types
*/
#define TEEC_NONE (0x00000000)
#define TEEC_VALUE_INPUT (0x00000001)
#define TEEC_VALUE_OUTPUT (0x00000002)
#define TEEC_VALUE_INOUT (0x00000003)
#define TEEC_MEMREF_TEMP_INPUT (0x00000005)
#define TEEC_MEMREF_TEMP_OUTPUT (0x00000006)
#define TEEC_MEMREF_TEMP_INOUT (0x00000007)
#define TEEC_MEMREF_WHOLE (0x0000000C)
#define TEEC_MEMREF_PARTIAL_INPUT (0x0000000D)
#define TEEC_MEMREF_PARTIAL_OUTPUT (0x0000000E)
#define TEEC_MEMREF_PARTIAL_INOUT (0x0000000F)
/*
* Session Login Methods
*/
#if 0
#define TEEC_LOGIN_PUBLIC (0x00000000)
#define TEEC_LOGIN_USER (0x00000001)
#define TEEC_LOGIN_GROUP (0x00000002)
#define TEEC_LOGIN_APPLICATION (0x00000004)
#define TEEC_LOGIN_USER_APPLICATION (0x00000005)
#define TEEC_LOGIN_GROUP_APPLICATION (0x00000006)
#endif
#define TEEC_PARAM_TYPES(t0, t1, t2, t3) \
((t0) | ((t1) << 4) | ((t2) << 8) | ((t3) << 12))
/*
* Shared Memory Control Flags
*/
#define TEEC_MEM_INPUT (0x00000001)
#define TEEC_MEM_OUTPUT (0x00000002)
typedef uint32_t TEEC_Result;
typedef void *TEEC_Context_Handle;
typedef void *TEEC_Session_Handle;
typedef void *TEEC_Operation_Handle;
typedef void *TEEC_SharedMemory_Handle;
typedef struct {
uint32_t timeLow;
uint16_t timeMid;
uint16_t timeHiAndVersion;
uint8_t clockSeqAndNode[8];
} TEEC_UUID;
typedef struct {
TEEC_Context_Handle imp;
} TEEC_Context;
typedef struct {
TEEC_Session_Handle imp;
} TEEC_Session;
typedef struct {
void *buffer;
size_t size;
uint32_t flags;
TEEC_SharedMemory_Handle imp;
} TEEC_SharedMemory;
typedef struct {
void *buffer;
size_t size;
} TEEC_TempMemoryReference;
typedef struct {
TEEC_SharedMemory *parent;
size_t size;
size_t offset;
} TEEC_RegisteredMemoryReference;
typedef struct {
uint32_t a;
uint32_t b;
} TEEC_Value;
typedef union {
TEEC_TempMemoryReference tmpref;
TEEC_RegisteredMemoryReference memref;
TEEC_Value value;
} TEEC_Parameter;
typedef struct {
uint32_t started;
uint32_t paramTypes;
TEEC_Parameter params[4];
TEEC_Operation_Handle imp;
} TEEC_Operation;
//FIXME, fake api to init/de-init osa and comm
#if 1
int TEEC_Init(void);
#endif
/**
* Register a block of existing memory as a shared block
* within the scope of the specified context.
*
* @context[in] poniter to an initialized TEE context.
* @sharedMem[out] pointer to the shared memory structure to register.
*/
TEEC_Result TEEC_RegisterSharedMemory(TEEC_SharedMemory *sharedMem);
/**
* Allocate shared memory for TEE.
*
* @context[in] poniter to an initialized TEE context.
* @sharedMem[out] Pointer to the allocated shared memory.
*/
TEEC_Result TEEC_AllocateSharedMemory(TEEC_SharedMemory *sharedMem);
/**
* Deregister or deallocate a previously initialized block of shared memory.
*
* @sharedMem[in] Pointer to the shared memory to be or deregistered or dealloacted.
*/
void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *sharedMem);
/**
* Open a new session with the specified trusted application.
*
* @context[in] Pointer to an initialized TEE context.
* @session[out] Pointer to a session structure to open.
* @destination[in] Pointer to the UUID of the destination trust application
* @connectionMethod[in] The connection method to use.
* @connectionData[in] Any necessary data required to support the connection method chosen.
* @operation[in] An operation structure to use in the session. May be set to NULL to
* signify no operation structure needed.
* @returnOrigin[out] Pointer to a variable which will contain the return origin.
* This field may be NULL if the return origin is not needed.
*/
TEEC_Result TEEC_OpenSession(
TEEC_Session *session,
const TEEC_UUID *destination,
TEEC_Operation *operation);
/**
* Close s session which has been opened with a trusted application.
*
* @session[in] The opened session to close.
*/
void TEEC_CloseSession(TEEC_Session *session);
/**
* Execute a command in the specified trusted application.
*
* @session[in] The open Session in which the command will be invoked.
* @commandID[in] Identifier of the command in the trusted application to invoke.
* @operation[in/out] An operation structure to use in the invoke command.
* May be set to NULL to signify no operation structure needed.
* @returnOrigin[out] A pointer to a variable which will contain the return origin.
* This field may be NULL if the return origin is not needed.
*/
TEEC_Result TEEC_InvokeCommand(TEEC_Session *session,
uint32_t commandID,
TEEC_Operation *operation);
/**
* Execute a cancel request in the specified trusted application.
*/
#if 0
void TEEC_RequestCancellation(TEEC_Operation *operation);
#endif
#endif /* _TEE_CLIENT_API_H_ */

View file

@ -0,0 +1,32 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_DBG_H_
#define _TEE_DBG_H_
#include "tee_types.h"
#include "tee_os_dep.h"
enum {
ERR = 0, /* error */
WRN = 1, /* warning */
INF = 2, /* information */
};
#define tee_dbg_print(_l, _f, _a ...) \
do { \
printk((const int8_t *)_f, ##_a); \
} while (0)
#define TEE_ASSERT(_x) \
do { \
if (!(_x)) { \
tee_dbg_print(ERR, (const int8_t *)"ASSERT FAILURE:\n"); \
tee_dbg_print(ERR, (const int8_t *)"%s (%d): %s\n", \
__FILE__, __LINE__, __FUNCTION__); \
while (1) /* loop */; \
} \
} while (0)
#endif /* _TEE_DBG_H_ */

View file

@ -0,0 +1,45 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_OS_DEP_H_
#define _TEE_OS_DEP_H_
#include "tee_types.h"
/* printk */
extern int printk(const char *fmt, ...);
/* malloc/free */
#define GFP_KERNEL 0
extern void *kmalloc(size_t size, int flags);
extern void kfree(const void *ptr);
#define malloc(sz) kmalloc(sz, GFP_KERNEL)
#define free(ptr) kfree(ptr)
/* string */
extern void *memcpy(void *dest, const void *src, size_t n);
extern void *memset(void *s, int32_t c, size_t n);
extern int32_t memcmp(const void *s1, const void *s2, size_t n);
extern size_t strlen(const int8_t *s);
extern int8_t *strcpy(int8_t *dest, const int8_t *src);
extern int32_t strncmp(const int8_t *s1, const int8_t *s2, size_t n);
extern char *strncpy(int8_t *dest, const int8_t *src, size_t count);
extern void backtrace(void);
#if 0
/* semaphore */
struct semaphore {
int32_t rsvd;
};
#define HZ 10000
#define MSEC_TO_JIFFIES(msec) (((msec) * HZ + 500) / 1000)
extern void sema_init(struct semaphore *sem, int val);
extern void down(struct semaphore *sem);
extern int down_trylock(struct semaphore *sem);
extern int down_timeout(struct semaphore *sem, long jiffies);
extern int down_interruptible(struct semaphore *sem);
extern void up(struct semaphore *sem);
#endif
#endif /* _TEE_OS_DEP_H_ */

View file

@ -0,0 +1,54 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_TYPES_H_
#define _TEE_TYPES_H_
#ifndef __STDINT__
#define __STDINT__
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
typedef signed long int ssize_t;
typedef unsigned long size_t;
typedef long long_t;
typedef unsigned long ulong_t;
#endif /* __STDINT__ */
#ifndef __STDBOOL__
#define __STDBOOL__
typedef unsigned char bool;
#endif /* __STDBOOL__ */
typedef uint32_t tee_stat_t;
#define INLINE
#ifndef false
#define false (0)
#endif
#ifndef true
#define true (1)
#endif
#ifndef NULL
#define NULL ((void *)0)
#endif
#endif /* _TEE_TYPES_H_ */

View file

@ -0,0 +1,18 @@
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
*/
#ifndef _TEEC_LPM_API_H_
#define _TEEC_LPM_API_H_
#include "tee_types.h"
/**
* switch to security to handle lpm.
*
* @arg[in] the arg.
* return 0 means seccess.
*/
uint32_t TEEC_lpm_to_security(void *arg);
#endif /* _TEEC_LPM_API_H_ */

View file

@ -0,0 +1 @@
ntw.lpmapi.rel.o

View file

@ -0,0 +1,35 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#include <stdarg.h>
#include "tee_types.h"
extern int printf(char *fmt, ...);
extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
extern void *malloc (unsigned int size);
extern void free (void *mem);
#define PRINTK_BUF_SZ (128)
int32_t printk(const int8_t *fmt, ...)
{
va_list args;
int8_t buf[PRINTK_BUF_SZ];
va_start(args, fmt);
vsnprintf(buf, sizeof(buf) - 1, fmt, args);
va_end(args);
buf[PRINTK_BUF_SZ - 1] = '\0';
printf("%s", buf);
return 0;
}
void *kmalloc(size_t size, int flags)
{
return malloc(size);
}
void kfree(const void *ptr)
{
return free((void *)ptr);
}

View file

@ -0,0 +1,224 @@
#
# Copyright (C) 2015-2016 The YunOS Project. All rights reserved.
#
# TW tee/app make rules. Don't modify!!!
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump
NM := $(CROSS_COMPILE)nm
AR := $(CROSS_COMPILE)ar
RANLIB := $(CROSS_PATH)ranlib
SIZE := $(CROSS_PATH)size
MAKE := make
######################
## platform special config
######################
ifeq ($(ARCH), c_sky)
CFLAGS := -mcpu=ck802t -g3 -Wall -c -Wa,-melrw -fno-builtin
ASFLAGS := -mcpu=ck802t -Wa,--gdwarf2 -Wa,-melrw -D__ASSEMBLY__
LDFLAGS := -mcpu=ck802t -nostartfiles -Wl,--gc-sections -fno-builtin
ifeq ($(BACKTRACE), Y)
CFLAGS += -mbacktrace
endif
endif
######################
## ID2 config ##
######################
ifeq ($(ID2_KEY_TYPE), RSA)
CFLAGS += -DCONFIG_ID2_RSA_KEY=1
else ifeq ($(ID2_KEY_TYPE), AES)
CFLAGS += -DCONFIG_ID2_AES_KEY=1
endif
######################
## crypto config ##
######################
ifeq ($(AES_SUPPORT), Y)
CFLAGS += -DAES_SUPPORT=1
ASFLAGS += -DAES_SUPPORT=1
endif
ifeq ($(RSA_SUPPORT), Y)
CFLAGS += -DRSA_SUPPORT=1
ASFLAGS += -DRSA_SUPPORT=1
endif
ifeq ($(SHA_SUPPORT), Y)
CFLAGS += -DSHA_SUPPORT=1
ASFLAGS += -DSHA_SUPPORT=1
endif
ifeq ($(RAND_SUPPORT), Y)
CFLAGS += -DRAND_SUPPORT=1
ASFLAGS += -DRAND_SUPPORT=1
endif
ifeq ($(TRNG_SUPPORT), Y)
CFLAGS += -DTRNG_SUPPORT=1
ASFLAGS += -DTRNG_SUPPORT=1
endif
ifeq ($(CONFIG_API_CB_MEM),Y)
CFLAGS += -DCONFIG_API_CB_MEM=1
ASFLAGS += -DCONFIG_API_CB_MEM=1
endif
ifeq ($(CONFIG_API_CB_FILE), Y)
CFLAGS += -DCONFIG_API_CB_FILE=1
ASFLAGS += -DCONFIG_API_CB_FILE=1
endif
ifeq ($(CONFIG_API_TST), Y)
CFLAGS += -DCONFIG_API_TST=1
ASFLAGS += -DCONFIG_API_TST=1
endif
ifeq ($(CONFIG_TST_STUB), Y)
CFLAGS += -DCONFIG_TST_STUB=1
ASFLAGS += -DCONFIG_TST_STUB=1
endif
######################
## PLATFORM ##
######################
CFLAGS += -DPLATFORM_$(PLATFORM)
ASFLAGS += -DPLATFORM_$(PLATFORM)
ifeq ($(TEST), Y)
CFLAGS += -DCONFIG_TEST=1
ASFLAGS += -DCONFIG_TEST=1
GEN_LDS_FLAGS += -DCONFIG_TEST=1
endif
######################
# TW CONFIG
######################
ifeq ($(CURRENT_BUILD), TW)
CFLAGS += -DCONFIG_TW
ASFLAGS += -DCONFIG_TW
# common include dir
CFLAGS += -I$(TOP)/inc -I$(TOP)/hw -I$(TOP)/drv/inc \
-I$(TOP)/../common/inc -I$(TOP)/crypto/inc \
-I$(TOP)/hw -I$(TOP)/platform/$(PLATFORM)/inc
ASFLAGS += -I$(TOP)/inc -I$(TOP)/hw -I$(TOP)/drv/inc \
-I$(TOP)/../common/inc -I$(TOP)/crypto/inc \
-I$(TOP)/hw -I$(TOP)/platform/$(PLATFORM)/inc
ifeq ($(DBG), Y)
CFLAGS += -DCONFIG_DBG
ASFLAGS += -DCONFIG_DBG
endif
ifeq ($(MEMORY_PROFILING), Y)
CFLAGS += -DCONFIG_MEMORY_PROFILING
ASFLAGS += -DCONFIG_MEMORY_PROFILING
endif
ifeq ($(BACKTRACE), Y)
CFLAGS += -DCONFIG_BACKTRACE
endif
ifeq ($(CORE_DBG), Y)
CFLAGS += -DCONFIG_CORE_DBG
endif
ifeq ($(POOL_DBG), Y)
CFLAGS += -DCONFIG_POOL_DBG
endif
ifeq ($(TEE_API_DBG), Y)
CFLAGS += -DCONFIG_TEE_API_DBG
endif
ifeq ($(DEVICE_DBG), Y)
CFLAGS += -DCONFIG_DEVICE_DBG
endif
ifeq ($(EFLASH_DRV_DBG), Y)
CFLAGS += -DCONFIG_EFLASH_DRV_DBG
endif
ifeq ($(CRYPTO_DRV_DBG), Y)
CFLAGS += -DCONFIG_CRYPTO_DRV_DBG
endif
ifeq ($(ALI_CRYPTO_DBG), Y)
CFLAGS += -DALI_CRYPTO_DBG
endif
ifeq ($(CONFIG_CK_PMU_DBG), Y)
CFLAGS += -DCONFIG_CK_PMU_DBG
endif
ifeq ($(CONFIG_ASC_DRV_DBG), Y)
CFLAGS += -DCONFIG_ASC_DRV_DBG
endif
ifeq ($(CONFIG_TRM_DRV_DBG), Y)
CFLAGS += -DCONFIG_TRM_DRV_DBG
endif
endif
###############
# TW CONFIG end
###############
###############
# NTW CONFIG end
###############
ifeq ($(CURRENT_BUILD), NTW)
CFLAGS += -DCONFIG_NTW
ASFLAGS += -DCONFIG_NTW
ifeq ($(DBG), Y)
CFLAGS += -DCONFIG_DBG
ASFLAGS += -DCONFIG_DBG
endif
ifeq ($(MEMORY_PROFILING), Y)
CFLAGS += -DCONFIG_MEMORY_PROFILING
ASFLAGS += -DCONFIG_MEMORY_PROFILING
endif
endif
###############
# NTW CONFIG end
###############
ifeq ($(VERBOSE), Y)
NOECHO =
else
NOECHO = @
endif
LDFLAGS += -nostdlib
# common compile flag
CFLAGS += -Os
%.o: %.c
@echo "CC $<"
$(NOECHO)$(CC) -c -o $*.o $(CFLAGS) $<
%.o: %.S
@echo "CC $<"
$(NOECHO)$(CC) -c -o $*.o $(ASFLAGS) $<
%.ntw.o: %.c
@echo "CC $<"
$(NOECHO)$(CC) -c -o $*.ntw.o $(CFLAGS) $<
%.ntw.o: %.S
@echo "CC $<"
$(NOECHO)$(CC) -c -o $*.ntw.o $(ASFLAGS) $<

View file

@ -0,0 +1,51 @@
TOP := .
CURRENT_BUILD := TW
include $(TOP)/tee.cfg
include $(TOP)/Make.rules
TW_DIRS := $(TOP)/platform/$(PLATFORM) $(TOP)/drv $(TOP)/mon_emu
OBJS := $(TOP)/platform/$(PLATFORM)/plat.o \
$(TOP)/drv/drv.o \
$(TOP)/mon_emu/mon_emu.o
ifeq ($(RSA_SUPPORT), Y)
OBJS += $(TOP)/tee/crypto.rsa.o
endif
ifeq ($(AES_SUPPORT), Y)
OBJS += $(TOP)/tee/crypto.aes.o
endif
ifeq ($(SHA_SUPPORT), Y)
OBJS += $(TOP)/tee/crypto.sha.o
endif
ifeq ($(RAND_SUPPORT), Y)
OBJS += $(TOP)/tee/crypto.rand.o
endif
ifeq ($(TRNG_SUPPORT), Y)
OBJS += $(TOP)/tee/crypto.rand.o
endif
.PHONY: all clean
LDFLAGS += -L$(TOP)/platform/$(PLATFORM) -T$(TOP)/sw.lds
BIN_NAME := sw
all: $(BIN_NAME).bin
$(BIN_NAME).bin: $(TOP)/sw.lds
for dir in $(TW_DIRS); do $(MAKE) -C $$dir; done
@echo 'const char build_message[] = "version $(VERSION), build time $(BUILD_TIME)";' | \
$(CC) -xc -c - -o $(TOP)/build_message.o $(CFLAGS)
$(NOECHO)$(CC) $(LDFLAGS) -Wl,--start-group $(OBJS) $(TOP)/build_message.o $(TOP)/tee/tw.sdk.o -Wl,--end-group -o $(BIN_NAME).elf -lgcc
$(NOECHO)$(OBJDUMP) -d $(BIN_NAME).elf > $(BIN_NAME).dump
$(NOECHO)$(NM) -n $(BIN_NAME).elf | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $(TOP)/system.map
$(NOECHO)$(OBJCOPY) -O binary -R .note -R .comment $(BIN_NAME).elf $@
$(TOP)/sw.lds: $(TOP)/sw.lds.S
$(NOECHO)$(CC) $(GEN_LDS_FLAGS) -I$(TOP)/inc -I$(TOP)/platform/$(PLATFORM)/inc -P -E -o $@ $<
clean:
@echo "cleaning up ..."
@for dir in $(TW_DIRS); do $(MAKE) -C $$dir clean; done
$(NOECHO)rm -f $(BIN_NAME).bin $(BIN_NAME).dump $(BIN_NAME).elf $(TOP)/sw.lds $(TOP)/system.map $(TOP)/build_message.o

View file

@ -0,0 +1,28 @@
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
TOP := ..
CURRENT_BUILD := TW
include $(TOP)/tee.cfg
include $(TOP)/Make.rules
DIRS := asc crypto flash trm #test
SRCS := $(wildcard $(addsuffix /*.c, $(DIRS)))
OBJS := $(addsuffix /built-in.o, $(DIRS))
LIBS := drv.o
all: $(OBJS) $(LIBS)
$(LIBS): $(OBJS)
$(NOECHO)$(LD) -r -o $(LIBS) $(OBJS)
@echo "Finish building $@..."
$(OBJS): $(SRCS)
@for dir in $(DIRS); do $(MAKE) -C $$dir; done
clean:
@ echo "Cleaning $(LIBS)..."
@ for dir in $(DIRS); do $(MAKE) -C $$dir clean; done
@-rm -f $(LIBS)

View file

@ -0,0 +1,33 @@
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
TOP := ../..
CURRENT_BUILD := TW
include $(TOP)/tee.cfg
include $(TOP)/Make.rules
SRCS :=
ifeq ($(PLATFORM), csky_phobos)
SRCS += ./tee_asc_phobos.c
else
ifeq ($(PLATFORM), csky_ch2201)
SRCS += ./tee_asc_ch2201.c
endif
endif
OBJS := $(patsubst %.cxx,%.o,$(patsubst %.c,%.o,$(SRCS)))
LIBS := built-in.o
#CFLAGS += -DTEE_ASC_DBG
all: $(OBJS) $(LIBS)
$(LIBS): $(OBJS)
$(NOECHO)$(LD) -r -o $(LIBS) $(OBJS)
@echo "Finish building $(LIBS)..."
clean:
@echo "Cleaning $(LIBS)..."
$(NOECHO)rm -f $(OBJS) $(LIBS)

View file

@ -0,0 +1,400 @@
/**
* Copyright (C) 2015-2016 The YunOS Project. All rights reserved.
*/
#include "hal_memmap.h"
#include "tee_asc.h"
#include "tee_dbg.h"
#include "tee_addr_map.h"
#ifdef CONFIG_ASC_DRV_DBG
#define ASC_DRV_DBG_E(str, x...) \
do { \
tee_dbg_print(ERR, "%s:%d: " str, __FUNCTION__, __LINE__, ## x); \
} while (0)
#define ASC_DRV_DBG_I(str, x...) \
do { \
tee_dbg_print(INF, "%s:%d: " str, __FUNCTION__, __LINE__, ## x); \
} while (0)
#else
#define ASC_DRV_DBG_E(str, x...) TEE_ERROR(-7)
#define ASC_DRV_DBG_I(str, x...)
#endif
#define IS_ALIGNED(x, n) ((x) % (n) == 0)
#define IS_POWERED(x) !((x) & (x - 1))
#define SASC_REGN_NUM (8)
#define SRAM_GRANULE_BNUM (2)
#define SRAM_REGN_SIZE_NUM (13)
#define FLASH_GRANULE_BNUM (9)
#define FLASH_REGN_SIZE_NUM (10)
typedef struct sram_asc_regs_t {
uint32_t car;
uint32_t cr;
uint32_t rg[8];
uint32_t cfg;
} sram_asc_regs_t;
typedef sram_asc_regs_t flash_asc_regs_t;
static int32_t _find_idle_region(bool is_sram, uint32_t *regn_idx)
{
uint32_t i;
volatile sram_asc_regs_t *asc_regs;
TEE_ASSERT(regn_idx);
if (is_sram) {
asc_regs = (sram_asc_regs_t *)PLATFORM_SRAM_SASC_BADDR;
} else {
/* flash asc structure is same as sram's */
asc_regs = (sram_asc_regs_t *)PLATFORM_FLASH_SASC_BADDR;
}
for (i = 0; i < SASC_REGN_NUM; i++) {
if (asc_regs->cr & (0x1 << i)) {
continue;
}
*regn_idx = i;
return 0;
}
return -1;
}
static int _calc_regn_size(bool is_sram, uint32_t paddr, uint32_t size, uint32_t *regn_size)
{
uint32_t i = 0;
uint32_t regn_alignment = 0;
TEE_ASSERT(regn_size);
if (is_sram) {
for (i = 0; i < SRAM_REGN_SIZE_NUM; i++) {
if (size == (0x1 << (i + SRAM_GRANULE_BNUM))) {
*regn_size = i + 5;
if (i != 0) {
regn_alignment = size;
}
if (regn_alignment && !IS_ALIGNED(paddr, regn_alignment)) {
ASC_DRV_DBG_E("paddr(%08x) does not meet rgn align(%08x)\n",
paddr, regn_alignment);
return -1;
}
return 0;
}
}
} else {
for (i = 0; i < FLASH_REGN_SIZE_NUM; i++) {
if (size == (0x1 << (i + FLASH_GRANULE_BNUM))) {
*regn_size = i;
if (i != 0) {
regn_alignment = size;
}
if (regn_alignment && !IS_ALIGNED(paddr, regn_alignment)) {
ASC_DRV_DBG_E("paddr(%08x) is not meet regn alignment(%08x)\n",
paddr, regn_alignment);
return -1;
}
return 0;
}
}
}
return -1;
}
static int32_t _asc_set_mem_perm(uint32_t paddr, uint32_t size, tee_asc_perm_t perm)
{
int32_t ret;
bool is_sram;
uint32_t base_addr;
uint32_t regn_idx, regn_size;
volatile sram_asc_regs_t *asc_regs;
TEE_ASSERT(size && IS_POWERED(size));
if (paddr >= SRAM_START && paddr < SRAM_END) {
is_sram = true;
base_addr = (paddr >> SRAM_GRANULE_BNUM) & 0xfff;
asc_regs = (sram_asc_regs_t *)PLATFORM_SRAM_SASC_BADDR;
} else if (paddr >= FLASH_START && paddr < FLASH_END) {
is_sram = false;
base_addr = (paddr >> FLASH_GRANULE_BNUM) & 0x1ff;
asc_regs = (sram_asc_regs_t *)PLATFORM_FLASH_SASC_BADDR;
} else {
ASC_DRV_DBG_E("set_mem_perm: invalid paddr(%08x)\n", paddr);
return -1;
}
ret = _find_idle_region(is_sram, &regn_idx);
if (ret < 0) {
ASC_DRV_DBG_E("_asc_set_mem_perm: no idle region left\n");
return -1;
}
ret = _calc_regn_size(is_sram, paddr, size, &regn_size);
if (ret < 0) {
ASC_DRV_DBG_E("_asc_set_mem_perm: calc regn size fail\n");
return -1;
}
if (perm.sec) {
asc_regs->car |= (0x1 << regn_idx);
} else {
asc_regs->car &= ~(0x1 << regn_idx);
}
if (is_sram) {
asc_regs->rg[regn_idx] = (base_addr << 20);
asc_regs->rg[regn_idx] |= regn_size;
} else {
asc_regs->rg[regn_idx] = (base_addr << 23);
asc_regs->rg[regn_idx] |= regn_size;
}
asc_regs->cr |= (0x1 << regn_idx);
asc_regs->cfg |= ((perm.ap & 0x3) << (regn_idx * 2));
asc_regs->cfg |= ((perm.cd & 0x3) << (regn_idx * 2 + 16));
#ifdef TEE_ASC_DBG
ASC_DRV_DBG_I("set_perm -- regn_idx: %d car: %08x cr: %08x cfg: %08x regn_rg: %08x\n",
regn_idx, asc_regs->car, asc_regs->cr, asc_regs->cfg, asc_regs->rg[regn_idx]);
#endif
return 0;
}
static int32_t _asc_get_mem_perm(uint32_t paddr, uint32_t size, tee_asc_perm_t *perm)
{
int32_t ret;
bool is_sram;
uint32_t i = 0;
uint32_t base_addr;
uint32_t regn_size;
volatile sram_asc_regs_t *asc_regs;
TEE_ASSERT(perm);
TEE_ASSERT(size && IS_POWERED(size));
if (paddr >= SRAM_START && paddr < SRAM_END) {
is_sram = true;
base_addr = (paddr >> SRAM_GRANULE_BNUM) & 0xfff;
asc_regs = (sram_asc_regs_t *)PLATFORM_SRAM_SASC_BADDR;
} else if (paddr >= FLASH_START && paddr < FLASH_END) {
is_sram = false;
base_addr = (paddr >> FLASH_GRANULE_BNUM) & 0x1ff;
asc_regs = (sram_asc_regs_t *)PLATFORM_FLASH_SASC_BADDR;
} else {
ASC_DRV_DBG_E("set_mem_perm: invalid paddr(%08x)\n", paddr);
return -1;
}
ret = _calc_regn_size(is_sram, paddr, size, &regn_size);
if (ret < 0) {
ASC_DRV_DBG_E("_asc_set_mem_perm: calc regn size fail\n");
return -1;
}
for (i = 0; i < SASC_REGN_NUM; i++) {
uint32_t cur_regn_addr, cur_regn_size;
if (asc_regs->cr & (0x1 << i)) {
if (is_sram) {
cur_regn_addr = (asc_regs->rg[i] >> 20) & 0xfff;
cur_regn_size = asc_regs->rg[i] & 0x1f;
} else {
cur_regn_addr = (asc_regs->rg[i] >> 23) & 0x1ff;
cur_regn_size = asc_regs->rg[i] & 0xf;
}
if (base_addr >= cur_regn_addr &&
base_addr + regn_size <= cur_regn_addr + cur_regn_size) {
perm->sec = (asc_regs->car >> i) & 0x1;
perm->ap = (asc_regs->cfg >> (2 * i)) & 0x3;
perm->cd = (asc_regs->cfg >> (2 * i + 16)) & 0x3;
#ifdef TEE_ASC_DBG
ASC_DRV_DBG_I("get_perm -- regn_idx: %d sec: %d ap: %d cd: %d\n",
i, perm->sec, perm->ap, perm->cd);
#endif
return 0;
}
}
}
return -1;
}
static int32_t _asc_clr_mem_perm(uint32_t paddr, uint32_t size)
{
int32_t ret;
bool is_sram;
uint32_t i = 0;
uint32_t base_addr;
uint32_t regn_size;
volatile sram_asc_regs_t *asc_regs;
TEE_ASSERT(size && IS_POWERED(size));
if (paddr >= SRAM_START && paddr < SRAM_END) {
is_sram = true;
base_addr = (paddr >> SRAM_GRANULE_BNUM) & 0xfff;
asc_regs = (sram_asc_regs_t *)PLATFORM_SRAM_SASC_BADDR;
} else if (paddr >= FLASH_START && paddr < FLASH_END) {
is_sram = false;
base_addr = (paddr >> FLASH_GRANULE_BNUM) & 0x1ff;
asc_regs = (sram_asc_regs_t *)PLATFORM_FLASH_SASC_BADDR;
} else {
ASC_DRV_DBG_E("set_mem_perm: invalid paddr(%08x)\n", paddr);
return -1;
}
ret = _calc_regn_size(is_sram, paddr, size, &regn_size);
if (ret < 0) {
ASC_DRV_DBG_E("_asc_set_mem_perm: calc regn size fail\n");
return -1;
}
for (i = 0; i < SASC_REGN_NUM; i++) {
uint32_t cur_regn_addr, cur_regn_size;
if (asc_regs->cr & (0x1 << i)) {
if (is_sram) {
cur_regn_addr = (asc_regs->rg[i] >> 20) & 0xfff;
cur_regn_size = asc_regs->rg[i] & 0x1f;
} else {
cur_regn_addr = (asc_regs->rg[i] >> 23) & 0x1ff;
cur_regn_size = asc_regs->rg[i] & 0xf;
}
if (base_addr >= cur_regn_addr &&
base_addr + regn_size <= cur_regn_addr + cur_regn_size) {
asc_regs->car &= ~(0x1 << i);
asc_regs->cr &= ~(0x1 << i);
asc_regs->rg[i] = 0x0;
asc_regs->cfg &= ~(0x1 << 2 * i);
asc_regs->cfg &= ~(0x1 << (2 * i + 16));
#ifdef TEE_ASC_DBG
ASC_DRV_DBG_I("clr_perm -- car: %08x cr: %08x rg: %08x cfg: %08x\n",
i, asc_regs->car, asc_regs->cr, asc_regs->rg, asc_regs->cfg);
#endif
return 0;
}
}
}
return -1;
}
static int32_t _tee_asc_open(dev_t *dev)
{
return 0;
}
static int32_t _tee_asc_close(dev_t *dev)
{
return 0;
}
static int32_t _tee_asc_ioctl(dev_t *dev, int32_t cmd, void *arg)
{
int ret;
tee_asc_arg_t *asc_arg;
asc_arg = (tee_asc_arg_t *)arg;
TEE_ASSERT(asc_arg);
ASC_DRV_DBG_I("_tee_asc_ioctl -- phys: %08x size: %08x cmd: %d\n",
asc_arg->paddr, asc_arg->size, cmd);
switch(cmd) {
case TEE_ASC_SET_MEM_PERM:
{
ret = _asc_set_mem_perm(asc_arg->paddr,
asc_arg->size, asc_arg->perm);
if (ret < 0) {
return ret;
}
break;
}
case TEE_ASC_GET_MEM_PERM:
{
ret = _asc_get_mem_perm(asc_arg->paddr,
asc_arg->size, &asc_arg->perm);
if (ret < 0) {
return ret;
}
}
case TEE_ASC_CLR_MEM_PERM:
{
ret = _asc_clr_mem_perm(asc_arg->paddr, asc_arg->size);
if (ret < 0) {
return ret;
}
break;
}
default:
ASC_DRV_DBG_E("illegal command\n");
return -1;
}
return 0;
}
static dev_ops_t _tee_asc_ops = {
.open = _tee_asc_open,
.close = _tee_asc_close,
.ioctl = _tee_asc_ioctl,
.read = NULL,
.write = NULL,
.suspend = NULL,
.resume = NULL,
};
static int32_t _tee_asc_probe()
{
dev_t *dev;
ASC_DRV_DBG_I("_tee_asc_probe\n");
dev = dev_register(TEE_DRV_ASC_NAME, &_tee_asc_ops);
if (dev == NULL) {
ASC_DRV_DBG_E("_tee_asc_probe: dev regs fail\n");
return -1;
}
return 0;
}
DEV_INIT(_tee_asc_probe, (uint8_t *)TEE_DRV_ASC_NAME);
int asc_set_perm(uint32_t paddr, uint32_t size, bool is_secure, uint8_t ap_perm, uint8_t cd_perm)
{
int32_t ret;
tee_asc_perm_t perm;
perm.sec = ((true == is_secure) ? (REGION_SIZE_SECURITY) : (REGION_SIZE_UNSECURITY));
perm.ap = ap_perm;
perm.cd = cd_perm;
ret = _asc_set_mem_perm(paddr, size, perm);
if (0 != ret) {
ASC_DRV_DBG_E("failed to set asc perm: _asc_set_mem_perm return: 0x%x!\n", ret);
return ret;
}
return 0;
}

View file

@ -0,0 +1,409 @@
/**
* Copyright (C) 2015-2016 The YunOS Project. All rights reserved.
*/
#include "hal_memmap.h"
#include "tee_asc.h"
#include "tee_dbg.h"
#include "tee_addr_map.h"
#ifdef CONFIG_ASC_DRV_DBG
#define ASC_DRV_DBG_E(str, x...) \
do { \
tee_dbg_print(ERR, "%s:%d: " str, __FUNCTION__, __LINE__, ##x); \
} while (0)
#define ASC_DRV_DBG_I(str, x...) \
do { \
tee_dbg_print(INF, "%s:%d: " str, __FUNCTION__, __LINE__, ##x); \
} while (0)
#else
#define ASC_DRV_DBG_E(str, x...) TEE_ERROR(-7)
#define ASC_DRV_DBG_I(str, x...)
#endif
#define IS_ALIGNED(x, n) ((x) % (n) == 0)
#define IS_POWERED(x) !((x) & (x - 1))
#define SASC_REGN_NUM (8)
#define SRAM_GRANULE_BNUM (2)
#define SRAM_REGN_SIZE_NUM (13)
#define FLASH_GRANULE_BNUM (9)
#define FLASH_REGN_SIZE_NUM (10)
typedef struct sram_asc_regs_t
{
uint32_t car;
uint32_t cr;
uint32_t rg[8];
uint32_t cfg;
} sram_asc_regs_t;
typedef sram_asc_regs_t flash_asc_regs_t;
static int32_t _find_idle_region(bool is_sram, uint32_t *regn_idx)
{
uint32_t i;
volatile sram_asc_regs_t *asc_regs;
TEE_ASSERT(regn_idx);
if (is_sram) {
asc_regs = (sram_asc_regs_t *)PLATFORM_SRAM_SASC_BADDR;
} else {
/* flash asc structure is same as sram's */
asc_regs = (sram_asc_regs_t *)PLATFORM_FLASH_SASC_BADDR;
}
for (i = 0; i < SASC_REGN_NUM; i++) {
if (asc_regs->cr & (0x1 << i)) {
continue;
}
*regn_idx = i;
return 0;
}
return -1;
}
static int _calc_regn_size(bool is_sram, uint32_t paddr, uint32_t size,
uint32_t *regn_size)
{
uint32_t i = 0;
uint32_t regn_alignment = 0;
TEE_ASSERT(regn_size);
if (is_sram) {
for (i = 0; i < SRAM_REGN_SIZE_NUM; i++) {
if (size == (0x1 << (i + SRAM_GRANULE_BNUM))) {
*regn_size = i + 5;
if (i != 0) {
regn_alignment = size;
}
if (regn_alignment && !IS_ALIGNED(paddr, regn_alignment)) {
ASC_DRV_DBG_E("paddr(%08x) does not meet rgn align(%08x)\n",
paddr, regn_alignment);
return -1;
}
return 0;
}
}
} else {
for (i = 0; i < FLASH_REGN_SIZE_NUM; i++) {
if (size == (0x1 << (i + FLASH_GRANULE_BNUM))) {
*regn_size = i;
if (i != 0) {
regn_alignment = size;
}
if (regn_alignment && !IS_ALIGNED(paddr, regn_alignment)) {
ASC_DRV_DBG_E(
"paddr(%08x) is not meet regn alignment(%08x)\n", paddr,
regn_alignment);
return -1;
}
return 0;
}
}
}
return -1;
}
static int32_t _asc_set_mem_perm(uint32_t paddr, uint32_t size,
tee_asc_perm_t perm)
{
int32_t ret;
bool is_sram;
uint32_t base_addr;
uint32_t regn_idx, regn_size;
volatile sram_asc_regs_t *asc_regs;
TEE_ASSERT(size && IS_POWERED(size));
if (paddr >= SRAM_START && paddr < SRAM_END) {
is_sram = true;
base_addr = (paddr >> SRAM_GRANULE_BNUM) & 0x7fff;
asc_regs = (sram_asc_regs_t *)PLATFORM_SRAM_SASC_BADDR;
} else if (paddr >= FLASH_START && paddr < FLASH_END) {
is_sram = false;
base_addr = (paddr >> FLASH_GRANULE_BNUM) & 0x1ff;
asc_regs = (sram_asc_regs_t *)PLATFORM_FLASH_SASC_BADDR;
} else {
ASC_DRV_DBG_E("set_mem_perm: invalid paddr(%08x)\n", paddr);
return -1;
}
ret = _find_idle_region(is_sram, &regn_idx);
if (ret < 0) {
ASC_DRV_DBG_E("_asc_set_mem_perm: no idle region left\n");
return -1;
}
ret = _calc_regn_size(is_sram, paddr, size, &regn_size);
if (ret < 0) {
ASC_DRV_DBG_E("_asc_set_mem_perm: calc regn size fail\n");
return -1;
}
if (perm.sec) {
asc_regs->car |= (0x1 << regn_idx);
} else {
asc_regs->car &= ~(0x1 << regn_idx);
}
if (is_sram) {
asc_regs->rg[regn_idx] = (base_addr << 17);
asc_regs->rg[regn_idx] |= regn_size;
} else {
asc_regs->rg[regn_idx] = (base_addr << 23);
asc_regs->rg[regn_idx] |= regn_size;
}
asc_regs->cr |= (0x1 << regn_idx);
asc_regs->cfg |= ((perm.ap & 0x3) << (regn_idx * 2));
asc_regs->cfg |= ((perm.cd & 0x3) << (regn_idx * 2 + 16));
#ifdef TEE_ASC_DBG
ASC_DRV_DBG_I("set_perm -- regn_idx: %d car: %08x cr: %08x cfg: %08x "
"regn_rg: %08x\n",
regn_idx, asc_regs->car, asc_regs->cr, asc_regs->cfg,
asc_regs->rg[regn_idx]);
#endif
return 0;
}
static int32_t _asc_get_mem_perm(uint32_t paddr, uint32_t size,
tee_asc_perm_t *perm)
{
int32_t ret;
bool is_sram;
uint32_t i = 0;
uint32_t base_addr;
uint32_t regn_size;
volatile sram_asc_regs_t *asc_regs;
TEE_ASSERT(perm);
TEE_ASSERT(size && IS_POWERED(size));
if (paddr >= SRAM_START && paddr < SRAM_END) {
is_sram = true;
base_addr = (paddr >> SRAM_GRANULE_BNUM) & 0x7fff;
asc_regs = (sram_asc_regs_t *)PLATFORM_SRAM_SASC_BADDR;
} else if (paddr >= FLASH_START && paddr < FLASH_END) {
is_sram = false;
base_addr = (paddr >> FLASH_GRANULE_BNUM) & 0x1ff;
asc_regs = (sram_asc_regs_t *)PLATFORM_FLASH_SASC_BADDR;
} else {
ASC_DRV_DBG_E("set_mem_perm: invalid paddr(%08x)\n", paddr);
return -1;
}
ret = _calc_regn_size(is_sram, paddr, size, &regn_size);
if (ret < 0) {
ASC_DRV_DBG_E("_asc_set_mem_perm: calc regn size fail\n");
return -1;
}
for (i = 0; i < SASC_REGN_NUM; i++) {
uint32_t cur_regn_addr, cur_regn_size;
if (asc_regs->cr & (0x1 << i)) {
if (is_sram) {
cur_regn_addr = (asc_regs->rg[i] >> 17) & 0x7fff;
cur_regn_size = asc_regs->rg[i] & 0x1f;
} else {
cur_regn_addr = (asc_regs->rg[i] >> 23) & 0x1ff;
cur_regn_size = asc_regs->rg[i] & 0xf;
}
if (base_addr >= cur_regn_addr &&
base_addr + regn_size <= cur_regn_addr + cur_regn_size) {
perm->sec = (asc_regs->car >> i) & 0x1;
perm->ap = (asc_regs->cfg >> (2 * i)) & 0x3;
perm->cd = (asc_regs->cfg >> (2 * i + 16)) & 0x3;
#ifdef TEE_ASC_DBG
ASC_DRV_DBG_I(
"get_perm -- regn_idx: %d sec: %d ap: %d cd: %d\n", i,
perm->sec, perm->ap, perm->cd);
#endif
return 0;
}
}
}
return -1;
}
static int32_t _asc_clr_mem_perm(uint32_t paddr, uint32_t size)
{
int32_t ret;
bool is_sram;
uint32_t i = 0;
uint32_t base_addr;
uint32_t regn_size;
volatile sram_asc_regs_t *asc_regs;
TEE_ASSERT(size && IS_POWERED(size));
if (paddr >= SRAM_START && paddr < SRAM_END) {
is_sram = true;
base_addr = (paddr >> SRAM_GRANULE_BNUM) & 0x7fff;
asc_regs = (sram_asc_regs_t *)PLATFORM_SRAM_SASC_BADDR;
} else if (paddr >= FLASH_START && paddr < FLASH_END) {
is_sram = false;
base_addr = (paddr >> FLASH_GRANULE_BNUM) & 0x1ff;
asc_regs = (sram_asc_regs_t *)PLATFORM_FLASH_SASC_BADDR;
} else {
ASC_DRV_DBG_E("set_mem_perm: invalid paddr(%08x)\n", paddr);
return -1;
}
ret = _calc_regn_size(is_sram, paddr, size, &regn_size);
if (ret < 0) {
ASC_DRV_DBG_E("_asc_set_mem_perm: calc regn size fail\n");
return -1;
}
for (i = 0; i < SASC_REGN_NUM; i++) {
uint32_t cur_regn_addr, cur_regn_size;
if (asc_regs->cr & (0x1 << i)) {
if (is_sram) {
cur_regn_addr = (asc_regs->rg[i] >> 17) & 0x7fff;
cur_regn_size = asc_regs->rg[i] & 0x1f;
} else {
cur_regn_addr = (asc_regs->rg[i] >> 23) & 0x1ff;
cur_regn_size = asc_regs->rg[i] & 0xf;
}
if (base_addr >= cur_regn_addr &&
base_addr + regn_size <= cur_regn_addr + cur_regn_size) {
asc_regs->car &= ~(0x1 << i);
asc_regs->cr &= ~(0x1 << i);
asc_regs->rg[i] = 0x0;
asc_regs->cfg &= ~(0x1 << 2 * i);
asc_regs->cfg &= ~(0x1 << (2 * i + 16));
#ifdef TEE_ASC_DBG
ASC_DRV_DBG_I(
"clr_perm -- car: %08x cr: %08x rg: %08x cfg: %08x\n", i,
asc_regs->car, asc_regs->cr, asc_regs->rg, asc_regs->cfg);
#endif
return 0;
}
}
}
return -1;
}
static int32_t _tee_asc_open(dev_t *dev)
{
return 0;
}
static int32_t _tee_asc_close(dev_t *dev)
{
return 0;
}
static int32_t _tee_asc_ioctl(dev_t *dev, int32_t cmd, void *arg)
{
int ret;
tee_asc_arg_t *asc_arg;
asc_arg = (tee_asc_arg_t *)arg;
TEE_ASSERT(asc_arg);
ASC_DRV_DBG_I("_tee_asc_ioctl -- phys: %08x size: %08x cmd: %d\n",
asc_arg->paddr, asc_arg->size, cmd);
switch (cmd) {
case TEE_ASC_SET_MEM_PERM: {
ret =
_asc_set_mem_perm(asc_arg->paddr, asc_arg->size, asc_arg->perm);
if (ret < 0) {
return ret;
}
break;
}
case TEE_ASC_GET_MEM_PERM: {
ret =
_asc_get_mem_perm(asc_arg->paddr, asc_arg->size, &asc_arg->perm);
if (ret < 0) {
return ret;
}
}
case TEE_ASC_CLR_MEM_PERM: {
ret = _asc_clr_mem_perm(asc_arg->paddr, asc_arg->size);
if (ret < 0) {
return ret;
}
break;
}
default:
ASC_DRV_DBG_E("illegal command\n");
return -1;
}
return 0;
}
static dev_ops_t _tee_asc_ops = {
.open = _tee_asc_open,
.close = _tee_asc_close,
.ioctl = _tee_asc_ioctl,
.read = NULL,
.write = NULL,
.suspend = NULL,
.resume = NULL,
};
static int32_t _tee_asc_probe()
{
dev_t *dev;
ASC_DRV_DBG_I("_tee_asc_probe\n");
dev = dev_register(TEE_DRV_ASC_NAME, &_tee_asc_ops);
if (dev == NULL) {
ASC_DRV_DBG_E("_tee_asc_probe: dev regs fail\n");
return -1;
}
return 0;
}
DEV_INIT(_tee_asc_probe, (uint8_t *)TEE_DRV_ASC_NAME);
int asc_set_perm(uint32_t paddr, uint32_t size, bool is_secure, uint8_t ap_perm,
uint8_t cd_perm)
{
int32_t ret;
tee_asc_perm_t perm;
perm.sec =
((true == is_secure) ? (REGION_SIZE_SECURITY) : (REGION_SIZE_UNSECURITY));
perm.ap = ap_perm;
perm.cd = cd_perm;
ret = _asc_set_mem_perm(paddr, size, perm);
if (0 != ret) {
ASC_DRV_DBG_E(
"failed to set asc perm: _asc_set_mem_perm return: 0x%x!\n", ret);
return ret;
}
return 0;
}

View file

@ -0,0 +1,400 @@
/**
* Copyright (C) 2015-2016 The YunOS Project. All rights reserved.
*/
#include "hal_memmap.h"
#include "tee_asc.h"
#include "tee_dbg.h"
#include "tee_addr_map.h"
#ifdef CONFIG_ASC_DRV_DBG
#define ASC_DRV_DBG_E(str, x...) \
do { \
tee_dbg_print(ERR, "%s:%d: " str, __FUNCTION__, __LINE__, ## x); \
} while (0)
#define ASC_DRV_DBG_I(str, x...) \
do { \
tee_dbg_print(INF, "%s:%d: " str, __FUNCTION__, __LINE__, ## x); \
} while (0)
#else
#define ASC_DRV_DBG_E(str, x...) TEE_ERROR(-7)
#define ASC_DRV_DBG_I(str, x...)
#endif
#define IS_ALIGNED(x, n) ((x) % (n) == 0)
#define IS_POWERED(x) !((x) & (x - 1))
#define SASC_REGN_NUM (8)
#define SRAM_GRANULE_BNUM (2)
#define SRAM_REGN_SIZE_NUM (13)
#define FLASH_GRANULE_BNUM (9)
#define FLASH_REGN_SIZE_NUM (10)
typedef struct sram_asc_regs_t {
uint32_t car;
uint32_t cr;
uint32_t rg[8];
uint32_t cfg;
} sram_asc_regs_t;
typedef sram_asc_regs_t flash_asc_regs_t;
static int32_t _find_idle_region(bool is_sram, uint32_t *regn_idx)
{
uint32_t i;
volatile sram_asc_regs_t *asc_regs;
TEE_ASSERT(regn_idx);
if (is_sram) {
asc_regs = (sram_asc_regs_t *)PLATFORM_SRAM_SASC_BADDR;
} else {
/* flash asc structure is same as sram's */
asc_regs = (sram_asc_regs_t *)PLATFORM_FLASH_SASC_BADDR;
}
for (i = 0; i < SASC_REGN_NUM; i++) {
if (asc_regs->cr & (0x1 << i)) {
continue;
}
*regn_idx = i;
return 0;
}
return -1;
}
static int _calc_regn_size(bool is_sram, uint32_t paddr, uint32_t size, uint32_t *regn_size)
{
uint32_t i = 0;
uint32_t regn_alignment = 0;
TEE_ASSERT(regn_size);
if (is_sram) {
for (i = 0; i < SRAM_REGN_SIZE_NUM; i++) {
if (size == (0x1 << (i + SRAM_GRANULE_BNUM))) {
*regn_size = i + 5;
if (i != 0) {
regn_alignment = size;
}
if (regn_alignment && !IS_ALIGNED(paddr, regn_alignment)) {
ASC_DRV_DBG_E("paddr(%08x) does not meet rgn align(%08x)\n",
paddr, regn_alignment);
return -1;
}
return 0;
}
}
} else {
for (i = 0; i < FLASH_REGN_SIZE_NUM; i++) {
if (size == (0x1 << (i + FLASH_GRANULE_BNUM))) {
*regn_size = i;
if (i != 0) {
regn_alignment = size;
}
if (regn_alignment && !IS_ALIGNED(paddr, regn_alignment)) {
ASC_DRV_DBG_E("paddr(%08x) is not meet regn alignment(%08x)\n",
paddr, regn_alignment);
return -1;
}
return 0;
}
}
}
return -1;
}
static int32_t _asc_set_mem_perm(uint32_t paddr, uint32_t size, tee_asc_perm_t perm)
{
int32_t ret;
bool is_sram;
uint32_t base_addr;
uint32_t regn_idx, regn_size;
volatile sram_asc_regs_t *asc_regs;
TEE_ASSERT(size && IS_POWERED(size));
if (paddr >= SRAM_START && paddr < SRAM_END) {
is_sram = true;
base_addr = (paddr >> SRAM_GRANULE_BNUM) & 0xfff;
asc_regs = (sram_asc_regs_t *)PLATFORM_SRAM_SASC_BADDR;
} else if (paddr >= FLASH_START && paddr < FLASH_END) {
is_sram = false;
base_addr = (paddr >> FLASH_GRANULE_BNUM) & 0x1ff;
asc_regs = (sram_asc_regs_t *)PLATFORM_FLASH_SASC_BADDR;
} else {
ASC_DRV_DBG_E("set_mem_perm: invalid paddr(%08x)\n", paddr);
return -1;
}
ret = _find_idle_region(is_sram, &regn_idx);
if (ret < 0) {
ASC_DRV_DBG_E("_asc_set_mem_perm: no idle region left\n");
return -1;
}
ret = _calc_regn_size(is_sram, paddr, size, &regn_size);
if (ret < 0) {
ASC_DRV_DBG_E("_asc_set_mem_perm: calc regn size fail\n");
return -1;
}
if (perm.sec) {
asc_regs->car |= (0x1 << regn_idx);
} else {
asc_regs->car &= ~(0x1 << regn_idx);
}
if (is_sram) {
asc_regs->rg[regn_idx] = (base_addr << 20);
asc_regs->rg[regn_idx] |= regn_size;
} else {
asc_regs->rg[regn_idx] = (base_addr << 23);
asc_regs->rg[regn_idx] |= regn_size;
}
asc_regs->cr |= (0x1 << regn_idx);
asc_regs->cfg |= ((perm.ap & 0x3) << (regn_idx * 2));
asc_regs->cfg |= ((perm.cd & 0x3) << (regn_idx * 2 + 16));
#ifdef TEE_ASC_DBG
ASC_DRV_DBG_I("set_perm -- regn_idx: %d car: %08x cr: %08x cfg: %08x regn_rg: %08x\n",
regn_idx, asc_regs->car, asc_regs->cr, asc_regs->cfg, asc_regs->rg[regn_idx]);
#endif
return 0;
}
static int32_t _asc_get_mem_perm(uint32_t paddr, uint32_t size, tee_asc_perm_t *perm)
{
int32_t ret;
bool is_sram;
uint32_t i = 0;
uint32_t base_addr;
uint32_t regn_size;
volatile sram_asc_regs_t *asc_regs;
TEE_ASSERT(perm);
TEE_ASSERT(size && IS_POWERED(size));
if (paddr >= SRAM_START && paddr < SRAM_END) {
is_sram = true;
base_addr = (paddr >> SRAM_GRANULE_BNUM) & 0xfff;
asc_regs = (sram_asc_regs_t *)PLATFORM_SRAM_SASC_BADDR;
} else if (paddr >= FLASH_START && paddr < FLASH_END) {
is_sram = false;
base_addr = (paddr >> FLASH_GRANULE_BNUM) & 0x1ff;
asc_regs = (sram_asc_regs_t *)PLATFORM_FLASH_SASC_BADDR;
} else {
ASC_DRV_DBG_E("set_mem_perm: invalid paddr(%08x)\n", paddr);
return -1;
}
ret = _calc_regn_size(is_sram, paddr, size, &regn_size);
if (ret < 0) {
ASC_DRV_DBG_E("_asc_set_mem_perm: calc regn size fail\n");
return -1;
}
for (i = 0; i < SASC_REGN_NUM; i++) {
uint32_t cur_regn_addr, cur_regn_size;
if (asc_regs->cr & (0x1 << i)) {
if (is_sram) {
cur_regn_addr = (asc_regs->rg[i] >> 20) & 0xfff;
cur_regn_size = asc_regs->rg[i] & 0x1f;
} else {
cur_regn_addr = (asc_regs->rg[i] >> 23) & 0x1ff;
cur_regn_size = asc_regs->rg[i] & 0xf;
}
if (base_addr >= cur_regn_addr &&
base_addr + regn_size <= cur_regn_addr + cur_regn_size) {
perm->sec = (asc_regs->car >> i) & 0x1;
perm->ap = (asc_regs->cfg >> (2 * i)) & 0x3;
perm->cd = (asc_regs->cfg >> (2 * i + 16)) & 0x3;
#ifdef TEE_ASC_DBG
ASC_DRV_DBG_I("get_perm -- regn_idx: %d sec: %d ap: %d cd: %d\n",
i, perm->sec, perm->ap, perm->cd);
#endif
return 0;
}
}
}
return -1;
}
static int32_t _asc_clr_mem_perm(uint32_t paddr, uint32_t size)
{
int32_t ret;
bool is_sram;
uint32_t i = 0;
uint32_t base_addr;
uint32_t regn_size;
volatile sram_asc_regs_t *asc_regs;
TEE_ASSERT(size && IS_POWERED(size));
if (paddr >= SRAM_START && paddr < SRAM_END) {
is_sram = true;
base_addr = (paddr >> SRAM_GRANULE_BNUM) & 0xfff;
asc_regs = (sram_asc_regs_t *)PLATFORM_SRAM_SASC_BADDR;
} else if (paddr >= FLASH_START && paddr < FLASH_END) {
is_sram = false;
base_addr = (paddr >> FLASH_GRANULE_BNUM) & 0x1ff;
asc_regs = (sram_asc_regs_t *)PLATFORM_FLASH_SASC_BADDR;
} else {
ASC_DRV_DBG_E("set_mem_perm: invalid paddr(%08x)\n", paddr);
return -1;
}
ret = _calc_regn_size(is_sram, paddr, size, &regn_size);
if (ret < 0) {
ASC_DRV_DBG_E("_asc_set_mem_perm: calc regn size fail\n");
return -1;
}
for (i = 0; i < SASC_REGN_NUM; i++) {
uint32_t cur_regn_addr, cur_regn_size;
if (asc_regs->cr & (0x1 << i)) {
if (is_sram) {
cur_regn_addr = (asc_regs->rg[i] >> 20) & 0xfff;
cur_regn_size = asc_regs->rg[i] & 0x1f;
} else {
cur_regn_addr = (asc_regs->rg[i] >> 23) & 0x1ff;
cur_regn_size = asc_regs->rg[i] & 0xf;
}
if (base_addr >= cur_regn_addr &&
base_addr + regn_size <= cur_regn_addr + cur_regn_size) {
asc_regs->car &= ~(0x1 << i);
asc_regs->cr &= ~(0x1 << i);
asc_regs->rg[i] = 0x0;
asc_regs->cfg &= ~(0x1 << 2 * i);
asc_regs->cfg &= ~(0x1 << (2 * i + 16));
#ifdef TEE_ASC_DBG
ASC_DRV_DBG_I("clr_perm -- car: %08x cr: %08x rg: %08x cfg: %08x\n",
i, asc_regs->car, asc_regs->cr, asc_regs->rg, asc_regs->cfg);
#endif
return 0;
}
}
}
return -1;
}
static int32_t _tee_asc_open(dev_t *dev)
{
return 0;
}
static int32_t _tee_asc_close(dev_t *dev)
{
return 0;
}
static int32_t _tee_asc_ioctl(dev_t *dev, int32_t cmd, void *arg)
{
int ret;
tee_asc_arg_t *asc_arg;
asc_arg = (tee_asc_arg_t *)arg;
TEE_ASSERT(asc_arg);
ASC_DRV_DBG_I("_tee_asc_ioctl -- phys: %08x size: %08x cmd: %d\n",
asc_arg->paddr, asc_arg->size, cmd);
switch(cmd) {
case TEE_ASC_SET_MEM_PERM:
{
ret = _asc_set_mem_perm(asc_arg->paddr,
asc_arg->size, asc_arg->perm);
if (ret < 0) {
return ret;
}
break;
}
case TEE_ASC_GET_MEM_PERM:
{
ret = _asc_get_mem_perm(asc_arg->paddr,
asc_arg->size, &asc_arg->perm);
if (ret < 0) {
return ret;
}
}
case TEE_ASC_CLR_MEM_PERM:
{
ret = _asc_clr_mem_perm(asc_arg->paddr, asc_arg->size);
if (ret < 0) {
return ret;
}
break;
}
default:
ASC_DRV_DBG_E("illegal command\n");
return -1;
}
return 0;
}
static dev_ops_t _tee_asc_ops = {
.open = _tee_asc_open,
.close = _tee_asc_close,
.ioctl = _tee_asc_ioctl,
.read = NULL,
.write = NULL,
.suspend = NULL,
.resume = NULL,
};
static int32_t _tee_asc_probe()
{
dev_t *dev;
ASC_DRV_DBG_I("_tee_asc_probe\n");
dev = dev_register(TEE_DRV_ASC_NAME, &_tee_asc_ops);
if (dev == NULL) {
ASC_DRV_DBG_E("_tee_asc_probe: dev regs fail\n");
return -1;
}
return 0;
}
DEV_INIT(_tee_asc_probe, (uint8_t *)TEE_DRV_ASC_NAME);
int asc_set_perm(uint32_t paddr, uint32_t size, bool is_secure, uint8_t ap_perm, uint8_t cd_perm)
{
int32_t ret;
tee_asc_perm_t perm;
perm.sec = ((true == is_secure) ? (REGION_SIZE_SECURITY) : (REGION_SIZE_UNSECURITY));
perm.ap = ap_perm;
perm.cd = cd_perm;
ret = _asc_set_mem_perm(paddr, size, perm);
if (0 != ret) {
ASC_DRV_DBG_E("failed to set asc perm: _asc_set_mem_perm return: 0x%x!\n", ret);
return ret;
}
return 0;
}

View file

@ -0,0 +1,49 @@
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
TOP := ../..
CURRENT_BUILD := TW
include $(TOP)/tee.cfg
include $(TOP)/Make.rules
SRCS := $(wildcard ./*.c)
ifeq ($(RSA_SUPPORT), Y)
SRCS += $(wildcard ./rsa/*.c)
CFLAGS += -I./rsa/
endif
ifeq ($(AES_SUPPORT), Y)
SRCS += $(wildcard ./aes/*.c)
CFLAGS += -I./aes/
endif
ifeq ($(SHA_SUPPORT), Y)
ifeq ($(PLATFORM), csky_phobos)
SRCS += ./sha/sha_drv_phobos.c
else
SRCS += ./sha/sha_drv.c
endif
CFLAGS += -I./sha/
endif
ifeq ($(TRNG_SUPPORT), Y)
SRCS += $(wildcard ./trng/*.c)
CFLAGS += -I./trng/
endif
OBJS := $(patsubst %.cxx,%.o,$(patsubst %.c,%.o,$(SRCS)))
LIBS := built-in.o
CFLAGS += -I$(TOP)/arch/c_sky/inc/ -I../inc
all: $(OBJS) $(LIBS)
$(LIBS): $(OBJS)
$(NOECHO)$(LD) -r -o $(LIBS) $(OBJS)
@echo "Finish building $(LIBS)..."
clean:
@echo "Cleaning $(LIBS)..."
$(NOECHO)rm -f $(OBJS) $(LIBS)

View file

@ -0,0 +1,532 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
**/
#include "tee_types.h"
#include "tee_dbg.h"
#include "aes_drv.h"
#include "device.h"
#include "crypto_drv.h"
#undef INTERRUPT_SUPPORT
/* pAES->CTRL: endian bit read always return 0 */
static volatile bool _g_aes_big_endian = false;
#ifdef INTERRUPT_SUPPORT
void _aes_intr(int32_t irq);
/* interrupt callback function point */
static void(*_aes_intr_callback)(void) = NULL;
/* irq handler infomations */
static irq_handler_t _aes_irq_handler = {
"AES_INTR",
INTC_AES,
INTC_AES%4,
_aes_intr,
false
};
static volatile bool _g_is_key_expand = false;
static volatile bool _g_is_data_completed = false;
void _aes_intr(int32_t irq)
{
if (_aes_get_intr_status(AES_IT_KEYINT)) {
_g_is_key_expand = true;
}
if (_aes_get_intr_status(AES_IT_DATAINT)) {
_g_is_data_completed = true;
}
if (NULL != _aes_intr_callback) {
_aes_intr_callback();
}
_aes_clear_intr_status(AES_IT_ALL);
}
#endif
/**********************************************************************
* Name: _aes_set_data
* Function: write 128 bits Data input
* Params: @pdata ---- a pointer point to the address of 4 words data
* Return: SUCCESS
*
*********************************************************************/
static int32_t _aes_set_data(uint32_t *pdata)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
int32_t i = 0;
if (_g_aes_big_endian) {
for (i = 0; i < 4; i++) {
//Endian is big endian
ptr->Din[3 - i] = *pdata++;
}
} else {
for (i = 0; i < 4; i++){
//Endian is little endian
ptr->Din[i] = *pdata++;
}
}
return SUCCESS;
}
/**************************************************
* Name: _aes_set_key
* Function: Write 255 bits Key
* Params: @pkey ---- a pointer point to key array
* Return: SUCCESS
*
*****************************************************/
static int32_t _aes_set_key(uint32_t *pkey, aes_keylength_t keylength)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
uint32_t length = keylength ?((keylength & 0x1)? 6 : 8) : 4;
int32_t i = 0;
if (_g_aes_big_endian) {
//if Endian is Big endian
for (i = 0; i < length; i++) {
ptr->KEY[length - 1 - i] = *pkey++;
}
} else {
for (i = 0; i < length; i++) {
ptr->KEY[i] = *pkey++;
}
}
return SUCCESS;
}
static int32_t _aes_set_iv(uint32_t *piv)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
int32_t i=0;
if (_g_aes_big_endian) {
//if Endian is Big endian
for (i = 0; i < 4; i++) {
ptr->IV[3 - i] = *piv++;
}
} else {
for (i = 0; i < 4; i++) {
ptr->IV[i] = *piv++;
}
}
return SUCCESS;
}
/**************************************************************************
* Name: _aes_set_endian
* Function: Set AES Endian
* Params: @endian ---- aes_endian_t : AES_Endian_Little or AES_Endian_Big
* Return: SUCCESS
**************************************************************************/
static int32_t _aes_set_endian(aes_endian_t endian)
{
_g_aes_big_endian = ((endian == AES_ENDIAN_BIG) ? (true) : (false));
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
/***** Endian Control bit is bit 8 in CTRL register ******/
ptr->CTRL = ((_g_aes_big_endian == false) ? (ptr->CTRL | 0x100):(ptr->CTRL & (~0x00000100)));
return SUCCESS;
}
/***********************************************************
* Name: _aes_set_opcode
* Function: Set opcode , encrypt or decrypt or key expand
* Params: @opcode ---- aes_opcode_t
* AES_OPCODE_ENCRYPT
* AES_OPCODE_DECRYPT
* AES_OPCODE_KEYEXPAND
* Return: SUCCESS
*
**********************************************************/
static int32_t _aes_set_opcode(aes_opcode_t opcode)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
/****** Opcode Control bits is bit[7:6] *******/
ptr->CTRL &= ~0x00C0; //clear bit[7:6]
ptr->CTRL |= (opcode<<6); //set opcode
return SUCCESS;
}
/***************************************************************
* Name: _aes_set_keylen
* Function: Set Key Length , 128 bits or 192 bits or 256 bits
* Params: @keylength ---- aes_keylen_t
* AES_KeyLen_128
* AES_KeyLen_192
* AES_KeyLen_256
* Return: SUCCESS
*
**************************************************************/
static int32_t _aes_set_keylen(aes_keylength_t keylength)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
/******* Key Length control bit is bit[5:4] *****/
ptr->CTRL &= ~0x0030; //clear bit[5:4]
ptr->CTRL |= (keylength << 4);// Set key length
return SUCCESS;
}
/*****************************************************
* Name: _aes_set_mode
* Function: Set AES Mode, CBC or EBC
* Params: @mode ---- aes_mode_t
* AES_MODE_CBC
* AES_Mode_EBC
* Return: SUCCESS
*
*****************************************************/
static int32_t _aes_set_mode(aes_mode_t mode)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
/******* Mode control bit is bit 3 ********/
ptr->CTRL &= ~0x0008; //clear bit 3
ptr->CTRL |= (mode << 3); //set mode
return SUCCESS;
}
#if INTERRUPT_SUPPORT
/*****************************************************
* Name: _aes_enable_data_intr
* Function: Enable data interrupter
* Params: None
* Return: None
*
*****************************************************/
static void _aes_enable_data_intr(void)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
/****** Interrupt Control bit is bit 2 ********/
ptr->CTRL |= (1 << 2);
}
#endif
/*****************************************************
* Name: _aes_disable_data_intr
* Function: Disable data interrupter
* Params: None
* Return: None
*
*****************************************************/
static void _aes_disable_data_intr(void)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
/****** Interrupt Control bit is bit 2 ********/
ptr->CTRL &= ~(1 << 2);
}
#if INTERRUPT_SUPPORT
/*****************************************************
* Name: _aes_enable_key_intr
* Function: Enable key interrupter
* Params: None
* Return: None
*
*****************************************************/
static void _aes_enable_key_intr(void)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
/****** Interrupt Control bit is bit 2 ********/
ptr->CTRL |= (1 << 1);
}
#endif
/*****************************************************
* Name: _aes_disable_key_intr
* Function: Disable key interrupter
* Params: None
* Return: None
*
*****************************************************/
static void _aes_disable_key_intr(void)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
/****** Interrupt Control bit is bit 2 ********/
ptr->CTRL &= ~(1 << 1);
}
/*****************************************************
* Name: _aes_enable
* Function: Enable AES
* Params: None
* Return: None
*
*****************************************************/
static void _aes_enable(void)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
/****** AES Control bit is bit 2 ********/
ptr->CTRL |= (1 << 0);
}
/****************************************************
* Name: _aes_disable
* Function: Disable AES
* Params: None
* Return: None
*
*****************************************************/
static void _aes_disable(void)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
/****** AES Control bit is bit 2 ********/
ptr->CTRL &= ~(1 << 0);
}
/*****************************************************
* Name: _aes_get_intr_status
* Function: Get AES interrupter status
* Params: @AES_IT ---- AES states bit
* AES_IT_DATAINT
* AES_IT_KEYINT
* AES_IT_BUSY
* Return: if interrupter happened, return true
* else return false
*
*****************************************************/
static bool _aes_get_intr_status(uint32_t AES_IT)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
/**** if AES_IT hava been set, it return true ******/
return (ptr->STATE & AES_IT) ? true : false;
}
#ifdef INTERRUPT_SUPPORT
/*****************************************************
* Name: _aes_clear_intr_status
* Function: Clear AES interrupter
* Params: @AES_IT ---- AES states bit
* AES_IT_DATAINT
* AES_IT_KEYINT
* AES_IT_BUSY
* AES_IT_ALL
* Return: None
*****************************************************/
static void _aes_clear_intr_status(uint32_t AES_IT)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
/***** write 1 to AES_IT's bit , it will clear Interrupter ***/
ptr->STATE &= ~AES_IT;
}
#endif
/******************************************************************************
* Name:_aes_get_data
* Function: Clear AES get data
* Params: @data ---- a pointer point to data address which used to save data
* Return: None
******************************************************************************/
static uint32_t *_aes_get_data(uint32_t* data)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
int32_t i = 0;
#ifdef INTERRUPT_SUPPORT
//wait for aes busy
while (!_g_is_data_completed);
_g_is_data_completed = false;
#else
while (_aes_get_intr_status(AES_IT_BUSY));
#endif
if (_g_aes_big_endian) {
//if Endian is Big endian
for (i = 0; i < 4; i++) {
*data++ = ptr->Dout[3 - i];
}
} else {
for (i = 0; i < 4; i++) {
*data++ = ptr->Dout[i];
}
}
return data;
}
int32_t _aes_clk_on(void)
{
return 0;
}
int32_t _aes_clk_off(void)
{
return 0;
}
int32_t aes_drv_suspend(dev_t *dev, int32_t state)
{
return SUCCESS;
}
int32_t aes_drv_resume(dev_t *dev)
{
return SUCCESS;
}
uint32_t _aes_save_context(uint32_t *buf)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
uint32_t i, sz;
sz = (sizeof(aes_reg_t) >> 2);
for (i = 0; i < sz; i++) {
*(buf + i) = *((uint32_t *)ptr + i);
}
return SUCCESS;
}
uint32_t _aes_restore_context(uint32_t *buf)
{
paes_reg_t ptr = (paes_reg_t)PLATFORM_AES_ADDRBASE;
uint32_t i, sz;
sz = (sizeof(aes_reg_t) >> 2);
for (i = 0; i < sz; i++) {
*((uint32_t *)ptr + i) = *(buf + i);
}
return SUCCESS;
}
int32_t aes_drv_get_ctx_size(void *arg)
{
aes_drv_ioctl_buf_size_t *p = (aes_drv_ioctl_buf_size_t *)arg;
if (!VALID_MAGIC(p->magic)) {
return EARG;
}
p->ctx_size = sizeof(aes_reg_t);
return SUCCESS;
}
int32_t aes_drv_init(void *arg)
{
aes_drv_ioctl_init_t *p = (aes_drv_ioctl_init_t *)arg;
aes_mode_t mode;
bool is_enc;
uint32_t *key;
aes_keylength_t keylen;
uint32_t *iv;
void *ctx;
if (!VALID_MAGIC(p->magic)) {
return EARG;
}
mode = p->mode;
is_enc = p->is_enc;
key = p->key;
keylen = p->keylen;
iv = p->iv;
ctx = p->ctx;
_aes_clk_on();
/* disable aes for safe */
_aes_disable();
/* reset aes engine */
_aes_disable_key_intr();
_aes_disable_data_intr();
_aes_disable();
_aes_set_endian(AES_ENDIAN_LITTLE);
_aes_set_key(key, keylen);
_aes_set_keylen(keylen);
_aes_set_mode(mode);
if (AES_MODE_CBC == mode) {
_aes_set_iv(iv);
}
if (!is_enc) {
_aes_set_opcode(AES_OPCODE_KEYEXPAND);
while (_aes_get_intr_status(AES_IT_KEYINT));
_aes_set_opcode(AES_OPCODE_DECRYPT);
} else {
_aes_set_opcode(AES_OPCODE_ENCRYPT);
}
/* disable aes after initialization*/
_aes_disable();
/* save aes context */
_aes_save_context((uint32_t *)(p->ctx));
_aes_clk_off();
return SUCCESS;
}
int32_t aes_drv_process(void *arg)
{
aes_drv_ioctl_process_t *p = (aes_drv_ioctl_process_t *)arg;
if (!VALID_MAGIC(p->magic)) {
return EARG;
}
_aes_clk_on();
/* disable aes for safe */
_aes_disable();
/* restore aes context */
_aes_restore_context((uint32_t *)(p->ctx));
/* set data */
_aes_set_data(p->src_blk);
/* start aes engine and get data */
_aes_enable();
_aes_get_data(p->dst_blk);
_aes_disable();
/* save aes context */
_aes_save_context((uint32_t *)(p->ctx));
_aes_clk_off();
return SUCCESS;
}
int32_t aes_drv_finish(void *arg)
{
aes_drv_ioctl_final_t *p = (aes_drv_ioctl_final_t *)arg;
if (!VALID_MAGIC(p->magic)) {
return EARG;
}
_aes_clk_on();
_aes_disable();
_aes_clk_off();
memset(p->ctx, 0, sizeof(aes_reg_t));
return SUCCESS;
}

View file

@ -0,0 +1,52 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
**/
#ifndef _AES_DRV_H_
#define _AES_DRV_H_
#include "tee_types.h"
#include "hal_memmap.h"
typedef struct _aes_reg_t {
uint32_t Din[4]; /* Data input 0~127 */
uint32_t KEY[8]; /* Key 0~255 */
uint32_t IV[4]; /* Initial Vector: 0~127 */
uint32_t CTRL; /* AES Control Register */
uint32_t STATE; /* AES State Register */
uint32_t Dout[4]; /* Data Output 0~31 */
} aes_reg_t, *paes_reg_t;
/******* Define IT Bits *********/
#define AES_IT_DATAINT 0x4
#define AES_IT_KEYINT 0x2
#define AES_IT_BUSY 0x1
#define AES_IT_ALL 0x7
/****** Enum of AES Edian ******/
typedef enum _aes_endian_t {
AES_ENDIAN_LITTLE,
AES_ENDIAN_BIG
} aes_endian_t;
/***** Enum of AES Opcode ******/
typedef enum _aes_opcode_t {
AES_OPCODE_ENCRYPT,
AES_OPCODE_DECRYPT,
AES_OPCODE_KEYEXPAND,
} aes_opcode_t;
/***** Enum of AES Key Length *****/
typedef enum _aes_keylength_t {
AES_KEYLEN_128,
AES_KEYLEN_192,
AES_KEYLEN_256
} aes_keylength_t;
/***** Enum of AES Mode *******/
typedef enum _aes_mode_t{
AES_MODE_EBC,
AES_MODE_CBC
} aes_mode_t;
#endif /* _AES_DRV_H_ */

View file

@ -0,0 +1,230 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
**/
#include "tee_types.h"
#include "tee_dbg.h"
#include "device.h"
#include "crypto_drv.h"
typedef int32_t (*ioctl_func_t)(void *arg);
static int32_t _crypto_open(dev_t *dev);
static int32_t _crypto_close(dev_t *dev);
static int32_t _crypto_ioctl(dev_t *dev, int32_t cmd, void *arg);
static int32_t _crypto_suspend(dev_t *dev, int32_t state);
static int32_t _crypto_resume(dev_t *dev);
const static ioctl_func_t _g_crypto_ioctl_ops[] = {
#ifdef RSA_SUPPORT
rsa_drv_mode_exp,
#endif
#ifdef AES_SUPPORT
aes_drv_get_ctx_size,
aes_drv_init,
aes_drv_process,
aes_drv_finish,
#endif
#ifdef SHA_SUPPORT
sha_drv_get_ctx_size,
sha_drv_init,
sha_drv_process,
sha_drv_finish,
#endif
#ifdef TRNG_SUPPORT
trng_random_get,
#endif
};
const static dev_ops_t _g_crypto_ops = {
.open = _crypto_open,
.close = _crypto_close,
.ioctl = _crypto_ioctl,
.read = NULL,
.write = NULL,
.suspend = _crypto_suspend,
.resume = _crypto_resume,
};
static struct _crypto_dev_t {
int8_t *name;
dev_t *crypto_dev;
int32_t open_cnt;
bool busy;
dev_ops_t *ops;
#ifdef RSA_SUPPORT
uint32_t rsa_addr_base;
#ifdef INTERRUPT_SUPPORT
irq_handler_t *rsa_irq;
#endif
#endif
#ifdef AES_SUPPORT
uint32_t aes_addr_base;
#ifdef INTERRUPT_SUPPORT
irq_handler_t *aes_irq;
#endif
#endif
#ifdef SHA_SUPPORT
uint32_t sha_addr_base;
#ifdef INTERRUPT_SUPPORT
irq_handler_t *hash_irq;
#endif
#endif
} _g_crypto_dev;
static int32_t _crypto_probe(void)
{
int32_t ret = 0;
memset(&_g_crypto_dev, 0, sizeof(_g_crypto_dev));
_g_crypto_dev.name = CRYPTO_DEV_NAME;
_g_crypto_dev.open_cnt = 0;
_g_crypto_dev.busy = false;
_g_crypto_dev.ops = (dev_ops_t *)(&_g_crypto_ops);
#ifdef RSA_SUPPORT
/* _g_crypto_dev.rsa_addr_base = PLATFORM_RSA_ADDRBASE; */
#ifdef INTERRUPT_SUPPORT
_g_crypto_dev.rsa_irq = &_rsa_irq_handler;
#endif
#endif
#ifdef AES_SUPPORT
/* _g_crypto_dev.aes_addr_base = PLATFORM_AES_ADDRBASE; */
#ifdef INTERRUPT_SUPPORT
_g_crypto_dev.aes_irq = &_aes_irq_handler;
#endif
#endif
#ifdef SHA_SUPPORT
/* _g_crypto_dev.hash_addr_base = CK_HASH_ADDRBASE; */
#ifdef INTERRUPT_SUPPORT
_g_crypto_dev.hash_irq = &_hash_irq_handler;
#endif
#endif
_g_crypto_dev.crypto_dev = dev_register(
_g_crypto_dev.name, _g_crypto_dev.ops);
if (NULL == _g_crypto_dev.crypto_dev) {
ret = -1;
goto __out;
}
__out:
return ret;
}
static int32_t _crypto_open(dev_t *dev)
{
if (dev != _g_crypto_dev.crypto_dev) {
return FAIL;
}
if (_g_crypto_dev.open_cnt) {
return EBUSY;
}
_g_crypto_dev.open_cnt++;
return SUCCESS;
}
static int32_t _crypto_close(dev_t *dev)
{
if (1 != _g_crypto_dev.open_cnt) {
return FAIL;
}
if (dev != _g_crypto_dev.crypto_dev) {
return FAIL;
}
_g_crypto_dev.open_cnt--;
return SUCCESS;
}
static int32_t _crypto_ioctl(dev_t *dev, int32_t cmd, void *arg)
{
int32_t ret = 0;
ioctl_func_t func;
if (dev != _g_crypto_dev.crypto_dev) {
return FAIL;
}
if (!arg) {
return EARG;
}
if (1 != _g_crypto_dev.open_cnt) {
return FAIL;
}
_g_crypto_dev.busy = true;
if (cmd > sizeof(_g_crypto_ioctl_ops)/sizeof(_g_crypto_ioctl_ops[0])) {
return EARG;
}
func = _g_crypto_ioctl_ops[cmd];
if (!func) {
return FAIL;
}
ret = func(arg);
_g_crypto_dev.busy = false;
return ret;
}
static int32_t _crypto_suspend(dev_t *dev, int32_t state)
{
if (_g_crypto_dev.busy) {
return EBUSY;
}
#ifdef RSA_SUPPORT
rsa_drv_suspend(dev, state);
#endif
#ifdef AES_SUPPORT
aes_drv_suspend(dev, state);
#endif
#ifdef SHA_SUPPORT
sha_drv_suspend(dev, state);
#endif
#ifdef TRNG_SUPPORT
trng_drv_suspend(dev, state);
#endif
return SUCCESS;
}
static int32_t _crypto_resume(dev_t *dev)
{
#ifdef RSA_SUPPORT
rsa_drv_resume(dev);
#endif
#ifdef AES_SUPPORT
aes_drv_resume(dev);
#endif
#ifdef SHA_SUPPORT
sha_drv_resume(dev);
#endif
#ifdef TRNG_SUPPORT
trng_drv_resume(dev);
#endif
return SUCCESS;
}
DEV_INIT(_crypto_probe, (uint8_t *)CRYPTO_DEV_NAME);

View file

@ -0,0 +1,450 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
**/
#include "tee_types.h"
#include "tee_dbg.h"
#include "rsa_drv.h"
#include "device.h"
#include "crypto_drv.h"
#undef INTERRUPT_SUPPORT
#ifdef INTERRUPT_SUPPORT
void _rsa_intr(uint32_t irq);
static irq_handler_t _rsa_irq_handler = {
"RSA_INTR",
INTC_RSA,
INTC_RSA%4,
_rsa_intr,
FALSE
};
/* interrupt callback function point */
static void (*_rsa_intr_callback)(void) = NULL;
void _rsa_intr(uint32_t irq)
{
if(NULL != _rsa_intr_callback)
_rsa_intr_callback();
}
#endif
/*
* write one to corresponding bit clear the interrupt
* Parameters: void
*/
static uint32_t _rsa_clear_intr(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
ptr->RSA_ISR = 0xffff;
ptr->RSA_IMR = 0x0000;
return SUCCESS;
}
/*
* write modulus M to MWID register
* Parameters:
* width: width of modulus M
*/
static uint32_t _rsa_set_mwidth(uint32_t width)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
ptr->RSA_MWID = width;
return SUCCESS;
}
/*
* write key D to DWID register
* Parameters:
* width: width of key D
*/
static uint32_t _rsa_set_dwidth(uint32_t width)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
ptr->RSA_DWID = width;
return SUCCESS;
}
/*
* write B to BWID register
* Parameters:
* width: width of B
*/
static uint32_t _rsa_set_bwidth(uint32_t width)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
ptr->RSA_BWID = width;
return SUCCESS;
}
/*
* set the CAL_Q and RSA_EN before encryption or decryption
* parameters: void
*/
static uint32_t _rsa_cal_q(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
ptr->RSA_CTRL |= 0x6;
return SUCCESS;
}
/*
* set the RSA start
* parameters: void
*/
static uint32_t _rsa_start(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
ptr->RSA_CTRL |= 0x3;
return SUCCESS;
}
/*
* software reset for RSA
* parameters: void
*/
static uint32_t _rsa_reset(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
ptr->RSA_RST |= 0x1;
return SUCCESS;
}
/*
* the counter of loop Modular Multiplication
* parameters: void
*/
static uint32_t _rsa_lp_cnt(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
uint32_t temp;
return temp = ptr->RSA_LP_CNT;
}
#if 0
/*
* calculate the Q value: Q0
* parameters: void
*/
static uint32_t _rsa_q0(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
uint32_t temp;
return temp = ptr->RSA_Q0;
}
/*
* calculate the Q value: Q1
* parameters: void
*/
static uint32_t _rsa_q1(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
uint32_t temp;
return temp = ptr->RSA_Q1;
}
#endif
/*
* wait cal_q calculation done
* parameters: void
*/
static uint32_t _rsa_cal_q_done(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
uint32_t temp = (ptr->RSA_ISR>>5) & 0x1;
return temp;
}
#ifdef INTERRUPT_SUPPORT
/*
* interrupt
* parameters: void
*/
static uint32_t _rsa_abnormal_1(void)
{
uint32_t temp;
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
return temp = (ptr->RSA_ISR >> 1) & 0x1;
}
/*
* interrupt
* parameters: void
*/
static uint32_t _rsa_abnormal_2(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
uint32_t temp;
return temp = (ptr->RSA_ISR >> 2) & 0x1;
}
/*
* interrupt
* parameters: void
*/
static uint32_t _rsa_abnormal_3(void)
{
uint32_t temp;
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
return temp = (ptr->RSA_ISR >> 3) & 0x1;
}
/*
* interrupt
* parameters: void
*/
static uint32_t _rsa_abnormal_4(void)
{
uint32_t temp;
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
return temp = (ptr->RSA_ISR >> 4) & 0x1;
}
#endif
/*
* RSA_DONE
* parameters: void
*/
static uint32_t _rsa_done(void)
{
uint32_t temp;
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
return temp = (ptr->RSA_ISR) & 0x1;
}
#ifdef INTERRUPT_SUPPORT
/*
* mask cal_q calculation
* parameters: void
*/
static uint32_t _rsa_unmask_cal_q_done(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
ptr->RSA_IMR |= 0x20;
return SUCCESS;
}
/*
* mask interrupt
* parameters: void
*/
static uint32_t _rsa_unmask_abnormal_1(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
ptr->RSA_IMR |= 0x2;
return SUCCESS;
}
/*
* mask interrupt
* parameters: void
*/
static uint32_t _rsa_unmask_abnormal_2(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
ptr->RSA_IMR |= 0x4;
return SUCCESS;
}
/*
* mask interrupt
* parameters: void
*/
static uint32_t _rsa_unmask_abnormal_3(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
ptr->RSA_IMR |= 0x8;
return SUCCESS;
}
/*
* mask interrupt
* parameters: void
*/
static uint32_t _rsa_unmask_abnormal_4(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
ptr->RSA_IMR |= 0x10;
return SUCCESS;
}
/*
* mask RSA_DONE
* parameters: void
*/
static uint32_t _rsa_unmask_done(void)
{
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
ptr->RSA_IMR |= 0x1;
return SUCCESS;
}
#endif
/*
* write RFM
* Parameters:
* data : store the modulus M
* length: the data length
*/
static uint32_t _rsa_load_m(uint32_t data[], uint32_t length)
{
int32_t i;
uint32_t baseaddr;
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
baseaddr = (uint32_t)&ptr->RSA_RFM;
for (i = 1; i < length + 1; i++) {
*(volatile uint32_t *)baseaddr = data[i - 1];
baseaddr = baseaddr+4;
}
return SUCCESS;
}
/*
* write RFD
* Parameters:
* data : store the exponent D
* length: the data length
*/
static uint32_t _rsa_load_d(uint32_t data[], uint32_t length)
{
int32_t i;
uint32_t baseaddr;
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
baseaddr = (uint32_t)&ptr->RSA_RFD;
for (i = 1; i < length + 1; i++) {
*(volatile uint32_t *)baseaddr = data[i - 1];
baseaddr = baseaddr + 4;
}
return SUCCESS;
}
/*
* write RFC
* Parameters:
* data : store the auxiliary key C
* length: the data length
*/
static uint32_t _rsa_load_c(uint32_t data[], uint32_t length)
{
int32_t i;
uint32_t baseaddr;
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
baseaddr = (uint32_t)&ptr->RSA_RFC;
for (i = 1; i < length + 1; i++) {
*(volatile uint32_t *)baseaddr = data[i - 1];
baseaddr = baseaddr + 4;
}
return SUCCESS;
}
/*
* write RFB
* Parameters:
* data : store the data B
* length: the data length
*/
static uint32_t _rsa_load_b(uint32_t data[], uint32_t length)
{
int32_t i;
uint32_t baseaddr;
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
baseaddr = (uint32_t)&ptr->RSA_RFB;
for (i = 1; i < length + 1; i++) {
*(volatile uint32_t *)baseaddr = data[i-1];
baseaddr = baseaddr + 4;
}
return SUCCESS;
}
/*
* write RFR
* Parameters:
* data : read the result data
* length: the data length
*/
static uint32_t _rsa_read_r(uint32_t data[], uint32_t length)
{
int32_t i;
uint32_t baseaddr;
volatile prsa_reg_t ptr = (prsa_reg_t)PLATFORM_RSA_ADDRBASE;
baseaddr = (uint32_t)&ptr->RSA_RFR;
for (i = 1; i < length + 1; i++) {
data[i-1] = *(volatile uint32_t *)baseaddr;
baseaddr = baseaddr + 4;
}
return SUCCESS;
}
int32_t _rsa_clk_on(void)
{
return 0;
}
int32_t _rsa_clk_off(void)
{
return 0;
}
int32_t rsa_drv_mode_exp(void *arg)
{
rsa_drv_ioctl_t *p = (rsa_drv_ioctl_t *)arg;
int32_t ret = SUCCESS;
if (!VALID_MAGIC(p->magic)) {
return EARG;
}
if ((p->words) & 1) {
return EARG;
}
/* reset for safe */
_rsa_reset();
/* clear and disable intr */
_rsa_clear_intr();
/* set m */
_rsa_set_mwidth((p->words) >> 1);
_rsa_load_m(p->m, p->words);
/* set d */
_rsa_set_dwidth((p->d_valid_bits) - 1);
_rsa_load_d(p->d, p->words);
/* set b */
_rsa_set_bwidth((p->words) >> 1);
_rsa_load_b(p->b, p->words);
/* set c */
_rsa_load_c(p->c, p->words);
_rsa_cal_q();
while(!_rsa_cal_q_done());
_rsa_start();
while((!_rsa_done()) && (_rsa_lp_cnt() < _MAX_RSA_LP_CNT));
_rsa_read_r(p->r, p->words);
if (_rsa_lp_cnt() >= _MAX_RSA_LP_CNT) {
ret = FAIL;
goto __out;
}
__out:
_rsa_reset();
return ret;
}
int32_t rsa_drv_suspend(dev_t *dev, int32_t state)
{
return SUCCESS;
}
int32_t rsa_drv_resume(dev_t *dev)
{
return SUCCESS;
}

View file

@ -0,0 +1,36 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
**/
#ifndef _RSA_DRV_H_
#define _RSA_DRV_H_
#include "tee_types.h"
#include "hal_memmap.h"
#define _MAX_RSA_LP_CNT (100000)
typedef struct _rsa_reg_t {
uint32_t RSA_MWID;
uint32_t RSA_DWID;
uint32_t RSA_BWID;
uint32_t RSA_CTRL;
uint32_t RSA_RST;
uint32_t RSA_LP_CNT;
uint32_t RSA_Q0;
uint32_t RSA_Q1;
uint32_t RSA_ISR;
uint32_t RSA_IMR;
uint32_t Rev1[54];
uint32_t RSA_RFM;
uint32_t Rev2[63];
uint32_t RSA_RFD;
uint32_t Rev3[63];
uint32_t RSA_RFC;
uint32_t Rev4[63];
uint32_t RSA_RFB;
uint32_t Rev5[63];
uint32_t RSA_RFR;
} rsa_reg_t, *prsa_reg_t;
#endif /* _RSA_DRV_H_ */

View file

@ -0,0 +1,617 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
**/
#include "hal_memmap.h"
#include "sha_drv.h"
#include "device.h"
#include "tee_dbg.h"
#include "crypto_drv.h"
#define SHA_MAX_TIME 20
#define SHA_MAX_SIZE 64
#define BLOCK_MAX_SIZE 128
static uint8_t sha1_hash[20] = {
0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09
};
static uint8_t sha224_hash[28] = {
0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9, 0x47, 0x61,
0x02, 0xbb, 0x28, 0x82, 0x34, 0xc4, 0x15, 0xa2, 0xb0, 0x1f,
0x82, 0x8e, 0xa6, 0x2a, 0xc5, 0xb3, 0xe4, 0x2f
};
static uint8_t sha256_hash[32] = {
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb,
0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4,
0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52,
0xb8, 0x55
};
static uint8_t sha384_hash[48] = {
0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, 0x4c, 0xd9,
0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, 0x21, 0xfd, 0xb7, 0x11,
0x14, 0xbe, 0x07, 0x43, 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6,
0xe1, 0xda, 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb,
0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b
};
static uint8_t sha512_hash[64] = {
0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, 0xf1, 0x54,
0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, 0xd6, 0x20, 0xe4, 0x05,
0x0b, 0x57, 0x15, 0xdc, 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c,
0xe9, 0xce, 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, 0x63, 0xb9,
0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, 0xa5, 0x38, 0x32, 0x7a,
0xf9, 0x27, 0xda, 0x3e
};
#ifdef SHA_DRV_DBG
static void _print_msg_data(uint8_t *data, uint32_t len)
{
uint32_t i;
for (i = 0; i < len; i += 8) {
CRYPTO_DRV_DBG_I("msg: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
data[i+0], data[i+1], data[i+2], data[i+3], data[i+4], data[i+5], data[i+6], data[i+7]);
}
return;
}
#endif
static uint32_t _sha_reverse_order(uint32_t data)
{
uint32_t result = 0;
__asm__("revb %0, %1\n"
: "=r" (result)
: "r" (data));
return result;
}
static void _sha_set_msg_size(uint32_t msg, uint32_t msg_size,
uint32_t total_size, sha_mode_t mode)
{
uint32_t *msg_buf = (uint32_t *)msg;
msg_buf += (msg_size + 0x3) / 4;
if (mode == SHA_MODE_SHA1 ||
mode == SHA_MODE_SHA224 || mode == SHA_MODE_SHA256) {
*(msg_buf) = 0;
*(msg_buf + 1) = total_size << 3;
} else {
*(msg_buf) = 0;
*(msg_buf + 1) = 0;
*(msg_buf + 2) = 0;
*(msg_buf + 3) = total_size << 3;
}
return;
}
static uint32_t _sha_calc_done(void)
{
uint32_t is_done = 0;
volatile sha_reg_t *sha_regs = (sha_reg_t *)PLATFORM_SHA_BADDR;
is_done = sha_regs->sha_intstate & 0x1;
return is_done;
}
static int32_t _cal_sha_without_count(uint32_t mode,
uint32_t msg, uint32_t msg_len, uint32_t hash)
{
uint32_t times = 0;
uint32_t is_done = 0;
volatile sha_reg_t *sha_regs = (sha_reg_t *)PLATFORM_SHA_BADDR;
#ifdef SHA_DRV_DBG
CRYPTO_DRV_DBG_I("without_count -- msg_len: %d mode: %d\n", msg_len, mode);
#endif
/* new encode */
sha_regs->sha_mode = 0x0;
sha_regs->sha_intstate = 0x0;
/* set src and dst addr */
sha_regs->sha_baseaddr = msg;
sha_regs->sha_destaddr = hash;
sha_regs->sha_mode |= mode & 0x7;
sha_regs->sha_mode |= 0x1 << 25;
sha_regs->sha_counter0 = msg_len << 3;
sha_regs->sha_counter1 = 0;
sha_regs->sha_counter2 = 0;
sha_regs->sha_counter3 = 0;
/* enable encode */
sha_regs->sha_ctrl |= 0x1;
do {
is_done = _sha_calc_done();
} while (!is_done && times++ < SHA_MAX_TIME);
if (times == SHA_MAX_TIME) {
CRYPTO_DRV_DBG_E("_cal_sha_without_counttime out\n");
return -1;
}
return 0;
}
static int32_t _cal_sha_without_count_enable_initial(uint32_t mode,
uint32_t msg, uint32_t msg_len, uint32_t hash)
{
uint32_t times = 0;
uint32_t is_done = 0;
volatile sha_reg_t *sha_regs = (sha_reg_t *)PLATFORM_SHA_BADDR;
#ifdef SHA_DRV_DBG
CRYPTO_DRV_DBG_I("without_count_enable_initial -- msg_len: %d mode: %d\n", msg_len, mode);
#endif
/* new encode */
sha_regs->sha_mode = 0x0;
sha_regs->sha_intstate = 0x0;
/* set src and dst addr */
sha_regs->sha_baseaddr = msg;
sha_regs->sha_destaddr = hash;
sha_regs->sha_mode |= mode & 0x7;
sha_regs->sha_mode |= 0x1 << 3;
sha_regs->sha_mode |= 0x1 << 25;
sha_regs->sha_counter0 = msg_len << 3;
sha_regs->sha_counter1 = 0;
sha_regs->sha_counter2 = 0;
sha_regs->sha_counter3 = 0;
/* enable encode */
sha_regs->sha_ctrl |= 0x1;
do {
is_done = _sha_calc_done();
} while (!is_done && times++ < SHA_MAX_TIME);
if (times == SHA_MAX_TIME) {
CRYPTO_DRV_DBG_E("_cal_sha_without_count_enable_initialtime out\n");
return -1;
}
return 0;
}
static int32_t _cal_sha_enable_initial(uint32_t mode,
uint32_t msg, uint32_t msg_len, uint32_t hash)
{
uint32_t times = 0;
uint32_t is_done = 0;
volatile sha_reg_t *sha_regs = (sha_reg_t *)PLATFORM_SHA_BADDR;
#ifdef SHA_DRV_DBG
CRYPTO_DRV_DBG_I("enable_initial -- msg_len: %d mode: %d\n", msg_len, mode);
_print_msg_data((uint8_t *)msg, msg_len);
#endif
/* new encode */
sha_regs->sha_mode = 0x0;
sha_regs->sha_intstate = 0x0;
/* set src and dst addr */
sha_regs->sha_baseaddr = msg;
sha_regs->sha_destaddr = hash;
sha_regs->sha_mode |= mode & 0x7;
sha_regs->sha_mode |= 0x1 << 3;
sha_regs->sha_counter0 = msg_len << 3;
sha_regs->sha_counter1 = 0;
sha_regs->sha_counter2 = 0;
sha_regs->sha_counter3 = 0;
/* enable encode */
sha_regs->sha_ctrl |= 0x1;
do {
is_done = _sha_calc_done();
} while (!is_done && times++ < SHA_MAX_TIME);
if (times == SHA_MAX_TIME) {
CRYPTO_DRV_DBG_E("_cal_sha_enable_initialtime out\n");
return -1;
}
return 0;
}
static void _sha_save_regs(uint32_t *buf)
{
uint32_t i;
uint32_t regs_num;
volatile sha_reg_t *sha_regs = (sha_reg_t *)PLATFORM_SHA_BADDR;
regs_num = sizeof(sha_reg_t)/ sizeof(uint32_t);
for (i = 0; i < regs_num; i++) {
*(buf + i) = *((uint32_t *)sha_regs + i);
}
return;
}
static void _sha_restore_regs(uint32_t *buf)
{
uint32_t i;
uint32_t regs_num;
sha_reg_t *sha_regs = (sha_reg_t *)PLATFORM_SHA_BADDR;
regs_num = sizeof(sha_reg_t)/ sizeof(uint32_t);
for (i = 0; i < regs_num; i++) {
*((uint32_t *)sha_regs + i) = *(buf + i);
}
return;
}
/* save hash value into dst buffer */
static void _sha_get_digest(uint32_t *src, uint32_t size, uint8_t *dst)
{
uint32_t i;
for (i = 0; i < size >> 2; i++) {
src[i] = _sha_reverse_order(src[i]);
#ifdef SHA_DRV_DBG
CRYPTO_DRV_DBG_I("hash: %08x\n", src[i]);
#endif
}
memcpy(dst, (uint8_t *)src, size);
return;
}
int32_t sha_drv_suspend(dev_t *dev, int32_t state)
{
return 0;
}
int32_t sha_drv_resume(dev_t *dev)
{
return 0;
}
int32_t sha_drv_get_ctx_size(void *arg)
{
sha_drv_ioctl_buf_size_t *get_arg;
TEE_ASSERT(arg);
get_arg = (sha_drv_ioctl_buf_size_t *)arg;
if (!VALID_MAGIC(get_arg->magic)) {
return -1;
}
get_arg->ctx_size = sizeof(sha_drv_ctx_t);
return 0;
}
int32_t sha_drv_init(void *arg)
{
sha_drv_ioctl_init_t *init_arg;
sha_drv_ctx_t *sha_ctx;
volatile sha_reg_t *sha_regs = (sha_reg_t *)PLATFORM_SHA_BADDR;
TEE_ASSERT(arg);
init_arg = (sha_drv_ioctl_init_t *)arg;
if (!VALID_MAGIC(init_arg->magic)) {
return -1;
}
sha_ctx = (sha_drv_ctx_t *)init_arg->ctx;
sha_ctx->state = SHA_DRV_INITED;
sha_ctx->data_size = 0;
sha_ctx->total_size = 0;
switch(init_arg->mode) {
case SHA_MODE_SHA1: {
sha_regs->sha_h0l = 0x67452301;
sha_regs->sha_h1l = 0xEFCDAB89;
sha_regs->sha_h2l = 0x98BADCFE;
sha_regs->sha_h3l = 0x10325476;
sha_regs->sha_h4l = 0xC3D2E1F0;
break;
}
case SHA_MODE_SHA256: {
sha_regs->sha_h0l = 0x6A09E667;
sha_regs->sha_h1l = 0xBB67AE85;
sha_regs->sha_h2l = 0x3C6EF372;
sha_regs->sha_h3l = 0xA54FF53A;
sha_regs->sha_h4l = 0x510E527F;
sha_regs->sha_h5l = 0x9B05688C;
sha_regs->sha_h6l = 0x1F83D9AB;
sha_regs->sha_h7l = 0x5BE0CD19;
break;
}
case SHA_MODE_SHA224: {
sha_regs->sha_h0l = 0xc1059ed8;
sha_regs->sha_h1l = 0x367cd507;
sha_regs->sha_h2l = 0x3070dd17;
sha_regs->sha_h3l = 0xf70e5939;
sha_regs->sha_h4l = 0xffc00b31;
sha_regs->sha_h5l = 0x68581511;
sha_regs->sha_h6l = 0x64f98fa7;
sha_regs->sha_h7l = 0xbefa4fa4;
break;
}
case SHA_MODE_SHA512: {
sha_regs->sha_h0h = 0x6a09e667;
sha_regs->sha_h0l = 0xf3bcc908;
sha_regs->sha_h1h = 0xbb67ae85;
sha_regs->sha_h1l = 0x84caa73b;
sha_regs->sha_h2h = 0x3c6ef372;
sha_regs->sha_h2l = 0xfe94f82b;
sha_regs->sha_h3h = 0xa54ff53a;
sha_regs->sha_h3l = 0x5f1d36f1;
sha_regs->sha_h4h = 0x510e527f;
sha_regs->sha_h4l = 0xade682d1;
sha_regs->sha_h5h = 0x9b05688c;
sha_regs->sha_h5l = 0x2b3e6c1f;
sha_regs->sha_h6h = 0x1f83d9ab;
sha_regs->sha_h6l = 0xfb41bd6b;
sha_regs->sha_h7h = 0x5be0cd19;
sha_regs->sha_h7l = 0x137e2179;
break;
}
case SHA_MODE_SHA384: {
sha_regs->sha_h0h = 0xcbbb9d5d;
sha_regs->sha_h0l = 0xc1059ed8;
sha_regs->sha_h1h = 0x629a292a;
sha_regs->sha_h1l = 0x367cd507;
sha_regs->sha_h2h = 0x9159015a;
sha_regs->sha_h2l = 0x3070dd17;
sha_regs->sha_h3h = 0x152fecd8;
sha_regs->sha_h3l = 0xf70e5939;
sha_regs->sha_h4h = 0x67332667;
sha_regs->sha_h4l = 0xffc00b31;
sha_regs->sha_h5h = 0x8eb44a87;
sha_regs->sha_h5l = 0x68581511;
sha_regs->sha_h6h = 0xdb0c2e0d;
sha_regs->sha_h6l = 0x64f98fa7;
sha_regs->sha_h7h = 0x47b5481d;
sha_regs->sha_h7l = 0xbefa4fa4;
break;
}
default: {
CRYPTO_DRV_DBG_E("sha_drv_init: invalid sha mode(%d)\n", init_arg->mode);
return -1;
}
}
_sha_save_regs((uint32_t *)&(sha_ctx->sha_regs));
return 0;
}
int32_t sha_drv_process(void *arg)
{
int ret;
uint32_t block_size;
uint32_t src_size;
uint8_t *src_data;
uint8_t hash[SHA_MAX_SIZE];
sha_drv_ioctl_proc_t *proc_arg;
sha_drv_ctx_t *sha_ctx;
TEE_ASSERT(arg);
proc_arg = (sha_drv_ioctl_proc_t *)arg;
if (!VALID_MAGIC(proc_arg->magic)) {
CRYPTO_DRV_DBG_E("sha_drv_process: bad magic(%08x)\n", proc_arg->magic);
return -1;
}
if (proc_arg->mode >= SHA_MODE_MAX ||
proc_arg->mode <= SHA_MODE_INVALID) {
CRYPTO_DRV_DBG_E("sha_drv_process: bad mode(%d)\n", proc_arg->mode);
return -1;
}
if (proc_arg->mode == SHA_MODE_SHA1 ||
proc_arg->mode == SHA_MODE_SHA256 ||
proc_arg->mode == SHA_MODE_SHA224) {
block_size = 64;
} else {
block_size = 128;
}
src_data = (uint8_t *)proc_arg->src_addr;
src_size = proc_arg->src_size;
sha_ctx = (sha_drv_ctx_t *)proc_arg->ctx;
_sha_restore_regs((uint32_t *)&sha_ctx->sha_regs);
if (sha_ctx->data_size + src_size <= block_size) {
if (src_size) {
memcpy(sha_ctx->data + sha_ctx->data_size,
src_data, src_size);
sha_ctx->data_size += src_size;
}
return 0;
}
if (sha_ctx->data_size < block_size) {
memcpy(sha_ctx->data + sha_ctx->data_size,
src_data, block_size - sha_ctx->data_size);
src_data += block_size - sha_ctx->data_size;
src_size -= block_size - sha_ctx->data_size;
}
if (sha_ctx->state == SHA_DRV_INITED) {
ret = _cal_sha_without_count(proc_arg->mode,
(uint32_t)sha_ctx->data, block_size, (uint32_t)hash);
if (ret < 0) {
CRYPTO_DRV_DBG_E("sha_drv_process: calc hash without count fail!\n");
return -1;
}
sha_ctx->state = SHA_DRV_STARTED;
} else {
ret = _cal_sha_without_count_enable_initial(proc_arg->mode,
(uint32_t)sha_ctx->data, block_size, (uint32_t)hash);
if (ret < 0) {
CRYPTO_DRV_DBG_E("sha_drv_process: calc first block hash with continue fail!\n");
return -1;
}
}
sha_ctx->data_size = 0;
sha_ctx->total_size += block_size;
while (src_size > block_size) {
uint32_t block[BLOCK_MAX_SIZE >> 2];
memcpy((uint8_t *)block, src_data, block_size);
ret = _cal_sha_without_count_enable_initial(
proc_arg->mode, (uint32_t)block, block_size, (uint32_t)hash);
if (ret < 0) {
CRYPTO_DRV_DBG_E("sha_drv_process: calc hash with continue fail!\n");
return -1;
}
src_data += block_size;
src_size -= block_size;
sha_ctx->total_size += block_size;
}
memcpy(sha_ctx->data, src_data, src_size);
sha_ctx->data_size = src_size;
_sha_save_regs((uint32_t *)&sha_ctx->sha_regs);
return 0;
}
int32_t sha_drv_finish(void *arg)
{
int ret = 0;
uint32_t block_size;
uint64_t total_size;
uint32_t msg_size;
uint32_t hash_size;
uint8_t *msg_buf = NULL;
uint32_t hash[SHA_MAX_SIZE >> 2];
sha_drv_ioctl_final_t *final_arg;
sha_drv_ctx_t *sha_ctx;
TEE_ASSERT(arg);
final_arg = (sha_drv_ioctl_final_t *)arg;
if (!VALID_MAGIC(final_arg->magic)) {
CRYPTO_DRV_DBG_E("sha_drv_finish: bad magic(%08x)\n", final_arg->magic);
return -1;
}
sha_ctx = (sha_drv_ctx_t *)final_arg->ctx;
msg_size = sha_ctx->data_size;
total_size = sha_ctx->total_size + msg_size;
switch(final_arg->mode) {
case SHA_MODE_SHA1: {
hash_size = 20;
block_size = 64;
if (total_size == 0) {
TEE_ASSERT(sha_ctx->state == SHA_DRV_INITED);
memcpy((uint8_t *)final_arg->dst_addr,
sha1_hash, hash_size);
return 0;
}
break;
}
case SHA_MODE_SHA256: {
hash_size = 32;
block_size = 64;
if (total_size == 0) {
TEE_ASSERT(sha_ctx->state == SHA_DRV_INITED);
memcpy((uint8_t *)final_arg->dst_addr,
sha256_hash, hash_size);
return 0;
}
break;
}
case SHA_MODE_SHA224: {
hash_size = 28;
block_size = 64;
if (total_size == 0) {
TEE_ASSERT(sha_ctx->state == SHA_DRV_INITED);
memcpy((uint8_t *)final_arg->dst_addr,
sha224_hash, hash_size);
return 0;
}
break;
}
case SHA_MODE_SHA512: {
hash_size = 64;
block_size = 128;
if (total_size == 0) {
TEE_ASSERT(sha_ctx->state == SHA_DRV_INITED);
memcpy((uint8_t *)final_arg->dst_addr,
sha512_hash, hash_size);
return 0;
}
break;
}
case SHA_MODE_SHA384: {
hash_size = 48;
block_size = 128;
if (total_size == 0) {
TEE_ASSERT(sha_ctx->state == SHA_DRV_INITED);
memcpy((uint8_t *)final_arg->dst_addr,
sha384_hash, hash_size);
return 0;
}
break;
}
default: {
CRYPTO_DRV_DBG_E("sha_drv_finish: invalid sha mode(%d)\n", final_arg->mode);
return -1;
}
}
TEE_ASSERT(sha_ctx->data_size <= block_size);
_sha_restore_regs((uint32_t *)&sha_ctx->sha_regs);
msg_buf = (uint8_t *)malloc(block_size + 16);
if (msg_buf == NULL) {
CRYPTO_DRV_DBG_E("sha_drv_finish: malloc fail\n");
return -1;
}
memset(msg_buf, 0x0, block_size + 16);
memcpy(msg_buf, (void *)sha_ctx->data, sha_ctx->data_size);
_sha_set_msg_size((uint32_t)msg_buf, msg_size, total_size, final_arg->mode);
ret = _cal_sha_enable_initial(final_arg->mode,
(uint32_t)msg_buf, msg_size, (uint32_t)hash);
if (ret < 0) {
CRYPTO_DRV_DBG_E("sha_drv_finish: calc hash fail!\n");
goto out;
}
_sha_get_digest(hash, hash_size, (uint8_t *)final_arg->dst_addr);
out:
if (msg_buf) {
free(msg_buf);
}
return ret;
}

View file

@ -0,0 +1,50 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
**/
#ifndef _SHA_DRV_h_
#define _SHA_DRV_h_
#include "tee_types.h"
#define SHA_DRV_INITED 0x0
#define SHA_DRV_STARTED 0x1
#define SHA_DRV_CONTINUE 0x2
typedef struct _sha_reg_t {
uint32_t sha_ctrl;
uint32_t sha_mode;
uint32_t sha_intstate;
uint32_t sha_baseaddr;
uint32_t sha_destaddr;
uint32_t sha_counter0;
uint32_t sha_counter1;
uint32_t sha_counter2;
uint32_t sha_counter3;
uint32_t sha_h0l;
uint32_t sha_h1l;
uint32_t sha_h2l;
uint32_t sha_h3l;
uint32_t sha_h4l;
uint32_t sha_h5l;
uint32_t sha_h6l;
uint32_t sha_h7l;
uint32_t sha_h0h;
uint32_t sha_h1h;
uint32_t sha_h2h;
uint32_t sha_h3h;
uint32_t sha_h4h;
uint32_t sha_h5h;
uint32_t sha_h6h;
uint32_t sha_h7h;
} sha_reg_t;
typedef struct _sha_drv_ctx_t {
uint32_t state;
uint8_t data[128];
uint32_t data_size;
uint32_t total_size;
sha_reg_t sha_regs;
} sha_drv_ctx_t;
#endif

View file

@ -0,0 +1,480 @@
/**
* Copyright (C) 2016 The YunOS Project. All rights reserved.
**/
#include "hal_memmap.h"
#include "sha_drv_phobos.h"
#include "device.h"
#include "tee_dbg.h"
#include "crypto_drv.h"
#define SHA_MAX_TIME 20
#define SHA_MAX_SIZE 64
#define BLOCK_MAX_SIZE 128
static const uint8_t sha1_hash[20] = {
0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09
};
static const uint8_t sha224_hash[28] = {
0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9, 0x47, 0x61,
0x02, 0xbb, 0x28, 0x82, 0x34, 0xc4, 0x15, 0xa2, 0xb0, 0x1f,
0x82, 0x8e, 0xa6, 0x2a, 0xc5, 0xb3, 0xe4, 0x2f
};
static const uint8_t sha256_hash[32] = {
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb,
0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4,
0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52,
0xb8, 0x55
};
static const uint8_t sha384_hash[48] = {
0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, 0x4c, 0xd9,
0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, 0x21, 0xfd, 0xb7, 0x11,
0x14, 0xbe, 0x07, 0x43, 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6,
0xe1, 0xda, 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb,
0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b
};
static const uint8_t sha512_hash[64] = {
0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, 0xf1, 0x54,
0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, 0xd6, 0x20, 0xe4, 0x05,
0x0b, 0x57, 0x15, 0xdc, 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c,
0xe9, 0xce, 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, 0x63, 0xb9,
0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, 0xa5, 0x38, 0x32, 0x7a,
0xf9, 0x27, 0xda, 0x3e
};
#ifdef SHA_DRV_DBG
static void _print_msg_data(uint8_t *data, uint32_t len)
{
uint32_t i;
for (i = 0; i < len; i += 8) {
CRYPTO_DRV_DBG_I("msg: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
data[i+0], data[i+1], data[i+2], data[i+3], data[i+4], data[i+5], data[i+6], data[i+7]);
}
return;
}
#endif
static inline void sha_enable_calc(void)
{
volatile sha_phobos_reg_t *ptr = (sha_phobos_reg_t *)PLATFORM_SHA_BADDR;
ptr->SHA_CON |= 1<<SHA_CONTROL_BITS_RUN;
}
static inline void sha_enable_int(void)
{
volatile sha_phobos_reg_t *ptr = (sha_phobos_reg_t *)PLATFORM_SHA_BADDR;
ptr->SHA_CON |= 1<<4;
}
static inline void sha_message_done(void)
{
volatile sha_phobos_reg_t *ptr = (sha_phobos_reg_t *)PLATFORM_SHA_BADDR;
while((ptr->SHA_CON & 0x40)!=0);
}
static void sha_input_data(uint32_t *data, uint32_t length)
{
volatile sha_phobos_reg_t *ptr = (sha_phobos_reg_t *)PLATFORM_SHA_BADDR;
uint32_t *input_data = (uint32_t *)&(ptr->SHA_DATA1);
uint8_t i;
for(i=0; i<length; i++) {
*(input_data + i) = *(data + i);
}
}
static void sha_get_data(uint32_t *data)
{
volatile sha_phobos_reg_t *ptr = (sha_phobos_reg_t *)PLATFORM_SHA_BADDR;
uint32_t *result = (uint32_t *)&ptr->SHA_H0L;
uint8_t i;
for(i=0; i<5; i++) {
data[i] = *(result + i);
}
}
static inline void sha_reverse_order(uint8_t *pdata, int length)
{
uint32_t wlen = length >> 2;
uint32_t result = 0;
uint32_t tmp_data[20];
int i = 0;
memcpy((void *)tmp_data, (void *)pdata, length);
for (i = 0; i < wlen; i++) {
__asm__("revb %0, %1\n"
: "=r" (result)
: "r" (tmp_data[i]));
tmp_data[i] = result;
}
memcpy((void *)pdata, (void *)tmp_data, length);
}
static void sha_deal_last_block(uint8_t *input, int total_size)
{
uint32_t index = 0;
uint8_t block_word=0;
uint8_t i;
//uint8_t block_num = 0;
uint32_t left_len = 0;;
uint32_t input_message[32];
uint32_t length = total_size;
uint32_t totallen = total_size;
// block_num = length >> 6;
left_len = length & 0x3f;
length = length << 3;
index = left_len >> 2;
totallen = totallen << 3;
if(index >= 14) {
block_word = 16;
}
memcpy(input_message, input, left_len);
if (left_len & 0x3) {
*((uint8_t *)input_message+left_len) = 0x80;
for(i=1; i<(4-(left_len & 0x3)); i++) {
*((uint8_t *)input_message+left_len+i) = 0x00;
}
index++;
input_message[index] = 0x00000000;
} else {
input_message[index] = 0x00000080;
}
for (i = index + 1; i < block_word + 15; i++) {
input_message[i] = 0x0;
}
totallen = ((((totallen >> 0) & 0xff) << 24) | \
(((totallen >> 8) & 0xff) << 16) | \
(((totallen >> 16) & 0xff) << 8) | \
((totallen >> 24) & 0xff));
input_message[i] = totallen;
sha_input_data(input_message, 16);
sha_enable_calc();
sha_message_done();
if(index >= 14) {
sha_input_data(&input_message[16], 16);
sha_enable_calc();
sha_message_done();
}
}
static void _sha_save_regs(uint32_t *buf)
{
uint32_t i;
uint32_t regs_num;
volatile sha_phobos_reg_t *sha_regs = (sha_phobos_reg_t *)PLATFORM_SHA_BADDR;
regs_num = sizeof(sha_phobos_reg_t)/ sizeof(uint32_t);
for (i = 0; i < regs_num; i++) {
*(buf + i) = *((uint32_t *)sha_regs + i);
}
return;
}
static void _sha_restore_regs(uint32_t *buf)
{
uint32_t i;
uint32_t regs_num;
sha_phobos_reg_t *sha_regs = (sha_phobos_reg_t *)PLATFORM_SHA_BADDR;
regs_num = sizeof(sha_phobos_reg_t)/ sizeof(uint32_t);
for (i = 0; i < regs_num; i++) {
*((uint32_t *)sha_regs + i) = *(buf + i);
}
return;
}
static int _sha_set_mode(sha_mode_t mode)
{
volatile sha_phobos_reg_t *sha_regs = (sha_phobos_reg_t*)PLATFORM_SHA_BADDR;
switch(mode) {
case SHA_MODE_SHA1: {
sha_regs->SHA_CON |= SHA_CONTROL_CALC_MODE_SHA1;
break;
}
case SHA_MODE_SHA256: {
sha_regs->SHA_CON |= SHA_CONTROL_CALC_MODE_SHA256;
break;
}
case SHA_MODE_SHA224: {
sha_regs->SHA_CON |= SHA_CONTROL_CALC_MODE_SHA224;
break;
}
case SHA_MODE_SHA512: {
sha_regs->SHA_CON |= SHA_CONTROL_CALC_MODE_SHA512;
break;
}
case SHA_MODE_SHA384: {
sha_regs->SHA_CON |= SHA_CONTROL_CALC_MODE_SHA384;
break;
}
default: {
CRYPTO_DRV_DBG_E("sha_drv_init: invalid sha mode(%d)\n", mode);
return -1;
}
}
return 0;
}
int32_t sha_drv_init(void *arg)
{
sha_drv_ioctl_init_t *init_arg;
sha_drv_ctx_t *sha_ctx;
volatile sha_phobos_reg_t *sha_regs = (sha_phobos_reg_t*)PLATFORM_SHA_BADDR;
TEE_ASSERT(arg);
init_arg = (sha_drv_ioctl_init_t *)arg;
if (!VALID_MAGIC(init_arg->magic)) {
return -1;
}
sha_ctx = (sha_drv_ctx_t *)init_arg->ctx;
sha_ctx->state = SHA_DRV_INITED;
sha_ctx->data_size = 0;
sha_ctx->total_size = 0;
if (_sha_set_mode(init_arg->mode) != 0) {
return -1;
}
sha_regs->SHA_CON |= SHA_CONTROL_ENDIAN_MODE_BIG_ENDIAN << SHA_CONTROL_BITS_ENDIAN;
sha_regs->SHA_CON |= 0 << SHA_CONTROL_BITS_INTERRUPT;
sha_regs->SHA_CON |= 1 << SHA_CONTROL_BITS_ENABLE_INIT;
_sha_save_regs((uint32_t *)&(sha_ctx->sha_regs));
return 0;
}
int32_t sha_drv_get_ctx_size(void *arg)
{
sha_drv_ioctl_buf_size_t *get_arg;
TEE_ASSERT(arg);
get_arg = (sha_drv_ioctl_buf_size_t *)arg;
if (!VALID_MAGIC(get_arg->magic)) {
return -1;
}
get_arg->ctx_size = sizeof(sha_drv_ctx_t);
return 0;
}
int32_t sha_drv_process(void *arg)
{
// int ret;
uint32_t block_size;
uint32_t src_size;
uint8_t *src_data;
sha_drv_ioctl_proc_t *proc_arg;
sha_drv_ctx_t *sha_ctx;
TEE_ASSERT(arg);
proc_arg = (sha_drv_ioctl_proc_t *)arg;
if (!VALID_MAGIC(proc_arg->magic)) {
CRYPTO_DRV_DBG_E("sha_drv_process: bad magic(%08x)\n", proc_arg->magic);
return -1;
}
if (proc_arg->mode >= SHA_MODE_MAX ||
proc_arg->mode <= SHA_MODE_INVALID) {
CRYPTO_DRV_DBG_E("sha_drv_process: bad mode(%d)\n", proc_arg->mode);
return -1;
}
if (proc_arg->mode == SHA_MODE_SHA1 ||
proc_arg->mode == SHA_MODE_SHA256 ||
proc_arg->mode == SHA_MODE_SHA224) {
block_size = 64;
} else {
block_size = 128;
}
src_data = (uint8_t *)proc_arg->src_addr;
src_size = proc_arg->src_size;
sha_ctx = (sha_drv_ctx_t *)proc_arg->ctx;
_sha_restore_regs((uint32_t *)&sha_ctx->sha_regs);
if (sha_ctx->data_size + src_size <= block_size) {
if (src_size) {
memcpy(sha_ctx->data + sha_ctx->data_size,
src_data, src_size);
sha_ctx->data_size += src_size;
}
return 0;
}
if (sha_ctx->data_size < block_size) {
memcpy(sha_ctx->data + sha_ctx->data_size,
src_data, block_size - sha_ctx->data_size);
src_data += block_size - sha_ctx->data_size;
src_size -= block_size - sha_ctx->data_size;
}
if ((sha_ctx->state != SHA_DRV_INITED) && (sha_ctx->state != SHA_DRV_STARTED)) {
return -1;
}
sha_ctx->state = SHA_DRV_STARTED;
sha_input_data((uint32_t *)sha_ctx->data, block_size >> 2);
sha_enable_calc();
sha_message_done();
sha_ctx->data_size = 0;
sha_ctx->total_size += block_size;
while (src_size > block_size) {
uint32_t block[BLOCK_MAX_SIZE >> 2];
memcpy((uint8_t *)block, src_data, block_size);
sha_input_data((uint32_t *)block, block_size >> 2);
sha_enable_calc();
sha_message_done();
src_data += block_size;
src_size -= block_size;
sha_ctx->total_size += block_size;
}
memcpy(sha_ctx->data, src_data, src_size);
sha_ctx->data_size = src_size;
_sha_save_regs((uint32_t *)&sha_ctx->sha_regs);
return 0;
}
int32_t sha_drv_finish(void *arg)
{
int ret = 0;
uint32_t block_size;
uint64_t total_size;
uint32_t msg_size;
uint32_t hash_size;
sha_drv_ioctl_final_t *final_arg;
sha_drv_ctx_t *sha_ctx;
TEE_ASSERT(arg);
final_arg = (sha_drv_ioctl_final_t *)arg;
if (!VALID_MAGIC(final_arg->magic)) {
CRYPTO_DRV_DBG_E("sha_drv_finish: bad magic(%08x)\n", final_arg->magic);
return -1;
}
sha_ctx = (sha_drv_ctx_t *)final_arg->ctx;
msg_size = sha_ctx->data_size;
total_size = sha_ctx->total_size + msg_size;
switch(final_arg->mode) {
case SHA_MODE_SHA1: {
hash_size = 20;
block_size = 64;
if (total_size == 0) {
TEE_ASSERT(sha_ctx->state == SHA_DRV_INITED);
memcpy((uint8_t *)final_arg->dst_addr,
sha1_hash, hash_size);
return 0;
}
break;
}
case SHA_MODE_SHA256: {
hash_size = 32;
block_size = 64;
if (total_size == 0) {
TEE_ASSERT(sha_ctx->state == SHA_DRV_INITED);
memcpy((uint8_t *)final_arg->dst_addr,
sha256_hash, hash_size);
return 0;
}
break;
}
case SHA_MODE_SHA224: {
hash_size = 28;
block_size = 64;
if (total_size == 0) {
TEE_ASSERT(sha_ctx->state == SHA_DRV_INITED);
memcpy((uint8_t *)final_arg->dst_addr,
sha224_hash, hash_size);
return 0;
}
break;
}
case SHA_MODE_SHA512: {
hash_size = 64;
block_size = 128;
if (total_size == 0) {
TEE_ASSERT(sha_ctx->state == SHA_DRV_INITED);
memcpy((uint8_t *)final_arg->dst_addr,
sha512_hash, hash_size);
return 0;
}
break;
}
case SHA_MODE_SHA384: {
hash_size = 48;
block_size = 128;
if (total_size == 0) {
TEE_ASSERT(sha_ctx->state == SHA_DRV_INITED);
memcpy((uint8_t *)final_arg->dst_addr,
sha384_hash, hash_size);
return 0;
}
break;
}
default: {
CRYPTO_DRV_DBG_E("sha_drv_finish: invalid sha mode(%d)\n", final_arg->mode);
return -1;
}
}
TEE_ASSERT(sha_ctx->data_size <= block_size);
_sha_restore_regs((uint32_t *)&sha_ctx->sha_regs);
sha_deal_last_block(sha_ctx->data, total_size);
sha_get_data((uint32_t *)final_arg->dst_addr);
sha_reverse_order((uint8_t *)final_arg->dst_addr, hash_size);
return ret;
}
int32_t sha_drv_suspend(dev_t *dev, int32_t state)
{
return 0;
}
int32_t sha_drv_resume(dev_t *dev)
{
return 0;
}

View file

@ -0,0 +1,71 @@
/**
* Copyright (C) 2016 The YunOS Project. All rights reserved.
**/
#ifndef _SHA_DRV_PHOBOS_h_
#define _SHA_DRV_PHOBOS_h_
#include "tee_types.h"
#define SHA_DRV_INITED 0x0
#define SHA_DRV_STARTED 0x1
#define SHA_DRV_CONTINUE 0x2
typedef enum _sha_control_bits_t {
SHA_CONTROL_BITS_CALC = 0, /* [2:0] */
SHA_CONTROL_BITS_ENABLE_INIT = 3, /* [3] */
SHA_CONTROL_BITS_INTERRUPT = 4, /* [4] */
SHA_CONTROL_BITS_ENDIAN = 5, /* [5] */
SHA_CONTROL_BITS_RUN = 6, /* [6] */
} sha_control_bits_t;
typedef enum _sha_control_calc_mode_t {
SHA_CONTROL_CALC_MODE_INVALID = 0x0,
SHA_CONTROL_CALC_MODE_SHA1 = 0x1,
SHA_CONTROL_CALC_MODE_SHA256 = 0x2,
SHA_CONTROL_CALC_MODE_SHA224 = 0x3,
SHA_CONTROL_CALC_MODE_SHA512 = 0x4,
SHA_CONTROL_CALC_MODE_SHA384 = 0x5,
SHA_CONTROL_CALC_MODE_SHA512_256 = 0x6,
SHA_CONTROL_CALC_MODE_SHA512_224 = 0x7,
SHA_CONTROL_CALC_MODE_MAX
} sha_control_calc_mode_t;
typedef enum _sha_control_endian_mode_t {
SHA_CONTROL_ENDIAN_MODE_BIG_ENDIAN = 0,
SHA_CONTROL_ENDIAN_MODE_LITTLE_ENDIAN = 1
} sha_control_endian_mode_t;
typedef struct _sha_phobos_reg_t {
uint32_t SHA_CON;
uint32_t SHA_INTSTATE;
uint32_t SHA_H0L;
uint32_t SHA_H1L;
uint32_t SHA_H2L;
uint32_t SHA_H3L;
uint32_t SHA_H4L;
uint32_t SHA_H5L;
uint32_t SHA_H6L;
uint32_t SHA_H7L;
uint32_t SHA_H0H;
uint32_t SHA_H1H;
uint32_t SHA_H2H;
uint32_t SHA_H3H;
uint32_t SHA_H4H;
uint32_t SHA_H5H;
uint32_t SHA_H6H;
uint32_t SHA_H7H;
uint32_t SHA_DATA1;
uint32_t REV[15];
uint32_t SHA_DATA2;
} sha_phobos_reg_t;
typedef struct _sha_drv_ctx_t {
uint32_t state;
uint8_t data[128];
uint32_t data_size;
uint32_t total_size;
sha_phobos_reg_t sha_regs;
} sha_drv_ctx_t;
#endif

View file

@ -0,0 +1,74 @@
/* ****************************************************************************
* *
* C-Sky Microsystems Confidential *
* ------------------------------- *
* This file and all its contents are properties of C-Sky Microsystems. The *
* information contained herein is confidential and proprietary and is not *
* to be disclosed outside of C-Sky Microsystems except under a *
* Non-Disclosured Agreement (NDA). *
* *
****************************************************************************/
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
**/
#include "tee_types.h"
#include "tee_dbg.h"
#include "trng.h"
#include "device.h"
#include "crypto_drv.h"
static uint32_t trng_data_get(void)
{
uint32_t data = 0;
int cnt = 200;
trng_enable();
do {
if (*(volatile uint32_t *)(TRNG_BASEADDR + TRNG_TCR) & 0x1) {
data = *(volatile uint32_t *)(TRNG_BASEADDR + TRNG_TDR);
break;
}
} while (cnt--);
trng_disable();
return data;
}
int32_t trng_random_get(void *arg)
{
trng_drv_ioctl_t *p = (trng_drv_ioctl_t *)arg;
uint8_t *data;
uint32_t len;
uint32_t i;
uint32_t tmp;
if (NULL == p) {
return EARG;
}
if (!VALID_MAGIC(p->magic)) {
return EARG;
}
data = p->buf;
len = p->len;
for (i = 0; i < len; i+=sizeof(uint32_t)) {
tmp = trng_data_get();
memcpy((void *)(data+i), (void *)&tmp, sizeof(uint32_t) > (len - i) ? len - i : sizeof(uint32_t));
}
return SUCCESS;
}
int32_t trng_drv_suspend(dev_t *dev, int32_t state)
{
return SUCCESS;
}
int32_t trng_drv_resume(dev_t *dev)
{
return SUCCESS;
}

View file

@ -0,0 +1,61 @@
/* ****************************************************************************
* *
* C-Sky Microsystems Confidential *
* ------------------------------- *
* This file and all its contents are properties of C-Sky Microsystems. The *
* information contained herein is confidential and proprietary and is not *
* to be disclosed outside of C-Sky Microsystems except under a *
* Non-Disclosured Agreement (NDA). *
* *
****************************************************************************/
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
**/
#ifndef TRNG_H
#define TRNG_H
#include "tee_types.h"
#define TRNG_BASEADDR 0x40015000
#define TRNG_TCR 0x0
#define TRNG_TDR 0x4
#define TRNG_EN 2
#define TRNG_LOWPER_MODE 4
static inline void trng_enable(void)
{
*(volatile uint32_t *)(TRNG_BASEADDR + TRNG_TCR) |= TRNG_EN;
}
static inline void trng_disable(void)
{
*(volatile uint32_t *)(TRNG_BASEADDR + TRNG_TCR) &= ~TRNG_EN;
}
static inline void trng_lowpermode_enable(void)
{
*(volatile uint32_t *)(TRNG_BASEADDR + TRNG_TCR) |= TRNG_LOWPER_MODE;
}
static inline void trng_lowpermode_disable(void)
{
*(volatile uint32_t *)(TRNG_BASEADDR + TRNG_TCR) &= ~TRNG_LOWPER_MODE;
}
static inline uint32_t trng_data_ready_status(void)
{
return (*(volatile uint32_t *)(TRNG_BASEADDR + TRNG_TCR) & 0x1);
}
int32_t trng_random_get(void *arg);
#endif

View file

@ -0,0 +1,23 @@
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
TOP := ../../
CURRENT_BUILD := TW
include $(TOP)/tee.cfg
include $(TOP)/Make.rules
SRCS := $(wildcard *.c *.cxx)
OBJS := $(patsubst %.cxx,%.o,$(patsubst %.c,%.o,$(SRCS)))
LIBS := built-in.o
all: $(OBJS) $(LIBS)
$(LIBS): $(OBJS)
$(NOECHO)$(LD) -r -o $(LIBS) $(OBJS)
@echo "Finish building $(LIBS)..."
clean:
@echo "Cleaning $(LIBS)..."
$(NOECHO)rm -f $(OBJS) $(LIBS)

View file

@ -0,0 +1,337 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*
* Filename : eflash.c
* Author : Jun Lin
* Date Created : 24/12/2015
* Description : eflash driver
*/
/*
******************************
* HEADERS
******************************
*/
#include "device.h"
#include "eflash_priv.h"
#include "tee_eflash.h"
#include "tee_dbg.h"
#include "tee_addr_map.h"
#include "hal_memmap.h"
/*
******************************
* MACROS
******************************
*/
#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
#define ROUNDDOWN(a, b) ((a) & ~((b)-1))
#define TEE_DRV_EFLASH_NAME "eflash"
#ifdef CONFIG_EFLASH_DRV_DBG
#define FLASH_DRV_DBG_E(str, x...) \
do { \
tee_dbg_print(ERR, "%s:%d: " str, __FUNCTION__, __LINE__, ## x); \
} while (0)
#define FLASH_DRV_DBG_I(str, x...) \
do { \
tee_dbg_print(INF, "%s:%d: " str, __FUNCTION__, __LINE__, ## x); \
} while (0)
#else
#define FLASH_DRV_DBG_E(str, x...) TEE_ERROR(-3)
#define FLASH_DRV_DBG_I(str, x...)
#endif
/*
******************************
* TYPES
******************************
*/
/*
******************************
* VARIABLES
******************************
*/
static dev_t *_g_eflash_dev = NULL;
/*
******************************
* FUNCTIONS
******************************
*/
/* Function: int32_t _eflash_read(dev_t *dev, int32_t pos, void *buf, int32_t length)
* granularity is 1 bytes
*
* pos: the start address of this operation
* buf: the point to the source buf
* length: the program length in bytes
*
* Return:
* -1 -- FAILURE; >0 -- SUCCESS read size
*/
static int32_t __eflash_read(dev_t *dev, int32_t pos, void *buf, int32_t length)
{
uint32_t copied = 0;
uint32_t word_len = length / sizeof(uint32_t);
uint32_t left_len = length % sizeof(uint32_t);
int32_t i = 0;
uint8_t *src = NULL, *dst = NULL;
FLASH_DRV_DBG_I("read name %s, pos 0x%08x buf 0x%08x size 0x%08x\n",
dev->name, pos, buf, length);
if (pos < FLASH_START || (pos + length) > (FLASH_START + FLASH_SIZE)) {
FLASH_DRV_DBG_E("bad args\n");
return EARG;
}
if (0 == length) {
return copied;
}
while (copied < word_len) {
*((uint32_t *)buf + copied) = *((uint32_t *)pos + copied);
copied++;
}
if (left_len) {
dst = (uint8_t *)((uint32_t *)buf + copied);
src = (uint8_t *)((uint32_t *)pos + copied);
for (i = 0; i < left_len; ++i) {
*(dst + i) = *(src + i);
}
}
return (copied * sizeof(uint32_t) + i);
}
/*
* erase a page of the flash device
* granularity is 1 SECTOR
*
* addr: start address of the page
* sec_num: erase sector numboer
* Return:
* 0 -- SUCCESS; -1 -- FAILURE
*/
static int32_t __eflash_erase(dev_t *dev, uint32_t addr, uint32_t sec_num)
{
unsigned long fbase = FLASH_CTRL_BASEADDR;
uint32_t src_addr = addr;
if (addr < FLASH_START ||
(ROUNDDOWN(addr, SECTOR_SIZE) + sec_num * SECTOR_SIZE)
> (FLASH_START + FLASH_SIZE)) {
FLASH_DRV_DBG_E("bad args\n");
return EARG;
}
if (0 == sec_num) {
return SUCCESS;
}
while(sec_num--) {
*(volatile uint32_t *)(fbase + FLASH_ADDR_OFS) = src_addr;
*(volatile uint32_t *)(fbase + FLASH_PE_OFS) = 0x1;
src_addr += SECTOR_SIZE;
}
return SUCCESS;
}
static int32_t ___eflash_save(uint32_t *src_addr, uint32_t size, uint32_t *dst_addr)
{
uint32_t i = 0;
if (0 != size % 4 || (uint32_t)src_addr < FLASH_START ||
(uint32_t)src_addr > FLASH_START + FLASH_SIZE) {
FLASH_DRV_DBG_E("bad args\n");
return EARG;
}
if (0 == size) {
return SUCCESS;
} else {
for (i=0; i < (size / 4); i++)
{
*(dst_addr + i) = *(src_addr + i);
}
}
return SUCCESS;
}
static int32_t ___do_eflash_program(uint32_t w_addr, uint32_t *buf, uint32_t b_length)
{
uint32_t *address = (uint32_t *)w_addr;
uint32_t word = 0;
unsigned long fbase = FLASH_CTRL_BASEADDR;
uint32_t w_length = 0;
if (0 != b_length % 4 || w_addr < FLASH_START ||
w_addr > FLASH_START + FLASH_SIZE) {
FLASH_DRV_DBG_E("bad args\n");
return EARG;
}
if (0 == b_length) {
return SUCCESS;
}
w_length = b_length / 4;
while(w_length--)
{
word = (uint32_t)(*buf);
*(volatile uint32_t *)(fbase + FLASH_ADDR_OFS) = (uint32_t)address;
*(volatile uint32_t *)(fbase + FLASH_WDATA_OFS) = word;
*(volatile uint32_t *)(fbase + FLASH_WE_OFS) = 0x1;
buf++;
address++;
}
return SUCCESS;
}
/* Function: int32_t _eflash_write(dev_t *dev, int32_t pos, void *buf, int32_t size)
* program data into the flash device, note that before you call this function;
* you should call flash_erase first.
* granularity is 4 bytes
*
* w_addr: the start address of this operation
* w_buf: the point to the source buf
* h_length: the program length in bytes
*
* Return:
* -1 -- FAILURE; >0 -- SUCCESS write size
*/
static int32_t __eflash_write(dev_t *dev, int32_t pos,
void *buf, int32_t size)
{
uint32_t addr = (uint32_t)pos;
uint32_t pre_space = 0, later_space = 0, nums = 0;
uint32_t pre_addr = 0, later_addr = 0;
uint32_t tmp[128];
int32_t ret = SUCCESS;
if (0 != pos % 4 || 0 != size % 4) {
FLASH_DRV_DBG_E("bad args\n");
return EARG;
}
FLASH_DRV_DBG_I("eflash write name %s, pos 0x%08x buf 0x%08x size 0x%08x\n",
dev->name, pos, buf, size);
pre_addr = ROUNDDOWN(addr, SECTOR_SIZE);
pre_space = (addr - pre_addr);
later_addr = ROUNDDOWN(addr + size, SECTOR_SIZE);
later_space = (addr + size - later_addr);
nums = (size + SECTOR_SIZE - 1) / SECTOR_SIZE;
FLASH_DRV_DBG_I("nums %d pre addr 0x%08x pre_spaceb 0x%08x later addr 0x%08x "
"later sapce 0x%08x\n",
nums, pre_addr, pre_space, later_addr, later_space);
if (0 == later_space) {
ret = ___eflash_save((uint32_t *)pre_addr, pre_space, tmp);
TEE_ASSERT(SUCCESS == ret);
ret = __eflash_erase(dev, pre_addr, nums);
TEE_ASSERT(SUCCESS == ret);
ret = ___do_eflash_program(pre_addr, tmp, pre_space);
TEE_ASSERT(SUCCESS == ret);
ret = ___do_eflash_program(addr, (uint32_t *)buf, size);
TEE_ASSERT(SUCCESS == ret);
} else {
if (pre_addr == later_addr) { /* range in 1 SECTOR_SIZE */
ret = ___eflash_save((uint32_t *)pre_addr, SECTOR_SIZE, tmp);
TEE_ASSERT(SUCCESS == ret);
ret = __eflash_erase(dev, pre_addr, nums);
TEE_ASSERT(SUCCESS == ret);
ret = ___do_eflash_program(pre_addr, tmp, SECTOR_SIZE);
TEE_ASSERT(SUCCESS == ret);
} else {
/* save pre_addr */
ret = ___eflash_save((uint32_t *)pre_addr, pre_space, tmp);
TEE_ASSERT(SUCCESS == ret);
ret = __eflash_erase(dev, pre_addr, nums);
TEE_ASSERT(SUCCESS == ret);
ret = ___do_eflash_program(pre_addr, tmp, pre_space);
TEE_ASSERT(SUCCESS == ret);
/* save later_addr */
ret = ___eflash_save((uint32_t *)(addr + size),
SECTOR_SIZE - later_space, tmp);
TEE_ASSERT(SUCCESS == ret);
ret = __eflash_erase(dev, addr + size, 1);
TEE_ASSERT(SUCCESS == ret);
ret = ___do_eflash_program(addr + size, tmp,
SECTOR_SIZE - later_space);
TEE_ASSERT(SUCCESS == ret);
}
ret = ___do_eflash_program(addr, (uint32_t *)buf, size);
TEE_ASSERT(SUCCESS == ret);
}
return (int32_t)size;
}
static int32_t _eflash_open(dev_t *dev)
{
return SUCCESS;
}
static int32_t _eflash_close(dev_t *dev)
{
return SUCCESS;
}
static int32_t _eflash_ioctl(dev_t *dev, int32_t cmd, void *arg)
{
int32_t ret = SUCCESS;
void *args = arg;
FLASH_DRV_DBG_I("eflash ioctl name %s, cmd 0x%08x, ref 0x%08x\n",
dev->name, cmd, dev->dev_ref);
switch (cmd) {
case EFLASH_ERASE:
ret = __eflash_erase(dev, ((tee_eflash_erase_args_t *)args)->addr,
((tee_eflash_erase_args_t *)args)->sec_num);
break;
default:
TEE_ASSERT(0);
break;
}
return ret;
}
static dev_ops_t _g_eflash_ops = {
.open = _eflash_open,
.close = _eflash_close,
.ioctl = _eflash_ioctl,
.read = __eflash_read,
.write = __eflash_write,
.suspend = NULL,
.resume = NULL,
};
static int32_t _eflash_init(void)
{
FLASH_DRV_DBG_I("tee_eflash_probe\n");
_g_eflash_dev = dev_register(TEE_DRV_EFLASH_NAME, &_g_eflash_ops);
if (NULL == _g_eflash_dev) {
FLASH_DRV_DBG_E("tee_eflash_probe: dev regs fail\n");
return -1;
}
#if 0
FLASH_DRV_DBG_I("tee eflash test\n");
eflash_test();
#endif
return SUCCESS;
}
DEV_INIT(_eflash_init, (uint8_t *)TEE_DRV_EFLASH_NAME);

View file

@ -0,0 +1,18 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*
*/
#ifndef _EFLASH_PRIV_H_
#define _EFLASH_PRIV_H_
#define SECTOR_SIZE 512
/* E FLASH */
#define FLASH_CTRL_BASEADDR 0x4003F000
#define FLASH_ADDR_OFS 0x04
#define FLASH_PE_OFS 0x10
#define FLASH_WE_OFS 0x18
#define FLASH_WDATA_OFS 0x1C
#endif

View file

@ -0,0 +1,157 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
**/
#ifndef _CRYPTO_DRV_H_
#define _CRYPTO_DRV_H_
#include "device.h"
#ifdef CONFIG_CRYPTO_DRV_DBG
#define CRYPTO_DRV_DBG_E(_f, _a ...) tee_dbg_print(ERR, _f, ##_a)
#define CRYPTO_DRV_DBG_I(_f, _a ...) tee_dbg_print(INF, _f, ##_a)
#else
#define CRYPTO_DRV_DBG_E(_f, _a ...)
#define CRYPTO_DRV_DBG_I(_f, _a ...)
#endif
enum {
#ifdef RSA_SUPPORT
CMD_RSA_MODE_EXP = 0,
#endif
#ifdef AES_SUPPORT
CMD_AES_BUF_SIZE,
CMD_AES_INIT,
CMD_AES_PROCESS,
CMD_AES_FINAL,
#endif
#ifdef SHA_SUPPORT
CMD_SHA_BUF_SIZE,
CMD_SHA_INIT,
CMD_SHA_UPDATE,
CMD_SHA_FINAL,
#endif
#ifdef TRNG_SUPPORT
CMD_GET_RAND,
#endif
CMD_MAX_END = 0xffff,
};
#define CRYPTO_DEV_NAME "CRYPTO"
#define INIT_MAGIC(m) (m = 0x11223344)
#define VALID_MAGIC(m) (0x11223344 == m)
#ifdef RSA_SUPPORT
typedef struct _rsa_drv_ioctl_t {
uint32_t magic;
int32_t words;
int32_t d_valid_bits;
uint32_t *m;
uint32_t *d;
uint32_t *c;
uint32_t *b;
uint32_t *r;
} rsa_drv_ioctl_t;
extern int32_t rsa_drv_suspend(dev_t *dev, int32_t state);
extern int32_t rsa_drv_resume(dev_t *dev);
extern int32_t rsa_drv_mode_exp(void *arg);
#endif
#ifdef AES_SUPPORT
typedef struct _aes_drv_ioctl_buf_size_t {
uint32_t magic;
int32_t ctx_size;
} aes_drv_ioctl_buf_size_t;
typedef struct _aes_drv_ioctl_init_t {
uint32_t magic;
int32_t mode;
bool is_enc;
uint32_t *key;
int32_t keylen;
uint32_t *iv;
void *ctx;
} aes_drv_ioctl_init_t;
typedef struct _aes_drv_ioctl_process_t {
uint32_t magic;
uint32_t *src_blk;
uint32_t *dst_blk;
uint32_t size;
void *ctx;
} aes_drv_ioctl_process_t;
typedef struct _aes_drv_ioctl_final_t {
uint32_t magic;
void *ctx;
} aes_drv_ioctl_final_t;
extern int32_t aes_drv_suspend(dev_t *dev, int32_t state);
extern int32_t aes_drv_resume(dev_t *dev);
extern int32_t aes_drv_get_ctx_size(void *arg);
extern int32_t aes_drv_init(void *arg);
extern int32_t aes_drv_process(void *arg);
extern int32_t aes_drv_finish(void *arg);
#endif
#ifdef SHA_SUPPORT
typedef enum _sha_mode_t {
SHA_MODE_INVALID = 0,
SHA_MODE_SHA1,
SHA_MODE_SHA256,
SHA_MODE_SHA224,
SHA_MODE_SHA512,
SHA_MODE_SHA384,
SHA_MODE_MD5_SW,
SHA_MODE_MAX,
} sha_mode_t;
typedef struct _sha_drv_ioctl_buf_size_t {
uint32_t magic;
uint32_t ctx_size;
} sha_drv_ioctl_buf_size_t;
typedef struct _sha_drv_ioctl_init_t {
uint32_t magic;
void *ctx;
sha_mode_t mode;
} sha_drv_ioctl_init_t;
typedef struct _sha_drv_ioctl_proc_t {
uint32_t magic;
void *ctx;
sha_mode_t mode;
uint32_t src_addr;
uint32_t src_size;
} sha_drv_ioctl_proc_t;
typedef struct _sha_drv_ioctl_final_t {
uint32_t magic;
void *ctx;
sha_mode_t mode;
uint32_t dst_addr;
} sha_drv_ioctl_final_t;
extern int32_t sha_drv_suspend(dev_t *dev, int32_t state);
extern int32_t sha_drv_resume(dev_t *dev);
extern int32_t sha_drv_get_ctx_size(void *arg);
extern int32_t sha_drv_init(void *arg);
extern int32_t sha_drv_process(void *arg);
extern int32_t sha_drv_finish(void *arg);
#endif
#ifdef TRNG_SUPPORT
typedef struct _trng_drv_ioctl_t {
uint32_t magic;
uint8_t *buf;
size_t len;
} trng_drv_ioctl_t;
extern int32_t trng_random_get(void *arg);
extern int32_t trng_drv_suspend(dev_t *dev, int32_t state);
int32_t trng_drv_resume(dev_t *dev);
#endif
#endif /* _CRYPTO_H_ */

View file

@ -0,0 +1,46 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_ASC_H_
#define _TEE_ASC_H_
#include "device.h"
#define TEE_DRV_ASC_NAME "asc"
#define TEE_ASC_SET_MEM_PERM (0x0)
#define TEE_ASC_GET_MEM_PERM (0x1)
#define TEE_ASC_CLR_MEM_PERM (0x2)
/* region security prop */
#define REGION_SIZE_UNSECURITY (0x0)
#define REGION_SIZE_SECURITY (0x1)
/* region AP authority */
#define REGION_READ_WRITE (0x0)
#define REGION_READ_ONLY (0x1)
#define REGION_WRITE_ONLY (0x3)
#define REGION_NO_ACCESS (0x4)
/* region CD authority */
#define REGION_ACCESS_DENY (0x0)
#define REGION_ONLY_DATA (0x1)
#define REGION_ONLY_INSTRUCT (0x2)
#define REGION_BOTH (0x3)
typedef struct _tee_asc_perm_t {
uint8_t sec;
uint8_t ap;
uint8_t cd;
} tee_asc_perm_t;
typedef struct _tee_asc_arg_t {
size_t paddr;
size_t size;
tee_asc_perm_t perm;
} tee_asc_arg_t;
extern int asc_set_perm(uint32_t paddr, uint32_t size, bool is_secure, uint8_t ap_perm, uint8_t cd_perm);
#endif

View file

@ -0,0 +1,33 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_EFLASH_H_
#define _TEE_EFLASH_H_
#include "tee_types.h"
enum eflash_cmd {
EFLASH_ERASE = 0,
EFLASH_INVALID = 1,
};
typedef struct _tee_eflash_read_args_t {
uint32_t addr;
uint8_t *buf;
uint32_t size;
} tee_eflash_read_args_t;
typedef struct _tee_eflash_write_args_t {
uint32_t addr;
uint32_t *buf;
uint32_t size;
} tee_eflash_write_args_t;
typedef struct _tee_eflash_erase_args_t {
uint32_t addr;
uint32_t sec_num;
} tee_eflash_erase_args_t;
#endif /* _TEE_ELASH_H_ */

View file

@ -0,0 +1,75 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_TRM_H_
#define _TEE_TRM_H_
#include "hal_memmap.h"
#include "device.h"
#define TEE_DRV_TRM_NAME "trm"
#define TEE_TRM_GET_ID2_ID (0x0)
#define TEE_TRM_GET_ID2_PRVK (0x1)
#define MANIFEST_IDX_MAGIC (0x78446E49) // "InDx"
/* position info type */
#define POS_INFO_TYPE_FUSE (0x1)
#define POS_INFO_TYPE_NANDFLASH (0x2)
#define POS_INFO_TYPE_NORFLASH (0x3)
#define POS_INFO_TYPE_SE (0x4)
//FIXME, this need be synced with BOOTROM
#define KEY_TYPE_MNF_TB_ADDR (1)
#define KEY_TYPE_JTAG_KEY (2)
#define KEY_TYPE_PUBK_TB (3)
#define KEY_TYPE_ID2_ID (4)
#define KEY_TYPE_ID2_PRVK (5)
#define KEY_TYPE_SOC_CONFIG (6)
#define KEY_TYPE_LPM_RECOVERY (7)
/* ID2 Key info */
#if CONFIG_ID2_RSA_KEY
#define ID2_KEY_BITS (1024)
#elif CONFIG_ID2_AES_KEY
#define ID2_AES_KEY_MAX_BITS (256)
#define ID2_AES_KEY_MAX_BYTES (32)
#define TEE_TRM_AES 0x01
#define TEE_TRM_DES 0x02
#define TEE_TRM_3DES 0x03
#endif /* CONFIG_ID2_RSA_KEY */
typedef struct _mft_key_flag_t {
uint16_t type:1; // key or data
uint16_t key_sche; //reserve if type is data;
} mft_key_flag_t;
typedef struct _mft_pos_info_t {
uint32_t info:28;
uint32_t type:4;
} mft_pos_info_t;
typedef struct _mft_key_meta_t {
uint16_t type;
uint16_t size;
uint16_t flag;
uint16_t rsvd;
mft_pos_info_t pos_info;
} mft_key_meta_t;
typedef struct _mft_idx_info_t {
uint32_t magic;
uint16_t version;
uint16_t key_num;
mft_key_meta_t key_metas[0];
} mft_idx_info_t;
typedef struct _tee_trm_arg_t {
void *data;
uint32_t size;
} tee_trm_arg_t;
#endif

View file

@ -0,0 +1,25 @@
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
TOP := ../../
CURRENT_BUILD := TW
include $(TOP)/tee.cfg
include $(TOP)/Make.rules
SRCS := $(wildcard *.c *.cxx)
OBJS := $(patsubst %.cxx,%.o,$(patsubst %.c,%.o,$(SRCS)))
LIBS := built-in.o
CFLAGS += -I$(TOP)/drv/flash
all: $(OBJS) $(LIBS)
$(LIBS): $(OBJS)
$(NOECHO)$(LD) -r -o $(LIBS) $(OBJS)
@echo "Finish building $(LIBS)..."
clean:
@echo "Cleaning $(LIBS)..."
$(NOECHO)rm -f $(OBJS) $(LIBS)

View file

@ -0,0 +1,218 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*
* Filename : eflash.c
* Author : Jun Lin
* Date Created : 24/12/2015
* Description : e flash driver
*/
/*
******************************
* HEADERS
******************************
*/
#include "device.h"
#include "eflash_priv.h"
#include "tee_addr_map.h"
#include "tee_eflash.h"
#include "tee_dbg.h"
/*
******************************
* MACROS
******************************
*/
#define TEE_DRV_EFLASH_NAME "eflash"
#define TEE_TEST_EFLASH_START_ADDR EFLASH_START + 8
#define TEE_TEST_EFLASH_SIZE SECTOR_SIZE + 32
#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
#define ROUNDDOWN(a, b) ((a) & ~((b)-1))
/*
******************************
* TYPES
******************************
*/
/*
******************************
* VARIABLES
******************************
*/
/*
******************************
* FUNCTIONS
******************************
*/
void eflash_test(void)
{
dev_t *ef_dev = NULL;
tee_eflash_read_args_t read_args;
tee_eflash_write_args_t write_args;
tee_eflash_erase_args_t erase_args;
int32_t ret;
ef_dev = dev_open(TEE_DRV_EFLASH_NAME);
if (NULL == ef_dev) {
tee_dbg_print(INF, "dev open elfash drv fail\n");
return;
}
tee_dbg_print(INF, "=========================================write\n");
write_args.addr = ROUNDDOWN(TEE_TEST_EFLASH_START_ADDR, SECTOR_SIZE);
write_args.buf = malloc(TEE_TEST_EFLASH_SIZE);
if (NULL == write_args.buf) {
tee_dbg_print(INF, "out of memory\n");
}
*((uint32_t *)write_args.buf) = 0xffeeddcc;
*((uint32_t *)write_args.buf + 1) = 0xccddeeff;
tee_dbg_print(INF, "test write pos 0x%08x buffer 0x%08x,data 0x%08x 0x%08x\n",
write_args.addr, write_args.buf,
*((uint32_t *)write_args.buf), *((uint32_t *)write_args.buf + 1));
write_args.size = TEE_TEST_EFLASH_SIZE;
dev_write(ef_dev, write_args.addr, write_args.buf, write_args.size);
free(write_args.buf);
tee_dbg_print(INF, "=========================================read\n");
read_args.addr = ROUNDDOWN(TEE_TEST_EFLASH_START_ADDR, SECTOR_SIZE);
read_args.buf = malloc(TEE_TEST_EFLASH_SIZE);
if (NULL == read_args.buf) {
tee_dbg_print(INF, "out of memory\n");
}
read_args.size = TEE_TEST_EFLASH_SIZE;
ret = dev_read(ef_dev, read_args.addr, read_args.buf, read_args.size);
if (read_args.size != ret) {
tee_dbg_print(INF, "test read eflash err 0x%08x", ret);
}
tee_dbg_print(INF, "test read eflash pos 0x%08x bufer 0x%08x "
"data 0x%08x 0x%08x 0x%08x 0x%08x\n",
read_args.addr, read_args.buf,
*((uint32_t *)read_args.buf), *((uint32_t *)read_args.buf + 1),
*((uint32_t *)read_args.buf + 2), *((uint32_t *)read_args.buf + 3));
free(read_args.buf);
tee_dbg_print(INF, "=========================================write\n");
write_args.addr = TEE_TEST_EFLASH_START_ADDR;
write_args.buf = malloc(TEE_TEST_EFLASH_SIZE);
if (NULL == write_args.buf) {
tee_dbg_print(INF, "out of memory\n");
}
*((uint32_t *)write_args.buf) = 0x12345678;
*((uint32_t *)write_args.buf + 1) = 0x87654321;
tee_dbg_print(INF, "test write pos 0x%08x buffer 0x%08x,data 0x%08x 0x%08x\n",
write_args.addr, write_args.buf,
*((uint32_t *)write_args.buf), *((uint32_t *)write_args.buf + 1));
write_args.size = TEE_TEST_EFLASH_SIZE;
dev_write(ef_dev, write_args.addr, write_args.buf, write_args.size);
free(write_args.buf);
tee_dbg_print(INF, "=========================================read\n");
read_args.addr = ROUNDDOWN(TEE_TEST_EFLASH_START_ADDR, SECTOR_SIZE);
read_args.buf = malloc(TEE_TEST_EFLASH_SIZE);
if (NULL == read_args.buf) {
tee_dbg_print(INF, "out of memory\n");
}
read_args.size = TEE_TEST_EFLASH_SIZE;
dev_read(ef_dev, read_args.addr, read_args.buf, read_args.size);
if (read_args.size != ret) {
tee_dbg_print(INF, "test read eflash err 0x%08x", ret);
}
tee_dbg_print(INF, "test read eflash pos 0x%08x bufer 0x%08x "
"data 0x%08x 0x%08x 0x%08x 0x%08x\n",
read_args.addr, read_args.buf,
*((uint32_t *)read_args.buf), *((uint32_t *)read_args.buf + 1),
*((uint32_t *)read_args.buf + 2), *((uint32_t *)read_args.buf + 3));
free(read_args.buf);
tee_dbg_print(INF, "=========================================write\n");
write_args.addr = TEE_TEST_EFLASH_START_ADDR + 2*SECTOR_SIZE;
write_args.buf = malloc(4);
if (NULL == write_args.buf) {
tee_dbg_print(INF, "out of memory\n");
}
*((uint32_t *)write_args.buf) = 0x11223344;
tee_dbg_print(INF, "test write pos 0x%08x buffer 0x%08x,data 0x%08x\n",
write_args.addr, write_args.buf, *((uint32_t *)write_args.buf));
write_args.size = 4;
dev_write(ef_dev, write_args.addr, write_args.buf, write_args.size);
free(write_args.buf);
tee_dbg_print(INF, "=========================================read\n");
read_args.addr = ROUNDDOWN(TEE_TEST_EFLASH_START_ADDR, SECTOR_SIZE);
read_args.buf = malloc(TEE_TEST_EFLASH_SIZE);
if (NULL == read_args.buf) {
tee_dbg_print(INF, "out of memory\n");
}
read_args.size = TEE_TEST_EFLASH_SIZE;
dev_read(ef_dev, read_args.addr, read_args.buf, read_args.size);
if (read_args.size != ret) {
tee_dbg_print(INF, "test read eflash err 0x%08x", ret);
}
tee_dbg_print(INF, "1111test read eflash pos 0x%08x bufer 0x%08x "
"data 0x%08x 0x%08x 0x%08x 0x%08x\n",
read_args.addr, read_args.buf,
*((uint32_t *)read_args.buf), *((uint32_t *)read_args.buf + 1),
*((uint32_t *)read_args.buf + 2), *((uint32_t *)read_args.buf + 3));
free(read_args.buf);
tee_dbg_print(INF, "=========================================read\n");
read_args.addr = TEE_TEST_EFLASH_START_ADDR + 2*SECTOR_SIZE;
read_args.buf = malloc(TEE_TEST_EFLASH_SIZE);
if (NULL == read_args.buf) {
tee_dbg_print(INF, "out of memory\n");
}
read_args.size = TEE_TEST_EFLASH_SIZE;
dev_read(ef_dev, read_args.addr, read_args.buf, read_args.size);
if (read_args.size != ret) {
tee_dbg_print(INF, "test read eflash err 0x%08x", ret);
}
tee_dbg_print(INF, "test read eflash pos 0x%08x bufer 0x%08x "
"data 0x%08x 0x%08x 0x%08x 0x%08x\n",
read_args.addr, read_args.buf,
*((uint32_t *)read_args.buf), *((uint32_t *)read_args.buf + 1),
*((uint32_t *)read_args.buf + 2), *((uint32_t *)read_args.buf + 3));
free(read_args.buf);
tee_dbg_print(INF, "=========================================erase\n");
erase_args.addr = TEE_TEST_EFLASH_START_ADDR;
erase_args.sec_num = 1;
dev_ioctl(ef_dev, EFLASH_ERASE, (void *)&erase_args);
tee_dbg_print(INF, "test erase eflash addr 0x%08x sec_num 0x%08x\n",
erase_args.addr, erase_args.sec_num);
tee_dbg_print(INF, "=========================================read\n");
read_args.addr = ROUNDDOWN(TEE_TEST_EFLASH_START_ADDR, SECTOR_SIZE);
read_args.buf = malloc(TEE_TEST_EFLASH_SIZE);
if (NULL == read_args.buf) {
tee_dbg_print(INF, "out of memory\n");
}
read_args.size = TEE_TEST_EFLASH_SIZE;
dev_read(ef_dev, read_args.addr, read_args.buf, read_args.size);
if (read_args.size != ret) {
tee_dbg_print(INF, "test read eflash err 0x%08x", ret);
}
tee_dbg_print(INF, "test read eflash pos 0x%08x bufer 0x%08x "
"data 0x%08x 0x%08x 0x%08x 0x%08x\n",
read_args.addr, read_args.buf,
*((uint32_t *)read_args.buf), *((uint32_t *)read_args.buf + 1),
*((uint32_t *)read_args.buf + 2), *((uint32_t *)read_args.buf + 3));
free(read_args.buf);
tee_dbg_print(INF, "=========================================read\n");
read_args.addr = TEE_TEST_EFLASH_START_ADDR + 2*SECTOR_SIZE;
read_args.buf = malloc(TEE_TEST_EFLASH_SIZE);
if (NULL == read_args.buf) {
tee_dbg_print(INF, "out of memory\n");
}
read_args.size = TEE_TEST_EFLASH_SIZE;
dev_read(ef_dev, read_args.addr, read_args.buf, read_args.size);
tee_dbg_print(INF, "test read eflash pos 0x%08x bufer 0x%08x "
"data 0x%08x 0x%08x 0x%08x 0x%08x\n",
read_args.addr, read_args.buf,
*((uint32_t *)read_args.buf), *((uint32_t *)read_args.buf + 1),
*((uint32_t *)read_args.buf + 2), *((uint32_t *)read_args.buf + 3));
free(read_args.buf);
}

View file

@ -0,0 +1,50 @@
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
TOP := ../..
CURRENT_BUILD := TW
include $(TOP)/tee.cfg
include $(TOP)/Make.rules
TEST := Y
ID2_AES_KEY_BITS := 128
SRCS := tee_trm.c
LIBS := built-in.o
ifeq ($(TEST), Y)
SRCS += tee_trm_fake.c
ifeq ($(ID2_AES_KEY_BITS), 128)
CFLAGS += -DCONFIG_AES_128_BIT=1
else ifeq ($(ID2_AES_KEY_BITS), 192)
CFLAGS += -DCONFIG_AES_192_BIT=1
else ifeq ($(ID2_AES_KEY_BITS), 256)
CFLAGS += -DCONFIG_AES_256_BIT=1
endif
else
SRCS += tee_trm_id2.c
endif
OBJS := $(patsubst %.cxx,%.o,$(patsubst %.c,%.o,$(SRCS)))
#CFLAGS += -DTEE_TRM_DBG
ifeq ($(PLATFORM), csky_phobos)
CFLAGS += -DTRM_FAKE_KEY_SEL0=1
else ifeq ($(PLATFORM), csky_ch2201)
CFLAGS += -DTRM_FAKE_KEY_SEL0=1
else
CFLAGS += -DTRM_FAKE_KEY_SEL1=1
endif
all: $(OBJS) $(LIBS)
$(LIBS): $(OBJS)
$(NOECHO)$(LD) -r -o $(LIBS) $(OBJS)
@ echo "Finish building $(LIBS)..."
clean:
@ echo "Cleaning $(LIBS)..."
$(NOECHO)rm -f $(OBJS) $(LIBS)

View file

@ -0,0 +1,193 @@
/**
* Copyright (C) 2015-2016 The YunOS Project. All rights reserved.
*/
#include "tee_trm.h"
#include "tee_trm_priv.h"
#if CONFIG_ID2_RSA_KEY
extern void _convert_buf_to_bndata(const uint8_t *src, int32_t src_bytes,
uint32_t *dst, int32_t dst_words);
extern int32_t _sw_exptmod_2_2m(const uint32_t *modulus, int32_t words, uint32_t *tmp_c);
uint32_t _g_id2_rsa_c_acc[ID2_KEY_BITS >> 5] = {0};
uint32_t _g_id2_rsa_n[ID2_KEY_BITS >> 5] = {0};
uint32_t _g_id2_rsa_e[ID2_KEY_BITS >> 5] = {0};
uint32_t _g_id2_rsa_d[ID2_KEY_BITS >> 5] = {0};
uint8_t _g_id2_rsa_fixed_raw_e[3] = {0x01, 0x00, 0x01};
#endif /* CONFIG_ID2_RSA_KEY */
#if CONFIG_ID2_AES_KEY
uint8_t _g_id2_aes_key[ID2_AES_KEY_MAX_BYTES] = { 0 };
uint32_t _g_id2_aes_key_bits = 0;
#endif /* CONFIG_ID2_AES_KEY */
static bool _g_id2_key_ready = false;
#if CONFIG_ID2_RSA_KEY
int tee_trm_get_rsa_key(uint32_t **n, uint32_t **d, uint32_t **e,
uint32_t **c_acc, uint32_t *key_bits)
{
if ((NULL == n) ||
(NULL == d) ||
(NULL == e) ||
(NULL == c_acc) ||
(NULL == key_bits)) {
TRM_DRV_DBG_E("bad parameter!\n");
return -1;
}
if (true == _g_id2_key_ready) {
*n = _g_id2_rsa_n;
*d = _g_id2_rsa_d;
*e = _g_id2_rsa_e;
#ifdef RSA_SUPPORT
*c_acc = _g_id2_rsa_c_acc;
#else
*c_acc = NULL;
#endif
*key_bits = ID2_KEY_BITS;
return 0;
} else {
TRM_DRV_DBG_E("ID2 RSA key not available!\n");
*n = NULL;
*d = NULL;
*e = NULL;
*c_acc = NULL;
*key_bits = 0;
return -1;
}
return 0;
}
#endif /* CONFIG_ID2_RSA_KEY */
#if CONFIG_ID2_AES_KEY
int tee_trm_get_aes_key(uint8_t **aes_key, uint32_t *key_bits)
{
if ((NULL == aes_key) ||
(NULL == key_bits)) {
TRM_DRV_DBG_E("bad parameter!\n");
return -1;
}
if (true == _g_id2_key_ready) {
*aes_key = _g_id2_aes_key;
*key_bits = _g_id2_aes_key_bits;
return 0;
} else {
TRM_DRV_DBG_E("ID2 AES key not available!\n");
*aes_key = NULL;
*key_bits = 0;
return -1;
}
return 0;
}
#endif /* CONFIG_ID2_AES_KEY */
static int32_t _tee_trm_open(dev_t *dev)
{
return 0;
}
static int32_t _tee_trm_close(dev_t *dev)
{
return 0;
}
static int32_t _tee_trm_ioctl(dev_t *dev, int32_t cmd, void *arg)
{
int ret;
tee_trm_arg_t *trm_arg;
trm_arg = (tee_trm_arg_t *)arg;
TEE_ASSERT(trm_arg);
switch(cmd) {
case TEE_TRM_GET_ID2_ID:
{
ret = trm_get_key_data(
KEY_TYPE_ID2_ID, trm_arg->data, &(trm_arg->size));
if (ret < 0) {
TRM_DRV_DBG_E("fail to get id2 id\n");
return ret;
}
break;
}
default:
TRM_DRV_DBG_E("illegal command(%d)\n", cmd);
return -1;
}
return 0;
}
static dev_ops_t _tee_trm_ops = {
.open = _tee_trm_open,
.close = _tee_trm_close,
.ioctl = _tee_trm_ioctl,
.read = NULL,
.write = NULL,
.suspend = NULL,
.resume = NULL,
};
static int32_t _tee_trm_probe()
{
int ret;
dev_t *dev;
TRM_DRV_DBG_I("_tee_trm_probe\n");
dev = dev_register(TEE_DRV_TRM_NAME, &_tee_trm_ops);
if (dev == NULL) {
TRM_DRV_DBG_E("_tee_trm_probe: dev regs fail\n");
return -1;
}
#if CONFIG_ID2_RSA_KEY
ret = tee_trm_read_rsa_key();
if (ret != 0) {
TRM_DRV_DBG_E("_tee_trm_probe: fail to read rsa_key N E D!\n");
return -1;
}
#ifdef RSA_SUPPORT
ret = _sw_exptmod_2_2m((const uint32_t *)_g_id2_rsa_n, (ID2_KEY_BITS >> 5), _g_id2_rsa_c_acc);
if (ret != 0) {
TRM_DRV_DBG_E("_tee_trm_probe: fail to caculate N exptmod 2^2m!\n");
goto __out;
}
#endif /* RSA_SUPPORT */
#endif /* CONFIG_ID2_RSA_KEY */
#if CONFIG_ID2_AES_KEY
ret = tee_trm_read_sym_key(TEE_TRM_AES);
if (ret) {
TRM_DRV_DBG_E("_tee_trm_probe: fail to read aes key!\n");
return -1;
}
#endif /* CONFIG_ID2_AES_KEY */
_g_id2_key_ready = true;
return 0;
#if CONFIG_ID2_RSA_KEY
__out:
memset(_g_id2_rsa_n, 0, (ID2_KEY_BITS >> 3));
memset(_g_id2_rsa_d, 0, (ID2_KEY_BITS >> 3));
memset(_g_id2_rsa_e, 0, (ID2_KEY_BITS >> 3));
memset(_g_id2_rsa_c_acc, 0, (ID2_KEY_BITS >> 3));
#endif /* CONFIG_ID2_RSA_KEY */
return ret;
}
DEV_INIT(_tee_trm_probe, (uint8_t *)TEE_DRV_TRM_NAME);

View file

@ -0,0 +1,183 @@
/**
* Copyright (C) 2015-2016 The YunOS Project. All rights reserved.
*/
#include "tee_trm.h"
#include "tee_trm_priv.h"
#if CONFIG_ID2_RSA_KEY
extern void _convert_buf_to_bndata(const uint8_t *src, int32_t src_bytes,
uint32_t *dst, int32_t dst_words);
extern uint32_t _g_id2_rsa_c_acc[ID2_KEY_BITS >> 5];
extern uint32_t _g_id2_rsa_n[ID2_KEY_BITS >> 5];
extern uint32_t _g_id2_rsa_e[ID2_KEY_BITS >> 5];
extern uint32_t _g_id2_rsa_d[ID2_KEY_BITS >> 5];
uint8_t _g_id2_rsa_fixed_raw_e[3] = {0x01, 0x00, 0x01};
#elif CONFIG_ID2_AES_KEY
extern uint8_t _g_id2_aes_key[ID2_AES_KEY_MAX_BYTES];
extern uint32_t _g_id2_aes_key_bits;
#endif /* CONFIG_ID2_AES_KEY */
/************************************************/
/* FAKE ID2 KEY and ID */
/************************************************/
#if CONFIG_ID2_RSA_KEY
#if TRM_FAKE_KEY_SEL0
char ID[18] = "Y0482208A0D6E011A";
uint8_t RSA_N[] = {
0xB9, 0xC2, 0x6A, 0x88, 0x90, 0xB0, 0xE1, 0x1B,
0xD3, 0x3F, 0x93, 0x99, 0xF8, 0xCB, 0xC4, 0xF2,
0x88, 0xB8, 0x56, 0x9A, 0x93, 0x24, 0x0B, 0x4A,
0x75, 0xB4, 0x8D, 0x6C, 0x32, 0x40, 0x52, 0xA7,
0x3D, 0x2B, 0x37, 0xCE, 0x57, 0x80, 0xFD, 0xA5,
0x08, 0xC7, 0x4A, 0x77, 0x94, 0x34, 0xBA, 0x56,
0x9F, 0xBA, 0x2E, 0xBA, 0x20, 0x1E, 0x80, 0x4A,
0x09, 0x40, 0x07, 0xF5, 0x1D, 0xB6, 0xFC, 0x8E,
0x5C, 0x4E, 0x02, 0x01, 0xD5, 0x97, 0x14, 0x83,
0x2A, 0x32, 0x90, 0x4E, 0xED, 0xDC, 0x6F, 0xD6,
0x0A, 0x1F, 0x44, 0x6A, 0xB1, 0xFE, 0x42, 0xBD,
0xBF, 0xD7, 0x6F, 0xB5, 0x9B, 0x78, 0x5F, 0x19,
0x07, 0x15, 0x4E, 0x65, 0xD2, 0x72, 0x09, 0x0C,
0x14, 0xAD, 0xE8, 0xC7, 0x76, 0x25, 0xE8, 0x94,
0xF8, 0xEE, 0x19, 0x93, 0xDF, 0xC9, 0x34, 0xEE,
0x42, 0x1A, 0xA6, 0xA8, 0x70, 0xE2, 0xC0, 0x99
};
uint8_t RSA_D[] = {
0x0D, 0x59, 0xA1, 0x9A, 0x6A, 0xFB, 0xAB, 0x51,
0xFA, 0x9E, 0xA9, 0x16, 0xF9, 0xC0, 0x7B, 0x49,
0x0A, 0xF6, 0x64, 0x92, 0xFB, 0x5C, 0x2D, 0xCB,
0x8E, 0x26, 0x09, 0xBB, 0xEA, 0xE8, 0xA0, 0x88,
0x10, 0x67, 0x58, 0xBD, 0x65, 0xA0, 0x89, 0x9A,
0x20, 0xC5, 0x61, 0xDE, 0xB2, 0x32, 0x0F, 0xEA,
0x45, 0xD4, 0x75, 0xA3, 0x3E, 0xC7, 0xB2, 0x64,
0x9F, 0xC1, 0x90, 0x50, 0xD7, 0x6F, 0xDD, 0x3A,
0xA6, 0xA3, 0x52, 0xED, 0xB6, 0xFC, 0x2B, 0x61,
0xA5, 0xDB, 0xE4, 0xC7, 0xF8, 0x21, 0x30, 0xEF,
0x7F, 0x21, 0x1E, 0x5B, 0x96, 0x45, 0x43, 0x4B,
0x74, 0x98, 0xC6, 0x1B, 0xD9, 0x66, 0x0A, 0x64,
0x41, 0x5F, 0xF6, 0xE0, 0x87, 0xD6, 0xFA, 0x00,
0x4D, 0x76, 0x9B, 0x4E, 0x36, 0xC5, 0x8A, 0x10,
0x8C, 0x61, 0xA1, 0x41, 0xB0, 0x8B, 0x25, 0xEC,
0x19, 0x25, 0x89, 0x45, 0x8E, 0xFB, 0xCF, 0xB9
};
#else /* !TRM_FAKE_KEY_SEL0 */
char ID[18] = "Y00F300016247B17C";
uint8_t RSA_N[] = {
0xC6, 0x99, 0x83, 0xD1, 0xC4, 0xAE, 0x92, 0xA4,
0xBF, 0x2E, 0x36, 0x31, 0xFA, 0x5D, 0x03, 0xCD,
0x1B, 0x3F, 0x52, 0x01, 0x06, 0xD2, 0x3E, 0xC4,
0x3A, 0x32, 0xC9, 0x35, 0x17, 0x6D, 0x9F, 0x9E,
0x71, 0x2F, 0x6F, 0x3B, 0xD0, 0xE8, 0xA6, 0x80,
0x83, 0x60, 0xD5, 0x8B, 0x3D, 0xAD, 0xFF, 0xFF,
0x62, 0x1A, 0x4C, 0xD5, 0x04, 0x43, 0x08, 0x6B,
0x57, 0x3B, 0x63, 0xF9, 0x48, 0x5A, 0x86, 0x4B,
0xAE, 0x4E, 0xC9, 0x6D, 0xF3, 0xAA, 0x28, 0x41,
0xB9, 0xA6, 0x2F, 0x0E, 0xD6, 0x18, 0x59, 0x76,
0x00, 0xBE, 0x61, 0xAE, 0x8A, 0x1A, 0xB9, 0x23,
0x29, 0xE6, 0xBD, 0xA0, 0xBA, 0xF6, 0x0D, 0x2B,
0xA6, 0xDE, 0x16, 0xC8, 0xE9, 0x82, 0x34, 0x71,
0x72, 0x13, 0x63, 0x64, 0x74, 0x85, 0x70, 0xC7,
0xE8, 0x8A, 0xDA, 0x7F, 0x42, 0x33, 0x7A, 0x98,
0x8C, 0x72, 0x66, 0x9D, 0x85, 0x5E, 0xF3, 0x3D
};
uint8_t RSA_D[] = {
0x2C, 0x70, 0xA3, 0xAF, 0xA7, 0xEC, 0x4C, 0x82,
0x33, 0x09, 0x9B, 0x34, 0xF9, 0xCA, 0x20, 0x94,
0x9F, 0xF9, 0x3E, 0x57, 0x5E, 0x78, 0x63, 0x75,
0x33, 0x74, 0xB3, 0xD3, 0x7E, 0x87, 0x98, 0x45,
0x33, 0x1C, 0xA3, 0x2E, 0x66, 0x63, 0xF9, 0x06,
0x1E, 0xDF, 0xE7, 0x48, 0xFE, 0x27, 0x56, 0x76,
0x86, 0x34, 0x4E, 0x67, 0x08, 0x4A, 0x1B, 0xB3,
0x31, 0x54, 0xE7, 0xDD, 0x1B, 0x54, 0xAE, 0x62,
0x12, 0x18, 0xCA, 0x43, 0x28, 0xA1, 0x7A, 0x3F,
0xB6, 0x2C, 0xA2, 0x3D, 0xED, 0x2D, 0x7E, 0x96,
0xE0, 0x12, 0x6F, 0xC6, 0x86, 0x20, 0x6B, 0x5A,
0x5E, 0x76, 0x79, 0x0C, 0x38, 0x80, 0x18, 0x50,
0xA6, 0x42, 0x8C, 0xB7, 0xC3, 0x17, 0xEF, 0xB4,
0xB8, 0xAE, 0x74, 0xDF, 0x0F, 0x69, 0xCD, 0xB5,
0x73, 0x3E, 0xD4, 0x75, 0x27, 0x1D, 0x94, 0x91,
0x8A, 0x1A, 0xA1, 0x8C, 0x08, 0x4A, 0x15, 0xE1
};
#endif /* TRM_FAKE_KEY_SEL0 */
#endif /* CONFIG_ID2_RSA_KEY */
#if CONFIG_ID2_AES_KEY
char ID[24] = "00FFFFFFFFFFFFA6F67AB700";
#if CONFIG_AES_256_BIT
#define FAKE_AES_BITS 256
uint8_t AES_KEY[] = {
0xa5, 0xd5, 0xae, 0x48, 0xc3, 0xbc, 0x31, 0xdd,
0x2b, 0xac, 0xd2, 0xff, 0xa3, 0x9d, 0x34, 0xf5,
0x0f, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09,
0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01
};
#elif CONFIG_AES_192_BIT
#define FAKE_AES_BITS 192
uint8_t AES_KEY[] = {
0xa5, 0xd5, 0xae, 0x48, 0xc3, 0xbc, 0x31, 0xdd,
0x2b, 0xac, 0xd2, 0xff, 0xa3, 0x9d, 0x34, 0xf5,
0x0f, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09,
};
#elif CONFIG_AES_128_BIT
#define FAKE_AES_BITS 128
uint8_t AES_KEY[] = {
0xa5, 0xd5, 0xae, 0x48, 0xc3, 0xbc, 0x31, 0xdd,
0x2b, 0xac, 0xd2, 0xff, 0xa3, 0x9d, 0x34, 0xf5,
};
#endif /* CONFIG_AES_256_BIT */
#endif /* CONFIG_ID2_AES_KEY */
int32_t trm_get_key_data(uint32_t key_type, void *data, uint32_t *size)
{
if (data == 0) {
TRM_DRV_DBG_E("trm_get_key_data: bad arg\n");
return -1;
}
if (key_type == KEY_TYPE_ID2_ID) {
if (*size < sizeof(ID) - 1) {
TRM_DRV_DBG_E("trm_get_key_data: ID2_ID size too short(0x%08x)\n", *size);
return -1;
}
memcpy(data, ID, sizeof(ID) - 1);
} else {
TRM_DRV_DBG_E("trm_get_key_data: bad arg\n");
return -1;
}
return 0;
}
#if CONFIG_ID2_RSA_KEY
int32_t tee_trm_read_rsa_key(void)
{
/* convert _g_id2_rsa_n and _g_id2_rsa_d and _g_id2_rsa_e */
_convert_buf_to_bndata((const uint8_t *)RSA_N, sizeof(RSA_N),
(uint32_t *)_g_id2_rsa_n, (ID2_KEY_BITS >> 5));
_convert_buf_to_bndata((const uint8_t *)RSA_D, sizeof(RSA_D),
(uint32_t *)_g_id2_rsa_d, (ID2_KEY_BITS >> 5));
_convert_buf_to_bndata((const uint8_t *)_g_id2_rsa_fixed_raw_e, sizeof(_g_id2_rsa_fixed_raw_e),
(uint32_t *)_g_id2_rsa_e, (ID2_KEY_BITS >> 5));
return 0;
}
#elif CONFIG_ID2_AES_KEY
int32_t tee_trm_read_sym_key(uint32_t type)
{
if (type == TEE_TRM_AES) {
memcpy(_g_id2_aes_key, AES_KEY, FAKE_AES_BITS >> 3);
_g_id2_aes_key_bits = FAKE_AES_BITS;
} else {
TRM_DRV_DBG_E("not support yet\n");
return -1;
}
return 0;
}
#endif /* CONFIG_ID2_AES_KEY */

View file

@ -0,0 +1,199 @@
/**
* Copyright (C) 2015-2016 The YunOS Project. All rights reserved.
*/
#include "tee_trm.h"
#include "tee_trm_priv.h"
#if CONFIG_ID2_RSA_KEY
extern void _convert_buf_to_bndata(const uint8_t *src, int32_t src_bytes,
uint32_t *dst, int32_t dst_words);
extern uint32_t _g_id2_rsa_n[ID2_KEY_BITS >> 5];
extern uint32_t _g_id2_rsa_e[ID2_KEY_BITS >> 5];
extern uint32_t _g_id2_rsa_d[ID2_KEY_BITS >> 5];
uint8_t _g_id2_rsa_fixed_raw_e[3] = {0x01, 0x00, 0x01};
#endif /* CONFIG_ID2_RSA_KEY */
#if CONFIG_ID2_AES_KEY
extern uint32_t _g_id2_aes_key[ID2_AES_KEY_MAX_BYTES];
extern uint32_t _g_id2_aes_key_bits;
#endif /* CONFIG_ID2_AES_KEY */
extern uint32_t g_mft_idx_base;
static int32_t _get_key_meta_info(mft_idx_info_t *mft_idx,
uint32_t key_type, mft_key_meta_t *key_meta)
{
uint32_t i;
TEE_ASSERT(mft_idx && key_meta);
for (i = 0; i < mft_idx->key_num; i++) {
if (mft_idx->key_metas[i].type == key_type) {
memcpy(key_meta,
&mft_idx->key_metas[i], sizeof(mft_key_meta_t));
return 0;
}
}
TRM_DRV_DBG_I("not find key meta for type(%d)", key_type);
return -1;
}
static int32_t _get_key_addr(mft_pos_info_t *pos_info, uint32_t *key_addr)
{
uint32_t bank_num;
uint32_t bit_idx;
uint32_t byte_idx;
if (pos_info == NULL || key_addr == NULL) {
tee_dbg_print(ERR, "_get_key_addr: bad args\n");
return -1;
}
if (pos_info->type == POS_INFO_TYPE_FUSE) {
bank_num = pos_info->info >> 16;
bit_idx = pos_info->info & 0xffff;
byte_idx = bit_idx >> 3;
*key_addr = bank_num*PLATFORM_OTP_BANK_SIZE + byte_idx + PLATFORM_OTP_SECURE_SECTOR_START;
} else {
TRM_DRV_DBG_E("_get_key_addr: not support this type(%d)\n", pos_info->type);
return -1;
}
return 0;
}
int32_t trm_get_key_data(uint32_t key_type, void *data, uint32_t *size)
{
int ret;
uint32_t key_addr;
mft_idx_info_t *mft_idx;
mft_key_meta_t key_meta;
if (data == 0) {
TRM_DRV_DBG_E("trm_get_key_data: bad arg\n");
return -1;
}
mft_idx = (mft_idx_info_t *)g_mft_idx_base;
if (mft_idx->magic != MANIFEST_IDX_MAGIC) {
TRM_DRV_DBG_E("trm_get_key_data: bad mft idx magic(0x%08x)\n", mft_idx->magic);
return -1;
}
ret = _get_key_meta_info(mft_idx, key_type, &key_meta);
if (ret < 0) {
TRM_DRV_DBG_E("trm_get_key_data: fail to get key meta\n");
return -1;
}
if (*size < key_meta.size) {
TRM_DRV_DBG_E("trm_get_key_data: short buffer %d vs %d\n",
*size, key_meta.size);
*size = key_meta.size;
return -1;
}
*size = key_meta.size;
ret = _get_key_addr(&key_meta.pos_info, &key_addr);
if (ret < 0) {
TRM_DRV_DBG_E("trm_get_key_data: get key addr fail\n");
return -1;
}
#ifdef TEE_TRM_DBG
TRM_DRV_DBG_I("key_meta.type: %d\n", key_meta.type);
TRM_DRV_DBG_I("key_meta.size: %d\n", key_meta.size);
TRM_DRV_DBG_I("key_meta.flag: 0x%04x\n", key_meta.flag);
TRM_DRV_DBG_I("key_addr: 0x%08x\n", key_addr);
#endif
memcpy(data, (void *)key_addr, key_meta.size);
return 0;
}
#if CONFIG_ID2_RSA_KEY
static int32_t tee_trm_read_rsa_key(void)
{
int32_t ret;
uint8_t *tmp_n_d;
uint32_t tmp_n_d_sz;
tmp_n_d_sz = ID2_KEY_BITS >> 2;
tmp_n_d = (uint8_t *)malloc(tmp_n_d_sz);
if (tmp_n_d == NULL) {
TRM_DRV_DBG_E("_tee_trm_read_rsa_key: malloc %d out of memory!\n", ID2_KEY_BITS >> 3);
return -1;
}
ret = trm_get_key_data(
KEY_TYPE_ID2_PRVK, tmp_n_d, &tmp_n_d_sz);
if (ret != 0) {
TRM_DRV_DBG_E("_tee_trm_read_rsa_key: fail to get id2 priv key\n");
goto __out;
}
_convert_buf_to_bndata((const uint8_t *)tmp_n_d, (tmp_n_d_sz >> 1),
(uint32_t *)_g_id2_rsa_n, (ID2_KEY_BITS >> 5));
_convert_buf_to_bndata((const uint8_t *)(tmp_n_d + (tmp_n_d_sz >> 1)), (tmp_n_d_sz >> 1),
(uint32_t *)_g_id2_rsa_d, (ID2_KEY_BITS >> 5));
_convert_buf_to_bndata((const uint8_t *)_g_id2_rsa_fixed_raw_e, sizeof(_g_id2_rsa_fixed_raw_e),
(uint32_t *)_g_id2_rsa_e, (ID2_KEY_BITS >> 5));
memset(tmp_n_d, 0, tmp_n_d_sz);
ret = 0;
__out:
free(tmp_n_d);
return ret;
}
#endif /* CONFIG_ID2_RSA_KEY */
#if CONFIG_ID2_AES_KEY
int32_t tee_trm_read_sym_key(uint32_t type)
{
int ret = 0;
uint8_t *sym_key = NULL;
uint32_t sym_key_byte = ID2_AES_KEY_MAX_BYTES;
sym_key = (uint8_t *)malloc(ID2_AES_KEY_MAX_BYTES);
if (!sym_key) {
TRM_DRV_DBG_E("_tee_trm_read_sym_key: malloc out of memory!\n");
return -1;
}
ret = trm_get_key_data(
KEY_TYPE_ID2_PRVK, sym_key, &sym_key_byte);
if (ret != 0) {
TRM_DRV_DBG_E("_tee_trm_read_rsa_key: fail to get id2 priv key\n");
goto __out;
}
switch (type) {
case TEE_TRM_AES: {
memcpy(_g_id2_aes_key, sym_key, sym_key_byte);
_g_id2_aes_key_bits = sym_key_byte << 3;
break;
}
default: {
TRM_DRV_DBG_E("_tee_trm_read_rsa_key: not support type\n", type);
goto __out;
}
}
__out:
if (sym_key) {
free(sym_key);
sym_key = NULL;
}
return ret;
}
#endif /* CONFIG_ID2_AES_KEY */

View file

@ -0,0 +1,34 @@
/**
* Copyright (C) 2015-2016 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_TRM_PRIV_H_
#define _TEE_TRM_PRIV_H_
#include "tee_dbg.h"
#ifdef CONFIG_TRM_DRV_DBG
#define TRM_DRV_DBG_E(str, x...) \
do { \
tee_dbg_print(ERR, "%s:%d: " str, __FUNCTION__, __LINE__, ## x); \
} while (0)
#define TRM_DRV_DBG_I(str, x...) \
do { \
tee_dbg_print(INF, "%s:%d: " str, __FUNCTION__, __LINE__, ## x); \
} while (0)
#else
#define TRM_DRV_DBG_E(str, x...) TEE_ERROR(-8)
#define TRM_DRV_DBG_I(str, x...)
#endif
int32_t trm_get_key_data(uint32_t key_type, void *data, uint32_t *size);
#if CONFIG_ID2_RSA_KEY
int32_t tee_trm_read_rsa_key(void);
#elif CONFIG_ID2_AES_KEY
int32_t tee_trm_read_sym_key(uint32_t type);
#endif /* CONFIG_ID2_RSA_KEY */
#endif /* _TEE_TRM_PRIV_H */

View file

@ -0,0 +1,75 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*
* Filename : device.h
* Author : Jun Lin
* Date Created : 08/12/2015
* Description : driver interface header
*/
#ifndef _DEVICE_H_
#define _DEVICE_H_
#include "tee_types.h"
#include "tee_list.h"
#include "tee_table.h"
#define DEV_NAME_LEN 8
#define DEV_TREE_MAGIC 0x44657654 /* DevT */
enum status {
SUCCESS = 0,
FAIL = -1,
ETIMEOUT = -2,
EARG = -3,
EBUSY = -4,
ESYSIO = -5,
EMEM = -6,
};
typedef struct _dev_t {
uint32_t magic;
tee_list_t node;
int8_t name[DEV_NAME_LEN];
struct _dev_ops_t *ops;
uint32_t dev_ref; /* device open reference */
#ifdef MUTLI_THREAD
tee_osa_sem_t lock; /* for dev_ref */
#endif
void *priv; /* private, could be set in device open */
} dev_t;
typedef struct _dev_ops_t {
int32_t (*open)(dev_t *dev);
int32_t (*read)(dev_t *dev, int32_t pos, void *buf, int32_t size);
int32_t (*write)(dev_t *dev, int32_t pos, void *buf, int32_t size);
int32_t (*ioctl)(dev_t *dev, int32_t cmd, void *arg);
int32_t (*suspend)(dev_t *dev, int32_t state);
int32_t (*resume)(dev_t *dev);
int32_t (*close)(dev_t *dev);
} dev_ops_t;
typedef struct _dev_tree_t {
uint32_t magic;
uint8_t *name;
int32_t (*probe)(void);
} dev_tree_t;
#define DEV_INIT(func, name_str) \
dev_tree_t _##func##_ TABLE_ATTR(devtree) = { DEV_TREE_MAGIC, \
name_str, \
func }
extern void device_init(void); /* should be call only once in bs */
extern dev_t *dev_register(int8_t *name, dev_ops_t *ops);
extern int32_t dev_unregister(dev_t *dev);
extern void *dev_open(int8_t *name);
extern int32_t dev_close(dev_t *dev);
extern int32_t dev_ioctl(dev_t *dev, int32_t cmd, void *arg);
extern int32_t dev_read(dev_t *dev, int32_t pos, void *buf, int32_t size);
extern int32_t dev_write(dev_t *dev, int32_t pos, void *buf, int32_t size);
extern int32_t dev_suspend(int32_t state);
extern int32_t dev_resume(void);
#endif /*_DEVICE_H_ */

View file

@ -0,0 +1,33 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_ADDR_MAP_H_
#define _TEE_ADDR_MAP_H_
#include "hal_memmap.h"
/*****************************************/
/* Memory Map for Sillicon */
/*****************************************/
/*******************************************************************/
/* TEE TW address map */
/*******************************************************************/
#define TW_RO_ADDR (FLASH_START)
#define TW_RO_SIZE (HAL_TW_RO_SIZE)
#define NTW_ENTRY_ADDR (TW_RO_ADDR + TW_RO_SIZE)
#define TW_RW_ADDR (SRAM_START)
#define TW_RW_SIZE (HAL_TW_RW_SIZE)
#define TEE_HEAP_SIZE (_SIZE_4K)
/*******************************************************************/
/* TEE NTW(test bed) address map */
/*******************************************************************/
#define NTW_RO_ADDR (FLASH_START + TW_RO_SIZE)
#define NTW_RO_SIZE (HAL_NTW_RO_SIZE)
#define NTW_RW_ADDR (SRAM_START + _SIZE_32K)
#define NTW_RW_SIZE (HAL_NTW_RW_SIZE)
#define NTW_HEAP_SIZE (_SIZE_8K)
#endif /* _TEE_ADDR_MAP_H_ */

View file

@ -0,0 +1,31 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_COMM_H_
#define _TEE_COMM_H_
#ifndef __ASSEMBLY__
#include "tee_types.h"
#endif
/* This may be included by assembly */
/* fall in Trusted OS Calls */
#define _NTW_SMC64_CALLING (0)
#define NTW_NEW_RQST (0x32000000 | ((_NTW_SMC64_CALLING) << 31))
#define NTW_NORM_CALL (0x33000000 | ((_NTW_SMC64_CALLING) << 31))
#define NTW_LPM_RQST (0x32000010 | ((_NTW_SMC64_CALLING) << 31))
#define _TW_SMC64_CALLING (0)
#define TW_NEW_RQST (0x34000000 | ((_TW_SMC64_CALLING) << 31))
#define TW_NORM_CALL (0x35000000 | ((_TW_SMC64_CALLING) << 31))
#define COMM_MSG_RQST (0x54535152) /* ASCII: RQST */
#define COMM_MSG_DONE (0x454E4F44) /* ASCII: DONE */
#ifndef __ASSEMBLY__
extern int32_t teec_comm_send(uint32_t smcid, uint32_t subcmd, const void *msg);
#endif
#endif /* _TEE_COMM_H_ */

View file

@ -0,0 +1,16 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_CORE_H_
#define _TEE_CORE_H_
#include "tee_types.h"
tee_stat_t tee_core_init(void);
void tee_core_cleanup(void);
tee_stat_t tee_core_proc(void *msg);
tee_stat_t tee_core_get_cur_uuid(TEE_UUID *uuid);
#endif /* _TEE_CORE_H_ */

View file

@ -0,0 +1,731 @@
/**
* Copyright (C) 2016 The YunOS Project. All rights reserved.
**/
/* Alibaba TEE Crypto API: version 1.0 */
#ifndef _TEE_CRYPTO_H_
#define _TEE_CRYPTO_H_
#include "tee_types.h"
typedef enum _tee_crypto_result {
TEE_CRYPTO_ERROR = 0x80000000, /* 0: Generic Error */
TEE_CRYPTO_NOSUPPORT, /* 1: Scheme not support */
TEE_CRYPTO_INVALID_KEY, /* 2: Invalid Key in asymmetric scheme: RSA/DSA/ECCP/DH etc */
TEE_CRYPTO_INVALID_TYPE, /* 3: Invalid aes_type/des_type/authenc_type/hash_type/cbcmac_type/cmac_type */
TEE_CRYPTO_INVALID_CONTEXT, /* 4: Invalid context in multi-thread cipher/authenc/mac/hash etc */
TEE_CRYPTO_INVALID_PADDING, /* 5: Invalid sym_padding/rsassa_padding/rsaes_padding */
TEE_CRYPTO_INVALID_AUTHENTICATION, /* 6: Invalid authentication in AuthEnc(AES-CCM/AES-GCM)/asymmetric verify(RSA/DSA/ECCP DSA) */
TEE_CRYPTO_INVALID_ARG, /* 7: Invalid arguments */
TEE_CRYPTO_INVALID_PACKET, /* 8: Invalid packet in asymmetric enc/dec(RSA) */
TEE_CRYPTO_LENGTH_ERR, /* 9: Invalid Length in arguments */
TEE_CRYPTO_OUTOFMEM, /* a: Memory alloc NULL */
TEE_CRYPTO_BUFFER_OVERFLOW, /* b: Output buffer is too short to store result */
TEE_CRYPTO_NULL, /* c: NULL pointer in arguments */
TEE_CRYPTO_ERR_STATE, /* d: Bad state in mulit-thread cipher/authenc/mac/hash etc */
TEE_CRYPTO_SUCCESS = 0, /* Success */
} tee_crypto_result;
#define AES_BLOCK_SIZE 16
#define AES_IV_SIZE 16
#define DES_BLOCK_SIZE 8
#define DES_IV_SIZE 8
typedef enum _sym_padding_t {
SYM_NOPAD = 0,
SYM_PKCS5_PAD = 1,
SYM_ZERO_PAD = 2,
} sym_padding_t;
typedef enum _aes_type_t {
AES_ECB = 0,
AES_CBC = 1,
AES_CTR = 2,
AES_CTS = 3,
AES_XTS = 4,
} aes_type_t;
typedef enum _des_type_t {
DES_ECB = 0,
DES_CBC = 1,
DES3_ECB = 2,
DES3_CBC = 3,
} des_type_t;
typedef enum _authenc_type_t {
AES_CCM = 0,
AES_GCM = 1,
} authenc_type_t;
typedef enum _hash_type_t {
SHA1 = 0,
SHA224 = 1,
SHA256 = 2,
SHA384 = 3,
SHA512 = 4,
MD5 = 5,
} hash_type_t;
enum {
MD5_HASH_SIZE = 16,
SHA1_HASH_SIZE = 20,
SHA224_HASH_SIZE = 28,
SHA256_HASH_SIZE = 32,
SHA384_HASH_SIZE = 48,
SHA512_HASH_SIZE = 64,
MAX_HASH_SIZE = 64,
};
#define HASH_SIZE(type) (((type) == SHA1) ? (SHA1_HASH_SIZE) : ( \
((type) == SHA224) ? (SHA224_HASH_SIZE) : ( \
((type) == SHA256) ? (SHA256_HASH_SIZE) : ( \
((type) == SHA384) ? (SHA384_HASH_SIZE) : ( \
((type) == SHA512) ? (SHA512_HASH_SIZE) : ( \
((type) == MD5) ? (MD5_HASH_SIZE) : (0)))))))
typedef enum _cbcmac_type_t {
AESCBCMAC = 0,
DESCBCMAC = 1,
DES3CBCMAC = 2,
} cbcmac_type_t;
typedef enum _cmac_type_t {
AESCMAC = 0,
} cmac_type_t;
typedef enum _rsa_key_attr_t {
RSA_MODULUS = 0x130,
RSA_PUBLIC_EXPONENT = 0x230,
RSA_PRIVATE_EXPONENT = 0x330,
RSA_PRIME1 = 0x430,
RSA_PRIME2 = 0x530,
RSA_EXPONENT1 = 0x630,
RSA_EXPONENT2 = 0x730,
RSA_COEFFICIENT = 0x830,
} rsa_key_attr_t;
typedef enum _rsa_pad_type_t {
RSA_NOPAD = 0,
RSAES_PKCS1_V1_5 = 10,
RSAES_PKCS1_OAEP_MGF1 = 11,
RSASSA_PKCS1_V1_5 = 20,
RSASSA_PKCS1_PSS_MGF1 = 21,
} rsa_pad_type_t;
typedef struct _rsa_padding_t {
rsa_pad_type_t type;
union {
struct {
hash_type_t type;
const uint8_t *lparam;
size_t lparamlen;
} rsaes_oaep;
struct {
hash_type_t type; /* md5/sha1/sha224/sha256/sha384/sha512 */
} rsassa_v1_5;
struct {
hash_type_t type; /* sha1/sha224/sha256/sha384/sha512 */
size_t salt_len;
} rsassa_pss;
} pad;
} rsa_padding_t;
typedef enum _dsa_padding_t {
DSA_SHA1 = 0,
DSA_SHA224 = 1,
DSA_SHA256 = 2,
} dsa_padding_t;
enum {
CRYPTO_STATUS_CLEAN = 0,
CRYPTO_STATUS_INITIALIZED = 1,
CRYPTO_STATUS_PROCESSING = 2,
CRYPTO_STATUS_FINISHED = 3,
};
/* internal data types */
typedef struct __rsa_keypair rsa_keypair_t;
typedef struct __rsa_pubkey rsa_pubkey_t;
typedef struct __dsa_keypair dsa_keypair_t;
typedef struct __dsa_pubkey dsa_pubkey_t;
typedef struct __dh_keypair dh_keypair_t;
typedef struct __dh_pubkey dh_pubkey_t;
typedef struct __ecc_keypair ecc_keypair_t;
typedef struct __ecc_pubkey ecc_pubkey_t;
/********************************************************************/
/* SYM */
/********************************************************************/
/*
* type[in]: must be AES_ECB/AES_CBC/AES_CTR/AES_CTS/AES_XTS
* size[out]: check size != NULL
* -- caller will alloc "size" memory as context buffer later
*/
tee_crypto_result tee_aes_get_ctx_size(aes_type_t type, size_t *size);
/*
* type[in]: must be AES_ECB/AES_CBC/AES_CTR/AES_CTS/AES_XTS
* is_enc[in]: [true] for encrypt, [false] for decrypt
* key1[in]: the encrypt key
* key2[in]: the tweak encrypt key for XTS mode
* keybytes[in]: the key length of the keys(each) in bytes, should be 16/24/32 bytes
* iv[in]: only valid for AES_CBC/AES_CTR/AES_CTS/AES_XTS
* -- function can read 16 bytes from this address as the internal iv
* context[in/out]: caller allocated memory used as internal context, which size is got through tee_aes_get_ctx_size
* -- [in]: status of context should be CLEAN or FINISHED
* -- [out]: status of context is changed to INITIALIZED
*/
tee_crypto_result tee_aes_init(aes_type_t type, bool is_enc,
const uint8_t *key1, const uint8_t *key2,
size_t keybytes, const uint8_t *iv, void *context);
/*
* src[in]: plaintext for encrypt, ciphertext for decrypt
* dst[out]: ciphertext for encrypt, plaintext for decrypt
* size[in]: the number of bytes to process
* -- ECB/CBC/CTS/XTS, must be multiple of the cipher block size
* -- CTR, any positive integer
* context[in/out]: internal context
* -- [in]: status of context should be INITED or PROCESSING
* -- [out]: status of context is changed to PROCESSING
*/
tee_crypto_result tee_aes_process(const uint8_t *src, uint8_t *dst,
size_t size, void *context);
/*
* src[in]: source data, plaintext for encrypt/ciphertext for decrypt
* -- may be NULL, which identify that no input data, only terminate crypto
* src_size[in]: the number of bytes to process, src_size == 0 if src == NULL
* -- encrypt: SYM_NOPAD - must be multiple of the cipher block size
* -- decrypt: ECB/CBC - must be multiple of the cipher block size
* dst[out]: destination data, which is used to save processed data
* -- may be NULL if no input src data(src == NULL && src_size == 0)
* -- ciphertext for encrypt, plaintext for decrypt
* -- if no SYM_NOPAD, should remove padding data accordingly
* dst_size[in/out]: the length of processed data, may be NULL if dst == NULL
* -- [in]: buffer size
* -- [out]: the actual encrypted/decrypted data size
* padding[in]: padding type for aes mode
* -- ECB/CBC: only support SYM_NOPAD
* -- CTR/CTS/XTS: padding is ignored
* context[in/out]: internal context
* -- [in]: status of context should be INITED or PROCESSING
* -- [out]: status of context is changed to FINISHED
*/
tee_crypto_result tee_aes_finish(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
sym_padding_t padding, void *context);
tee_crypto_result tee_aes_reset(void *context);
tee_crypto_result tee_aes_copy_context(void *dst_ctx, void *src_ctx);
/* AES fips */
tee_crypto_result tee_aes_cipher_id2_fips(aes_type_t type,
bool is_enc, const uint8_t *iv,
uint8_t *src, uint32_t src_len,
uint8_t *dest, uint32_t *dest_len);
/* des include des3 */
/*
type: must be DES_ECB/DES_CBC/DES3_ECB/DES3_CBC
size: check size != NULL
*/
tee_crypto_result tee_des_get_ctx_size(des_type_t type, size_t *size);
/*
type: must be DES_ECB/DES_CBC/DES3_ECB/DES3_CBC
is_enc: [true] for encrypt, [false] for decrypt.
key: function will read 'keybytes' of data as key.
keybytes: for DES_ECB/DES_CBC, must be 64.
for DES3_ECB/DES3_CBC, must be 128 or 192.
iv: for DES_ECB/DES3_ECB: must be NULL.
for DES_CBC/DES3_CBC: function will read 8 bytes as algo iv.
context: function will use size which return from function 'tee_des_get_ctx_size'
as internal context.
function will check the [status[ of 'context', must be CLEAN or FINISH.
function will initialize the [status] of 'context' to INIT.
function will save the 'type', 'is_enc', or maybe 'iv', 'key', 'keybytes' in 'context'.
function will initialize the 'context' to a valid context.
*/
tee_crypto_result tee_des_init(des_type_t type, bool is_enc,
const uint8_t *key, size_t keybytes,
const uint8_t *iv, void *context);
/*
src: function will read 'size' of data from this area as source data.
MUST be NULL if 'size' is 0
dst: function will write 'size' of data to this area as destination data.
MUST be NULL if 'size' is 0
size: the length of source data.
must be multiple of 8 bytes. or 0.
if size == 0, src MUST be NULL, dst MUST be NULL, return TEE_SUCCESS.
context: function will use size which return from function 'tee_des_get_ctx_size'
as internal context.
function will check it is a valid context.
function will check the [status] of 'context', must be INIT or PROCESS.
function will change the [status] of 'context' to PROCESS.
function will do encrypt or decrypt indicated by the content in 'context'.
*/
tee_crypto_result tee_des_process(const uint8_t *src, uint8_t *dst,
size_t size, void *context);
/*
src: function will read 'src_size' of data from this area as source data.
MUST be NULL if 'src_size' is 0.
src_size: the length of source data. this have different rules for differnt 'type' and 'padding'.
a. for 'padding' is SYM_NOPAD:
a.1 MUST be multiple of 16 bytes. or 0.
b. for other 'padding':
b.1 can be any integer or 0.
if 'src_size' == 0, 'src' MUST be NULL, 'dst' MUST be NULL, and this function will reaturn SUCCESS.
dst: function will write certain length which is retuned by 'dst_size'
of data to this area as destination data.
MUST be NULL if 'size' is 0
dst_size: function will wirte some integer to this area to indicate the length of destination data.
the return value depends on 'src_size' and 'padding'
a.1 for 'padding' is SYM_NOPAD, dst_size is equal to src_size.
a.2 for other 'padding', 'dst_size' is 16 bytes align up of 'src_size'.
padding: the padding type of finish.
can be anyone of SYM_NOPAD/SYM_PKCS5_PAD/SYM_ZERO_PAD.
context: function will use size which return from function 'tee_des_get_ctx_size'
as internal context.
function will check it is a valid context.
function will check the [status] of 'context', must be INIT or PROCESS.
function will change the [status] of 'context' to FINISH.
function will do encrypt or decrypt indicated by the content in 'context'.
function MUST clean the content of context before this fucntion return.
*/
tee_crypto_result tee_des_finish(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
sym_padding_t padding, void *context);
tee_crypto_result tee_des_reset(void *context);
tee_crypto_result tee_des_copy_context(void *dst_ctx, void *src_ctx);
/********************************************************************/
/* Authenticated Encryption */
/********************************************************************/
/*
type: MUST be AES_CCM/AES_GCM
size: check size != NULL
*/
tee_crypto_result tee_authenc_get_ctx_size(authenc_type_t type, size_t *size);
/*
type: MUST be AES_CCM/AES_GCM
is_enc: [true] for encrypt, [false] for decrypt.
key: function will read 'keybytes' of data as key.
keybytes: MUST be 16(128 bits)/24(256 bits)/32(512 bits).
nonce: the operation 'nonce' for AES_CCM, the IV of AES_GCM.
function will read 'nonce_len' of data as nonce or IV.
nonce_len: the nonce length for AES_CCM, the IV length for AES_GCM.
tag_len: the tag byte length.
payload_len: only valid for AES_CCM, the payload length. Ignore for AES_GCM.
aad_len: only valid for AES_CCM, the aad length. Ignore for AES_GCM.
context: function will use size which return from function 'tee_authenc_get_ctx_size'
as internal context.
function will check the [status] of 'context', must be CLEAN or FINISH.
function will initialize the [status] of 'context' to INIT.
function will save the 'type', 'is_enc', or maybe 'nonce', 'nonce_len',
'tag_len', 'payload_len', 'aad_len' in 'context'.
function will initialize the 'context' to a valid context.
*/
tee_crypto_result tee_authenc_init(authenc_type_t type, bool is_enc,
const uint8_t *key, size_t keybytes,
const uint8_t *nonce, size_t nonce_len,
size_t tag_len,
size_t payload_len, /* valid only in CCM */
size_t aad_len, /* valid only in CCM */
void *context);
/*
aad: the address of aad.
function will read 'aad_size' of data from this address as aad.
aad_size: the length in bytes of aad.
for AES_CCM:
the total summary of 'aad_size' of multiple calling this function MUST equal to
the 'aad_len' parameter in tee_authenc_init.
context: function will use size which return from function 'tee_authenc_get_ctx_size'
as internal context.
function will check it is a valid context.
function will check the [status] of 'context', must be INIT or UPDATE_AAD.
function will change the [status] of 'context' to UPDATE_AAD.
*/
tee_crypto_result tee_authenc_update_aad(
const uint8_t *aad, size_t aad_size, void *context);
/*
src: function will read 'size' of data from this area as source data.
MUST be NULL if 'size' is 0
dst: function will write 'size' of data to this area as destination data.
MUST be NULL if 'size' is 0
size: the length of source data, can be any integer or 0.
for AES_CCM.
the total summary of 'size' of multiple calling this function MUST equal to
the 'payload_len' parameter in tee_authenc_init.
context: function will use size which return from function 'tee_authenc_get_ctx_size'
as internal context.
function will check it is a valid context.
function will check the [status] of 'context', must be UPDATE_AAD or PROCESS.
function will change the [status] of 'context' to PROCESS.
function will do encrypt or decrypt indicated by the content in 'context'.
*/
tee_crypto_result tee_authenc_process(const uint8_t *src, uint8_t *dst,
size_t size, void *context);
/*
src: function will read 'size' of data from this area as source data.
MUST be NULL if 'src_size' is 0.
src_size: the length of source data.
if 'src_size' == 0, 'src' MUST be NULL, 'dst' MUST be NULL, and this function will reaturn SUCCESS.
dst: function will write certain length which is retuned by 'dst_size'
of data to this area as destination data.
MUST be NULL if 'size' is 0
dst_size: function will wirte some integer to this area to indicate the length of destination data.
tag: the tag returned by ae encrypt.
tag_len: the tag length.
context: function will use size which return from function 'tee_authenc_get_ctx_size'
as internal context.
function will check it is a valid context.
function will check the [status] of 'context', must be UPDATE_AAD or PROCESS.
function will change the [status] of 'context' to FINISH.
the 'is_enc' indicated by the content in 'context' MUST be ture.
function will do encrypt or decrypt indicated by the content in 'context'.
function MUST clean the content of context before this fucntion return.
*/
tee_crypto_result tee_authenc_enc_finish(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
uint8_t *tag, size_t *tag_len,
void *context);
/*
src: function will read 'size' of data from this area as source data.
MUST be NULL if 'src_size' is 0.
src_size: the length of source data.
if 'src_size' == 0, 'src' MUST be NULL, 'dst' MUST be NULL, and this function will reaturn SUCCESS.
dst: function will write certain length which is retuned by 'dst_size'
of data to this area as destination data.
MUST be NULL if 'size' is 0
dst_size: function will wirte some integer to this area to indicate the length of destination data.
tag: the tag parameter.
function will read 'tag_len' of data from this address as the decrypt tag.
tag_len: the tag length.
context: function will use size which return from function 'tee_authenc_get_ctx_size'
as internal context.
function will check it is a valid context.
function will check the [status] of 'context', must be UPDATE_AAD or PROCESS.
function will change the [status] of 'context' to FINISH.
the 'is_enc' indicated by the content in 'context' MUST be false.
function will do encrypt or decrypt indicated by the content in 'context'.
function MUST clean the content of context before this fucntion return.
*/
tee_crypto_result tee_authenc_dec_finish(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
const uint8_t *tag, size_t tag_len,
void *context);
tee_crypto_result tee_authenc_reset(void *context);
tee_crypto_result tee_authenc_copy_context(void *dst_ctx, void *src_ctx);
/********************************************************************/
/* HASH */
/********************************************************************/
tee_crypto_result tee_hash_get_ctx_size(hash_type_t type, size_t *size);
tee_crypto_result tee_hash_init(hash_type_t type, void *context);
tee_crypto_result tee_hash_update(const uint8_t *src, size_t size, void *context);
tee_crypto_result tee_hash_final(uint8_t *dgst, void *context);
tee_crypto_result tee_hash_reset(void *context);
tee_crypto_result tee_hash_copy_context(void *dst_ctx, void *src_ctx);
tee_crypto_result tee_hash_digest(hash_type_t type,
const uint8_t *src, size_t size, uint8_t *dgst);
/********************************************************************/
/* MAC */
/********************************************************************/
/* hmac */
tee_crypto_result tee_hmac_get_ctx_size(hash_type_t type, size_t *size);
tee_crypto_result tee_hmac_init(hash_type_t type,
const uint8_t *key, size_t keybytes, void *context);
tee_crypto_result tee_hmac_update(const uint8_t *src, size_t size, void *context);
tee_crypto_result tee_hmac_final(uint8_t *dgst, void *context);
tee_crypto_result tee_hmac_reset(void *context);
tee_crypto_result tee_hmac_copy_context(void *dst_ctx, void *src_ctx);
tee_crypto_result tee_hmac_digest(hash_type_t type,
const uint8_t *key, size_t keybytes,
const uint8_t *src, size_t size, uint8_t *dgst);
/* cbcmac */
tee_crypto_result tee_cbcmac_get_ctx_size(cbcmac_type_t type, size_t *size);
tee_crypto_result tee_cbcmac_init(cbcmac_type_t type,
const uint8_t *key, size_t keybytes, void *context);
tee_crypto_result tee_cbcmac_update(const uint8_t *src, size_t size, void *context);
tee_crypto_result tee_cbcmac_final(
sym_padding_t padding, uint8_t *dgst, void *context);
tee_crypto_result tee_cbcmac_reset(void *context);
tee_crypto_result tee_cbcmac_copy_context(void *dst_ctx, void *src_ctx);
tee_crypto_result tee_cbcmac_digest(cbcmac_type_t type,
const uint8_t *src, size_t size,
sym_padding_t padding, uint8_t *dgst);
/* cmac */
tee_crypto_result tee_cmac_get_ctx_size(cmac_type_t type, size_t *size);
tee_crypto_result tee_cmac_init(cmac_type_t type,
const uint8_t *key, size_t keybytes, void *context);
tee_crypto_result tee_cmac_update(const uint8_t *src, size_t size, void *context);
tee_crypto_result tee_cmac_final(
sym_padding_t padding, uint8_t *dgst, void *context);
tee_crypto_result tee_cmac_reset(void *context);
tee_crypto_result tee_cmac_copy_context(void *dst_ctx, void *src_ctx);
tee_crypto_result tee_cmac_digest(cmac_type_t type,
const uint8_t *src, size_t size,
sym_padding_t padding, uint8_t *dgst);
/********************************************************************/
/* ASYM */
/********************************************************************/
/* RSA */
/*
* e: Public exponent
* d: Private exponent
* n: Modulus
*
* Optional CRT parameters
* p, q: N = pq
* qp: 1/q mod p
* dp: d mod (p-1)
* dq: d mod (q-1)
*/
/*
* keybits[in]: key length in bits
* size[out]: total size in bytes of rsa keypair
*/
tee_crypto_result tee_rsa_get_keypair_size(size_t keybits, size_t *size);
/*
* keybits[in]: key length in bits
* size[out]: total size in bytes of rsa public key
*/
tee_crypto_result tee_rsa_get_pubkey_size(size_t keybits, size_t *size);
/*
* Initialize RSA keypair
*
* keybits[in]: rsa keypair length in bits
* n/n_size[in]: rsa modulus data and size in bytes
* e/e_size[in]: rsa public exponent data and size in bytes
* d/d_size[in]: rsa private exponent data and size in bytes
* p/p_size[in]: rsa prime1 data and size in bits, may be NULL/0
* q/q_size[in]: rsa prime2 data and size in bits, may be NULL/0
* dp/dp_size[in]: rsa exponent2 data and size in bits, may be NULL/0
* dq/dq_size[in]: rsa exponent2 data and size in bits, may be NULL/0
* dq/dq_size[in]: rsa coefficient data and size in bits, may be NULL/0
* keypair[out]: output buffer, which is used to save initialized rsa key pair
*/
tee_crypto_result tee_rsa_init_keypair(size_t keybits,
const uint8_t *n, size_t n_size,
const uint8_t *e, size_t e_size,
const uint8_t *d, size_t d_size,
const uint8_t *p, size_t p_size,
const uint8_t *q, size_t q_size,
const uint8_t *dp, size_t dp_size,
const uint8_t *dq, size_t dq_size,
const uint8_t *qp, size_t qp_size,
rsa_keypair_t *keypair);
/*
* Initialize RSA public key
*
* keybits[in]: rsa key length in bits
* n/n_size[in]: rsa modulus data and size in bytes
* e/e_size[in]: rsa public exponent data and size in bytes
* pubkey[out]: output buffer, which is used to save initialized rsa public key
*/
tee_crypto_result tee_rsa_init_pubkey(size_t keybits,
const uint8_t *n, size_t n_size,
const uint8_t *e, size_t e_size,
rsa_pubkey_t *pubkey);
/*
* Generate RSA keypair
*
* keybits[in]: rsa key length in bits
* e[in]: optional, public exponent
* e_size[in]: optional, public exponent size in bytes
* keypair[out]: output buffer, which is used to save generated rsa key pair
*/
tee_crypto_result tee_rsa_gen_keypair(size_t keybits,
const uint8_t *e, size_t e_size,
rsa_keypair_t *keypair);
/*
* Get key attribute
*
* attr[in]: rsa key attribute ID
* keypair[in]: rsa keypair buffer
* buffer[out]: buffer, which is used to save required attribute
* size[in/out]: buffer max size and key attribute actual size in bytes
*/
tee_crypto_result tee_rsa_get_key_attr(rsa_key_attr_t attr,
rsa_keypair_t *keypair, void *buffer, size_t *size);
tee_crypto_result tee_rsa_public_encrypt(const rsa_pubkey_t *pub_key,
const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
rsa_padding_t padding);
tee_crypto_result tee_rsa_private_decrypt(const rsa_keypair_t *priv_key,
const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
rsa_padding_t padding);
/*
* dig[in]: the digest to sign
* dig_size[in]: the length of the digest to sign (byte)
* sig[out]: the signature data
* sig_size[in/out]: the buffer size and resulting size of signature
*/
tee_crypto_result tee_rsa_sign(const rsa_keypair_t *priv_key,
const uint8_t *dig, size_t dig_size,
uint8_t *sig, size_t *sig_size, rsa_padding_t padding);
/*
* dig[in]: the digest of message that was signed
* dig_size[in]: the digest size in bytes
* sig[in]: the signature data
* sig_size[in]: the length of the signature data (byte)
*/
tee_crypto_result tee_rsa_verify(const rsa_pubkey_t *pub_key,
const uint8_t *dig, size_t dig_size,
const uint8_t *sig, size_t sig_size,
rsa_padding_t padding, bool *result);
/* RSA FIPS */
tee_crypto_result tee_rsa_sign_id2_fips(const uint8_t *dig, size_t dig_size,
uint8_t *sig, size_t *sig_size, rsa_padding_t padding);
tee_crypto_result tee_rsa_verify_id2_fips(const uint8_t *dig, size_t dig_size,
const uint8_t *sig, size_t sig_size,
rsa_padding_t padding, bool *result);
tee_crypto_result tee_rsa_public_encrypt_id2_fips(
const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
rsa_padding_t padding);
tee_crypto_result tee_rsa_private_decrypt_id2_fips(
const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
rsa_padding_t padding);
/* DSA sign/verify */
/*
g: Generator of subgroup (public)
p: Prime number (public)
q: Order of subgroup (public)
y: Public key
x: Private key
*/
tee_crypto_result tee_dsa_get_keypair_size(size_t keybits, size_t *size);
tee_crypto_result tee_dsa_get_pubkey_size(size_t keybits, size_t *size);
tee_crypto_result tee_dsa_init_keypair(size_t keybits,
const uint8_t *g, size_t g_size,
const uint8_t *p, size_t p_size,
const uint8_t *q, size_t q_size,
const uint8_t *y, size_t y_size,
const uint8_t *x, size_t x_size,
dsa_keypair_t *keypair);
tee_crypto_result tee_dsa_init_pubkey(size_t keybits,
const uint8_t *g, size_t g_size,
const uint8_t *p, size_t p_size,
const uint8_t *q, size_t q_size,
const uint8_t *y, size_t y_size,
dsa_pubkey_t *pubkey);
tee_crypto_result tee_dsa_gen_keypair(size_t keybit,
const uint8_t *g, size_t g_size,
const uint8_t *p, size_t p_size,
const uint8_t *q, size_t q_size,
dsa_keypair_t *keypair);
tee_crypto_result tee_dsa_sign(const dsa_keypair_t *priv_key,
const uint8_t *src, size_t src_size,
uint8_t *signature, size_t *sig_size,
dsa_padding_t padding);
tee_crypto_result tee_dsa_verify(const dsa_pubkey_t *pub_key,
const uint8_t *src, size_t src_size,
const uint8_t *signature, size_t sig_size,
dsa_padding_t padding, bool *result);
/* DH derive shared secret */
/*
g: Generator of Z_p
p: Prime modulus
y: Public key y = g^x
x: Private key
q: Optional
xbits: Optional
*/
tee_crypto_result tee_dh_get_keypair_size(size_t keybits, size_t *size);
tee_crypto_result tee_dh_get_pubkey_size(size_t keybits, size_t *size);
tee_crypto_result tee_dh_init_keypair(size_t keybits,
const uint8_t *g, size_t g_size,
const uint8_t *p, size_t p_size,
const uint8_t *y, size_t y_size,
const uint8_t *x, size_t x_size,
const uint8_t *q, size_t q_size, /* optional */
size_t xbits, /* optional */
dh_keypair_t *keypair);
tee_crypto_result tee_dh_init_pubkey(size_t keybits,
const uint8_t *g, size_t g_size,
const uint8_t *p, size_t p_size,
const uint8_t *y, size_t y_size,
dh_pubkey_t *pubkey);
tee_crypto_result tee_dh_gen_keypair(size_t keybit,
const uint8_t *g, size_t g_size,
const uint8_t *p, size_t p_size,
const uint8_t *q, size_t q_size,
size_t xbits, dh_keypair_t *keypair);
tee_crypto_result tee_dh_derive_secret(
const dh_keypair_t *priv_key,
const dh_pubkey_t *peer_pub_key,
uint8_t *shared_secret, size_t *secret_size);
/*
d: Private value
x: Public value x
y: Public value y
curve: Curve type
*/
tee_crypto_result tee_ecc_get_keypair_size(size_t curve, size_t *size);
tee_crypto_result tee_ecc_get_pubkey_size(size_t curve, size_t *size);
tee_crypto_result tee_ecc_init_keypair(
const uint8_t *x, size_t x_size,
const uint8_t *y, size_t y_size,
const uint8_t *d, size_t d_size,
size_t curve, ecc_keypair_t *keypair);
tee_crypto_result tee_ecc_init_pubkey(
const uint8_t *x, size_t x_size,
const uint8_t *y, size_t y_size,
size_t curve, ecc_pubkey_t *pubkey);
tee_crypto_result tee_ecc_gen_keypair(
size_t curve, ecc_keypair_t *keypair);
/* ECDSA sign/verify */
tee_crypto_result tee_ecdsa_sign(const ecc_keypair_t *priv_key,
const uint8_t *src, size_t src_size,
uint8_t *signature, size_t *sig_size);
tee_crypto_result tee_ecdsa_verify(const ecc_pubkey_t *pub_key,
const uint8_t *src, size_t src_size,
const uint8_t *signature, size_t sig_size,
bool *result);
/* ECDH derive shared secret */
tee_crypto_result tee_ecdh_derive_secret(
const ecc_keypair_t *priv_key,
const ecc_pubkey_t *peer_pubkey_key,
uint8_t *shared_secret, size_t *secret_size);
/* random generator */
tee_crypto_result tee_seed(uint8_t *seed, size_t seed_len);
tee_crypto_result tee_rand_gen(uint8_t *buf, size_t len);
tee_crypto_result tee_crypto_init(void);
void tee_crypto_cleanup(void);
#endif /* _TEE_CRYPTO_H_ */

View file

@ -0,0 +1,79 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_DBG_H_
#define _TEE_DBG_H_
#include "tee_types.h"
#include "tee_tos.h"
#ifdef CONFIG_DBG
#define tee_dbg_print(_l, _f, _a ...) \
({ \
int32_t __ret__ = 0; \
if ((_l) <= g_dbg_level) { \
__ret__ = printf(_f, ##_a); \
} \
__ret__; \
})
#define tee_err_handle(_err) \
do { \
tee_chk_stk_boundary(); \
backtrace(); \
} while (0)
#define TEE_ASSERT(_x) \
do { \
if (!(_x)) { \
tee_dbg_print(ERR, "ASSERT FAILURE:\n"); \
tee_dbg_print(ERR, (int8_t *)"%s (%d): %s\n", \
__FILE__, __LINE__, __FUNCTION__); \
tee_err_handle(-1); \
while (1) /* loop */; \
} \
} while (0)
#define TEE_ERROR(_x) \
do { \
tee_dbg_print(ERR, "TEE ERROR: 0x%08x:\n", (_x)); \
tee_err_handle(_x); \
} while (0)
#else /* !CONFIG_DBG */
#define tee_dbg_print(_l, _f, _a ...)
#define TEE_ASSERT(_x) \
do { \
if (!(_x)) { \
tee_err_handle(-1); \
while (1) /* loop */; \
} \
} while (0)
#define TEE_ERROR(_x) \
do { \
tee_err_handle(_x); \
} while (0)
#endif
#ifdef CONFIG_DBG
enum {
ERR = 0, /* error */
WRN = 1, /* warning */
INF = 2, /* information */
};
extern uint32_t g_dbg_level;
#endif
#ifndef CONFIG_DBG
void tee_err_handle(uint32_t err);
#endif
#ifdef CONFIG_DBG
void backtrace(void);
void tee_set_stk_boundary(void *boundary);
void tee_chk_stk_boundary(void);
#endif
#endif /* _TEE_DBG_H_ */

View file

@ -0,0 +1,79 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_LIST_H_
#define _TEE_LIST_H_
#include "tee_types.h"
typedef struct _tee_list_t {
struct _tee_list_t *next;
struct _tee_list_t *prev;
} tee_list_t;
/* initialize list head staticly */
#define TEE_LIST_INIT(list) {&(list), &(list)}
static inline void tee_list_init(tee_list_t *head)
{
head->prev = head;
head->next = head;
}
static inline void tee_list_add(tee_list_t *head, tee_list_t *elem)
{
elem->next = head->next;
head->next->prev = elem;
head->next = elem;
elem->prev = head;
}
static inline void tee_list_add_tail(tee_list_t *head, tee_list_t *elem)
{
elem->prev = head->prev;
head->prev->next = elem;
head->prev = elem;
elem->next = head;
}
#define tee_list_add_before(entry, new_entry) tee_list_add_tail(entry, new_entry)
static inline void tee_list_del(tee_list_t *elem)
{
elem->prev->next = elem->next;
elem->next->prev = elem->prev;
elem->prev = elem->next = 0;
}
static inline tee_list_t *tee_list_prev(tee_list_t *list, tee_list_t *item) {
if (item->prev != list) {
return item->prev;
} else {
return NULL;
}
}
static inline tee_list_t* tee_list_next(tee_list_t *list, tee_list_t *item) {
if (item->next != list) {
return item->next;
} else {
return NULL;
}
}
#define tee_list_empty(list) ((list)->next == list)
#define tee_list_entry(addr, type, member) ({ \
type tmp; \
int offset = (int)(&tmp.member) - (int)&tmp; \
(type *)((int)addr - offset); \
})
#define tee_list_iterate(head, entry) \
for ((entry) = (head)->next; (entry) != (head); (entry) = (entry)->next)
#define tee_list_iterate_safe(head, entry, n) \
for (entry = (head)->next, n = entry->next; entry != (head); \
entry = n, n = entry->next)
#endif /* _TEE_LIST_H_ */

View file

@ -0,0 +1,131 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_SRV_H_
#define _TEE_SRV_H_
#include "tee_types.h"
#include "tee_tos.h"
#define IS_TEE_SRV_VALID(_srv) (('T' == (_srv)->magic[0]) && \
('s' == (_srv)->magic[1]) && \
('R' == (_srv)->magic[2]) && \
('v' == (_srv)->magic[3]))
typedef struct _tee_srv_intf_t
{
TEE_Result (*TA_CreateEntryPoint)(void);
void (*TA_DestroyEntryPoint)(void);
TEE_Result (*TA_OpenSessionEntryPoint)(
uint32_t paramTypes,
TEE_Param params[4],
void **sessionContext);
void (*TA_CloseSessionEntryPoint)(void *sessionContext);
TEE_Result (*TA_InvokeCommandEntryPoint)(
void *sessionContext,
uint32_t commandID,
uint32_t paramTypes,
TEE_Param param[4]);
} tee_srv_intf_t;
typedef enum _tee_srv_prop_type_t
{
TEE_SRV_PROP_TYPE_INVALID,
TEE_SRV_PROP_TYPE_STR,
TEE_SRV_PROP_TYPE_BOOL,
TEE_SRV_PROP_TYPE_INT,
TEE_SRV_PROP_TYPE_BINARY,
TEE_SRV_PROP_TYPE_UUID,
TEE_SRV_PROP_TYPE_IDENTITY,
TEE_SRV_PROP_TYPE_MAX,
} tee_srv_prop_type_t;
typedef struct _tee_srv_prop_t
{
int8_t *name;
tee_srv_prop_type_t type;
union
{
int8_t *str;
bool boolean;
uint32_t u32;
struct
{
void *buf;
uint32_t size;
} bin;
TEE_UUID uuid;
TEE_Identity id;
} data;
} tee_srv_prop_t;
typedef struct _tee_srv_data_t
{
tee_srv_intf_t *intf;
tee_srv_prop_t (*prop)[];
} tee_srv_data_t;
typedef struct _tee_srv_head_t
{
uint8_t magic[4];
uint8_t ver;
uint8_t rsvd[3];
uint32_t tee_fix; /* rsvd for smart computing */
uint32_t data_link_start;
uint32_t data_link_end;
uint32_t data_offset;
uint32_t bss_link_start;
uint32_t bss_link_end;
uint32_t bss_offset;
tee_srv_data_t srv_data;
} tee_srv_head_t;
#define TEE_SRV_DATA_START(create, destroy, open_ss, close_ss, invoke_cmd) \
static tee_srv_intf_t _g_$$intf$$ __attribute__((__used__)) = { \
create, destroy, open_ss, close_ss, invoke_cmd \
}; \
static tee_srv_prop_t _g_$$prop$$[] __attribute__((__used__)) = {
#define TEE_SRV_UUID_PROPERTY(n, val) \
{ \
.name = n, \
.type = TEE_SRV_PROP_TYPE_UUID, \
.data.uuid = val, \
},
#define TEE_SRV_STR_PROPERTY(n, val) \
{ \
.name = n, \
.type = TEE_SRV_PROP_TYPE_STR, \
.data.str = val, \
},
#define TEE_SRV_INT_PROPERTY(n, val) \
{ \
.name = n, \
.type = TEE_SRV_PROP_TYPE_INT, \
.data.u32 = val, \
},
#define TEE_SRV_BOOL_PROPERTY(n, val) \
{ \
.name = n, \
.type = TEE_SRV_PROP_TYPE_BOOL, \
.data.boolean = val, \
},
#define TEE_SRV_DATA_END \
{ \
.name = NULL, \
.type = TEE_SRV_PROP_TYPE_INVALID, \
.data.u32 = 0, \
}, \
}; \
\
volatile static tee_srv_data_t _g_$$srv$$_$$data$$ \
__attribute__((__used__)) \
__attribute__((__section__(".srv.data"))) = \
{ &_g_$$intf$$, &_g_$$prop$$ };
#endif /* _TEE_SRV_H_ */

View file

@ -0,0 +1,39 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_TABLE_H_
#define _TEE_TABLE_H_
/*
* Define a new Table
* SORT .table section in lds is a MUST!!
* usage: NEW_TABLE(struct dev_t, dev)
*
* table.name.begin
* table.name.data
* table.name.data
* tabl.name.end
*/
#define NEW_TABLE(type, name) \
type g_table_##name##_start[0] __attribute__((__section__(".table." #name ".begin"))); \
type g_table_##name##_end[0] __attribute__((__section__(".table." #name ".end"))); \
/*
* Add a new element to the .table.name.data
* usage: struct dev_t uart_dev TABLE_ATTR(name) = { };
*/
#define TABLE_ATTR(name) \
__attribute__((__section__(".table." #name ".data")))
/*
* query the table.name.data. p variable should be decleared as volatile because
* the table could be empty.
* usage: struct dev_t *p;
* TABLE_FOREACH(p, dev) {
* }
*/
#define TABLE_FOREACH(p, name) \
for((p) = g_table_##name##_start; (g_table_##name##_start != g_table_##name##_end) && ((p)!= g_table_##name##_end); (p)++)
#endif /* _TEE_TABLE_H_ */

View file

@ -0,0 +1,117 @@
/**
* Copyright (C) 2016 The YunOS Project. All rights reserved.
**/
#ifndef _TEE_TOS_H_
#define _TEE_TOS_H_
#include "tee_types.h"
#include <stdarg.h>
#define TEE_SUCCESS (0x00000000)
#define TEE_ERROR_GENERIC (0xFFFF0000)
#define TEE_ERROR_ACCESS_DENIED (0xFFFF0001)
#define TEE_ERROR_CANCEL (0xFFFF0002)
#define TEE_ERROR_ACCESS_CONFLICT (0xFFFF0003)
#define TEE_ERROR_EXCESS_DATA (0xFFFF0004)
#define TEE_ERROR_BAD_FORMAT (0xFFFF0005)
#define TEE_ERROR_BAD_PARAMETERS (0xFFFF0006)
#define TEE_ERROR_BAD_STATE (0xFFFF0007)
#define TEE_ERROR_ITEM_NOT_FOUND (0xFFFF0008)
#define TEE_ERROR_NOT_IMPLEMENTED (0xFFFF0009)
#define TEE_ERROR_NOT_SUPPORTED (0xFFFF000A)
#define TEE_ERROR_NO_DATA (0xFFFF000B)
#define TEE_ERROR_OUT_OF_MEMORY (0xFFFF000C)
#define TEE_ERROR_BUSY (0xFFFF000D)
#define TEE_ERROR_COMMUNICATION (0xFFFF000E)
#define TEE_ERROR_SECURITY (0xFFFF000F)
#define TEE_ERROR_SHORT_BUFFER (0xFFFF0010)
#define TEE_PENDING (0xFFFF2000)
#define TEE_ERROR_TIMEOUT (0xFFFF3001)
#define TEE_ERROR_OVERFLOW (0xFFFF300F)
#define TEE_ERROR_TARGET_DEAD (0xFFFF3024)
#define TEE_ERROR_STORAGE_NO_SPACE (0xFFFF3041)
#define TEE_ERROR_MAC_INVALID (0xFFFF3071)
#define TEE_ERROR_SIGNATURE_INVALID (0xFFFF3072)
#define TEE_ERROR_TIME_NOT_SET (0xFFFF5000)
#define TEE_ERROR_TIME_NEEDS_RESET (0xFFFF5001)
#define TEE_PARAM_TYPE_NONE (0)
#define TEE_PARAM_TYPE_VALUE_INPUT (1)
#define TEE_PARAM_TYPE_VALUE_OUTPUT (2)
#define TEE_PARAM_TYPE_VALUE_INOUT (3)
#define TEE_PARAM_TYPE_MEMREF_INPUT (5)
#define TEE_PARAM_TYPE_MEMREF_OUTPUT (6)
#define TEE_PARAM_TYPE_MEMREF_INOUT (7)
#define TEE_ORIGIN_API (0x00000001)
#define TEE_ORIGIN_COMMS (0x00000002)
#define TEE_ORIGIN_TEE (0x00000003)
#define TEE_ORIGIN_TRUSTED_APP (0x00000004)
typedef uint32_t TEE_Result;
typedef struct
{
uint32_t timeLow;
uint16_t timeMid;
uint16_t timeHiAndVersion;
uint8_t clockSeqAndNode[8];
} TEE_UUID;
typedef struct
{
uint32_t login;
TEE_UUID uuid;
} TEE_Identity;
#define TEE_PARAM_TYPES(t0, t1, t2, t3) \
((t0) | ((t1) << 4) | ((t2) << 8) | ((t3) << 12))
#define TEE_PARAM_TYPE_GET(t, i) (((t) >> (i*4)) & 0xF)
typedef union
{
struct
{
void *buffer;
uint32_t size;
} memref;
struct
{
uint32_t a, b;
} value;
} TEE_Param;
/* strings */
extern void *memcpy(void *dest, const void *src, size_t n);
extern void *memmove(void *dest, const void *src, size_t n);
extern void *memset(void *s, int c, size_t n);
extern int memcmp(const void *s1, const void *s2, size_t n);
extern char *strcpy(char *dest, const char *src);
extern char *strncpy(char *dest, const char *src, size_t n);
extern char *strcat(char *dest, const char *src);
extern char *strncat(char *dest, const char *src, size_t n);
extern int strcmp(const char *s1, const char *s2);
extern int strncmp(const char *s1, const char *s2, size_t n);
extern size_t strlen(const char *s);
extern size_t strnlen(const char *s, size_t maxlen);
/* pool */
extern void *malloc(size_t size);
extern void *realloc(void *ptr, size_t size);
extern void *memalign(size_t size, size_t alignment);
extern void free(void *ptr);
/* print */
extern void uart_print_uint8(unsigned char data);
extern void uart_print_uint32(unsigned int data);
extern void uart_print_string(char *data);
#ifdef CONFIG_DBG
extern int printf(const char *format, ...);
extern int sprintf(char *s, const char *format, ...);
extern int vsprintf(char *s, const char *format, va_list arg);
extern int snprintf(char *s, size_t maxlen, const char *format, ...);
extern int vsnprintf(char *s, size_t maxlen, const char *format, va_list arg);
#endif
#endif /* _TEE_TOS_H_ */

View file

@ -0,0 +1,68 @@
/**
* Copyright (C) 2016 The YunOS Project. All rights reserved.
**/
#ifndef _TEE_TST_H_
#define _TEE_TST_H_
#if CONFIG_API_TST
typedef enum
{
TEE_SEEK_SET = 0,
TEE_SEEK_CUR = 1,
TEE_SEEK_END = 2
} TEE_Whence;
typedef enum _tee_open_flag_t
{
TOF_CREAT = 0x00000001,
TOF_EXCL = 0x00000002,
TOF_READ = 0x00000004,
TOF_WRITE = 0x00000008,
} tee_open_flag_t;
typedef void * tee_file_iter_t;
/*
* return >0:success -1:error
*/
int32_t tee_open(const int8_t *name, int32_t flags);
/*
* return 0:success -1:error
*/
int32_t tee_close(int32_t fd);
/*
* return 0:success -1:error
*/
int32_t tee_close_delete(int32_t fd);
/*
* return success: return read data size. error: -1
*/
ssize_t tee_read(int32_t fd, void *buf, size_t size);
/*
* return success: return write data size. error: -1
*/
ssize_t tee_write(int32_t fd, const void *buf, size_t size);
/*
* return 0:success -1:error
*/
int32_t tee_ioctl(int32_t fd, int32_t cmd, ... /* args */);
/*
* return success: the resulting offset location. error: -1
*/
int32_t tee_lseek(int32_t fd, int32_t offset, int32_t whence);
/*
* return 0:success -1:error
*/
int32_t tee_ltruncate(int32_t fd, int32_t length);
tee_file_iter_t tee_create_file_iter(void);
void tee_destroy_file_iter(tee_file_iter_t iter);
/*
* return 0:success -1:error
*/
int32_t tee_iter_file(tee_file_iter_t iter, int8_t *name);
#endif
#endif /* _TEE_TST_H_ */

View file

@ -0,0 +1,49 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#ifndef _TEE_TYPES_H_
#define _TEE_TYPES_H_
#ifndef __STDINT__
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
typedef signed long int ssize_t;
typedef unsigned long size_t;
typedef long long_t;
typedef unsigned long ulong_t;
#endif /* __STDINT__ */
typedef unsigned char bool;
typedef int32_t tee_stat_t;
#ifndef false
#define false (0)
#endif
#ifndef true
#define true (1)
#endif
#ifndef NULL
#define NULL ((void *)0)
#endif
/* EXPORT_SYMBOL is used to export the available symbols to TAs */
#define EXPORT_SYMBOL(_symbol_)
#endif /* _TEE_TYPES_H_ */

View file

@ -0,0 +1,27 @@
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
TOP := ..
CURRENT_BUILD := TW
include $(TOP)/tee.cfg
include $(TOP)/Make.rules
SRCS := $(wildcard *.c *.cxx)
SRCS += $(wildcard ./lpm/*.c ./lpm/*.S)
OBJS := $(patsubst %.S,%.o,$(patsubst %.cxx,%.o,$(patsubst %.c,%.o,$(SRCS))))
LIBS := mon_emu.o
CFLAGS += -I$(TOP)/arch/c_sky/inc
CFLAGS += -DLPM_BTM_EMU
ASFLAGS += -DLPM_BTM_EMU
all: $(OBJS) $(LIBS)
$(LIBS): $(OBJS)
$(NOECHO)$(LD) -r -o $(LIBS) $(OBJS)
@echo "Finish building $(LIBS)..."
clean:
@echo "Cleaning $(LIBS)..."
$(NOECHO)rm -f $(OBJS) $(LIBS)

View file

@ -0,0 +1,40 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#include "tee_types.h"
#include "tee_tos.h"
#include "tee_core.h"
#include "tee_dbg.h"
#include "tee_comm.h"
extern int32_t sw_to_lpm(void *msg);
int32_t dispatcher_main(uint32_t smcid, uint32_t subcmd, uint32_t buf, uint32_t rsvd)
{
int32_t ret = COMM_MSG_DONE;
if (NTW_NEW_RQST == smcid) {
if (TEE_SUCCESS != tee_core_proc((void *)buf)) {
ret = COMM_MSG_DONE;
}
}
#ifdef CONFIG_MEMORY_PROFILING
else if (0x12345678 == smcid) {
extern void mem_profiling_dump_stack_usage(void);
extern void mem_profiling_dump_heap_usage(void);
mem_profiling_dump_stack_usage();
mem_profiling_dump_heap_usage();
}
#endif
else if (NTW_LPM_RQST == smcid) {
if (TEE_SUCCESS == sw_to_lpm((void *)buf)) {
ret = COMM_MSG_DONE;
}
} else {
ret = -1;
}
return ret;
}

View file

@ -0,0 +1,515 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
/*
******************************
* HEADERS
******************************
*/
#include "ck_pmu.h"
#include "device.h"
#include "tee_addr_map.h"
#include "tee_eflash.h"
#include "tee_dbg.h"
#include "hal_memmap.h"
/*
******************************
* MACROS
******************************
*/
#ifdef CONFIG_CK_PMU_DBG
#define CK_PUM_DBG_E(_f, _a ...) tee_dbg_print(ERR, _f, ##_a)
#define CK_PUM_DBG_I(_f, _a ...) tee_dbg_print(INF, _f, ##_a)
#else
#define CK_PUM_DBG_E(_f, _a ...) TEE_ERROR(-9)
#define CK_PUM_DBG_I(_f, _a ...)
#endif
#define TEE_DRV_EFLASH_NAME "eflash"
/*(PowerManagement) base Address*/
#define P_CK_PMU ((ck_pmu_t *)PLATFORM_PMU_ADDRBASE)
#define STORE_REG_SIZE (0x70 * (sizeof(uint32_t)))
/*
******************************
* TYPES
******************************
*/
/* CPU work mode */
typedef enum {
CK_POWM_PREWAIT = 0 ,
CK_POWM_PREDOZE = 1 ,
CK_POWM_PRESTOP = 2,
CK_POWM_PRECLOCK = 3,
CK_POWM_PRESTANDBY = 4,
CK_POWM_WAIT = 5 ,
CK_POWM_DOZE = 6 ,
CK_POWM_STOP = 7,
CK_POWM_STANDBY = 8,
POWM_CLOCK = 9
} ck_cpu_mode;
typedef struct _ck_pmu_t
{
volatile uint32_t LPCR;
volatile uint32_t MCLKSEL;
volatile uint32_t CRCR;
volatile uint32_t CGCR;
volatile uint32_t CGSR;
volatile uint32_t CLKDSENR;
volatile uint32_t CLKSTBR;
volatile uint32_t CLKSTBST;
volatile uint32_t CLKSTBMK;
volatile uint32_t CSSCR;
volatile uint32_t DFCC;
volatile uint32_t PCR;
volatile uint32_t PLTR;
volatile uint32_t SWHRC;
volatile uint32_t SWHRD;
volatile uint32_t SWPRC;
volatile uint32_t SWPRD;
volatile uint32_t SWRE;
volatile uint32_t BOOTSEL;
} ck_pmu_t;
typedef struct _ck_register_t
{
uint32_t *base;
uint32_t nums;
uint32_t *data;
char *name;
} ck_register_t;
typedef struct _lpm_args_t
{
ck_cpu_mode mode;
uint32_t gate;
uint32_t irqid;
} lpm_args_t;
/*
******************************
* VARIABLES
******************************
*/
static volatile ck_register_t *_g_pmu_regs = NULL;
static volatile void *_g_cur_reg_strore_addr = NULL;
uint32_t lpm_resume_stack[LPM_RESERVE_STACK_SIZE/sizeof(uint32_t)];
/*
******************************
* FUNCTIONS
******************************
*/
extern uint32_t arch_tw_do_cpu_save(void *addr);
extern uint32_t arch_tw_do_cpu_resume(void *addr);
extern uint32_t resume_from_ram_wrapper(void);
extern uint32_t resume_from_disk_wrapper(void);
extern int32_t hal_uart_init(uint32_t addr, uint32_t baudrate, uint32_t parity,
int32_t wordsize, int32_t stopbit);
static int32_t _alloc_for_cur_regs(void)
{
if (NULL == _g_cur_reg_strore_addr) {
_g_cur_reg_strore_addr = malloc(STORE_REG_SIZE);
if (NULL == _g_cur_reg_strore_addr) {
CK_PUM_DBG_E("out of memory\n");
return EMEM;
}
}
return SUCCESS;
}
static void _free_for_cur_regs(void)
{
if (NULL != _g_cur_reg_strore_addr) {
free((void *)_g_cur_reg_strore_addr);
_g_cur_reg_strore_addr = NULL;
}
}
static void _arch_tw_cpu_resume(void)
{
if (NULL == _g_cur_reg_strore_addr) {
TEE_ASSERT(0);
}
arch_tw_do_cpu_resume((void *)_g_cur_reg_strore_addr);
}
static int32_t _tw_save_pmu_regs(void)
{
int i = 0;
_g_pmu_regs = (ck_register_t *)malloc(sizeof(ck_register_t));
if (NULL == _g_pmu_regs) {
CK_PUM_DBG_E("out of memory\n");
return EMEM;
}
_g_pmu_regs->name = "pmu";
_g_pmu_regs->base = (uint32_t *)PLATFORM_PMU_ADDRBASE;
_g_pmu_regs->nums = 19;
_g_pmu_regs->data = (uint32_t *)malloc((_g_pmu_regs->nums << 2));
if (NULL == _g_pmu_regs->data) {
CK_PUM_DBG_E("out of memory\n");
return EMEM;
}
for (i=0; i<_g_pmu_regs->nums; i++) {
*(_g_pmu_regs->data + i) = *(_g_pmu_regs->base + i);
}
return SUCCESS;
}
static int32_t _tw_restore_pmu_regs(ck_cpu_mode mode)
{
int i = 0;
if (mode == CK_POWM_STOP || mode == CK_POWM_STANDBY) {
for (i=0; i<_g_pmu_regs->nums; i++) {
*(_g_pmu_regs->base + i) = *(_g_pmu_regs->data + i);
}
free(_g_pmu_regs->data);
free((void *)(_g_pmu_regs));
_g_pmu_regs = NULL;
}
return SUCCESS;
}
static int32_t _eflash_program(uint32_t addr, uint32_t *buf, uint32_t length)
{
dev_t *ef_dev = NULL;
tee_eflash_write_args_t write_args;
int32_t ret = SUCCESS;
ef_dev = dev_open(TEE_DRV_EFLASH_NAME);
if (NULL == ef_dev) {
CK_PUM_DBG_E("dev open elfash drv fail\n");
return ESYSIO;
}
#if 0
int i =0 ;
for (i=0;i<20;++i) {
CK_PUM_DBG_I("%08x \n", *(buf + i));
}
CK_PUM_DBG_I("\n");
#endif
write_args.addr = addr;
write_args.buf = buf;
write_args.size = length;
ret = dev_write(ef_dev, write_args.addr, write_args.buf, write_args.size);
if (length != ret) {
CK_PUM_DBG_E("eflash write fail 0x%08x\n", ret);
dev_close(ef_dev);
return ESYSIO;
}
dev_close(ef_dev);
return SUCCESS;
}
static uint32_t _eflash_read(uint32_t *buf, uint32_t flash_addr, uint32_t length)
{
uint32_t copied = 0;
CK_PUM_DBG_I("eflash read 0x%08x buf 0x%08x size 0x%08x\n",
flash_addr, (uint32_t)buf, length);
/* becasue the isram is lost, so we need copy directly */
if (0 == length) {
return copied;
}
#if 0
int i =0 ;
for (i=0;i<20;++i) {
CK_PUM_DBG_I("%08x \n", *((uint32_t *)flash_addr + i));
}
CK_PUM_DBG_I("\n");
#endif
while (copied < length) {
*((uint8_t *)buf + copied) = *((uint8_t *)flash_addr + copied);
copied++;
}
return copied;
}
/*
* Function : resume_from_ram();
*/
void resume_from_ram(void)
{
int32_t ret = SUCCESS;
hal_uart_init(PLATFORM_UART_ADDRBASE0, 9600, 0, 8, 1);
dev_resume();
CK_PUM_DBG_I("resume from stop\n");
ret = _tw_restore_pmu_regs(CK_POWM_STOP);
_arch_tw_cpu_resume();
}
/*
* Function : resume_from_disk();
*/
void resume_from_disk(void)
{
int32_t ret = SUCCESS;
hal_uart_init(PLATFORM_UART_ADDRBASE0, 9600, 0, 8, 1);
/* restore isram */
_eflash_read((uint32_t *)LPM_RW_BASE,
(uint32_t)LPM_RW_SAVED_ADDR,
(uint32_t)LPM_RW_SAVED_SIZE);
dev_resume();
CK_PUM_DBG_I("resume from standby\n");
ret = _tw_restore_pmu_regs(CK_POWM_STANDBY);
_arch_tw_cpu_resume();
}
/*
* Function : _resume_addr_save();
* save the resume function to an address
* Parameters:
* mode -- under the different mode to save the context.
* addr -- save the resume function the addr.
* Return: 0.
*/
static int32_t _resume_addr_save(ck_cpu_mode mode, uint32_t *addr)
{
volatile uint32_t resume_addr[2] = {(uint32_t)resume_from_ram_wrapper,
(uint32_t)resume_from_disk_wrapper};
int32_t ret = SUCCESS;
if (mode == CK_POWM_STOP) {
ret = _eflash_program((uint32_t)addr, (uint32_t *)(&resume_addr[0]), 0x4);
} else if (mode == CK_POWM_STANDBY) {
ret = _eflash_program((uint32_t)addr, (uint32_t *)(&resume_addr[1]), 0x4);
}
return ret;
}
/*
* Function : _ck_powm_clockgate();
*/
static int32_t _ck_powm_clockgate(uint32_t gate)
{
P_CK_PMU->CGCR = ~gate ;
return SUCCESS;
}
/*
* Function : _save_context();
* Save the IP Context.
* Parameters:
* mode -- under the different mode to save the context.
* Return: 0.
*/
static int32_t _save_context(ck_cpu_mode mode)
{
int32_t ret = SUCCESS;
ret = _tw_save_pmu_regs();
if (SUCCESS != ret) {
return ret;
}
if (mode == CK_POWM_STOP) {
ret = dev_suspend(CK_POWM_STOP);
if (SUCCESS != ret) {
CK_PUM_DBG_E("dev suspend fail %x\n", ret);
goto _err_after_save_pmu;
}
} else if (mode == CK_POWM_STANDBY) {
ret = dev_suspend(CK_POWM_STANDBY);
if (SUCCESS != ret) {
CK_PUM_DBG_E("dev suspend fail %x\n", ret);
goto _err_after_save_pmu;
}
ret = _eflash_program((uint32_t)LPM_RW_SAVED_ADDR,
(uint32_t *)LPM_RW_BASE,
(uint32_t)LPM_RW_SAVED_SIZE);
if (SUCCESS != ret) {
CK_PUM_DBG_E("eflash write fail %x\n", ret);
goto _err_after_suspend;
}
}
return SUCCESS;
_err_after_suspend:
dev_resume();
_err_after_save_pmu:
_tw_restore_pmu_regs(mode);
return ret;
}
/*
* Function : _tw_to_wait();
* Security, enter Wait mode
* Parameters:
* gate -- choose the ip clock you want to close.
* Return: 0.
*/
static int32_t _tw_to_wait(uint32_t gate)
{
P_CK_PMU->LPCR = CK_POWM_LPCR_ENABLE;
_ck_powm_clockgate(gate);
__asm__("wait");
_ck_powm_clockgate(~gate);
return SUCCESS;
}
/*
* Function : _tw_to_doze();
* Security, enter Doze mode
* Return: 0.
*/
static int32_t _tw_to_doze(void)
{
P_CK_PMU->LPCR = CK_POWM_LPCR_ENABLE;
__asm__("doze");
return SUCCESS;
}
#ifdef LPM_BTM_EMU
extern void write_btm_resume_jpm_addr(void);
void write_btm_jmp_addr(void)
{
write_btm_resume_jpm_addr();
}
#endif
/*
* Function : _tw_to_stop();
* Security, enter Stop mode
* Parameters:
* mode -- enter the different mode.
* irqid -- the wakeup source interrupt num.
* Return: 0.
*/
static int32_t _tw_to_stop(ck_cpu_mode mode)
{
P_CK_PMU->LPCR = CK_POWM_LPCR_STOP;
int32_t ret = SUCCESS;
#ifdef LPM_BTM_EMU
write_btm_jmp_addr();
#endif
ret = _alloc_for_cur_regs();
if (SUCCESS != ret) {
return ret;
}
if (SUCCESS == arch_tw_do_cpu_save((void *)_g_cur_reg_strore_addr)) {
ret = _save_context(mode);
if (SUCCESS != ret) {
goto _finish;
}
ret = _resume_addr_save(mode, (uint32_t *)LPM_RESUEM_POINT_SAVED_ADDR);
if (SUCCESS != ret) {
goto _finish;
}
CK_PUM_DBG_I("enter stop\n");
__asm__("stop");
}
_finish:
_free_for_cur_regs();
return ret;
}
/*
* Function : Security_To_Standby();
* Security, enter Standby mode
* Parameters:
* mode -- enter the different mode.
* Return: 0.
*/
static uint32_t _tw_to_standby(ck_cpu_mode mode)
{
P_CK_PMU->LPCR = CK_POWM_LPCR_STANDBY ; /* enter into standby mode */
int32_t ret = SUCCESS;
#ifdef LPM_BTM_EMU
write_btm_jmp_addr();
#endif
ret = _alloc_for_cur_regs();
if (SUCCESS != ret) {
return ret;
}
if (SUCCESS == arch_tw_do_cpu_save((void *)_g_cur_reg_strore_addr)) {
ret = _save_context(mode);
if (SUCCESS != ret) {
goto _finish;
}
ret = _resume_addr_save(mode, (uint32_t *)LPM_RESUEM_POINT_SAVED_ADDR);
if (SUCCESS != ret) {
goto _finish;
}
CK_PUM_DBG_I("enter standby\n");
__asm__("stop");
}
_finish:
_free_for_cur_regs();
return ret;
}
/*
* Function : sw_to_lpm();
* Security, enter the lowpower mode the upper interface.
* Parameters:
* mode -- enter the different mode.
* gate -- choose the ip clock you want to close.
* irqid -- the wakeup source interrupt num.
* Return: 0.
*/
int32_t sw_to_lpm(void *msg)
{
int32_t ret = SUCCESS;
lpm_args_t *args = (lpm_args_t *)msg;
CK_PUM_DBG_I("lpm enter mode %d\n", args->mode);
switch (args->mode) {
case CK_POWM_WAIT:
ret = _tw_to_wait(args->gate);
break;
case CK_POWM_DOZE:
ret = _tw_to_doze();
break;
case CK_POWM_STOP:
ret = _tw_to_stop(args->mode);
break;
case CK_POWM_STANDBY:
ret = _tw_to_standby(args->mode);
break;
default:
TEE_ASSERT(0);
}
CK_PUM_DBG_I("ret from lpm %d\n", ret);
return ret;
}

View file

@ -0,0 +1,28 @@
/**
* Copyright (C) 2015-2016 The YunOS Project. All rights reserved.
*/
#ifndef _CK_PMU_H_
#define _CK_PMU_H_
#define CK_INTC_POWM 18
#define CK_POWM_CPU_WAKECOUNT 0x70000
#define CK_POWN_PLL_WAITCOUNT 0x20000
#define CK_POWM_CLEARINT 0x00
#define CK_POWM_LPCR_ENABLE 0x04
#define CK_POWM_LPCR_STANDBY 0x34
#define CK_POWM_LPCR_STOP 0x2c
#define CK_POWM_MCLK_PLL 0x08
#define CK_POWM_MCLK_IHS 0x00
#define CK_POWM_MCLK_ILS 0x04
#define CK_POWM_MCLK_EHS 0x02
#define CK_POWM_MCLK_ELS 0x05
#define CK_POWM_IRQID CK_INTC_POWM
#define GPIO_MIN_IRQ 0
#define GPIO_MAX_IRQ 7
#define LPM_RESERVE_STACK_SIZE (0x200)
#endif /* _CK_PMU_H_ */

View file

@ -0,0 +1,47 @@
/**
* Copyright (C) 2015-2016 The YunOS Project. All rights reserved.
*/
#ifdef LPM_BTM_EMU
#include "ck_pmu.h"
#include "tee_addr_map.h"
#include "hal_memmap.h"
.import LPM_RESUEM_POINT_SAVED_ADDR
.global write_btm_resume_jpm_addr
write_btm_resume_jpm_addr:
/* for lpm test */
push r15
lrw r0,_lpm_entry
lrw r1,0x0
st.w r0, (r1,0x0)
pop r15
_lpm_entry:
lrw r0, PLATFORM_PMU_ADDRBASE
ld.w r1, (r0,0x0)
btsti r1, 5
bt STOP
bf .
STOP:
lrw r0, PLATFORM_PMU_ADDRBASE
ld.w r1, (r0,0x0)
btsti r1, 3
bt __goto_resume_func
bf STANDBY
STANDBY:
lrw r0, PLATFORM_PMU_ADDRBASE
ld.w r1, (r0,0x0)
btsti r1, 4
bt __goto_resume_func
__goto_resume_func:
lrw r0, LPM_RESUEM_POINT_SAVED_ADDR
ld.w r2, (r0,0x0)
jmp r2
#endif

View file

@ -0,0 +1,124 @@
/**
* Copyright (C) 2015 The YunOS Project. All rights reserved.
*/
#include "ck_pmu.h"
.import resume_from_ram
.import resume_from_disk
.import lpm_resume_stack
#ifdef CONFIG_FPGA
.import revise_bus_prio_for_fpga
#endif
.global arch_tw_do_cpu_save
.global arch_tw_do_cpu_resume
.global resume_from_ram_wrapper
.global resume_from_disk_wrapper
arch_tw_do_cpu_save:
subi r14, 4
stw r0, (r14, 0x0)
stw r1, (r0, 0x4)
stw r2, (r0, 0x8)
stw r3, (r0, 0xc)
stw r4, (r0, 0x10)
stw r5, (r0, 0x14)
stw r6, (r0, 0x18)
stw r7, (r0, 0x1c)
stw r8, (r0, 0x20)
stw r9, (r0, 0x24)
stw r10, (r0, 0x28)
stw r11, (r0, 0x2c)
stw r12, (r0, 0x30)
stw r13, (r0, 0x34)
stw r15, (r0, 0x3c)
mfcr r2, psr
stw r2, (r0, 0x40)
mfcr r2, vbr
stw r2, (r0, 0x44)
mfcr r2, epsr
stw r2, (r0, 0x48)
mfcr r2, epc
stw r2, (r0, 0x4c)
mfcr r2, cr<11, 0>
stw r2, (r0, 0x50)
mfcr r2, cr<12, 0>
stw r2, (r0, 0x54)
mfcr r2, cr<13, 0>
stw r2, (r0, 0x58)
mfcr r2, cr<18,0>
stw r2, (r0, 0x5c)
mfcr r2, cr<19,0>
stw r2, (r0, 0x60)
mfcr r2, cr<20,0>
stw r2, (r0, 0x64)
mfcr r2, cr<21,0>
stw r2, (r0, 0x68)
ldw r2, (r14, 0x0)
addi r14, 4
stw r14, (r0, 0x38)
stw r2, (r0, 0x0)
movi r0, 0
jmp r15
arch_tw_do_cpu_resume:
ldw r1, (r0, 0x4)
ldw r3, (r0, 0xc)
ldw r4, (r0, 0x10)
ldw r5, (r0, 0x14)
ldw r6, (r0, 0x18)
ldw r7, (r0, 0x1c)
ldw r8, (r0, 0x20)
ldw r9, (r0, 0x24)
ldw r10, (r0, 0x28)
ldw r11, (r0, 0x2c)
ldw r12, (r0, 0x30)
ldw r13, (r0, 0x34)
ldw r14, (r0, 0x38)
ldw r15, (r0, 0x3c)
ldw r2, (r0, 0x40)
mtcr r2, psr
ldw r2, (r0, 0x44)
mtcr r2, vbr
ldw r2, (r0, 0x48)
mtcr r2, epsr
ldw r2, (r0, 0x4c)
mtcr r2, epc
ldw r2, (r0, 0x50)
mtcr r2, cr<11, 0>
ldw r2, (r0, 0x54)
mtcr r2, cr<12, 0>
ldw r2, (r0, 0x58)
mtcr r2, cr<13, 0>
ldw r2, (r0, 0x5c)
mtcr r2, cr<18, 0>
ldw r2, (r0, 0x60)
mtcr r2, cr<19, 0>
ldw r2, (r0, 0x64)
mtcr r2, cr<20, 0>
ldw r2, (r0, 0x68)
mtcr r2, cr<21, 0>
ldw r2, (r0, 0x8)
ldw r0, (r0, 0x0)
movi r0, 1
jmp r15
resume_from_ram_wrapper:
#ifdef CONFIG_FPGA
bsr revise_bus_prio_for_fpga
#endif
lrw r13, LPM_RESERVE_STACK_SIZE
lrw r14, lpm_resume_stack
add r14, r13, r14
bsr resume_from_ram
resume_from_disk_wrapper:
#ifdef CONFIG_FPGA
jbsr revise_bus_prio_for_fpga
#endif
lrw r13, LPM_RESERVE_STACK_SIZE
lrw r14, lpm_resume_stack
add r14, r13, r14
bsr resume_from_disk

View file

@ -0,0 +1,28 @@
#
# Copyright (C) 2015 The YunOS Project. All rights reserved.
#
TOP := ../..
CURRENT_BUILD := TW
include $(TOP)/tee.cfg
include $(TOP)/Make.rules
SRCS := $(wildcard *.c *.S )
OBJS := $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(SRCS)))
ENTRY := startup.o
OBJS := $(filter-out $(ENTRY), $(OBJS))
LIBS := plat.o
CFLAGS += -I./inc
ASFLAGS += -I./inc
all: $(OBJS) $(LIBS)
$(LIBS): $(OBJS) $(ENTRY)
$(NOECHO)$(LD) -r -o $(LIBS) $(OBJS)
@echo "Finish building $(LIBS)..."
clean:
@echo "Cleaning $(LIBS)..."
$(NOECHO)rm -f $(OBJS) $(ENTRY) $(LIBS)

Some files were not shown because too many files have changed in this diff Show more