话不多说,书接上文。
3、TA镜像合法性的验证
到这里终于到了我的目的地。
为什么不直接看这个地方呢,因为没有前面知识的铺垫,其实我直接看这个是真的会比较难受的。还是需要一些前置知识,毕竟这个年纪,主要是要从任务中去学到一些东西。
当TA镜像文件被加载到共享内存后,OP-TEE会对获取到的数据进行合法性检查。合法才能加载到OPTEE中。怎么检查呢?
检查TA镜像文件中的哈希(hash)值、magic值、flag值等是否一致,并对镜像文件中的电子签名部分做验证。整个验证过程如18-3所示。
前面我们知道签名后的TA镜像长这个样子。digest(就是签名的消息)。这里的私钥应该使用OEM厂商自有的私钥替换掉该密钥。)(这里要是伪装修改了Shdr和TA row image,那么digest就会不一样,那么signature就不会一样了。)(row image的意思就是二进制镜像)
3.1 验证TA镜像合法性使用的RSA公钥的产生和获取
上面我们知道了TA镜像的合法性的校验过程,检查TA镜像文件中的哈希(hash)值、magic值、flag值等是否一致,对镜像文件中的电子签名部分做验证。其中这个电子签名验证是需要公钥的,这个公钥是怎么获取的产生的?来看看
编译整个工程时会生成一个ta_pub_key.c文件,该文件中存放的是RSA公钥,用于验证TA镜像文件合法性。
该文件是在编译gensrcs-y目标中的ta_pub_key成员时生成的,该部分的内容定义在optee_os/core/sub.mk文件中,其内容如下:
编译ta_pub_key目标时会调用recipe-ta_pub_key命令来生成ta_pub_key.c文件,该文件被保存在optee_os/out/arm/core/目录中。
recipe-ta_pub_key命令调用pem_to_pub_c.py文件解析optee_os/keys目录中的RSA密钥来获取RSA公钥,并将该公钥保存到ta_pub_key. c文件中。
pem_to_pub_c.py脚本的内容如下:
生成的ta_pub_key.c文件中将定义三个全局变量并赋值,这三个变量就是RSA公钥的内容,作用和内容分别为:
这三个变量作为全局变量被使用,在对TA镜像文件的签名信息进行验签操作时被使用到。
3.2 TA镜像文件合法性的检查
对TA镜像文件内容合法性的检查是通过调用check_shdr函数来实现的,该函数除了会对TA镜像文件中的签名信息进行验签操作外,还会校验TA镜像文件的shdr部分,check_shdr代码内容如下:
校验TA镜像签名时使用的RSA公钥是由ta_public_key.c文件中的ta_pub_key_exponent和ta_pub_key_modulus变量的值组成。
4、加载TA镜像到OP-TEE的用户空间
前面我们解决了TA镜像文件的编译与签名、然后将其加载到共享内存、然后进行了校验,通过了校验之后就到最后的一步将TA加载到OPTEE的用户空间。
待共享内存中的TA镜像文件校验通过后,OP-TEE就会将共享内存中的TA的内容复制到OP-TEE用户空间的TA内存区域, 并初始化该TA运行于用户空间时的上下文。
这些操作通过调用load_elf函数来实现。(两件事:复制、初始化)
(这个复制以后,那个共享内存应该会释放掉吧)
(链接器最终生成的 ELF 格式的可执行文件又被称为镜像文件(Image file))
(感觉这个函数命名,这函数可能是公用的elf镜像加载函数。)
TA镜像文件的TA原始文件是ELF格式,在加载前需要先解析该ELF格式文件,获取该ELF文件中哪些段在运行时是必需的、需要保存在什么位置,从而决定用户空间中该TA运行时需要的内存大小和堆栈空间大小。解析完后再将ELF格式的必要段的内容复制到为该TA分配的OP-TEE用户空间内存中。
5、TA运行上下文的初始化
到这里加载完毕,跑起来baby
TA镜像的内容从共享内存复制到OP-TEE用户空间内存区域后会返回到ta_load函数继续执行(load_elf()函数是在ta_load函数中的一步),执行初始化该TA运行上下文的操作,并将该上下文添加到OP-TEE的TA运行上下文队列中。ta_load的内容如下:
待ta_load执行完后,加载TA镜像到OP-TEE的操作也就全部完成。这里看到动态TA的加载是因为需要了,然后去加载,加载完了,那是不是就该使用了。
ta_load函数完成了加载和初始化,然后就和CA挂钩,然后在CA中执行的创建会话操作会得到该TA的会话ID,用于REE侧的CA对该TA执行调用命令的操作。
以上就到这了这个终点站,关于这部分,其实最好的文档就是源码,可以跟着资料然后自己去ctrl不断的观看代码逻辑,这是最好的解释。
(最后关于这个共享内存的地方,我现在的认识是建立在REE内核态的,后面会继续阅读确认这个事情的。对就是内核空间,这里我把EL3和内存直接搞迷惑了,不是每个等级都对应的有各自的内存,只是内存应该分为安全内存和非安全内存,每个分类又分为内核内存和用户态内存。)
因为REE的内核内存,我TEE的可以来随意拿取,但是我TEE的,那可不行。所以TEE的内核内存可以访问整个内存,特权。同时你REE要什么,你来派人求我,经过验证是我的白名单,那么我把这数据通过使者给你传出来,但是我的地方,你不能直接来随意进出。
感谢,如果有帮助,欢迎点赞关注!!!
周末愉快!!!
参考资料:
https://blog.csdn.net/chq1005613740/article/details/122099489
https://blog.csdn.net/chali1314/article/details/123788662
《手机安全和可信应用开发指南》