第10章 - TA开发基础
Trusted Application (TA)开发需要特定的工具链和环境配置。Android NDK (Native Development Kit) 提供了必要的编译工具和库来构建TA。
# 下载并安装Android NDK
wget https://dl.google.com/android/repository/android-ndk-r25b-linux.zip
unzip android-ndk-r25b-linux.zip
export ANDROID_NDK_HOME=$(pwd)/android-ndk-r25b
# 设置环境变量
export PATH=$PATH:$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-android-
典型的TA项目目录结构:
ta_project/
├── Android.mk # 构建配置文件
├── ta/ # TA源代码目录
│ ├── include/ # 头文件
│ ├── src/ # 源文件
│ └── manifest.json # TA描述文件
├── host/ # 客户端代码
└── build/ # 构建输出目录
示例Android.mk文件:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# TA配置
LOCAL_MODULE := my_ta
LOCAL_SRC_FILES := ta/src/main.c ta/src/crypto_ops.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/ta/include
LOCAL_CFLAGS := -Wall -Werror
# 指定为Trusted Application
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/trusty
include $(BUILD_TRUSTY_APP)
图10.1: TA生命周期状态转换
TA的加载由Trusty内核管理,主要步骤包括:
每个TA必须实现以下关键函数:
| 函数 | 描述 | 调用时机 |
|---|---|---|
| TA_CreateEntryPoint | TA创建时的初始化 | 首次加载时 |
| TA_OpenSessionEntryPoint | 新会话创建时的处理 | 每次客户端连接时 |
| TA_InvokeCommandEntryPoint | 命令处理主函数 | 每次客户端调用命令时 |
| TA_CloseSessionEntryPoint | 会话关闭时的清理 | 会话结束时 |
| TA_DestroyEntryPoint | TA销毁前的清理 | TA卸载前 |
#include <trusty_app_manifest.h>
#include <trusty_std.h>
// TA UUID - 必须全局唯一
TA_UUID(my_ta_uuid, 0x12345678, 0x9abc, 0xdef0,
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0);
// TA属性定义
TA_APP_MANIFEST(my_ta_manifest,
TA_UUID_REF(my_ta_uuid),
TA_STACK_SIZE(0x2000), // 8KB栈空间
TA_FLAGS(TA_FLAG_EXEC_DDR),
TA_VERSION(1, 0, 0),
TA_PERMISSIONS(TA_PERM_READ | TA_PERM_WRITE),
);
// TA创建入口点
TEE_Result TA_CreateEntryPoint(void) {
LOG_I("TA创建中...");
// 初始化资源
return TEE_SUCCESS;
}
// TA销毁入口点
void TA_DestroyEntryPoint(void) {
LOG_I("TA销毁中...");
// 释放资源
}
// 会话打开入口点
TEE_Result TA_OpenSessionEntryPoint(uint32_t paramTypes,
TEE_Param params[4],
void** sessionContext) {
LOG_I("新会话创建");
return TEE_SUCCESS;
}
// 会话关闭入口点
void TA_CloseSessionEntryPoint(void* sessionContext) {
LOG_I("会话关闭");
}
我们将实现一个提供以下功能的TA:
| 命令ID | 功能 | 输入参数 | 输出参数 |
|---|---|---|---|
| 0 | AES加密 | 密钥(16B), 明文(变长) | 密文(变长) |
| 1 | AES解密 | 密钥(16B), 密文(变长) | 明文(变长) |
| 2 | SHA-256哈希 | 输入数据(变长) | 哈希值(32B) |
| 3 | 生成随机数 | 长度(4B) | 随机数据(变长) |