# sample_trustzone 使用说明

## 功能概述

sample_trustzone 分别完成了 TA 和 CA 的简单示例代码，用户可以通过 sample_ta 和 sample_ca 了解如何创建并使用 TA 和 CA 进行命令交互操作。

sample_ta 添加三条自定义命令，分别处理整型和字符串类型数据
- 数据自加命令 `TA_SAMPLE_CMD_INC_VALUE` : 由 TA 将传入的数值加 1，并返回给 CA
- 数据自减命令 `TA_SAMPLE_CMD_DEC_VALUE`: 由 TA 将传入的数值减 1，并返回给 CA
- 字符串回显命令 `TA_SAMPLE_CMD_ECHO_STR`:  由 TA 将传入的字符串追加 `[TA]`，并回显给 CA


### 软件架构说明

![sample_trustzone_software_arch.png](./_static/_images/sample_trustzone/sample_trustzone_software_arch.png)

### 代码位置及目录结构

- 代码位置 `app/samples/platform_samples/sample_trustzone`
- 目录结构

```bash
sample_trustzone
├── sample_ca
│   ├── Makefile
│   └── sample_ca.c
└── sample_ta
    ├── Makefile
    ├── include
    │   └── sample_ta.h
    ├── sample_ta.c
    ├── sub.mk
    └── user_ta_header_defines.h
```

### API 流程说明

![sample_trustzone_api_process.png](./_static/_images/sample_trustzone/sample_trustzone_api_process.png)

## 编译
下面分别说明 sample_ta 与 sample_ca 的编译方法

### sample_ta 编译

- 拷贝 sample_ta 源码

**注意: sample_ta 并不是直接在 plamform_samples 目录下编译，需要拷贝至 `miniboot/optee/hobot_tee_devkit/ta/customer` 下编译**

使用如下命令

```shell
cp app/samples/platform_samples/sample_trustzone/sample_ta  miniboot/optee/hobot_tee_devkit/ta/customer/ -rf
```

- 创建 UUID

**使用示例自带 UUID 可跳过此步骤**

系统中允许存在多个 TA，每个 TA 需配置不同的 UUID。

UUID 可以通过此网址生成  https://www.uuidgenerator.net/

![sample_trustzone_generate_uuid.png](./_static/_images/sample_trustzone/sample_trustzone_generate_uuid.png)

如上所示，生成 UUID 值 `ed53d67d-4e58-4b9a-8514-0a61c3c94401`

- 配置 UUID

**使用示例自带 UUID 可跳过此步骤**

上一个步骤生成的 UUID，需填入以下几处源码。

路径 `sample_ta/include/sample_ta.h`

```C
#define TA_SAMPLE_UUID \
	{ 0xed53d67d, 0x4e58, 0x4b9a, \
		{ 0x85, 0x14, 0x0a, 0x61, 0xc3, 0xc9, 0x44, 0x01} }
```

路径 `sample_ta/Makefile`
```Makefile
# The UUID for the Trusted Application
BINARY=ed53d67d-4e58-4b9a-8514-0a61c3c94401
```

- 将 sample_ta 添加到编译选项

修改  `miniboot/optee/hobot_tee_devkit/ta/customer/Makefile`，将 sample_ta 追加到变量 `CTA_DIRS`

```Makefile
CTA_DIRS := sample_ta
```

- 编译

在 SDK 根目录下执行命令 `./bd.sh miniboot`，将自动编译 sample_ta。
其编译成果物位于 `miniboot/optee/hobot_tee_devkit/out/ta/sample_ta`。

TA 运行程序命名规则为 `[UUID].ta`，根据之前步骤配置的 UUID，即 `ed53d67d-4e58-4b9a-8514-0a61c3c94401.ta`。


### sample_ca 编译

- 配置 UUID

**使用示例自带 UUID 可跳过此步骤**

CA 是通过 UUID 指定需要调用的 TA，需要在代码中配置 TA 的 UUID。

```C
// 匹配之前步骤配置的 TA UUID
TEEC_UUID uuid =  { 0xed53d67d, 0x4e58, 0x4b9a, \
		{ 0x85, 0x14, 0x0a, 0x61, 0xc3, 0xc9, 0x44, 0x01} };

// ...(省略部分代码)...
// 在 open session 的时候传入 UUID
res = TEEC_OpenSession(&ctx, &sess, &uuid,
			       TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);
// ...(省略部分代码)...

```

- 编译

在 sample_ca 源码路径下执行 `make` 命令即可完成编译：

```Shell
cd app/samples/platform_samples/sample_trustzone/sample_ca
make
```

详细的程序编译方式请查阅 [ 编译方法 ](overview.html#span-id-sample-build) 章节。


## 部署
下面分别说明 sample_ta 与 sample_ca 的部署方法

### sample_ta 部署

将上面步骤生成的 sample_ta 程序复制到 `out/deploy/system/usr/lib/optee_armtz` 目录。

执行 `./bd.sh system`，将 sample_ta 程序打包进 system 分区。

刷写系统软件镜像后 , sample_ta 文件位于板端 : `/usr/lib/optee_armtz`

### sample_ca 部署

刷写系统软件镜像后 , sample_ca 的可执行文件位于板端 : `/app/platform_samples/sample_trustzone/sample_ca`。


## 运行

### 程序运行方法

- 直接执行程序 `./sample_ca -h` 可以获得帮助信息：

### 程序参数选项说明

```bash
Usage: sample_ca [OPTIONS] [value]
Options:
  -i <value>      Increase value From TA
  -d <value>      Decrease value From TA
  -c <string>     Echo string From TA
  -h              Show this help message
```

**选项：**

- `i <value>`: 由 TA 将传入的数值加 1，并返回给 CA
- `d <value>`: 由 TA 将传入的数值减 1，并返回给 CA
- `c <string>`:  由 TA 将传入的字符串追加 `[TA]`，并回显给 CA
- `h`: 显示帮助信息。



### 运行效果

#### 验证数据自加命令
执行命令 `./sample_ca -i 10`，将 10 传给 sample_ta。

打印 log 如下

```
Establish Context with OP-TEE!
Establish Session with TA!
I/TC: RPMB: Using generated key
D/TA:  TA_CreateEntryPoint:39 has been called
D/TA:  TA_OpenSessionEntryPoint:68 has been called
D/TA:  inc_value:105 has been called
I/TA: Got value: 10 from NW
I/TA: Increase value to: 11
TA incremented value to 11
Disconnect Session with TA!
D/TA:  TA_DestroyEntryPoint:50 has been called
Disconnect Context with OP-TEE!
```

可以看到 TA 处理并返回数据 11 给 CA

#### 验证数据自减命令

执行命令 `./sample_ca -d 10`，将 10 传给 sample_ta。

打印 log 如下

```
Establish Context with OP-TEE!
Establish Session with TA!
D/TA:  TA_CreateEntryPoint:39 has been called
D/TA:  TA_OpenSessionEntryPoint:68 has been called
D/TA:  dec_value:125 has been called
I/TA: Got value: 10 from NW
I/TA: Decrease value to: 9
TA incremented value to 9
Disconnect Session with TA!
D/TA:  TA_DestroyEntryPoint:50 has been called
Disconnect Context with OP-TEE!
```

可以看到 TA 处理并返回数据 9 给 CA

#### 验证字符串回显命令

执行命令 `./sample_ca -c hello`，将字符串传给 sample_ta。

打印 log 如下

```
Establish Context with OP-TEE!
Establish Session with TA!
D/TA:  TA_CreateEntryPoint:39 has been called
D/TA:  TA_OpenSessionEntryPoint:68 has been called
D/TA:  echo_str:146 has been called
I/TA: Got sting from NW: hello
TA Echo: hello[TA]
Disconnect Session with TA!
D/TA:  TA_DestroyEntryPoint:50 has been called
Disconnect Context with OP-TEE!
```

可以看到 TA 处理并返回字符串 `hello[TA]` 给 CA


## 常见问题

### 执行 CA 程序调用 TA 提示 Verify key 错误

![sample_trustzone_error.jpg](./_static/_images/sample_trustzone/sample_trustzone_error.jpg)

- **解决方法：**
TA 的加载需依赖 user root key。
关于 user root key 的烧录方法，请参考 [ efuse ](../linux_development/system_component_development/security_development/efuse/efuse_update.md)


