
【AutoSAR 网络安全】SecOC1. SecOC简介1.1 SecOC 在 AUTOSAR 架构中的位置2 缩略语2.1 缩写表3 对其他模块的依赖4 SecOC功能概述4.1 SecOC的核心功能4.2 安全报文Trip CounterReset CounterMessage Counter4.3 加密算法4.3.1 对称加密4.3.2 非对称加密4.3. 3 AES-128-CMAC算法4.4 报文类型4.4.1 SecOC同步报文4.4.2 SecOC的同步请求报文4.5 SecOC通信过程Secured IPdu的发送构建Secured IPdu的接收验证4.6 FVM4.6.1 新鲜度值的构建4.6.2 FVM 接口参考资料1. SecOC简介在车载网络中CAN 总线作为常用的通讯总线之一其大部分数据是以明文方式广播发送且无认证接收。这种方案具有低成本、高性能的优势但是随着汽车网联化智能化的业务需要数据安全性被大家越来越重视。传统的针对报文添加Rolling Counter 和 Checksum的信息实现的安全性十分有限也容易被逆向破解伪造报文控制车辆。在AUTOSAR架构中对于网络安全的机制有E2EEnd to End保护另外还有SecOC主要实现对车内敏感数据信息进行认证。SecOC是在AUTOSAR软件包中添加的信息安全组件该特性增加了加解密运算密钥管理、新鲜值管理和分发等一系列功能和新要求。SecOC模块在PDU级别上为关键数据提供有效可行的身份验证机制。该规范主要使用带有消息认证码MACMessage Authentication Code的对称认证方法。与不对称方法对比他们使用更小的密钥实现了相同级别的安全性并且可以在软件和硬件中紧凑高效地实现。但是规范提供了两种必要的抽象级别因此对称和非对称身份验证方法都可使用。由于非对称加密计算量大目前主要都是采用对称加密。1.1 SecOC 在 AUTOSAR 架构中的位置更加详细一点就是① 获取完整新鲜度值由 FVM 模块实现这个是 SWC 模块实现的也就是完全由软件工程师手写代码去实现的这个没啥问题。② CMAC由加密相关模块实现也就是说对于 SecOC 功能图中右边这么多加密相关的模块目的只有一个计算 CMAC。2 缩略语2.1 缩写表Abbreviation / AcronymDescriptionCSMAUTOSAR Crypto Service ManagerSecOCSecure Onboard CommunicationMACMessage Authentication CodeFVFreshness ValueFMFreshness Manager3 对其他模块的依赖模块作用PduR路由 I-PDU连接 SecOC 与 COM、底层接口CanIf/LinIf/FrIf/EthIf底层总线接口提供收发函数Csm (Crypto Service Manager)密码服务调度MAC 生成/验证接口CryIf (Crypto Interface)加密驱动抽象层Crypto Driver (HW/SW)实际执行 AES-CMAC 等算法可借助 HSM硬件安全模块NvM (NVRAM Manager)断电存储新鲜度值防掉电后计数器回退导致重放漏洞IdsM (Intrusion Detection System Manager)接收 SecOC 上报的安全事件用于入侵检测E2E保护 (可选)功能安全相关的端到端保护可与 SecOC 叠加先加 E2E 头再作为 SecOC 原始数据保护EcuM/SchMECU状态管理与调度SecOC需要周期性调用SecOC_MainFunction处理异步操作4 SecOC功能概述4.1 SecOC的核心功能消息认证Message Authentication使用对称密钥由加密栈管理和AES-CMAC等算法为原始数据生成消息认证码MAC。接收方通过相同的密钥和输入数据重新计算MAC若与收到的MAC一致则证明报文在传输过程中未被篡改且确实来自持有合法密钥的发送方。防重放攻击Replay Protection每条受保护报文都绑定一个单调递增的新鲜度值计数器或时间戳。接收方记录上一次成功验证的新鲜度值新报文的取值必须大于该记录值允许一定跳变窗口以容忍丢帧。若新鲜度值过小或重复则判定为重放攻击并丢弃报文。新鲜度值管理Freshness Management发送方为每个安全PDU维护独立计数器每次发送时递增。接收方维护预期新鲜度值窗口。当收到报文时尝试用本地高位与报文中的截断低位合成完整新鲜度值用于MAC验证和重放校验。同步机制若因掉电、干扰等导致双方新鲜度值偏差过大超出窗口SecOC可通过预设的恢复策略如利用多次有效认证或存储于NVM的初始值重新同步。截断Truncation与可配置性为节省带宽新鲜度值可只传输其低位部分如只传1~4字节高位由接收方在本地维护。MAC也可截断为较短长度如4~16字节在安全强度与通信开销间取得平衡。元数据绑定Metadata BindingMAC的计算输入除了原始数据和完整新鲜度值外还可包含元数据如CAN ID、源/目标地址等。此功能可防止报文被拷贝到其他ID或通道上将消息与其通信属性强绑定。4.2 安全报文在SecOC标准中AUTOSAR主要基于两种手段来实现数据的真实性和完整性的校验基于MAC的身份验证和基于Freshness的防重放攻击。首先MACMessage Authentication Code是保障信息完整性和认证的密码学方法之一其中CMACCipher–based Message Authentication CodeCMAC一般用于对称加密整车厂可在车辆下线刷写程序时静态分配密钥也可选择使用云端服务器动态地给车辆分配密钥。是车载总线加密认证常用方案。MAC的作用不是防止有效数据被泄露而是为了保护数据不会被攻击方篡改即完成数据来源的认证。如需保护通信数据不被攻击方监听则报文的有效数据还需要进行额外的加密。为了降低重复攻击的风险则需要在Secured I-PDU中加入新鲜度值Freshness Value是一个根据一定逻辑不断更新的数值Freshness Value的更新方法多种多样AUTOSAR 标准将计数器或基于时间的新鲜度值作为典型选项。具体使用何种和具体的加密方式以及如何定义新鲜度度其实并不在标准之内这就给OEM有了各自定制化方案的可选余地因此OEM 在实施 SecOC 方案时需要定义和做好两个关键部分新鲜度值管理和密钥管理。安全报文由一个头和真实的I-PDU新鲜度值和用新鲜度值创建的认证器eg.MAC组成。由于SecOC机制需要占用总线带宽因此一般适用于CANFD通讯网络。其中身份验证器例如MAC是指使用密钥、安全I-PDU的数据标识符ID、真实有效负载和新鲜度值生成的唯一身份验证数据字符串。消息头可用来指明安全PDU的长度。数据结构如下Authentic I-PDU是需要被保护的数据Authenticator为认证信息通常使用消息认证码即Message Authentication Code简称MACSecured I-PDU Header为可选用的报头Freshness Value为可选用的新鲜度值。安全报文由以下元素组成报头header可用来指明安全PDU的长度真实的I-PDUAuthentic I-PDU需要被保护的数据新鲜度值Freshness Value和身份验证器Authenticator通常使用消息认证码即Message Authentication Code简称MAC由于SecOC机制需要占用总线带宽因此一般适用于CANFD通讯网络。而在实际使用中新鲜度值和MAC可能会使用较多长度的数据来提高安全性但这又会消耗大量的带宽等资源所以常使用截取的方式做平衡处理。新鲜度值和MAC都按照完整的值来生成但是在发送和认证的时候只会截取一部分。新鲜度值管理在SecOC中给出了多种新鲜度值管理方案基于Counter的递增即包含了原有方案的机制基于全局时间戳源于时间戳的唯一性基于同步的复合Counter这里我们主要谈一下第三种方案。在此方案中完整的新鲜度值包括同步计数器Trip Counter、重置计数器Reset Counter、消息计数器Message Counter和重置标志值Reset Flag。其中消息计数器又分为高值和低值而真正在报文中发送的值只包含消息计数器的低值和重置标志值。由图可见新鲜度值总共由3个部分组成①TripCounter ②ResetCounter ③MessageCounter明明图中还有最后一部分ResetFlag为啥说实际上是3部分呢因为最后面的那个ResetFlag就是指ResetCounter的低位。具体是最低的多少位则取决于客户要求有可能是最低1位也可能是最低2位。可见新鲜度值的组成是比较复杂的。因此需要有个模块专门管理这个新鲜度值于是大家常听到的FVM (Freshness Value Management) 就是指这个模块。这里需要提一嘴的是FVM并不是Autosar规范中BSW的某个模块大家可以去官网找找它是没有专门描述FVM模块的文档的。注 对于TripCounter 和ResetCounter交由master Ecu节点统一管理而作为slave Ecu节点需要从master Ecu发送的同步报文中同步这两个值。Trip Counter简单概括来说即如下几点当Trip Counter自身达到最大值时重设为初始值。(ECU首次上电也会设初始值Trip Counter初始值为0或者1。(具体是0还是1我们后面再讲当ECU唤醒、复位Trip Counter需要1。Trip Counter的最大长度是24Bit即3个Byte。所以所谓Trip Counter你可以简单理解为上电次数计数器。这里其实你就看出来了TripCnt这玩意在ECU没电的时候它是需要一直存储起来的。SecOC会涉及到存储NvM功能实际上存的就是Trip Counter。Reset Counter当TripCnt1时Reset Counter重设为初始值。Reset Counter初始值为0或者1。(具体是0还是1取决于ECU是Master还是Slave这个我们后面再讲每固定的一个时间间隔计时达到时(例如每30秒Reset Counter1Reset Counter1。Reset Counter的最大长度是24Bit即3个Byte。Message Counter当ResetCnt1或ResetCnt初始化时MsgCnt设为初始值。Message Counter初始值为0。报文发送后Message Counter 1。Message Counter的最大长度是48Bit即6个Byte。我们前面讲新鲜度值的各个组成时候提到过每个部分的最大长度但是如果都用最大长度总长度已经到10几个byte了这是不允许的因此对于不同的项目新鲜度值各个组成部分的长度是变化的。完整新鲜度值各个部分长度举例如下图所示4.3 加密算法4.3.1 对称加密对称加密算法的加密和解密使用的密匙是相同的也就是说如果通讯两方如果使用对称加密算法来加密通讯数据那么通讯双方就需要都知道这个密匙收到通讯数据后用这个密匙来解密数据。4.3.2 非对称加密非对称算法中用到的密匙有两个,分别是公匙和私匙要求通讯双方都有自己的公匙和私匙自己公匙加密的数据只有自己的私匙才能解开自己私匙加密的数据也只有自己的公匙才能解开。公匙是可以公布在网络上的相当于一个公共的电话簿可以被其他人获取到的。以一个通信的例子来说明非对称算法A 要和 B 进行通信A在网络上获取到B的公匙然后把数据用B的公匙进行加密发送给BB收到了数据后就用自己的私匙进行解密数据然后就可以看到数据内容了即使在网络传输中加密数据被黑客截取由于黑客没有对应的私匙他也无法解密数据进行查看。在通信中对称加密算法比较高效但是需要告知对方加密钥匙在实际运用时比较麻烦所以一般都是用非对称加密算法来加密对称加密算法的钥匙然后发送给对方对方收到对称加密算法的钥匙后后续通信就用对称加密算法来加密消息内容了。4.3. 3 AES-128-CMAC算法AES-128-CMAC算法是一个固定的标准算法(对称加密)。因此当我们开发完SecOC功能要测试验证就可以使用CANoe工具写测试脚本在CAPL脚本中直接调用CANoe自带的AES-128-CMAC算法接口函数。好了我们看看AES-128-CMAC算法的接口AES_128_CMACCalculate(constuint8*Key,constuint8*InputData,uint32 Datalen,uint8*CmacOut);可以看到总共有4个参数①Key②InputData③DataLen④CmacOut1、Key密钥, 实际就是一串固定16Byte的数据。在实际项目中一般车企都会对这个Key又加一层额外操作比如车企会要求最终的Key是通过原始Key、VIN码以及另外的算法算出来的。具体什么算法我们不用管车企会直接给算法代码通过这样的方式使得Key更加复杂、强度更高。2、InputData输入数据就是会参与CMAC计算的数据。①对于SecOC的安全报文来说InputData组成如下:②对于SecOC的同步报文来说InputData组成如下需要注意的是DataID一般是报文的CANID。3、DataLen即数据长度它指的是InputData的总长度。4、CmacOut即AES-128-CMAC计算输出结果。需要注意的是这个算法的计算结果长度固定是16Byte。4.4 报文类型如果每个ECU都自己管理自己的新鲜度值都以自己的新鲜度值为准。这就会导致一些问题。就以ResetCnt的计时来说总线上由数十个ECU如果每个ECU都自己计时自己的那么各个ECU的计时偏差一定是存在的ECU单次运行的越久偏差则越大。因此SecOC功能中规定新鲜度值的TripCnt和ResetCnt只由总线中固定1个ECU管理。而这个管理新鲜度值的TripCnt和ResetCnt的ECU就是主节点Master其它的ECU则是从节点Slave。4.4.1 SecOC同步报文主节点通过发送同步报文的方式告诉从节点当前的TripCnt和ResetCnt否则从节点搞不到完整的新鲜度值就要罢工了。同步报文的结构如下需要注意的是同步报文也是跟其它SecOC报文一样是需要被加密的。即跟我们前面说的SecOC报文一样同步报文也是由待校验数据 校验结果组成。同步报文中的TripCounter和ResetCounter是完整的不是截取的。关于TripCnt和ResetCntMaster和Slave的初始值是不一样。TripCnt和ResetCnt对于Master ECU初始值都是1对于Slave ECU初始值都是0。并且无论主从节点TripCnt都需要实现下电存储只要发送方不存 TripCnt所有上电前的有效报文都可以被重放接收方不存则会拒绝服务或者被重放攻击。同步报文如上图所示包含行程计数器和重置计数器以及授权码授权码由SecOC计算追加用于校验同步计数器“TripCnt |ResetCnt”值的完整性和真实性校验。行程计数器主节点每次上电、唤醒可包含复位和检测到新的通讯安全从节点加入网络通信时使发送的行程计数器 1第二帧和第三帧保持不变连发三帧间隔50ms之后按1s周期发送。发送属性根据项目需求可自定义。重置计数器同步报文每次发送第一帧时加1第二帧第三帧保持不变。同步报文发送时序图同步报文接收时序图4.4.2 SecOC的同步请求报文如果某个时刻有个Slave节点出现了BusOff并且BusOff好几分钟然后恢复了。而这个Slave节点恢复之后是需要发送或者接收SecOC报文的但是Slave节点记录着的新鲜度值早就“不新鲜”了。这可咋办Slave节点总不能先罢工干等着Master下一次发同步报文吧。因此Slave节点这时就需要主动去请求Master发同步报文。这条报文就叫做同步请求报文。至于同步请求报文的格式这个就完全看项目了。但一般情况下同步报文都是不需要进行加密的。如同步请求报文格式可以为CANID为0x450报文长度固定为8Byte0固定为0x88Byte1~Byte7固定为0x00。当Master节点收到同步请求时立即向外发送同步报文且ResetCnt1。4.5 SecOC通信过程Secured IPdu的发送构建创建一个Secured IPdu分为以下六步准备Secured IPdu分配所需buffer获取待构建数据也即Data IDAuthentic IPdu还有新鲜值生成验证码构建Secured IPdu增加新鲜值发送Secured IPduSecured IPdu的接收验证Secured IPdu的验证也分为六步解析Authentic IPdu新鲜值和验证码从新鲜值管理器获取新鲜值获取待验证数据检查验证信息给新鲜值管理器发送确认将Authentic IPdu传给上层4.6 FVM4.6.1 新鲜度值的构建先了解一下下面几个名词1、 Latest value最新的值来自于主节点的同步消息包括 TripCnt, RstCnt2.、Previous value先前的值成功发送和成功接收安全报文时维护的新鲜度值3、 Receive value接收的安全报文的值,包括 MsgCnt Lower, Reset Flag对于发送报文的新鲜值构建对于接收报文的新鲜值维护主要分为三个步骤step1 : 先比较ResetFlag判断同步消息和接收数据的关系情况数量关系 (Received Value 相对于 Latest Value)状态描述丢失同步实体 次数1Received Latest同一个 RstCycle 内正常接收数据完全同步。无丢失2Received Latest - 1RstCycle 临界点如发送方刚复位发送方还未更新计数器或线路丢帧。发送方丢失一次同步3Received Latest 1RstCycle 临界点如接收方刚复位接收方还未更新记录而发送方已正常递增。接收方丢失一次同步4Received Latest - 2发送方连续丢帧或滞后接收到的值比记录值小 2。发送方丢失两次同步5Received Latest 2接收方连续丢帧或滞后收到的值比记录值大 2。接收方丢失两次同步step2: 比较Trip counter and reset counterstep3: 比较Message counter (lower end)对接受节点的新鲜度值构造做一个总结比较接受到的Reset Flag和最新的Reset Flag获得差值X哪个节点存在同步消息丢失代入X并比较最新的TripRest和先前的TripReset判断是否更新TripReset比较接受的MsgCnt Lower和先前的MsgCnt Lower判断是否进位MsgCnt Upper4.6.2 FVM 接口Std_ReturnTypeFvm_SetTripResetSyncMsg(uint16 syncId,uint32 tripcnt,uint32 resetCnt);Std_ReturnTypeFvm_GetTripResetSyncMsg(uint16 syncId,uint32*tripCnt,uint32*resetCnt);voidFvm_ResetTripCounter(void);uint32Fvm_IncreaseTripCounter(uint16 syncId);voidFvm_Init(constFvm_RWFunc*func);typedefStd_ReturnType(*Fvm_WriteTripFunc)(uint16 tripId,uint32 tripCounter);typedefStd_ReturnType(*Fvm_ReadTripFunc)(uint16 tripId,uint32*tripCounter);uint32Fvm_GetRxMsgCnt(uint16 freshnessValueID);参考资料一文读懂 AUTOSAR SecOC 通讯