1.什么是AES:
AES 是一种分组密码算法。基于 AES,衍生出了多种工作模式(如 ECB、CBC、CTR、CFB、OFB、GCM)用于加密,以及多种认证算法(如 CMAC、GCM)用于完整性校验。本篇文章重点讲解项目中常见的 ECB、CBC 和 CMAC,以下我只从目前项目实践中常见的算法讲解。在讲解之前我们需要了解加密和认证的区别。AES-ECB 和 AES-CBC 是加密算法,即明文使用固定的密钥和填充方式加密可以得到唯一的密文,而密文通过相同的密钥和填充方式可以还原出明文;AES-CMAC 是认证算法,它是单向性的,明文可以通过密钥计算出一个 MAC 值,但是 MAC 却不可以还原出明文。
2.它们的原理:
ECB、CBC、CMAC 每次计算都是以 128bit(16byte)为 1 Block。
ECB 模式每一块都是独立加解密:
1. 输入的明文是多大的长度(不是 16byte 的倍数会根据填充方式填充到 16byte 倍数),加密输出的密文就是多大的长度(16byte 的倍数)。
2. 输入的密文不是 16byte 倍数直接报错。
加密:
明文 P1 → AES 加密 → 密文 C1
明文 P2 → AES 加密 → 密文 C2
解密:
密文 C1 → AES 解密 → 明文 P1
密文 C2 → AES 解密 → 明文 P2
CBC 模式需要前一块的密文作为反馈。第一块明文在加密前与IV(初始化向量)异或,IV 必须随机且不可预测,且对同一密钥不应重复使用。
1.输入的明文是多大的长度(不是16byte的倍数会根据填充方式填充到16byte倍数),加密输出的密文就是多大的长度(16byte的倍数)。
2.输入的密文不是16byte倍数直接报错。
加密:
明文 P1→ 与 IV 异或 → AES 加密 → 密文 C1
明文 P2 → 与 C1 异或 → AES 加密 → 密文 C2
明文 P3 → 与 C2 异或 → AES 加密 → 密文 C3
解密:
密文 C1 → AES 解密 → 与 IV 异或 → 明文 P1
密文 C2→ AES 解密 → 与 C1 异或 → 明文 P2
密文 C3→ AES 解密 → 与 C2 异或 → 明文 P3
CMAC模式是基于CBC模式的消息认证
无论输入长度多大,标准输出128bit(16字节)的认证值,但实际使用中常根据协议要求截断(如截取前8字节或6字节)或不截断
3.它们的使用场景:
在项目中,ECB和CBC使用得很少,主要是CMAC用得多
ECB和CBC主要在SHE密钥注入的时候会使用到,这是另外一个章节了,想具体了解的可以自行查看,我只讲简要的:在SHE规范中,密钥是非常重要的,它在传输过程中一定是要严格保密的,所以SHE密钥注入孕育而出。在注入密钥的时候AES-CBC参与到M2的计算。M2的明文结构为:28bit CID + 5bit FID + 95bit 0 + 128bit LoadKey,共256bit。使用派生密钥K1以IV=0进行AES-CBC加密,得到M2,并做为上位机发送的一部分发送给ECU;AES-ECB参与到M4的计算。M4P的明文结构为:28bit CID + 1bit固定值1 + 99bit 0,共128bit。使用派生密钥K3进行AES-ECB加密,得到M4,并做为ECU返回验证的一部分发送给上位机。
CMAC在项目中使用得非常多:
1.安全诊断27服务:
1)上位机通过27服务发送解锁请求,MCU收到上位机请求后通过HSM随机生成16byte的种子Seed,并返回挑战种子。
2)上位机收到种子Seed后,使用AES-27-Key通过AES-CMAC算法计算出认证值CMAC,并发送认证值CMAC到MCU。
3)MCU使用AES-27-Key通过AES-CMAC算法计算出认证值CMAC,对比是否一致。
2.基于对称算法方案的安全启动:以下安全启动方案与标准方案有所区别,只是我目前接触到项目的使用方案
1) 步骤一:系统复位后,MCU开始启动。Host 核心发送 PBL 的启动地址和大小给 HSM。HSM 通过 AES_KEY 计算 PBL 的MAC 值,并与存储的 PBL MAC 对比一致从而判断是否校验通过。
a)校验通过,则进行步骤二。
b)检验失败,则启动失败。
2)步骤二:HSM将比较结果返还Host,Host执行PBL程序,PBL发送SBL的启动地址和大小给HSM。HSM通过AES_KEY使用算法计算SBL的MAC值,并与存储的 SBL MAC 对比一致从而判断是否校验通过
a)校验通过,则进行步骤三。
b)检验失败,则启动失败。
3)步骤三:HSM将比较结果返还PBL,PBL执行SBL程序,并发送APP 的启动地址和大小给HSM。HSM通过AES_KEY使用算法计算APP的MAC值,并与存储的 APP MAC 对比一致从而判断是否校验通过
a)校验通过,MCU执行APP程序。
b)检验失败,则启动失败。
3.安全日志:
安全日志应当缓存或存储事件及信息,以支持正确的故障和调试分析,识别并分析系统如何受到危害,追溯攻击者的行为
安全日志使用AES-128-CMAC算法计算(时间戳,事件类型,事件标号,事件计数器)的MAC值(截取前六字节),并将它们存储到EEPROM里面
4.SECOC:
因为SECOC这一块我们没有用到,所以就不做详细讲解,它里面涉及的模块非常多,我只讲最主要的: AES-CMAC参与计算CAN ID+原始PDU数据+完整新鲜度值的MAC,并截断MAC值参与发送到总线上
4.常用API以及参数:
下面我是基于NXP HSE讲解AES里面常用的API
accessMode:决定这次调用是单次完成还是流式处理的一步
ONE-PASS模式:一次调用完成全部计算
流模式:
Start:流模式第一步,初始化上下文
Update:流模式中间步,喂数据块(可多次)
Finish:流模式最后一步,输出Tag
streamId:流标识符,用于把Start/Update/Finish多次调用关联到同一个流上下文
macScheme:MAC算法,有CMAC,HMAC,GMAC
keyHandle:密钥句柄,指定用哪个密钥来计算 MAC
inputLength:消息总长度
pInput:指向的消息
pTagLength:输出标签的长度
pTag:输出标签缓冲区的地址
inputSgtType:分散/聚集选项,决定pInput是普通指针还是SGT 列表。
返回值:计算是否成功
5.项目避坑
因为我们是手写的CSM这些模块,不是用工具自动生成的,所以或多或少都会出现一些坑,但这也是一件好事,因为它巩固了我对HSM的理解:
- HOST与HSM传输的内容一定要定义在共享内存里面,不然HOST传输过去的地址在HSM那边不可访问的话,HSM无法得到正确的结果;同样HSM输出的结果不在共享内存的话,HOST端也不能得到正确的结果