前言

年末假期的最后一天信誓旦旦的说,希望年前把这个系列做完,最后还是只做了第一篇,因为最近告诉自己不能熬夜了。一晃就是年后的假期倒数第二天了。时间真的好快。

今天就到了学校,老实讲虽然家里也吵吵闹闹,热热闹闹,但是亲人的羁绊永远都在那里。

蛮有感触的是今年回家将自己的奖学金给家人都包了一些红包礼物,收到的时候他们还很错愕,仿佛我一下子长大了一样。

一直在外求学的路途很远,邻居的奶奶还在念叨说我们越走越远了,其实也不过就是一个省会城市,这几百公里对很多人来说不过是几个小时的事,对于他们来说确实一年的四季,盼过这四季,才能在田头看到归乡的我们。

扯远了。

前面讲诉一个CA是怎么创建的,但是CA和TA是相辅相成的,在讲诉一个TA的创建之前,我们先来看看CA和TA的交流逻辑。

  • CA在使用libteec库中的接口来实现调用TA的操作时,

    • 一般过程是需要先建立context,
    • 然后建立与需要调用的TA之间的session,
    • 再通过执行invoke操作向TA发送command ID来实现具体的操作需求,
    • 待TA中command ID的内容执行完成之后,如果后续也不需要再次调用TA时,可以通过close session和final context来释放资源,完全关闭该CA与TA之间的联系。


这里面实现的接口都是在libteec中。

一、可信应用TA的开发

1、知识名词

TA的全称是Trust Application,即可信任应用程序。

CA的全称是Client Applicant,即客户端应用程序。

TA运行在OP-TEE的用户空间,CA运行在REE侧。

CA执行时代入特定的UUID和命令ID参数就能实现请求特定TA执行特定操作的需求,并将执行结果返回给CA。

通过CA对TA的调用可实现在REE侧对安全设备和安全资源的操作。

普通用户无法知道TA的具体实现,例如操作使用了什么算法、操作了哪些资源、获取了哪些数据等,这也就确保了相关资源和数据的安全

GP规范定义了CA调用TA的所有接口以及相关结构体和变量类型,同时也定义了TEE侧用户空间的所有接口和相关结构体和变量类型。

如果TEE方案提供方是遵循GP规范实现了规范中定义的接口,上层应用开发者按照GP规范开发的CA和TA就能正常运行于各家TEE平台中。

CA与TA有一些基本的概念,这些部分组成了TA与CA之间进行交互的基本条件,这些基本概念的说明如下。

    1. TEE Contexts
    • TEE上下文(TEE Contexts)用于表示CA与TEE之间的抽象连接,即通过TEE上下文可将REE侧的操作请求发送到TEE侧。需注意的是,在执行打开CA与TA之间的会话之前必须先获取到TEE上下文。一般该值是打开REE侧的TEE驱动设备时返回的句柄,如果在REE侧支持多个TEE驱动,则在调用TEEC_InitializeContext时可指定具体的驱动设备名来获得特定的TEE上下文
    1. Session
    • 会话(Session)是CA与特定TA之间的抽象连接。只有建立了CA与TA之间的会话后,CA才可调用TA中的命令来执行特定的操作。调用TEEC_OpenSession函数后,TEE会将建立的会话内容返回给CA,一个会话包含TEE上下文和会话ID值。
    1. Commands
    • 命令(Commands)是CA与TA之间通过会话进行具体操作的基础。在交互过程中,CA通过指定命令ID通知TA执行与命令ID匹配的操作。至于TA中执行什么操作则完全由TA开发者决定,命令ID只是CA与TA约定的某个特殊操作的ID值。
    1. Share Memroy
    • 共享内存(Share Memroy)被用于CA与TEE之间进行数据交互,CA可通过注册或分配的方式通知TEE注册或分配CA与TA之间的共享内存,CA和TEE对该块共享内存都具有指定的读写权限。
    1. Memory References
    • Memroy Reference是CA与TEE之间一段固定范围的共享内存,Memory Reference可指定一个完整的共享内存块,也可指定共享内存块中的特定区域
    1. UUID
    • UUID是一个TA的身份标识ID。当CA需要调用某个TA时,TEE侧通过UUID来决定要加载和运行哪个TA镜像

2、GP标准

GP标准的全称是GlobalPlatform,该标准对TEE的框架和安全需求做出了明确的规,并对REE侧提供的接口函数、数据类型和数据结构体也做出了明确的定义,并对TEE侧提供给TA开发者使用的接口函数、数据类型、数据结构体做出了明确的规定和定义。

关于GP规范与TEE相关的文档,读者可到如下链接中自行查阅和下载:

http://www.globalplatform.org/mediaguidetee.asp

对CA和TA的开发者而言,需要仔细阅读GP对REE侧和TEE侧各种接口函数和数据结构体的定义,只有熟悉了接口函数以及数据结构体的定义后才能正确使用这些接口来开发特定的CA和TA。

3、GP标准对TA属性的定义

TA的属性定义了该TA的运行方式、链接方式、堆栈大小、版本等信息

在GP标准中对一个TA所需要具有的属性进行了严格的定义和说明,这些属性的名称、作用、值的内容说明如表所示。

  • TA个属性说明表
  • OP-TEE中TA的扩展属性如表21-2所示。

    需要被设定的TA属性都在TA源代码的user_ta_headr_defines.h文件中被定义,gpd.ta. appID的值通常被设置成该文件中TA_UUID的值

gpd.ta.singleInstance、gpd.ta.multiSession、gpd.ta.instanceKeepAlive的值通过在该文件中定义TF_FLAGS的值来确定。

  • gpd.ta.dataSize的值由该文件中定义TA_DATA_SIZE的值来确定。

  • gpd.ta.stackSize的值由该文件中定义TA_STACK_SIZE的值来确定。

  • 在OP-TEE中gpd.ta.version和gpd.ta.description的值使用默认值。gp.ta.description和gp.ta.version的值由TA_CURRENT_TA_EXT_PROPERTIES宏定义来确定。

4、GP标准定义的接口

GP标准中对REE侧和TEE侧提供给CA和TA调用的接口都做出了明确的定义,包括接口函数的函数名、作用、参数说明、返回值等。(CA的部分我们在上一篇以及讲诉了。)

GP官方网站中名称为TEE_Client_API_Specification-Vx.x_c.pdf的文档给出了这些接口的详细说明,根据发布版本的不同,定义的接口可能也会有所不同。

TEE侧定义的接口函数属于内部接口,详细内容查阅GP提供的名称为GPD_TEE_Internal_Core_API_Specification_vx.x.pdf的文档。

1 GP定义的客户端接口

GP定义的客户端接口包括9个函数和1个,使用这9个接口函数和宏就可满足CA的开发只是CA需要配合TA一起使用,双方定义的UUID的值和命令ID的值需保持一致,这9个函数和宏的名称和作用如表21-3所示。

上述9个函数的函数原型、作用、参数说明、返回值的说明在上一篇中已进行了详细的介绍。这部分接口的实现会被编译到libteec库文件中,最终会被CA调用。

2 GP定义的内部接口

GP定义的内部接口是供TEE侧的TA或其他功能模块使。大致可以分为Framwork层API对数据和密钥操作的API密码学操作API时钟API大整数算法API。由于API较多,故在本书中就不对每个API进行一一说明,只给出各API的作用和名称。

1. Framwork层接口

Framwork层API是TEE用户空间实现对内存、TA属性等资源进行操作的API,该类API的说明如下表21-4所示。

2.对数据和密钥操作的API

GP规定了特定的操作接口,用于TEE实现对各种数据流和密钥的操作。在使用安全存储、加解密等操作时都需使用该部分的接口。

对数据流的操作是以object的方式完成的对密钥的操作则是使用attr的方式来完成的。该部分API名称以及作用关系如表21-5所示。

3.密码学操作接口

TEE最重要的功能之一是提供了各种密码学算法的实现,并确保这些算法运行于安全环境中。GP定义了各种密码学的操作接口,这些API的名称和作用说明如表21-6所示。

4.时间操作接口

GP对在TEE中操作系统时间的接口也作出了明确的规定,这部分接口的函数名称和作用说明如表21-7所示。

5.大整数算法接口

TEE中会提供对大整数的操作接口,GP规范对该部分的接口进行了定义,由于篇幅有限,这部分的内容就不详细列出。这部分的接口主要包括对大整数的初始化、加减乘除、转换、对比、获取具体的位、模幂运算等,详细内容可参阅GP的文档。

秉承功能模块化的理念,建议在创建TA中的源代码文件时分为三个部分。

  • 第一个部分为TA的入口调用文件,该TA中TA_xxxEntryPoint接口的实现将保存在该文件中。

  • 第二部分为TA的处理文件,该文件中的内容是调用TA_InvokeCommandEntryPoint函数时switch case中各case中的具体实现。

  • 第三部分为TA具体操作的实现,建议将不同的功能实现保存在不同的文件中,这样从代码阅读或调试时便于理解。

建立完目录结构和相关文件后,需将OP-TEE中的user_header_defines.h文件保存到TA的源代码中。通过修改该文件中的内容可实现对该TA属性的设定。

5、TA代码的实现

TA代码需实现具体功能的所有操作,TA被TEE调用的各种操作的入口函数就是在表21-4(Framwork层接口)部分的API。

所以需要在TA中实现这些API,最重要的是对TA_InvokeCommand-EntryPoint函数的实现。

该函数需要定义各种命令ID对应的操作,至于每个命令ID需要实现什么功能就由开发者决定,但该命令ID的定义需要与CA中的命令ID的定义保持一致。

TA属性的设定可通过修改user_ta_head_defines.h文件来实现,主要需修改如下的宏定义:

  • □ TA_UUID:该TA的UUID值;
  • □ TA_FLAGS:TA的访问属性,具体内容请参阅21.3节和GP规范;
  • □ TA_STACK_SIZE:指定该TA运行时栈空间的大小;
  • □ TA_DATA_SIZE:指定该TA运行时堆空间的大小;
  • □ TA_CURRENT_TA_EXT_PROPERTIES:该TA的扩展属性,主要包括TA名字、版本等。

6、TA的实现源码

#define STR_TRACE_USER_TA "HELLO_WORLD"#include <tee_internal_api.h>
#include <tee_internal_api_extensions.h>#include "ta_hello_world.h"/** Called when the instance of the TA is created. This is the first call in* the TA.*/
TEE_Result TA_CreateEntryPoint(void)
{return TEE_SUCCESS;
}/** Called when the instance of the TA is destroyed if the TA has not* crashed or panicked. This is the last call in the TA.*/
void TA_DestroyEntryPoint(void)
{
}/** Called when a new session is opened to the TA. *sess_ctx can be updated* with a value to be able to identify this session in subsequent calls to the* TA.*/
TEE_Result TA_OpenSessionEntryPoint(uint32_t param_types,TEE_Param  params[4], void **sess_ctx)
{uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE,TEE_PARAM_TYPE_NONE,TEE_PARAM_TYPE_NONE,TEE_PARAM_TYPE_NONE);if (param_types != exp_param_types)return TEE_ERROR_BAD_PARAMETERS;/* Unused parameters */(void)&params;(void)&sess_ctx;/** The DMSG() macro is non-standard, TEE Internal API doesn't* specify any means to logging from a TA.*/DMSG("Hello World!\n");/* If return value != TEE_SUCCESS the session will not be created. */return TEE_SUCCESS;
}/** Called when a session is closed, sess_ctx hold the value that was* assigned by TA_OpenSessionEntryPoint().*/
void TA_CloseSessionEntryPoint(void *sess_ctx)
{(void)&sess_ctx; /* Unused parameter */DMSG("Goodbye!\n");
}static TEE_Result inc_value(uint32_t param_types, TEE_Param params[4])
{uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INOUT,TEE_PARAM_TYPE_NONE,TEE_PARAM_TYPE_NONE,TEE_PARAM_TYPE_NONE);if (param_types != exp_param_types)return TEE_ERROR_BAD_PARAMETERS;params[0].value.a++;return TEE_SUCCESS;
}/** Called when a TA is invoked. sess_ctx hold that value that was* assigned by TA_OpenSessionEntryPoint(). The rest of the paramters* comes from normal world.*/
TEE_Result TA_InvokeCommandEntryPoint(void *sess_ctx, uint32_t cmd_id,uint32_t param_types, TEE_Param params[4])
{(void)&sess_ctx; /* Unused parameter */switch (cmd_id) {case TA_HELLO_WORLD_CMD_INC_VALUE:return inc_value(param_types, params);default:return TEE_ERROR_BAD_PARAMETERS;}
}

代码框架:


之前我们也说了这个TA是一个文件,是一个镜像文件。你看这个里面其实还有一些集成的东西。这个就放在下一篇来讲讲怎么在实现CA和TA后进行集成。

参考资料:
《手机安全与可信应用开发指南》

【CA-TA实战系列二】如何创建一个TA相关推荐

  1. 【Youtobe trydjango】Django2.2教程和React实战系列二【settings配置文件】

    [Youtobe trydjango]Django2.2教程和React实战系列二[settings配置文件] 1. Django项目初始化过程 2. 全貌 3. 详细解释 4. 增加其他配置 1. ...

  2. SAP UI5 应用开发教程之三十二 - 如何创建一个自定义 SAP UI5 控件试读版

    一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 应用开发教程之一:Hello World SAP UI5 应用开发教程之二:SAP U ...

  3. xen虚拟化实战系列(二)之xen虚拟机安装

    xen虚拟化实战系列文章列表 xen虚拟化实战系列(一)之xen虚拟化环境安装 xen虚拟化实战系列(二)之xen虚拟机安装 xen虚拟化实战系列(三)之xen虚拟机复制 xen虚拟化实战系列(四)之 ...

  4. 【Youtobe trydjango】Django2.2教程和React实战系列四【创建Django应用】

    [Youtobe trydjango]Django2.2教程和React实战系列四[创建Django应用] 1. 创建应用 2. 修改应用 1. 创建应用 打开cmd黑框,也可以用下列方法打开项目根目 ...

  5. Skype For Business 2015实战系列14:创建Office Web App服务器场

    Skype For Business 2015实战系列14:创建Office Web App服务器场 前面的操作中我们已经成功的安装了Office Web App Server,今天我们将创建Offi ...

  6. mysql用创建的用户登陆并修改表格_MySQL 基础学习二:创建一个用户表,并增删改查...

    MySQL 基础学习二:创建一个用户表,并 增删改查 提示:MySQL 命令建议都用大写,因为小写运行时,还是翻译成大写的. 第一步,创建一个用户表 1,打开控制台,进入数据库 C:\Users\Ad ...

  7. threejs 绘制球体_实战:用 threejs 创建一个地球

    原标题:实战:用 threejs 创建一个地球 提示: 讲座 前端大型免费公开课讲座 教程 从零基础学前端教程,都在这~ 上个月底,在朋友圈看到一个号称"这可能是地球上最美的h5" ...

  8. MP实战系列(二)之集成swagger

    其实与spring+springmvc+mybatis集成swagger没什么区别,只是之前写的太不好了,所以这次决定详细写. 提到swagger不得不提rest,rest是一种架构风格,里面有对不同 ...

  9. FMS3系列(二):创建可交互的FMS连接--I can say:Hello World

    在做FMS开发中,flash客户端与FMS服务器通信交互数据等是常见的,比如flash客户端需要一播放一个视频,需要获得FMS发向flash端的一条消息等.那么我们要怎么才能实现flash客户端与FM ...

最新文章

  1. P1283 平板涂色
  2. Xamarin Essentials教程语音播报TextToSpeech
  3. 编程之美-控制CPU占用率曲线方法整理
  4. 使自定义控件居中于父容器的计算公式
  5. mybatis plug 只查id_Mybatis一对多/多对多查询时只查出了一条数据
  6. python3 threading是否被抛弃_Python3中的线程模块是否发生了变化?如果是,怎么办?...
  7. H5案例分析和场景应用
  8. 计算机二级2018VB题库百度云,2018年计算机二级VB考试真题
  9. Java题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
  10. Visio设计产品流程图
  11. Linux查看及测试网络
  12. 国产_系统_加油 by tmddebaba
  13. 8.Redis主从复制
  14. 操作系统实验:系统内存使用统计
  15. 模仿微信图片编辑器--动画实现向上弹出文字编辑框(遮罩)界面
  16. 【DEBUG】OMAPL138 Connect to PRSC failed
  17. unity制作mmd视频
  18. ELK企业应用-kibana页面显示不正常(一)
  19. 腾讯游戏助手运行闪退日志查看
  20. 22岁高中学历的我 如何做到CTO年薪50万(1)

热门文章

  1. 【快乐分享】这个端午很快乐!
  2. Seay代码审计工具
  3. dedecms后台验证码显示不正常的四种处理办法
  4. 北师大网络教育计算机试题六答案,北京师范大学网络教育---小学数学教学论答案...
  5. Hibernate查询——HQL,包括分页查询
  6. 基于 JavaWeb 的社区管理系统
  7. 自己动手写操作系统系列第1篇,从开机加电到切换保护模式
  8. apcups命令_APCups电源如何安装计算机AP9631 串口超级终端配置
  9. 赫美收购再发力 打造线上线下全产业链战略布局
  10. Python机器学习算法入门指南(全)