快速搭建平头哥安全处理器的可信执行环境

快速搭建平头哥安全处理器的可信执行环境

安全平台移植介绍

平头哥的安全处理器和安全SoC安全机制具有良好的兼容性和健壮性,基于TEE OS接口的扩展性和移植性,可以方便地快速地移植到其他平头哥安全处理器的芯片平台上。

快速搭建平头哥安全处理器的可信执行环境

根据底层硬件的安全机制,可以将安全平台组件分为5大部分:

  • 安全芯片ROM

主要负责和低功耗模块相关的安全功能。

  • 安全处理器可信执行环境机制

基于处理器内核的可信执行环境硬件机制, 主要负责安全内核切换的上下文管理,安全中断管理,内核切换异常处理等。

  • 常规平台驱动

主要是平台的基本驱动,比如中断,串口,NV操作驱动等。

  • 系统低功耗

用于管理低功耗指令处理和系统唤醒机制。

  • 安全IP驱动

涉及所有和硬件安全相关的驱动。

安全平台的移植组件

从官网下载TEE SDK,解压缩后可以看下如下目录

vincent@cui:~/csky/work/csky-tee$ ls 
arch   config  driver   lib       project  tee     test
build  csi     include  makefile  ree      tee_ca

目录说明如下:

├── arch        安全处理器架构部分
├── build        编译临时文件存放目录
├── config        安全平台配置文件
├── csi            中天标准接口
├── driver        平台驱动包
├── include        TEE OS头文件
├── lib            系统库文件
├── makefile    主makefile编译脚本
├── ree            REE OS第三方算法库
├── tee            TEE OS以及TA源文件
├── tee_ca        TEE CA源文件
└── test        平台测试文件

TEE SDK 输出文件,我们需要关注以下四个文件, 以ch2201平台为例,

ree_os
tee_os
./tee_ca/lib/libtee_os_ch2201.a
./tee_ca/lib/libcsiteeca.a

其中ree_os和tee_os用来本地测试, libtee_os_ch2201.a和libcsiteeca.a用于部署到YoC SDK里去,分别用于生成TEE OS和开发安全应用程序。

注意,如果新平台名字为sample, 那就会生成libtee_os_sample.a

以上就是对TEE SDK的大体描述,现在大家TEE SDK有了一个整体概念,接下来我们按照具体的安全组件一个一个细化说明,讲解如何移植。

安全芯片ROM

芯片ROM是系统上电后第一个执行的镜像,其固化在芯片的ROM介质,具有执行速度快,初始化系统到一个已知状态,为后续的引导做准备。当系统唤醒的时候,芯片ROM会判断本次启动时正常重启还是低功耗唤醒,如果是低功耗唤醒就直接跳转到唤醒点,进行系统上下文恢复。由于本组件和系统低功耗安全相关,所以在这里描述下,可以更好的理解整个可信执行环境平台移植。

安全处理器可信执行环境机制

新建处理器目录

在arch目录下创建新处理器型号sample目录,通常做法复制一份ck802t,改名为sample。

vincent@cui:~/csky/work/csky-tee/arch$ ls
ck802t sample

在./arch/ck802t/tw/inc目录下创建新的平台文件夹,且删掉原来的平台文件夹。

vincent@cui:~/csky/work/csky-tee/arch/ck802t/tw/inc$ ls
sample_pt  tee_misc.h

第一次内核切换的上下文管理

启动过程中第一次由TEE跳转到REE的上下文管理比较特殊,利用内核硬件切换机制,需要在REE的SP寄存器指示的堆栈出预先写入跳转的PC和PSR寄存器的值,然后执行RTE指令,处理器就就根据当前的SP寄存器的值去获取PC和PSR的值,然后加载到REE的PC和PSR寄存器后继续执行,此时GPR寄存器的值是预置的0,如果跳转后需要传递参数的情况下,可以改变R0,R1,R2,R3. 第一次的内核切换处理接口位于./arch/sample/tw/exception.S 文件里的rte_to_ntw 函数,部分参考代码如下:

 /* 3. save psr to epsr, because SC == 1 in PSR */
    mfcr    r0, psr
    mtcr    r0, epsr

    /* 4. disable EE/IE clear SP */
    bclri   r0, 29  /* clear SP */
    bclri   r0, 8   /* disable EE */
    bclri   r0, 6   /* disable IE */
    mtcr    r0, psr

    /* 5. set non-secure SP */
    lrw  r0, NTW_RW_ADDR + NTW_RW_SIZE
    subi r0, 8
    mtcr r0, cr<6, 3>

    /* 6. prepare non-secure stack */
    lrw     r1, g_ntw_addr  /* set pc */
    ldw     r1, (r1, 0)

    ldw     r3, (r1, 4)
    lrw     r2, 0x594B5343
    cmpne   r3, r2
    bf      __magic_path
    ldw     r1, (r1, 0)
__magic_path:
    movi    r2, 0
    bseti   r2, 31              /* set psr */
    stw     r2, (r0, 0)
    stw     r1, (r0, 4)

    movi r0, 0
    movi r1, 0
    movi r2, 0
    movi r3, 0
    /* Ready to NTW */
    rte

其中NTW_RW_ADDR和NTW_RW_SIZE定义在./arch/ck802t/tw/inc/sample_pt/tee_addr_map.h, 示例代码如下:

#define NTW_RO_ADDR     0x10010000
#define NTW_RO_SIZE     0x00010000
#define NTW_RW_ADDR     0x60001000
#define NTW_RW_SIZE     0x00008000

可以根据平台的实际地址空间更改。

内核切换异常处理

内核切换异常处理发生在REE OS执行WSC指令后, 这时候处理器切换到可信内核后,从EBR寄存器里取出内核切换异常处理函数入口,然后开始执行。

EBR寄存器在系统启动的时候设备,位于./arch/sample/tw/startup.S里_start函数里

内核切换异常处理函数的入口定义的示例代码:

ckcpu_vsr_table:

/* 0: Rest */
.long wsc_intr_handler   /* Use ckcpu_vsr_table[0] as ebr entry */

EBR寄存器的初始化示例代码:

    lrw      a2, ckcpu_vsr_table
    mtcr     a2, vbr
    mtcr     a2, cr<1,1>      /* Use ckcpu_vsr_table[0] as ebr entry. cr<1,1> is T_EBR */

内核切换的异常处理函数定义在./arch/sample/tw/exception.S里的wsc_intr_handler函数,示例代码如下

 /* 1. save NTW GP registers to stack */
    subi sp, GP_CONTEXT_SIZE
    addi sp, 8
    stm r4-r13, (sp)
    subi sp, 8
    stw r15,    (sp, 0x30)

    /* 2. restore TW GP registers from stack */
    addi sp, GP_CONTEXT_SIZE
    ldw r15,    (sp, 0x28)
    ldm r4-r13, (sp)

    /* 3. restore sp */
    subi sp, GP_CONTEXT_SIZE

    /* 4. enable ie */
    psrset ie
    /* now we are ready for TEE dispatcher! */
    bsr     dispatcher_main
    psrclr ie

    /* we have finished one command */

    /* 1. save TW GP registers */
    addi sp, GP_CONTEXT_SIZE
    addi sp, 8
    stm r4-r13, (sp)
    subi sp, 8
    stw r15,    (sp, 0x30)

    /* 2. restore NTW GP registers */
    subi sp, GP_CONTEXT_SIZE
    ldw r15,    (sp, 0x28)
    ldm r4-r13, (sp)

    /* 3. restore sp */
    addi sp, GP_CONTEXT_SIZE

    /* now we are ready to return */
    rte

上下文的大小定义在位于./arch/sample/tw/inc/tee_misc.h文件里的GP_CONTEXT_SIZE这个宏,目前只需要保存GPR寄存器即可, 如果需要更改,可以修改这个宏,然后在wsc_intr_handler处理函数里增加需要格外保存的寄存器资源代码即可。

安全中断管理

安全中断向量表定义在./arch/ck802t/tw/startup.S文件里,示例代码如下

ckcpu_vsr_table:
.long Default_Handler         /*  0:  GPIOA          */
.long Default_Handler         /*  1:  core Timer     */
.long Default_Handler         /*  2:  TimerA0         */
.long Default_Handler         /*  3:  TimerA1         */
.long Default_Handler
.long Default_Handler         /*  5:  WDT            */
.long Default_Handler         /*  6:  UART0          */
.long USART1_IRQHandler       /*  7:  UART1          */
.long Default_Handler         /*  8:  UART2          */
.long Default_Handler         /*  9:  I2C0           */
.long Default_Handler         /*  10: I2C1           */
.long Default_Handler         /*  11: SPI1           */
.long Default_Handler         /*  12: SPI0           */
.long Default_Handler         /*  13: RTC            */
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler          /*  17: DMAC           */
.long Default_Handler
.long Default_Handler          /*  19: PWM            */
.long Default_Handler
.long Default_Handler          /*  21: UART3          */
.long Default_Handler
.long Default_Handler          /*  23: TimerB0        */
.long Default_Handler          /*  24: TimerB1        */
.long Default_Handler
.long AES_IRQHandler           /*  26:  AES            */
.long Default_Handler          /*  27:  GPIOB          */
.long Default_Handler
.long SHA_IRQHandler           /*  29:  SHA            */
.long Default_Handler
.long Default_Handler

再通过在启动代码里配置到VBR寄存器里去, 示例代码如下:

 /*
     * Setup secure initial vector base table for interrupts and exceptions
     */
    lrw      a2, ckcpu_vsr_table
    mtcr     a2, vbr

对于需要设置安全中断的IRQ,可以通过如下接口来完成设置。

void drv_nvic_enable_sirq(int32_t IRQn)

安全堆栈寄存器配置

在./arch/ck802t/tw/startup.S文件里的启动代码里配置安全堆栈寄存器,示例代码如下:

  /* Initialize the normal stack pointer from the end of TW volatile mem. */
    lrw      a1, TW_RW_ADDR + TW_RW_SIZE
    bclri    a1, 0  /* Make sure 4Bytes align */
    bclri    a1, 1

    mov      sp, a1

其中TW_RW_ADDR和TW_RW_SIZE定义在./arch/ck802t/tw/inc/sample_pt/tee_addr_map.h, 示例代码如下:

#define TW_RO_ADDR      0x10001000
#define TW_RO_SIZE      0x00006000
#define TW_RW_ADDR      0x60000000
#define TW_RW_SIZE      0x00001000

可以根据平台的实际地址空间更改。

增加平台编译宏定义

arch目录下新增目录可以通过在makefile里定义平台宏来编译,示例代码如下:

ifeq ($(CONFIG_PLATFORM_SAMPLE),y)
TARGET_PLATEFORM = sample_pt
endif

通过将arch下的文件加到makefile文件里的TEE_SRCS宏里,示例代码如下:

TEE_SRCS += $(ROOTDIR)/arch/sample/tw/startup.S \
            $(ROOTDIR)/arch/sample/tw/exception.S

正确设置后,在最后编译的时候就会指定处理器平台文件进行编译。

常规平台驱动

在./driver/下复制一个新的文件夹,然后改名为sample,如下

vincent@cui:~/csky/work/csky-tee/driver$ ls
common  driver.mk  hobbit1_2  hobbit3  include  phobos  zx297100 sample

实现./driver/sample/platform.c里的hal_platform_init接口,示例代码如下:

int hal_platform_init(void)
{
    hal_intc_init();

#if (CONFIG_SECURE_SPACE > 0)
    eflash_secure_config();
    sram_secure_config();
#endif
    drv_pmu_initialize(0, 0);

    return 0;
}

我们可以在hal_platform_init接口里实现系统需要实现的平台驱动程序。

在./driver/sample/uart.c里实现console_init接口,实现打印log的串口初始化,如果CSI已经实现了新平台的串口实现,则可以忽略该接口实现。

在./driver/common/intc.c里实现hal_intc_init的初始化,完成中断默认优先级的配置,示例代码如下

void hal_intc_init(void)
{
    volatile uint32_t *intc_reg_addr = (volatile uint32_t *)HOBBIT_VIC_BASE;

    intc_reg_addr[VIC_IPR0 >> 2] = 0x00000000;
    intc_reg_addr[VIC_IPR1 >> 2] = 0x00000000;
    intc_reg_addr[VIC_IPR2 >> 2] = 0x00000000;
    intc_reg_addr[VIC_IPR3 >> 2] = 0x00000000;
    intc_reg_addr[VIC_IPR4 >> 2] = 0x00000000;
    intc_reg_addr[VIC_IPR5 >> 2] = 0x00000000;
    intc_reg_addr[VIC_IPR6 >> 2] = 0x00000000;
    intc_reg_addr[VIC_IPR7 >> 2] = 0x00000000;

    __asm__ volatile("psrclr sie");
}

其他的平台驱动,比如FLASH操作等驱动,可以参考CSI的代码实现具 体参考CSI接口章节。

安全IP驱动

安全访问区域配置

安全访问区域属性设置的驱动包括FLASH和RAM两部分,因为在SoC上属于不同的两个安全访问控制器,我们主要实现如下两个区域。其在hal_platform_init接口中调用实现。

void sram_secure_config(void);
void eflash_secure_config(void);

安全算法引擎的驱动包括SHA, AES, RSA, TRNG等,取决于硬件有没有实现该类的加速器。具体接口定义和参考示例详见后面的章节。

  • SHA移植接口
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);
  • AES移植接口
tee_crypto_result tee_aes_get_ctx_size(aes_type_t type, size_t *size);
tee_crypto_result tee_aes_init(aes_type_t type, bool is_enc, const uint8_t *key1,
                             const uint8_t *key2, size_t keybytes,                                                  uint8_t *iv, void *context);
tee_crypto_result tee_aes_process(const uint8_t *src, uint8_t *dst, 
                                size_t size, void *context);
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);
  • DES移植接口
tee_crypto_result tee_des_get_ctx_size(des_type_t type, size_t *size);
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);
tee_crypto_result tee_des_process(const uint8_t *src, uint8_t *dst,                                                     size_t size, void *context);
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);
  • RSA移植接口
tee_crypto_result tee_rsa_get_keypair_size(size_t keybits, 
                                         size_t *size);
tee_crypto_result tee_rsa_get_pubkey_size(size_t keybits, 
                                        size_t *size);
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);
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);
tee_crypto_result tee_rsa_gen_keypair(size_t keybits,
                                    const uint8_t *e, size_t e_size,
                                    rsa_keypair_t *keypair);
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,
                                       tee_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,
                                        tee_rsa_padding_t padding);
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, 
                             tee_rsa_padding_t padding);
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,
                               tee_rsa_padding_t padding, bool *result);
  • TRNG移植接口
tee_crypto_result tee_seed(uint8_t *seed, size_t seed_len);
tee_crypto_result tee_rand_gen(uint8_t *buf, size_t len);

安全设备控制配置

安全设备控制通过在安全模式下访问TIPC控制寄存器来实现,该寄存器的每一个BIT表示一个设备,具体可以参考平台手册。结合安全中断的配置,一旦设备被配制成安全设备,其中断也必须配置成安全中断。

快速搭建平头哥安全处理器的可信执行环境

Key Provision解析

KP用于是密钥和隐私信息的集合,在生产的时候写入安全OTP或eFUSE区域, TEE OS通过解析KP文件获取密钥和其他安全信息。KP文件需要符合YoC安全应用方案,如果需要扩展新的密钥类型,可以更新密钥类型结构体:

typedef enum {
    KEY_MANIFEST = 1,
    KEY_JTAGKEY,
    KEY_PUBKEY,
    KEY_DEVID,
    KEY_DEVIDPRIVKEY,
    KEY_SOCCONFIG,
    KEY_LPM,
    KEY_INVAILD
} key_type_e;

主要实现的接口如下:

int kp_get_key(key_type_e key_type, uint32_t *key);
int kp_version();
int kp_get_manifest_addr(uint32_t *addr);

如果KP文件格式不变,可跳过该组件移植。

Manifest TaBle解析

类似KP文件,MTB是一套系统镜像的信息集合,其格式符合YoC安全应用方案,TEE TA服务可以提供MTB的功能,主要功能接口如下:

int mtb_get_img_info(char *name, mtb_img_info_t *img_info);
int mtb_get_os_version(uint8_t *buf, uint32_t *size);
int mtb_get_img_buf(uint8_t *buf, uint32_t *size, char *name);
int mtb_get_partition_buf(uint8_t *buf, uint32_t *size);
int mtb_get_ntw_addr(uint32_t *addr);
int mtb_verify_image(const char *name);
int mtb_get_key_info(key_info_t *info);
int mtb_get_pubkey_info(key_info_t *info);

如果MTB文件格式不变,可以跳过该组件移植。

系统低功耗

TEE OS提供的低功耗服务接口位于LPM TA里,支持如下四种低功耗模式:

  • WAIT
  • DOZE
  • STOP
  • STANDBY

进入深睡眠前,需要保存系统上下文到NV里,通过调用以下接口实现,

int32_t arch_do_cpu_save(void);

其利用汇编实现,位于./arch/ck802t/tw/cpu_ctx.S文件里,示例代码如下:

arch_do_cpu_save:
    subi    r14, 4
    stw r0, (r14, 0x0)
    lrw r0, arch_tw_cpu_saved
    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)
    // save NT_SSP
    mfcr    r2, cr<6, 3>
    stw r2, (r0, 0x50)
    // save NT_PSR
    mfcr    r2, cr<0, 3>
    stw r2, (r0, 0x54)
    // save NT_VBR
    mfcr    r2, cr<1, 3>
    stw r2, (r0, 0x58)
    // save NT_EPSR
    mfcr    r2, cr<2, 3>
    stw r2, (r0, 0x5c)
    // save NT_EPC
    mfcr    r2, cr<4, 3>
    stw r2, (r0, 0x60)
    // save NT_EBR
    mfcr    r2, cr<10,3>
    stw r2, (r0, 0x64)
    // save T_EBR
    mfcr    r2, cr<1,1>
    stw r2, (r0, 0x68)
    //save jtag
    mfcr    r2, cr<8, 3>
    stw r2, (r0, 0x6c)

    ldw r2, (r14, 0x0)
    addi    r14, 4
    stw r14, (r0, 0x38)
    stw r2, (r0, 0x0)
    movi    r0, 0
    jmp r15

系统被唤醒后,芯片ROM里的低功耗代码会直接跳转到上下文恢复入口地址(该地址在系统进入低功耗前设置在一块NV空间), 然后调用arch_resume_context进行上下文恢复,示例代码如下:

arch_resume_context:
    lrw     r0, SOC_CONIG_ADDR
    ldw     r0, (r0, 0)
    btsti   r0, 4
    bf      .LRECV
    mfcr    r0, cr<8, 3>
    bseti   r0, 1
    bseti   r0, 0
    mtcr    r0, cr<8, 3>
.LRECV:
    lrw     r0, EFLASH_CONTROL_BASE
    movi    r1, 0x35
    stw     r1, (r0, 0x24)
    movi    r1, 0x16
    stw     r1, (r0, 0x28)
    movi    r1, 0x35
    stw     r1, (r0, 0x2c)
    movi    r1, 0x1b9
    stw     r1, (r0, 0x30)
    movi    r1, 0x8b10
    stw     r1, (r0, 0x34)
    lrw r0, CSKY_LPM_BASE
    ldw r1, (r0, 0x0)
    btsti r1, 3
    bt arch_sp_resume_from_stop
    bf arch_sp_resume_from_standby

新建平台配置文件

在./config目录下复制一个新文件,然后改名为sample_release_defconfig,如下

vincent@cui:~/csky/work/csky-tee/config$ ls
hobbit1_2_release_defconfig  phobos_release_defconfig  zx297100_release_defconfig
sample_release_defconfig

根据系统需求的配置文件,示例代码如下:

#
# TEE Platform
#
# CONFIG_PLATFORM_PHOBOS is not set
# CONFIG_PLATFORM_ZX297100 is not set
CONFIG_PLATFORM_SAMPLE=y
CONFIG_CSKY=y

#
# TEE Feature
#
CONFIG_TB_KP=y
CONFIG_STACK_PROTECT=y
CONFIG_SECURE_SPACE=y
CONFIG_DEVID=y
CONFIG_ALGO_SHA=y
CONFIG_ALGO_TRNG=y
CONFIG_ALGO_AES=y
CONFIG_ALGO_RSA=y
CONFIG_ALGO_LPM=y
CONFIG_ALGO_BASE64=y
CONFIG_ALGO_HMAC=y
# CONFIG_ALGO_DES3 is not set
# CONFIG_REE_VERIFY is not set
CONFIG_TEE_DEBUG=n
CONFIG_MBEDTLS=y
CONFIG_TEE_VERSION="2.1.10"
CONFIG_USART=y
CONFIG_TRNG=y
CONFIG_AES=y
CONFIG_RSA=y
CONFIG_SHA=y
CONFIG_WDT=y
CONFIG_PMU=y
CONFIG_EFLASH=y
#
# TEE TEST
#
CONFIG_TEST=y

平台移植编译

所有组件开发和配置完成后,就可以I在根目录下执行make指令来完成整个TEE的编译,执行完以后可以在根目录下找到以下文件:

./tee_os
./ree_os
./tee_ca/lib/libtee_os_sample.a
./tee_ca/lib/libcsiteeca.a

其中libtee_os_sample.a和libcsiteeca.a是部署在YoC SDK里的,具体如何使用参考安全应用开发文档。

tee_os和ree_os用于测试。

新平台运行

  • 利用烧写工具将tee_os和ree_os烧写到SAMPLE开发板里,利用GDB运行。
  • 在串口出看到如下打印表示xor TA运行成功。
xor value: 55aa55aa
xor length: 4

原文作者:cui_632
点击查看原文

上一篇:快速进行ECS服务器后端开发环境搭建工作


下一篇:《BackTrack 5 Cookbook中文版——渗透测试实用技巧荟萃》—第3章3.9节绘制网络