|
汽车零部件采购、销售通信录 填写你的培训需求,我们帮你找 招募汽车专业培训老师
前言
本文参考连接如下:
https://www.autosar.org/fileadmin/standards/R23-11/FO/AUTOSAR_FO_TR_SecureHardwareExtensions.pdf
链接是安全硬件的一部分规范,在这份规范中,有一个CMD_LOAD_KEY函数,整个函数的处理流程巨巨巨复杂,本文仅是就这个函数,仔细分析。
CMD_LOAD_KEY函数定义
如上图所示,这个函数是为了将密钥注入到Secure Hardware中的标准函数接。
此函数有5个入参,分别是M1,M2,M3,M4,M5。其中M1,M2,M3是Input,M4,M5是Output。函数返回值表征函数调用的过程中是否报错。
在CMD_LOAD_KEY函数调用之前,需要提前计算好M1,M2,M3。在CMD_LOAD_KEY调用之后,需要验证函数的输出M4,M5。
名词解释
UID:Unique identification, 120 Bits。表征ECU的全局唯一的ID号,每一个ECU均不一样。
MASTER_ECU_KEY:AES128算法的ECU主密钥,128 Bits。
Memory Slot:内存槽,用于存储AES128算法的密钥
KeyID:AES128算法密钥的Memory Slot ID号。ID详细信息见下图。
CID:密钥的计数器值,28 Bits。
FID:密钥的Flags值,5 Bits。详细信息如下图所示。
KEY_UPDATE_ENC_C:16字节的常量。用于加密解密密钥的生成。
KEY_UPDATE_MAC_C:16字节的常量。用于AES128_CMAC算法密钥的生成。
LoadKey/NewKey:需要更新的AES128算法的密钥值
AuthKey:对LoadKey/NewKey实现认证的密钥,一般是Master Key。
LoadKeyID:LoadKey/NewKey的Memory ID。
AuthKeyID:AuthKey的Memory ID。
IV:AES128算法初始化向量表。
ECB/CBC/CMAC:AES128算法的模式。
KDF:Key derivations。
AES_MP:基于AES算法的Miyaguchi-Preneel压缩算法
K1/K2/K3/K4:使用KDF算法生成的AES128算法密钥
上位机:与SHE通信的设备。
下位机:SHE。
上位机密钥注入SHE全过程
M1的计算
M1的计算运行在上位机中,M1 = UID|LoadKeyID|AuthKeyID的组合。M1总长16字节。
MSB ---------------------->>>> LSB
Bit16*8 -1 -------->>>>---------------Bit 0
UID等于Bit 16*8-1 ~ Bit8。
Bit7~4等于LoadKey ID。
Bit3~0等于AuthKey ID。
在计算M1时,需要提前在上位机中知道UID, LoadKey ID, AuthKey ID。即需要知道往哪个SHE硬件(UID)中的哪个一个密钥槽(LoadKey ID)写入密钥。写入的密钥用哪个密钥槽的密钥(AuthKey ID)进行加密。
K1的计算
K1的计算运行在上位机中,K1的计算采用AuthKey和KEY_UPDATE_ENC_C,基于AES_MP/KDF算法,得到K1。K1总长16字节。
在计算K1时,需要提前知道SHE中的AuthKey ID中对应的密钥值(AuthKey)。
M2的计算
M2的计算运行在上位机中,采用AES128_CBC算法进行加密,密钥为K1,IV值为0。明文数据为:从MSB到LSB的数据依次为:28 Bits的CID,5 Bits的FID,95 Bits的0,128Bits 的LoadKey。明文数据总计32字节。
加密之后得到32字节的密文数据,此密文数据即是M2。
K2的计算
K2的计算运行在上位机中,K2的计算采用AuthKey和KEY_UPDATE_MAC_C,基于AES_MP算法,得到K2。K2总长16字节。
在计算K2时,需要提前知道SHE中的AuthKey ID中对应的密钥值(AuthKey)。
M3的计算
M3的计算运行在上位机中,采用AES128_CMAC算法进行加密,密钥为K2。明文数据为:从MSB到LSB的数据依次为:16字节M1,32字节的M2。明文数据总计48字节。
计算CMAC之后得到16字节的MAC值,此MAC值即是M3。
K3的计算
K3的计算运行在上位机中,K3的计算采用LoadKey和KEY_UPDATE_ENC_C,基于AES_MP算法,得到K3。K3总长16字节。
M4的验证
当调用CMD_LOAD_KEY函数之后,上位机将获得函数的输出值M4。上位机需要验证这个M4的正确性。
M4的0~15字节为M1。M4的16~31字节验证计算运行在上位机中,采用AES128_ECB算法进行加密,密钥为K3。明文数据为:从MSB到LSB的数据依次为:120 Bits CID,1 Bit 的1,7Bits的0。明文数据总计16字节。
加密之后得到16字节的密文数据,此密文数据即是M4的16~31字节。
将计算得到的数据M4与接口获取的M4进行比较,进而验证密钥注入过程的正确性。
K4的计算
K4的计算运行在上位机中,K4的计算采用LoadKey和KEY_UPDATE_MAC_C,基于AES_MP算法,得到K4。K4总长16字节。
M5的验证
M5的验证计算运行在上位机中,采用AES128_CMAC算法进行加密,密钥为K4。明文数据为:从MSB到LSB的数据依次为:16字节M4。明文数据总计16字节。
计算CMAC之后得到16字节的MAC值,此MAC值即是M5。
将计算得到的M5与函数返回的M5进行比较,进而验证密钥注入过程的正确性。
下位机密钥注入SHE全过程
如上图所示,SHE中收到上位机发送过来的M1,M2,M3值,对其进行验证并将CID,FID以及LoadKey更新进存储中,并计算M4,M5,发送会上位机。
M1的解析
M1在下位机中完成解析,解析之后得到上位机发送过来的UID,上位机发送过来的AuthKey ID, 上位机发送过来的LoadKey ID。
比较上位机发送过来的UID和下位机存储的UID是否相等。验证LoadKey ID对应的FID是否有写保护(WRITE_PROTECTION)。
根据AuthKey ID可以把存储在下位机中的Auth Key读取出来。
因此,M1解析完成之后,得到UID,LoadKey ID,AuthKey ID, Auth Key。
M3的验证
M1解析完成之后,就有了AuthKey,就可以计算K2。有了K2,使用AES128_CMAC算法就可以验证M3。
根据上位机M3的计算的描述过程可以得到下位机的M3,将其与上位机发过来的M3进行比较,就可以验证M3的正确性。
M2的解析
M1解析完成之后,就有了AuthKey,就可以计算K1。有了K1,使用AES128_ECB算法就可以解密M2。
M2的解密计算运行在下位机中,采用AES128_CBC算法进行解密,密钥为K1,IV值为0。密文数据为:32字节的M2。密文数据总计32字节。
解密之后得到32字节的明文数据,对明文数据进行解析,可以得到上位机设置的CID,上位机设置的FID,上位机设置的LoadKey。
若上位机设置的CID大于当前下位机存储的LoadKey所对应的CID值,则存储上位机设置的CID,上位机设置的FID,上位机设置的LoadKey。
K3和K4的计算
有了M2解析得到的LoadKey,则可以计算K3和K4。
M4的计算
重新从存储中读取UID,CID,AuthKey ID,LoadKeyID,并且重新计算M1。
M4的0~15字节为重新计算的M1。M4的16~31字节计算运行在下位机中,采用AES128_ECB算法进行加密,密钥为K3。明文数据为:从MSB到LSB的数据依次为:120 Bits CID,1 Bit 的1,7Bits的0。明文数据总计16字节。
加密之后得到16字节的密文数据,此密文数据即是M4的16~31字节。
M5的计算
M5的计算运行在下位机中,采用AES128_CMAC算法进行加密,密钥为K4。明文数据为:从MSB到LSB的数据依次为:16字节M4。明文数据总计16字节。
计算CMAC之后得到16字节的MAC值,此MAC值即是M5。
KDF生成原理
KDF或者AES_MP采用基于AES算法的Miyaguchi-Preneel压缩算法生成密钥。
Miyaguchi-Preneel压缩算法原理
Miyaguchi-Preneel压缩算法原理如下:
所需要计算的数据为M,长度为Y个Bit位。对数据M进行填充,填充的数据规则如下从MSB到LSB分别为
1 Bit 1,X个Bit位的0,Y占据40个Bit。
X和Y满足方程:
((Y+1+X)%128 )== (88%128),其中Y为最小正整数。
此问题是一个数论问题。则当Y%128大于87时,X=(87+128-Y%128)。当Y%128小于等于87时,X=(87-Y%128)。
例如M为0x6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51,总计256 Bits。
因此,计算得到X等于87。因此,得到的填充值为:
1,87个Bit的0,最后40Bit为0x0000000100(256)。
即0x80000000000000000000000000000100。
因此需要压缩的明文数据为:X1=0x6bc1bee22e409f96e93d7e117393172a X2=0xae2d8a571e03ac9c9eb76fac45af8e51
X3=0x80000000000000000000000000000100
压缩步骤如下:
采用AES128_ECB算法,按16字节为1块进行加密。
初始化密钥OUT0为0。
第一步:使用OUT0加密X1,将结果与OUT0和X1进行异或,得到OUT1。
第二步:使用OUT1加密X2,将结果与OUT1和X2进行异或,得到OUT2。
第三步:使用OUT2加密X3,将结果与OUT2和X3进行异或,得到OUT3。
即例子结果等于:0xc7277a0dc1fb853b5f4d9cbd26be40c6。
KDF计算原理
实际上CMD_LOAD_KEY函数中所计算得到的K1,K2,K3和K4。输入均是16字节的密钥和16字节的常数。
因此,X1=16字节的密钥,X2等于16字节的常数。
按照Miyaguchi-Preneel压缩算法原理中的压缩步骤所描述的那样。初始化密钥OUT0为0。
第一步:使用OUT0加密X1(16字节的密钥),将结果与OUT0和X1进行异或,得到OUT1。
第二步:使用OUT1加密X2(常量),将结果与OUT1和X2进行异或,得到OUT2。
OUT2就是此处的K1或者K2或者K3或者K4。 |
|