接上文
4、应用实例
本节详细介绍了使用身份验证框架的可信引导实现。本示例对应于TBBR客户端文档中指定的应用功能模式(AFM)。建议阅读本指南和源代码。
4.1 、The TBBR CoT (CoT的信任板级引导要求)
Trusted Board Boot Requirements
在CoT中指定了BL1和BL2分别位于drivers/auth/tbbr/tbbr_cot_bl1.c 和 drivers/auth/tbbr/tbbr_cot_bl2.c
BL1和BL2之间公用的部分在drivers/auth/tbbr/tbbr_cot_common.c.
CoT包含了一系列镜像的指针,这个用宏 REGISTER_COT(cot_desc)注册在框架中。cot_desc必须是数组的名称(传递指针或任何其他类型的间接指向数组的东西将导致注册过程失败)必须要数组。
在这个启动流程有多少个镜像是由CoT决定的。在这里规定了在TF-A中,所有COT最少必须呈现的镜像有以下:
? BL2 ? SCP_BL2 (platform specific) ? BL31 ? BL32 (optional) ? BL33
(BL1不在信任链里面,why)
TBBR指定了这些图像必须附带的其他证书,以便进行正确的身份验证。具体的去看看这个TBBR 的document(后面会讲到)
根据接口的说明,平台必须提供唯一的镜像标识符和证书,这些东西会在启动过程加载。如果平台是按照TBBR的参考,这些标识符可以在include/common/tbbr/tbbr_img_def.h拿到。ARM平台这个文件放在include/plat/arm/common/arm_def.h. 其他的平台也包含这些文件用来提供他们自己的标识符。
身份验证模块使用这些标识符对CoT数组进行索引,因此数组中的描述符位置必须与标识符匹配。(哪个描述符在哪要对应好,别搞错了位置)
每个镜像的描述符必须包含:
?img_id:平台定义的对应镜像唯一标识符。
?img_type:镜像解析器模块使用镜像类型调用正确的解析库,以检查镜像完整性并提取所需的身份验证参数。目前支持三种类型的镜像: + –IMG_RAW:镜像是原始二进制。除了读取整个镜像之外,没有任何解析功能可用。 + –IMG_PLAT:镜像格式是特定于平台的。平台可以将此类型用于身份验证框架不直接支持的自定义镜像。 + –IMG_CERT:镜像是x509v3证书
?父级:指向父级镜像描述符的指针。父级将包含验证当前镜像所需的信息。如果父级为空,则将从平台获取身份验证参数(例如BL2和可信密钥证书使用ROT私钥签名,追溯上去他们自身就是根,其公共部分存储在平台中)。
?认证方法:这指向一个数组,该数组定义了必须实现的身份验证方法,通过这些方法去对图像进行身份验证。每个方法都包含了一系列参数的类型和描述符。一个参数的描述符又包含了指向从镜像获取特定参数的类型和cookie。 (i.e. if the parameter is stored in an x509v3 extension, the cookie will point to the extension OID)。根据方法类型,必须指定不同数量的参数。此指针不应为空。支持的方法有:
-
–AUTH_METHOD_HASH:镜像的哈希必须与从父镜像提取的哈希匹配。必须指定以下参数描述符: ? 数据:要散列的数据(从当前镜像获得) ? 哈希:参考哈希(从父映像获得) (就是自己的和父镜像的对上了,才能说明这个就我要的,这个在下载软件的时候,有时候也需要做一些校验) -
–AUTH_METHOD_SIG:镜像(通常是证书)必须使用从父镜像(如果父镜像为空,则为平台)中提取公共部分的私钥进行签名。必须指定以下参数描述符: ? pk:公钥(从父镜像获取) ? sig:数字签名(从当前镜像获得) ? alg:使用的签名算法(从当前镜像获得) ? 数据:要签名的数据(从当前镜像获取) -
authenticated_data:该数组指针说明了镜像经过身份验证后必须从中提取哪些身份验证参数。每个参数由参数描述符和存储参数的缓冲区地址组成(参数描述符+参数的buffer地址)。CoT负责分配存储参数所需的内存。此指针可能为空。(这里可能是因为镜像的内存区复用,这样的话,就就需要提前把下一个镜像所需要的东西放到其他内存中,可能这个镜像后面没有镜像了,那么也就可能不需要其他的地址了。)
在tbbr_cot*.c文件中,有很多的buffers拿来存放从证书中获得的参数。比如在TBBR CoT中,这些参数是hashes和公钥。在DER格式中, RSA-4096 public key requires 550 bytes, and a hash requires 51 bytes. 根据CoT和身份验证过程,一些缓冲区可能在引导过程中的不同阶段重复使用。(因为有的key或者hash的用处不唯一这个可以理解)
5、BL31的信任链
在bl31的信任链中有四个镜像的描述符: 可信密钥证书使用ROT私钥签名,并包含作为x509v3扩展的可信世界公钥和非可信世界公钥。这必须分别使用img_auth_methods和authenticated_data数组在镜像描述符中指定。
通过使用ROTPK检查其数字签名来验证可信密钥证书。检查签名需要四个参数:公钥、算法、签名和已签名的数据。因此,身份验证方法必须指定四个参数描述符:
-
?subject_pk:AUTH_PARAM_PUB_KEY类型的参数描述符。此类型用于从父镜像中提取公钥。如果cookie是OID,则从相应的x509v3扩展中提取密钥。如果cookie为空,则检索主题公钥。在这种情况下,由于父镜像为空,因此从平台获取公钥(该密钥将是ROTPK)。(三种格式嘛之前提到的) -
?sig:AUTH_PARAM_sig类型的参数描述符。它用于从证书中提取签名。 -
?sig_alg:AUTH_PARAM_sig类型的参数描述符。它用于从证书中提取签名算法。 -
?raw_data:AUTH_PARAM_raw_ data类型的参数描述符。它用于从证书中提取要签名的数据。
**一旦检查了签名并验证了证书,就需要从证书中提取可信世界公钥。**为此,在authenticated_data数组中创建一个新条目。在该条目中,必须指定相应的参数描述符以及存储参数值的缓冲区地址。在这种情况下,trusted_world_pk描述符用于从具有OID trusted-world_ pk_OID的x509v3扩展中提取公钥。BL31密钥证书将使用此描述符作为签名身份验证方法中的参数。密钥存储在trusted_world_pk_buf缓冲器中。
**BL31密钥证书通过使用先前从可信密钥证书获得的可信世界公钥检查其数字签名来认证。**在镜像描述符中,我们通过签名指定一个身份验证方法,其公钥是trusted_world_pk。一旦该证书通过身份验证,我们就必须提取存储在soc_fw_content_pk指定的扩展中的BL31公钥。该密钥将被复制到content_pk_buf缓冲区。
**BL31证书通过使用先前从BL31密钥证书获得的BL31公钥检查其数字签名来认证。**我们指定了使用soc_fw_content_pk作为公钥的身份验证方法。认证后,我们需要提取BL31哈希,存储在soc_fw_hash指定的扩展中。该散列将被复制到soc_fw_hash_buf缓冲器。
**BL31镜像通过计算其散列并将其与从BL31证书获得的散列进行匹配来认证。**镜像描述符包含通过散列的单个身份验证方法。散列方法的参数是参考散列、soc_fw_hash和要散列的数据。在这种情况下,它是整个镜像,因此我们指定raw_data。
(检查了签名并验证了证书–>从证书中提取可信世界公钥–>BL31密钥证书验证–>BL31公钥—>BL31证书验证–>hash–>BL31镜像–>OKK) (检查了签名并验证了证书是:平台或者链式的上一级,或者拓展x509v3)
6、镜像解析库
镜像的解析模块是依赖于镜像解析库去实现镜像的校验完整性和认真参数提取的。前面也说过CoT中镜像对应的解析库是各自不一样的,原始二进制进行不需要解析库,平台估计自己有,因此就需要x509v3需要。
Arm平台将使用基于mbed TLS的x509v3库。该库可以在drivers/auth/mbedtls/mbedtls_x509_parser.c中找到。它里面有三个函数: (看函数名就知道函数的用途是什么)
使用宏REGISTER_IMG_PARSER_LIB()在框架中注册库,然后就可以使用这个镜像镜像的解析。每当图像解析器模块需要访问IMG_CERT类型的图像时(或者是实现镜像的认证的功能时),它将调用该文件中导出的相应函数。
必须更新构建系统以包含相应的库和mbed TLS源。Arm平台使用Arm_common.mk文件来pull资源。
7、密码库
加密模块依赖于密码库来执行所需的操作:例如验证散列或数字签名。Arm平台将使用基于mbed TLS的库,可以在驱动程序/auth/mbedtls/mbedtls_crypto.c中找到。该库使用宏REGISTER_cryto_LIB()在验证框架中注册,并支持以下四个函数:
mbedTLS库算法由TF_MBEDTL_KEY_ALG和TF_ mbedTLS_KEY_SIZE变量配置。
-
?TF_MBEDTLS_KEY_ALG可接受3个值:rsa、ecdsa或rsa+ecdsa。此变量允许Makefile在各种算法的构建中包含相应的源。将变量设置为rsa+ecdsa可以让mbedTLS库支持rsa和ecdsa算法。 -
?TF_MBEDTLS_KEY_SIZE设置TFA支持的RSA密钥大小。有效值包括1024、2048、3072和4096 -
?TF_MBEDTLS_USE_AES_GCM设置是否支持基于AES-GCM算法的认证解密。有效值为0和1。
注意:如果需要考虑代码大小,可以在平台Makefile中定义构建选项BEDTLS_SHA256_small。 通过这个操作将使mbed TLS采用SHA-256的实现,这样的好处内存占用更小(大约少1.5 KB),但速度更慢(大约30%)。(以时间换空间)
到这里终于把CoT信任链翻译完毕,其中肯定会存在问题,欢迎各位在评论区指出,如果有点帮助对您,欢迎收藏点赞关注。
下一篇时关于Arm Cpu一些特定的,在构建时用的宏。
|