01.概述
今天聊点比较暧昧的话题--车规MCU安全启动方案。
说暧昧,因为安全启动被芯片厂或者信息安全解决方案供应商视为核心资产的一部分;说不暧昧,因为本身方案就那么几种,拉开差距主要在启动流程的HARA\TARA分析、密钥的安全部署、存储和管理上。
我个人理解,讲清楚方案能更好地做红蓝对抗或者模糊测试,从而进一步保证安全启动。
从嵌入式角度出发,安全启动最早应用在linux系统上,全称叫secure boot;它是一种逐级验证镜像,从而实现固件可信运行。
以常见的uboot启动为例,通常要经过BootRom -> SPL -> uboot三个大阶段(其中BootRom出厂时掩膜在ROM介质中,不可更改,SPL(Secondaty Program Loader)用于初始化C语言环境等);BootRom作为信任根,会首先验证SPL代码(这里不讨论具体算法),确认SPL无误后,加载SPL代码到DDR或者SRAM;然后由SPL对uboot进行校验;方式同上,最后验证无误完成启动。
图片来源:Intel AN759
上述简述中各位发现问题没?
在传统汽车控制类ECU上,很少有加载镜像运行的方式,因为大部分程序(非座舱类)都放在Flash中,属于XIP(execute in place)范畴,同时在汽车MCU中,系统启动时间对OEM来说是一个比较严苛条件,通常要求50ms内具备接收和处理NM报文、100ms内具备外发报文的能力,所以如果沿用uboot的安全启动流程,从时间维度是完全无法满足要求。
因此针对汽车MCU的安全启动,大家有了不同方案。
02.安全启动目标
首先直奔主题,汽车安全启动目标:
(1)保证将要运行的目标代码是可信(可溯源)且完整(未破坏)
(2)保证当前ECU系统可快速安全启动;
基于上述目标,我们来依次拆解出策略:
保证代码可信且完整,常见方式有签名验证、HASH、CMAC等,因此需要HSM外设以提供上述服务;
加快安全启动速度和每次复位都要验证目标代码,因此需要高效的代码、加密引擎的硬件加速能力、可信的启动引导程序。
所以想要做好安全启动,首先有MCU中最好自带符合EVITA的HSM模块,其次在MCU内部最好有属于自己的信任根,最后在硬件上需要设计高效的host和hsm核之间交互策略,从而给软件提供了实现不同启动方式的平台。
进一步的,从产品维度来看,根据我们之前汽车ECU的开发经验,
安全启动需要保护的内容如下:
(1)用户的bootloader程序不被篡改或者破坏;
(2)用户的app程序不被篡改或者破坏;
(3)用户的敏感信息(例如VIN、整车通信密钥、里程数据等)不被篡改或者破坏;
(4)用户的ram区不执行恶意代码;
(5)HSM内部的固件不被篡改或者破坏。
同时,安全启动的需求包括:
(1)HSM固件、用户代码执行前均需要被验证;
(2)系统上电之后50-100ms内需接收NM报文和发送报文(普通报文或NM报文)。
基于上述需求和目标,我们来分析不同启动方式对系统启动效率的影响。
03.安全启动方式
根据Intel的安全启动流程,我们可以很清晰地看到它是属于一个逐级验证的过程,因此车规MCU可不可以借鉴这种启动方式呢?当然可以。
3.1 逐级验证启动
逐级验证启动,我一般叫它顺序启动,顾名思义,即按顺序验证Flash中的代码,验证成功方可进行运行代码。
那么要验证哪些代码呢?首先确定信任根--HSM 的bootrom,这个不用校验。
那么需要校验的内容就有:HSM的bootloader、HSM的App程序、应用程序的bootloader、app程序、data数据等。
具体流程示例如下:
这里面就出现了一个很矛盾的点,HSM BootRom是如何知道HSM固件、用户程序存放的位置以及对应签名或者MAC值的呢?BootRom不能改,是不是提前就得定好程序、签名、MAC存放位置?那这样风险不就又增加了,虽说大家都要签NDA。
所以,我很少看到有在BootRom里就做安全启动的;那不在BootROM里做校验,这种情况信任根和信任锚点就出现了转移。这是后话,扯远了。
回到正题,很明显,顺序启动需要将flash所有程序和数据验证完毕后,HSM才会通知Host代码运行,HSM如何快捷通知?神奇的HSM_Ready,我竟在不同芯片上都看到了,到底谁是幕后黑手?
3.2 并行启动方式
并行启动就很好描述了,Host启动HSM之后,继续运行其App代码,HSM自行启动,去验证HSM固件、HOST App代码,一旦验证不通过,HSM有权限将整个系统重启,并在一个可行环境中运行(这里其实也有绕开的办法)。
其流程如下:
这种方式启动速度很快,但是缺点也很明显,一旦运行被篡改的程序,不知道会发生什么样的危险事件,未知的才是恐惧的。
3.3 混合启动
基于上述顺序和并行启动方式的优缺点,目前还有一个启动方式,即混合启动。
混合启动的出现兼顾效率和信息安全,比如说,要快速发报文,那我就先校验通信栈,先发再说,应用程序等HSM校验完成后再运行。当然这也是一种投机倒把的技巧。
那么我们可以怎么做呢?
为满足启动速度的要求,它基于AUTOSAR 通信栈的结构层次,将Com、NM、ComM、CanIf、Can、CanSM等模块通过链接脚本单独存放在HSM的指定位置(非HSM独占的flash,这部分我简称 HSM CheckCom),其余代码则根据编译器自行存放在Flash其他位置中;
在设计时,把HSM CheckCom作为一个单独的group进行校验,当校验HSM CheckCom没问题时,直接选择通知host,host就可以跑HSM CheckCom代码,从而达到接收NM和发送Com报文的效果;
但从实际经验来看,这种方式首先需要主机厂在设计时就要考虑把这部分代码拆解出来,放在哪个位置,同时在处理NM报文时,有很多callout需要用户自定义。从实际结果看,许多AUTOSAR点点工程师对此非常痛苦。
那么到底有没有办法呢?有呀,粗犷一点,就按大的应用程序来进行校验。
从配置工具上提供校验程序的配置(我这里称之为group),例如group的起始位置和大小,group的分类、group是按照顺序启动校验还是并行启动检验;同时提供了link的配置,从根本上解决了配置困难这个问题,但是callout和callback还是需要自己定义,不过这已经是大大的进步了。
3.4 安全启动常见验证方式
上面三个小章节介绍了启动的方式,下面解析下安全启动中使用的验证方式(我也很容易搞混淆):
- MAC
Message Authentication Code,中文叫消息认证码,目的是为了验证出当前接收到的消息是否被篡改;为什么要用这个呢?因为在对称加密中,发送和接收双方密钥都是相同的,如果在消息传递过程中,密文被篡改,那么接收方解密出来的明文就存在风险了。因此,在加密的基础上,添加一个单向Hash,保证数据没有篡改。
具体做法为: 发送方将发送消息和密钥进行MAC运算,得到MAC值,并把MAC值与消息一同发送给接收方。接收方接收到消息后,将消息部分与事先共享的密钥进行MAC运算,得到MAC值,将MAC值与发送方发送的MAC值进行比较,如果一致,证明消息是来自发送方。
这样,即使密钥泄露,由于有MAC(Hash单向性),对于同一条消息,攻击者基本无法伪造出相同的MAC,从而保证该消息是正确且没有被篡改。
常见的算法有:AES-CMAC\SHA-HMAC。而随着加密引擎的硬件化,上述算法效率大大提升。
- HASH
既然上面提到的MAC属于Hash,我们来讲下Hash。
Hash就是将任意数据转换成一个固定长度的字符串,很明显,这个字符串无法反向推导出原文,因此不可逆。常见为SHA-2-256(目前 MD5 和 SHA1 已经被破解,一般推荐至少使用 SHA2-256 算法。)
- Signature
数字签名具备认证功能,采用非对称算法,发送方首先使用Hash对整个代码进行Hash计算,然后使用自己的私钥对其进行签名;接收方收到之后,首先是用发送方的公钥进行验签,然后对整个代码进行Hash计算比对。
04.小结
上文,我们详解了安全启动方式(顺序、并行、混合),分析了不同启动的优劣势;梳理了安全验证的三种不同方式:签名、Hash、MAC。
作者:快乐的肌肉
文章来源:汽车MCU软件设计
推荐阅读
更多汽车电子干货请关注汽车电子与软件专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。