01 前言
在前两篇文章中,我们依次介绍了OP-TEE的技术背景、整体架构,以及OP-TEE OS的编译与部署方法。在OP-TEE的整体软件栈中,除了运行在安全世界的OP-TEE OS外,普通世界也需要有一套对应的支持组件,以便用户应用能够与安全世界交互。这套组件就是OP-TEE Client。

OP-TEE Client提供了GlobalPlatform TEE Client API的标准实现,包含用户态库和后台服务程序。通过它,普通世界的应用程序(CA, Client Application)可以向安全世界的Trusted Application(TA)发起请求,并获取执行结果。因此,理解并掌握OP-TEE Client的构建与使用,是开发TA/CA应用的必要前提。
本文将系统性地介绍OP-TEE Client,包括:
OP-TEE Client的架构与作用。
源码获取方式。
Yocto内的编译流程。
独立于Yocto的编译方法。
OP-TEE Client的关键组件(libteec.so与tee-supplicant)。
使用示例(以Hello World与Secure Storage为例)。
02 OP-TEE Client架构与功能
2.1 GlobalPlatform TEE Client API

GlobalPlatform为TEE定义了标准化接口,其中TEE Client API用于描述REE(普通世界)应用如何与TEE通信。典型API包括:
TEEC_InitializeContext():初始化与TEE的通信上下文。
TEEC_OpenSession():与某个TA建立会话。
TEEC_InvokeCommand():向TA发送命令。
TEEC_CloseSession():关闭会话。
TEEC_FinalizeContext():释放上下文。
OP-TEE Client提供了这些API的完整实现,并打包为共享库libteec.so,供用户应用调用。
2.2 OP-TEE Client的组成
OP-TEE Client主要由两个部分组成:
2.2.1 TEE Client Library(libteec.so)
提供GP TEE Client API的实现。
供普通世界应用程序(CA)调用,用于与OP-TEE OS通信。
负责构建消息,传递给内核驱动。
2.2.2 TEE Supplicant(tee-supplicant)
运行过程中tee-supplicant和OP-TEE driver,OP-TEE Core关系粗略展示:

后台运行的守护进程。
处理OP-TEE OS无法直接完成、需要普通世界协助的操作,例如:
文件系统访问(secure storage)
RPMB访问
时间服务
没有supplicant,TA无法正常工作。
2.3 调用链路
一个典型的CA调用TA的链路如下:
CA调用libteec.so的API。
libteec通过Linux optee driver与内核交互。
内核驱动通过SMC调用将请求转发到OP-TEE OS。
OP-TEE OS找到对应的TA,并执行。
如需文件系统或RPMB操作,OP-TEE OS会反向请求tee-supplicant协助。
执行结果返回给CA。
03源码获取
OP-TEE Client是一个独立的开源仓库。
源码地址请扫描下方二维码或复制链接到浏览器打开查阅。
OP-TEE Client源码地址
$ git clone https://github.com/OP-TEE/optee_client.git
在RZ/G2L VLP SDK中,Yocto会自动获取并构建OP-TEE Client,源码路径通常位于:
左右滑动查看完整内容
build/tmp/work/.../optee-client//git/
开发者既可以直接使用Yocto提供的版本,也可以独立下载并编译最新的社区版本。
04 Yocto下的编译方法
在Yocto中,编译OP-TEE Client非常简单,只需在构建环境中执行:
左右滑动查看完整内容
$ bitbake optee-client -fc compile $ bitbake optee-client -fc install $ bitbake optee-client -fc populate_sysroot
编译完成后,Yocto会生成:
/usr/lib/libteec.so
/usr/bin/tee-supplicant
这些文件会被打包进最终的rootfs中。
05 独立编译OP-TEE Client
在某些场景(如非Yocto环境或移植到其他Linux平台),需要独立编译OP-TEE Client。
5.1 获取源码
git clone
git clone git://github.com/OP-TEE/optee_client.git
源码地址
git checkout 3.19.0
5.2 编译步骤
optee_client不支持Linaro编译器编译,因为Linaro-7.5.0交叉编译工具链默认只包含Linux内核头文件(如linux/uuid.h),而不包含用户空间库libuuid的开发文件(即uuid/uuid.h)
因此编译之前请确保已正确安装poky编译器。
进入optee_client源码目录,执行:
左右滑动查看完整内容
$ export PATH=/opt/linaro/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/:$PATH
make clean && make -j$(nproc) CROSS_COMPILE=${CROSS_COMPILE}
编译结果:

重点关注以下几个文件:
out/export/lib/libteec.so
out/export/include/tee_client_api.h
out/tee-supplicant
将这些文件安装到目标文件系统后,CA程序即可使用TEE功能。
06 关键组件介绍
6.1 libteec.so
这是TEE Client API的实现库,所有CA程序都需要链接它。
典型使用流程:
左右滑动查看完整内容
TEEC_Context ctx;
TEEC_Session sess;
TEEC_Operation op = {0};
TEEC_UUID uuid = TA_HELLO_WORLD_UUID;
TEEC_InitializeContext(NULL, &ctx);
TEEC_OpenSession(&ctx, &sess, &uuid, TEEC_LOGIN_PUBLIC, NULL, NULL, NULL);
TEEC_InvokeCommand(&sess, TA_HELLO_WORLD_CMD, &op, NULL);
TEEC_CloseSession(&sess);
TEEC_FinalizeContext(&ctx);
6.2 tee-supplicant
守护进程,通常在Linux启动后自动运行。它负责处理来自OP-TEE OS的请求,例如:
创建/读取安全存储文件。
与RPMB设备通信。
获取系统时间。
没有tee-supplicant,许多安全功能无法正常使用。
07 使用示例
Host TA除了在运行时依赖tee-supplicant守护进程,编译的时候,也需要指定上一步编译optee_client生成的out路径。我们以OPTEE官方的optee_example例程中比较经典的hello_world和secure_storage的编译为例。
optee_examples源码的获取:
git clone
https://github.com/linaro-swg/optee_examples.git
optee_examples源码工程:

7.1 Hello World示例
hello_world的源码工程:

optee_examples提供的每一个样例工程都包含了两个子目录host和ta,它们分别是Host Application(CA)和Trusted Application(TA)。CA的编译需要依赖optee_client的编译后输出目录。
hello_world样例CA编译步骤:
CA的编译,既可以选择yocto导出的poky也可以选择Linaro编译器进行编译,这里以Linaro编译器为例:
左右滑动查看完整内容
$ cd optee_examples/hello_world/host
$ export PATH=/opt/linaro/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/:$PATH
$ CROSS_COMPILE=aarch64-linux-gnu-
$ export PLATFORM=rz
$ export TEEC_EXPORT=/home/aaron/workspace/rzg/optee/optee_client/out/export/usr/
$ make -j$(nproc)
CROSS_COMPILE=${CROSS_COMPILE}
PLATFORM=${PLATFORM}
TEEC_EXPORT=${TEEC_EXPORT}
--no-builtin-variables
编译完成生成optee_example_hello_world
Helloworld运行时:

CA程序向TA发送一个命令。
TA在安全世界处理请求。
返回结果,CA输出"Hello, OP-TEE world"。
7.2 Secure Storage示例
secure_storage的源码工程:

Secure_storage源码工程的Host Application(CA)编译的时候同样依赖optee_client的编译后输出目录。
Secure_storage样例CA编译步骤:
左右滑动查看完整内容
$ cd optee_examples/secure_storage/host
$ export PATH=/opt/linaro/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/:$PATH
$ CROSS_COMPILE=aarch64-linux-gnu-
$ export PLATFORM=rz
$ export TEEC_EXPORT=/home/aaron/workspace/rzg/optee/optee_client/out/export/usr/
$ make -j$(nproc)
CROSS_COMPILE=${CROSS_COMPILE}
PLATFORM=${PLATFORM}
TEEC_EXPORT=${TEEC_EXPORT}
--no-builtin-variables
编译完成生成optee_example_secure_storage
以上可以看出不管哪个sample,它的CA的编译过程是一样的,都依赖optee_client的编译后输出目录完成Host Application的编译链接最终生成目标程序。这里对secure_storage的运行不做讲解,后续计划单开一章对CA和TA的开发做更深入的讲解。
08 总结
本文详细介绍了OP-TEE Client的作用、架构及其关键组件:
OP-TEE Client由libteec.so与tee-supplicant组成,前者提供GP TEE Client API,后者处理文件系统和RPMB访问。
提供了Yocto内外的编译方法,并说明了如何将编译产物安装到目标系统。
展示了典型示例(Hello World与Secure Storage)的调用流程。
至此,读者应能够在目标平台上构建并运行OP-TEE Client,从而使普通应用能够与安全世界的TA通信。下一篇文章将深入介绍OP-TEE Driver,即Linux内核中为OP-TEE提供支持的专用驱动。
全部0条评论
快来发表一下你的评论吧 !