赞
踩
首先,重新分析之前忽略掉的 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)模块的接口之一,主要功能
因为镜像可能有不同的格式(例如,认证镜像可以是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)提供:
认证流程:
第二个:
是最新增加的认证方法,防止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需要的认证数据有哪些类型:
最后,置标志位:
递归返回后,所有的加载并认证镜像的工作完成。
本章结束。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。