ATF(Arm Trusted Firmware)/TF-A Chapter 04 Authentication Framework

 

4.1. 代码分析

首先,重新分析之前忽略掉的 TRUSTED_BOARD_BOOT =1 的情况,bl1_platform_setup->arm_bl1_platform_setup->arm_load_tb_fw_config.

看138行,load_auth_image会调用load_auth_image_internal:

 

此时会执行236行宏控制的代码。243行,首先找到这个id的父id,递归调用认证镜像(我们也会注意到,如果支持TBBR,头文件中定义的stack大小也会相应的变大)。

237行,

当TRUSTED_BOARD_BOOT =1的前提下,并且定了DYN_DISABLE_AUTH,arm提供的这个方案是认证可以动态的打开和关闭,这在开发的时候是很有帮助的。先不定义DYN_DISABLE_AUTH,方便分析。

回到load_auth_image_internal,load前会获取这个image_id的parent_id,此时image_id=TB_FW_CONFIG_ID,

auth_mod_get_parent_id内部:

通过cot_desc_ptr这个全局变量,获取id的auth_img_desc_t类型的指针地址

cot_desc_ptr。通过查找代码,我们会发现在driver/tbbr/tbbr_cot.c中:

宏定义在include/driver/auth/auth_mod.h

Cot_desc是固定的,也在driver/tbbr/tbbr_cot.c中.

结构体变量类型:

看TB_FW_CONFIF的parent id:

证书级别:

通过密钥级别,递归到TRUSTED_BOOT_FW_CERT_ID已经没有父id了,auth_mod_get_parent_id返回非0,此时parent_id=TRUSTED_BOOT_FW_CERT_ID.在load_image后,继续load_auth_image_internal的260行.

auth_mod_verify_img(drivers/auth/auth_mod.c ,343行)是验签接口。

357行,首先检查镜像完整性。

img_parser_check_integrity是Image Parser Module (IPM)模块的接口之一,主要功能

  1. 检查通过IO framework加载的镜像完整性
  2. 根据由CoT描述符中的内容获取认证参数。

因为镜像可能有不同的格式(例如,认证镜像可以是x509v3证书,签名的ELF文件或平台特定的格式)。 IPM允许为CoT中的每种镜像格式分别注册一个镜像解析库Image Parser Library(IPL)。 实现具体的解析方法。 IPM从CoT获取镜像格式并调用正确的IPL来检查完整性并提取认证参数。

在代码中:

img_parser_check_integrity(Driver/auth/img_parser_mod.c, 66行)函数的84行

Parser_lib_indices是什么时候被赋值的?

bl1_main->auth_mod_init->img_parser_init:

第17,18行:

在bl1.ld.s中:

IPL必须实现如下接口:

并使用宏注册IPL函数:

我们看drivers/auth/mbedtls_x509_parser.c:

在include/driver/auth/img_parser_mod.h中:

函数的具体介绍在“auth-framework  1.2.1.   Describing the image parsing methods”有详细介绍。

注意:要想支持trust boot,即TRUSTED_BOARD_BOOT = 1和GENERATE_COT = 1则必须指定mbedtls库。需要先编译这个库。具体内容在后面的章节中分析。

img_parser_check_integrity完成后,获取认证方法,认证方法在定义cot时,已经写好了。

看TRUSTED_BOOT_FW_CERT_ID的auth_method,在auth_img_desc_s的auth_method_desc_t中:

有两种认证方法:AUTH_METHOD_SIG和AUTH_METHOD_NV_CTR,第一个方法很好理解,

关于auth_img_desc_s,有以下几种认证方法:

认证相关的接口,由 Authentication Module (AM)提供:

认证流程:

  1. 由IPM的get_auth_param()函数,从镜像中提取认证参数。
  2. 在调用Cryptographic Module (CM)和 TF-A Platform Port (PP)的验证函数时,对参数进行预处理。
  3. 从父镜像中提取验证参数用来验证子镜像

第二个:

是最新增加的认证方法,防止rollback攻击。所以,对于可更新的固件来说,需要进行两次认证。这个方法在后面有分析。

 

auth_mod_verify_img执行时,会按顺序循环调用所有有效的认证方法,首先是AUTH_METHOD_SIG的auth_signature函数,传入的参数是auth_method->param.sig = .img_auth_methods.param.sig,变量使用宏定义,例如pk结构体:

结构体的第二个参数,前面说了,是用来在x509中定位扩展域的OID指针,告诉认证代码,要提取的hash或者公钥数据的指针,0表示不使用这个字段。

auth_signature的第二个参数img_desc=auth_img_desc_t类型的TRUSTED_BOOT_FW_CERT_ID,第三四个参数分别是base addr和length。

154,158,164行,最终会调用SoC厂商自己实现的注册在IPL接口中的get_auth_param函数指针指向的函数。

171行,获取parent的参数,对当前的image验签。由于没有parent,所以执行174行的plat_get_rotpk_info,否则会先获取parent的参数。plat_get_rotpk_info在porting guide中:

ROPTK必须是ASN.1格式的DER编码,有两种形式,一是返回ROTPK本身,另一个是返回他的hash。通过int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,

unsigned int *flags) 的flag参数区分

如果返回的是hash,则必须先使用ROTPK对image验签,在比较ROTPK的hash

如果flag是ROTPK_NOT_DEPLOVED,则跳过ROTPK hash比较。

在回到171行,除了跟证书之外,会执行auth_get_param获取pk_ptr,并且此时flag=0,直接对当前的image验签。

继续分析第二个验签方法AUTH_METHOD_NV_CTR:auth_mod_verify_img中,337行:

看下注释怎么说的(drivers/auth/auth_mod.c):

硬件上,SoC有一个non-volatile计数器,值只能增加。

证书中,所有证书都包含一个计数器值。

证书的值不应低于non-volatile计数器的值。 如果证书的值较大,则必须将non-volatile计数器的值更新为新值。

返回到auth_mod_verify_img,两个认证完成后,还需要更新认证数据。

auth_mod_verify_img(Drivers/auth/auth_mod.c ,390行,)把需要的类型拷贝到ptr指向的地址中:

看下TRUSTED_BOOT_FW_CERT_ID需要的认证数据有哪些类型:

最后,置标志位:

递归返回后,所有的加载并认证镜像的工作完成。

4.2 模块划分

本章结束。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值