Android AVB 之 avb_vbmeta_image_verify:校验vbmeta.img
总体思路:
先读header(固定256字节),算 header + auxiliary 的hash,与authentication block中存的hash比较,hash相同说明header和auxiliary部分的数据正常,没有被篡改。
avb_sha256_init(&sha256_ctx);
avb_sha256_update(&sha256_ctx, header_block, sizeof(AvbVBMetaImageHeader));
avb_sha256_update(&sha256_ctx, auxiliary_block, h.auxiliary_data_block_size);
computed_hash = avb_sha256_final(&sha256_ctx);
if (avb_safe_memcmp(authentication_block + h.hash_offset,//hash存在authentication block中
computed_hash,
h.hash_size) != 0) {
avb_error("Hash does not match!\n");
ret = AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH;
goto out;
}
再用rsa公钥(存在auxiliary block中,前面已经通过hash校验了这部分数据可信,所以用于验签的rsa公钥也可信)对signature进行验签,得到hash,最后与authentication block中的hash比较。hash相同则验签成功,说明hash和signature数据可信。也就是authentication block数据没有问题。
如此,vbmeta.img的数据就都校验完成了。那么如果整个img都是被改过的怎么办?比如恶意方用自己的rsa 私钥进行签名,公钥放到auxiliary block中,那么有可能这样的vbmeta经hash和rsa验签出来也没有问题。所以在avb_vbmeta_image_verify之后,会有个public key的确认过程。用保存在uboot中的public key来和auxiliary block中的public key比较。uboot在此前的secure boot时已经校验过,说明uboot中的public key一定是正确的。恶意方不可能改掉uboot中的public key,这样就能保证整个校验过程可信了。
verification_result = avb_rsa_verify(auxiliary_block + h.public_key_offset,//public key在auxiliary block中 h.public_key_size, authentication_block + h.signature_offset,//signature在authentication block中 h.signature_size, authentication_block + h.hash_offset,//hash在authentication block中,用于和验签出来的hash做比较 h.hash_size, algorithm->padding, algorithm->padding_len);
关于数据:
vbmeta.img分3块,256字节的header + authentication block + auxiliary block。
前面256字节的数据读出来后,根据AvbVBMetaImageHeader的定义,可以确定很多内容。
比如,authentication block和auxiliary block在img中的具体位置(后续校验和验签的时候,需要用到hash和signature,这俩值就是在authentication中的,用时就能取到了)。
再比如,hash和signature在authentication block中的具体位置,校验的时候,就直接通过offset和size拿到hash和signature的值来运算或者比较等。
还有rsa public key,该值在auxiliary block中,对signature进行验签时,需要用到该值。
vbmeta.img校验过程: