在实际的诊断中我们要经常和安全访问(Security Access)打交道,为了方便的处理这些问题,写CAPL脚本是一个很好的方案,所以我整理了Vector官方提供的与安全访问(Security Access)有关的函数,并对常用的进行简单说明。
本文CAPL函数有关几乎全部摘录自Vector的官方文档,只是做了整理与翻译。
一、 介绍安全访问(Security Access)
关于ISO 14229的安全访问(Security Access)一个比较好的介绍文档: 安全访问(ISO14229系列之27服务)
当客户端连接到服务端(即ECU)时,客户端有一个会话(session)和一个安全级别(security level)。
1.1 不同的会话(Session)模式
默认情况下,服务器通过为新客户端分配默认会话(Default Session) 来迎接新客户端,在该会话中,只有少数特定服务可以访问,如读取DTC。
但是还有些操作可能涉及到安全或者其他方面的原因,不允许在默认会话(Default Session)中使用,因此如果需要更高的权限,就必须切换到其他的会话中。
在ISO14229中规定了那些服务可以在默认会话中使用,那些不可以在默认会话中使用, 如下:
如果需要从默认会话(Default Session)切换到其他会话中使用UDS的10
服务, 我们本文介绍的诊断会话(extendedDiagnosticSession) 是ISO 14229规定的必须要提供的会话模式,该会话模式代号通常是03
。 也即是说如果要切换到该会话,使用命令为10 03
.
1.2 安全访问(Security Access)的工作流程
因为诊断会话(extendedDiagnosticSession) 中包含高权限的操作,因此切换到这个会话后,必须要执行解锁(unlock) 操作才能进行后续的使用。所谓的解锁(unlock) 操作需要使用UDS提供的安全访问(Security Access)服务,也就是UDS的27服务。
0x27 安全访问(Security Access)服务的典型工作流程如下:
- Client先主动发送一个: 请求种子(Seed) 的消息
- ECU(也就是Server端)收到来自Client的请求后,ECU会发送种子(Seed)
- Client在收到ECU发送过来的种子(Seed) 后,客户端对种子(Seed)进行计算,并发送计算后的 密钥(Key)
- ECU在收到密钥(Key) 后对其进行校验,如果密钥(Key) 是有效的,那么ECU会将自己解锁,并向Client发送积极响应;否则返回否定响应
1.2.1 安全访问(Security Access)的步骤1:客户端发送请求种子(Seed)
Client端发送请求种子(Seed) 的消息格式如下:
虽然第二个参数可以是0x01
、0x03
、0x05
、0x07
等奇数,但是我们最常用的还是0x01
, 另外securityAccessDataRecord
通常为空,所以Client最常用的请求Seed的报文为:27 01
1.2.2 安全访问(Security Access)的步骤2:ECU发送种子(Seed)
ECU端在收到步骤1的请求消息后,如果请求格式正确,那么会发送积极响应,也就是发送种子(Seed) , 消息格式如下:
第2个参数一般和Client发送请求时的SubFunction
是一致的,也就是最常用的0x01
;
第3个以及后面的参数securitySeed
通常为2、4个字节。
所以ECU最常用的发送Seed的报文为:67 01 XX XX
或者67 01 XX XX XX XX
1.2.3 安全访问(Security Access)的步骤3:客户端发送密钥(Key)
Client端发送密钥(Key) 的消息格式如下:
虽然第二个参数可以是0x02
、0x04
、0x06
、0x08
等偶数(必须为发送Seed时使用的SubFunction
加1),但是我们最常用的还是0x02
, 也就是最常用的请求报文为:27 02 + securityKey
1.2.4 安全访问(Security Access)的步骤4:ECU发送最终的响应
ECU在收到密钥(Key) 后对其进行校验,于是就分为两种情况:
- 情况1: 如果密钥(Key) 是有效的,那么ECU会将自己解锁,并向Client发送积极响应。 这种情况下的报文格式比较简单,类似于上面的Table 44。 但是我们最常见的报文还是
67 02
- 情况2: 如果密钥(Key) 是无效的,返回否定响应,格式如下:
1.3 不同的安全等级(Security level)
安全等级(Security level) 是客户端通过提供安全密钥来解锁服务器内的功能而获得的状态。UDS被设计为允许多达64个安全级别,这些级别是在服务端中设置的布尔标志。
这些安全级别以及它们解锁的内容不是由UDS定义的,而是由ECU制造商定义的。安全级别可以解锁整个服务、子功能或对特定值的访问。例如,写入车辆识别码(VIN)可能需要特定的安全级别,该级别不同于写入最大速度或超越车辆IO所需的安全级别。
下图摘自ISO 14229-1, 描述了SecurityAccess处理的状态图(state chart):
上图中的1-10含义,可以参考ISO 14229-1 中的**“Table I.2 — State transitions – disjunctive normal form representation”**
在默认会话(Default Session) 中不允许解锁安全等级(Security level) 。要获得一些权限,客户端必须首先切换到启用SecurityAccess服务的非默认会话。只有这样,客户端才能执行握手,从而解锁所需的功能。
在ISO 14229中对于安全等级有两个比较重要的描述:
- 在任何时刻,只有一个安全级别处于活动(active)状态
- 安全级别(security level)编号是随意的,不同级别之间不意味着有任何关系
二、 介绍常用函数
CAPL中与CRC有关的函数如下:
Functions | Short Description |
---|---|
diagGenerateKeyFromSeed |
生成一个密钥(Key)以在ECU内执行安全的诊断功能 |
diagStartGenerateKeyFromSeed |
使用 Seed & Key DLL从种子(Seed)开始生成安全密钥(security key) |
TestWaitForGenerateKeyFromSeed |
使用配置的 Seed & Key DLL从种子(Seed)生成安全密钥(security key) |
_Diag_GenerateKeyResult |
显示使用DiagStartGenerateKeyFromSeed 启动的安全密钥计算的结果 |
补充说明:
Windows和Linux支持这些CAPL功能。Linux下的功能尚未经过全面测试。
2.1 函数: diagGenerateKeyFromSeed()
函数功能描述
创建一个密钥(key) 以在设备内执行安全的诊断功能(secured diagnostic functions)。
密钥(key) 将与设备的种子(Seed) 一起定义。
如果计算耗时超过1毫秒,则应使用:diagStartGenerateKeyFromSeed
、_Diag_GenerateKeyResult
结合来完成。
函数语法
long diagGenerateKeyFromSeed(byte seedArray[],
dword seedArraySize,
dword securityLevel,
char variant[],
char ipOption[],
byte keyArray[],
dword maxKeyArraySize,
dword& keyActualSizeOut); // form 1
long DiagGenerateKeyFromSeed(char ecuQualifier