1.UDS-10.4 SecurityAccess (27) service
2.Unix Domain Socket 内核数据结构整理
3.S32K324 UDS Bootloader开发-下位机篇-FlashDriver的基于制作
UDS-10.4 SecurityAccess (27) service
来自:ISO -1-.pdf
安全访问()服务的目的是提供一种访问数据和/或诊断服务的方法,特别是源码源代当这些服务出于安全、排放或安全原因被限制访问时。基于诊断服务如例程或数据下载/上传到服务器,源码源代以及从服务器读取特定内存位置,基于是源码源代arch 源码可能需要安全访问的典型情况。不当的基于程序或数据下载到服务器可能导致电子设备或车辆部件受损,危害排放、源码源代安全或安保标准。基于安全概念通过种子和密钥的源码源代关系实现。例如,基于使用这项服务的源码源代典型情况如下:'requestSeed'子功能参数值总是奇数,与相同安全级别的基于' sendKey'子功能参数值的关系是,后者等于前者加一。源码源代
任何时候只有一个安全级别处于活动状态。基于例如,如果与requestSeed 相关联的安全级别是活动的,并且测试者请求成功解锁与requestSeed 相关联的安全级别,那么只有与requestSeed 相关联的安全级别所支持的安全功能将被解锁。之前由与requestSeed 关联的安全级别解锁的任何额外安全功能都将不再激活。安全级别编号是任意的,与级别之间的关系无关。
客户端通过发送服务SecurityAccess 'requestSeed'消息请求服务器“解锁”。服务器应响应此消息通过发送一个“种子”来回应。然后,无线继电器源码客户端将通过使用适当的服务SecurityAccess 'sendKey'请求消息返回一个“密钥”给服务器。服务器将此“密钥”与内部存储/计算的“密钥”进行比较。如果两个数字匹配,服务器将启用客户端对特定服务/数据的访问,并通过服务SecurityAccess 'sendKey'积极响应消息指示。如果两个号码不匹配,则被视为一次错误的访问尝试。无效的密钥将要求客户端重新开始使用SecurityAccess 'requestSeed'消息,如附件I所述。关于安全访问处理细节的其他说明在附件I中规定。
如果服务器支持安全访问,但在接收SecurityAccess 'requestSeed'消息时请求的安全级别已解锁,服务器应响应SecurityAccess 'requestSeed'消息,其种子值为零(0)。服务器永远不会为当前锁定的给定安全级别发送全零种子。客户端应使用此方法通过检查非零种子来确定服务器是否针对特定安全级别被锁定。
服务器在上电/重置后,以及在一定次数的错误访问尝试之后(参见下面的进一步描述),可能需要车辆制造商特定的时间延迟来响应来自客户端的SecurityAccess 'requestSeed'消息。如果支持此延迟定时器,则在达到车辆制造商指定的错误访问尝试次数之后,或者当服务器上电/重置并且之前执行的SecurityAccess服务由于一次错误访问尝试而失败时,将激活延迟。如果服务器支持延迟定时器,视觉运动框架源码在sendKey成功执行后,服务器应清除上电/重置时延迟定时器调用的服务器内部指示信息。如果服务器支持延迟定时器,并且无法确定在上电/重置之前执行的SecurityAccess服务是否失败,则延迟定时器应在上电/重置后始终处于活动状态。只有当服务器在上电/重置时被锁定时才需要延迟。车辆制造商应选择是否支持延迟计时器。
安全系统的访问不应妨碍正常的车辆通信或其他诊断通信。如果在服务器被锁定时请求安全服务,提供安全性的服务器应该支持拒绝消息。在特定诊断会话期间请求的某些诊断功能/服务可能需要一个成功的安全访问序列。在这种情况下,应要求下列服务顺序:服务器中启用的诊断会话(会话启动)允许使用不同的accessModes。重要:服务器和客户端必须满足8.7中规定的请求和响应消息行为。
请求消息定义如下:
表指定了请求消息定义- SubFunction = requestSeed。
表指定了请求消息定义- SubFunction = sendKey。
请求消息子函数参数$Level (LEV_)定义如下:SubFunction参数securityAccessType向服务器指示该服务正在进行的步骤、客户端希望访问的安全级别以及种子和密钥的格式。如果服务器支持不同级别的安全,则每个级别都由requestSeed值标识,该值与sendKey值有固定的关系。requestSeed和sendKey的值在表中定义(suppressPosRspMsgIndicationBit(位7)未显示)。
注: - :ISOSAEReserved(ISOSAERESRVD),此值为本文档保留。经典cci公式源码 - :requestSeed(RSD),使用汽车制造商定义的安全级别RequestSeed。 - :sendKey(SK),使用汽车制造商定义的安全级别的SendKey。 - , , 到:requestSeed(RSD),RequestSeed与汽车制造商定义的不同安全级别。 - 、、到:sendKey(SK),由汽车制造商定义的不同安全级别的SendKey。 - 到5E:ISOSAEReserved(ISOSAERESRVD),此值由本文档保留,以供将来定义。 - 5F:ISO-2值(RSD),为ISO -2中定义的机载烟火装置的寿命结束激活定义了不同安全级别的种子。 - :ISO-2 sendKey值(SK),SendKey具有不同级别的安全定义,用于ISO -2中定义的机载烟火装置的寿命结束激活。 - 到7E:systemSupplierSpecific(SSS),这个范围的值是为系统供应商特定的使用而保留的。 - 7F:ISOSAEReserved(ISOSAERESRVD),此值由本文档保留,以供将来定义。
请求消息数据参数定义如下:表指定请求消息的什么是源码搭建数据参数。
注: - securityKey(高字节和低字节):请求消息中的“Key”参数是由安全算法生成的值,对应于特定的“Seed”值。 - securityAccessDataRecord:此参数记录是用户可选的,用于在请求种子信息时向服务器传输数据。例如,它可以包含在服务器中验证的客户机标识。
响应消息定义如下:
表指定了积极响应消息。
注: - #1:安全访问响应服务标识符(SAPR),值为[] - #2:子功能= [安全访问类型](LEV_SAT_SK),值为[-7F] - #3,...,#n:安全种子[] = [种子#1(高字节),...,种子#m(低字节)](SECSEED_SEED1HB,...,SECSEED_SEEDmLB),值为[到FF,...,到FF] - C:该参数的存在取决于参数securityAccessType。如果securityAccessType参数表示客户端希望从服务器检索种子,则必须出现该参数。
响应消息数据参数定义如下:表指定响应消息的数据参数。
- securityAccessType:该参数是请求消息中SubFunction参数的第6位到第0位的回显。
- securitySeed(高字节和低字节):seed参数是服务器发送的数据值,客户端在计算访问安全性所需的密钥时使用它。只有在发送请求消息时,SubFunction设置为请求服务器种子的值,securitySeed数据字节才会出现在响应消息中。
支持的消极响应码如下:表记录了每个响应代码发生的情况。如果错误场景适用于服务器,则列出的否定响应应使用。 |NRC| 描述 |助记符| |--|:--|:--| | | SubFunctionNotSupported:如果SubFunction参数不支持,将发送此NRC。 | SFNS| | | incorrectMessageLengthOrInvalidFormat:如果信息长度错误,则应发送此NRC。 | IMLOIF| | | conditionsNotCorrect:如果不满足安全访问请求的标准,则该NRC将被返回。 | CNC| | | requestSequenceError:如果sendKey子函数没有先接收到requestSeed请求消息,则发送。 | RSE| | | requestOutOfRange:如果用户可选的securityAccessDataRecord包含无效数据,将发送此NRC。 | ROOR| | | invalidKey:如果接收到期望的sendKey子函数值,该键的值与服务器内部存储/计算的键不匹配,并且延迟计时器不被此请求激活。 | IK| | | exceededNumberOfAttempts:如果接收到一个期望的' sendKey '子函数,密钥的值与服务器内部存储/计算的密钥不匹配,并且延迟计时器被这个请求激活(即由于达到了激活延迟计时器的错误访问尝试的限制)。 | ENOA| | | requiredTimeDelayNotExpired:如果接收到requestSeed子函数,并且延迟定时器为所请求的安全级别激活,则发送。 | RTDNE|
消息流举例:SecurityAccess如下:
假设服务器处于“锁定”状态,以下条件可以成功解锁: - SubFunction请求种子: (requestSeed) - 子函数发送密钥: (sendKey) - 服务器的种子(2字节): - 服务器的密钥(2字节):C9A9(例如,2的种子值的补码)
通过将suppressPosRspMsgIndicationBit (SubFunction参数的第7位)设置为"FALSE"('0'),客户端请求有一个响应消息。
例1 - server处于“locked”状态
步骤#1:请求种子
表指定了SecurityAccess请求消息流示例#1 -步骤#1。
步骤#2:发送密钥
表指定了SecurityAccess请求消息流示例#1 -步骤#2。
例2 - server处于“未锁定”状态
步骤#1: 请求种子
表指定了SecurityAccess请求消息流示例#2 -步骤#1。
步骤#2: 正向响应消息
表指定了SecurityAccess正向响应消息流示例#2 -步骤#2。
Unix Domain Socket 内核数据结构整理
整理Unix Domain Socket(UDS)在Linux内核(4.9)的数据结构,重点关注af_unix.c文件。创建socket时,会调用unix_family_ops数据结构。socket(2)系统调用根据AF_UNIX/PF_UNIX定位此结构,并调用其unix_create函数。创建函数主要完成两步:设置socket.ops和创建unix_sock结构。UDS操作基于此结构定义,代码相对简单。详细解析如下:
以创建SOCK_STREAM类型为例,unix_create函数负责设置socket的操作并初始化unix_sock结构。UDS操作几乎都在此结构上进行。
窥探代码细节,以unix_stream_connect函数为例,实现连接过程。用户层使用UDS连接,内核实现逻辑简单。connect操作过程直接,无TCP的复杂三次握手。
Client尝试连接后,sk_buff放入Server接收队列。Server进程阻塞中,通过unix_accept函数处理连接请求。函数内首先从接收队列获取sk_buff,然后通过sock_graft接口将tsk信息赋值给newsock。
连接成功后,Client和Server开始通信,使用write(2)进行数据发送。内核中调用unix_stream_sendmsg函数,循环发送数据至对端。计算发送量,控制在发送缓冲区大小的一半,并与特定值比较取最小值。数据拷贝至skb并插入接收队列,通知对端数据就绪。
综上,通过解析Unix Domain Socket的内核数据结构和操作流程,可以看出UDS在Linux内核中的简洁高效实现,适用于进程间通信,提供了一种快速、低延迟的数据传输机制。
SK UDS Bootloader开发-下位机篇-FlashDriver的制作
本文详细介绍了如何为SK UDS Bootloader开发制作Flash Driver的过程。首先,我们回顾了上一篇文章中对 SK UDS Bootlodaer 开发中UDS相关更改的介绍,并指出本文将着重于Flash Driver的制作。
参考NXP官网提供的SK UBL,发现其中的FlashDriver并未包含Flash擦除和写入的函数,仅涉及寄存器配置的修改。这导致,在Flash Driver未写入时,调用Flash擦除和写入功能无法实现预期效果。因此,实际的FlashDriver功能仅由C_Ip_StartSequence函数实现。
针对ld文件配置,考虑到FlashDriver应放置在起始地址为0x的RAM区域,boot程序中的配置与之对应。通过判断Flash_IsFlashDriverSoftwareData,确保FlashDriver的位置及大小正确。
在bootloader中加入FlashDriver代码,并通过编译、使用hexview提取函数地址,完成代码生成。在main函数中调用该函数以确保FlashDriver功能实现。提取出对应的ram区域的hex文件后,FlashDriver即制作完成。
为了正确使用FlashDriver,实际函数中在初始化阶段调用C_Ip_StartSequenceInit获取RAM区域地址。同时,对C_IP.c进行修改,增加宏定义与初始化获取RAM区域的函数。此外,还需对C_Ip_MainInterfaceSectorErase和C_Ip_MainInterfaceWrite函数进行相应的修改。
在处理FLASH_HAL_WriteData函数的bug时,通过修正第行代码,解决了潜在问题。至此,FlashDriver的制作与使用流程完成。
最后,本文总结了关于FlashDriver提取与使用的关键点,并预告了后续内容将涉及Bootloader调试中的修改点以及APP的实现。若有帮助,请点赞、关注、收藏或转发,您的鼓励是对我最大的支持。欢迎加入《汽车电子学习笔记》的微信公众号,文章内容将同步更新。