【AutoCS】汽车信息安全 -- S32K1 如何更新BOOT_MAC

文摘   2025-01-10 16:42   上海  


 目录

1.安全启动模式回顾

2.为什么要讨论BOOT_MAC

3.S32K1如何更新?


1.安全启动模式回顾

之前提到过,S32K1系列提供了Crypto Service Engine硬件加密模块(简称CSEc),大家可以通过该芯片系统寄存器SDID.FEATURES(System Device Identification Register)来判断自己的片子是否带Security。


根据RM描述,CSEc符合HIS-SHE和GM SHE+标准,因此在固件更新、数据保护、安全启动上的设计是可以通过规范窥探一二的。
我们可以在SHE规范文档4.10章节看到关于Secure Booting的需求:


 根据这个需求,CSEc提供了三种安全启动模式供用户选择:
  • Paraller Secure Boot:CSEc模块执行“安全启动”程序,同时用户应用程序也运行;值得一提的是,如果验证失败,应用程序不会停止,只是用户无法使用设置了BOOT_PROT属性的密钥;
  • Sequential Secure Boot:CSEc先执行“安全启动”程序,验证成功后才会释放Host Core执行用户程序;当然如果验证失败,Sanction与并行启动一致;
  • Strict Boot:所谓严苛的启动,就是在顺序启动基础上,新增了验证失败后CPU一直复位的Sanction。并且一旦配置了该启动模式,就不可逆了。
这里并没有我们现在经常配置的混合启动,这和芯片是否具备Secure Core、Secure NVM槽位设计有关。
我们知道,一旦出现不可逆这几个字眼,就很难为我们写代码的了,比如典型的TC3xx刷UCB稍不留神就锁板,能救回来的很少。
所以,搞清楚每块片子的启动逻辑是有道理的。

2.为什么要讨论BOOT_MAC

首先我们要明白,安全启动其实只是用于验证应用程序\数据有没有被篡改、破坏,这就是要保证数据的完整性和真实性,常见的方式就有HMAC、CMAC;在SHE的规范中提到需要使用AES128-CMAC来生成或者校验MAC值,那么在CSEc中安全启动所用算法就确定了;


其次,既然是验证MAC,那就必须有一个本次计算的MAC和预置MAC比较的动作,很明显预置MAC和对应算法所使用的密钥的安全就显得尤为重要了,因此在SHE的逻辑架构里,就专门划分了对应Secure NVM 槽位,如下图红框所示:


 一般来说,Secure NVM就只能有SHE中的控制逻辑访问,CPU、Debug、DMA等等外设都不能访问这块空间,从隔离这个角度保证了这块NVM的数据安全可靠;
但是如果用户程序在量产后进行BugFix升级,那针对用户程序的MAC值就必须同步进行修改,因此讨论BOOT_MAC的更新也是非常有必要的。

3.S32K1如何更新?

BOOT_MAC位于Secure NVM,因此肯定会出现首次为空需要添加、用户程序升级后需要更新这两种情况,我们分别来讨论。
针对首次添加BOOT_MAC到指定槽位,CSEc提供了两种方式:
  • 手动添加BOOT_MAC
  • CSEc自动添加BOOT_MAC
找到了关于CSEc使用的SDK,链接放到文后了:
具体来看看手动添加BOOT_MAC的流程:
  1. 导入BOOT_MAC_KEY到CSEc模块中的Secure NVM(其他Key也可同步导入);
  2. 送CMD_BOOT_DEFINE或者调用SDK API -- BOOT_DEFINE来定义需要计算MAC的Flash空间、定义启动模式;
  3. 使用BOOT_MAC_KEY计算上述Flash空间的MAC,可以通过加载RAM_KEY的方式进行计算;
  4. 将计算好的MAC加载到BOOT_MAC槽位中;
  5. 复位设备,CSEc会进行MAC匹配,通过FCSESTAT.BOK = 1可判断安全启动是否成功。
具体代码如下:
/* Step-2 Define the secure boot flavor and the BOOT_SIZE*/    csec_error = BOOT_DEFINE(128*1024*8, 1);    /* ----- For Automatic BOOT_MAC generation stop execution here and reset the part twice for automatic BOOT_MAC generation and verification ----- */    /* ----- For Manually set-up BOOT_MAC continue with the following steps ----- */    /* Step-3 Calculate the CMAC using RAM_KEY feature of the CSEc */    /*Load BOOT_MAC_KEY into RAM_KEY slot */  csec_error = LOAD_RAM_KEY(BOOT_MAC_KEY_VALUE);    /*Generate MAC for first 128kB data starting at memory address 0x0. */    uint32_t *flash_pointer = (uint32_t *)(0x00000000);  csec_error = MAC_SECURE_BOOT(boot_mac, flash_pointer, RAM_KEY, 128*1024*8);  /* Step-4 Store BOOT_MAC at secure location */    calculate_M1_to_M5(M1, M2, M3, M4, M5, MASTER_ECU_KEY_VALUE, boot_mac, MASTER_ECU_KEY, BOOT_MAC, 1, 0); /* Calculate M1 to M5 in Software, Authorizing Key = Master ECU Key */    csec_error = LOAD_KEY(M4_out, M5_out, M1, M2, M3, BOOT_MAC); /* Load the key using M1 to M3, returns M4 and M5 */
自动更新MAC,前置步骤相同,仅仅在Step3、4合并,全权交由CSEc进行计算和存储,不是很明白这块代码是具体怎么做的。
自动更新和手动计算MAC看起来一样,唯一区别在于,手动计算调用API时需要在数据前增加128bit的Header,格式:00...00(96bits) || BootSize(32bits),代码如下:
CSE_PRAM->RAMn[4].DATA_32 = 0;CSE_PRAM->RAMn[5].DATA_32 = 0;CSE_PRAM->RAMn[6].DATA_32 = 0;CSE_PRAM->RAMn[7].DATA_32 = message_length;
那么如果要用户程序升级后需要更新BOOT_MAC呢?这里就要分成两种情况:
  • CSEc密钥槽中的所有密钥没有设置写保护属性,可以重新擦除该区域恢复到出厂设置,然后按照首次添加BOOT_MAC进行更新,广泛用于开发阶段;
  • CSEc密钥槽任一或者多个密钥设置写保护属性,根据协议要求,该属性不可逆,密钥也不能再修改,因此只能将BOOT_MAC_KEY加载到RAM_KEY区域,然后进行计算;或者通过离线计算再根据协议进行BOOT_MAC的更新即可,一般用于ECU量产阶段。
CSEc使用的SDK链接如下: 
https://github.com/nxp-auto-support/AN5401_sw/tree/master


ArtiAuto 匠歆汽车
匠歆会展是一家全球性的活动公司,通过会议和培训向汽车制造、出行、教育、生命科学等行业的领先商业、学术、政府和研究机构提供前沿信息。旗下品牌包括匠歆汽车(ArtiAuto)、匠歆出行(ArtiMobi)、匠歆教育(ArtiEdu)等。
 最新文章