前言:
本文讲解的是比较深入一点知识,对于一些刚入门的同学,建议直接先看一遍14229规范,然后找一个实际项目练练手!然后再来看本文,相信你会对0x27服务有更深的认知!!!
进入正题!!
1、0x27服务的目的是什么?
为了保护关键数据不被篡改,故你打开任何一个主机厂的诊断调查表,你就会发现基本0x2E服务和0x23服务都是需要安全解锁后,才能写入数据。0x2F,0x34/0x35/0x36/0x37服务都会用到安全解锁服务。甚至一些0x22关键信息的提取,都需要安全解锁。
2、安全解锁的几个常见的问题
2.1、安全seed和key的长度是多少?
ISO-14229规范中,并没有规定seed和key的长度,常见的有2byte,4byte,一般是偶数字节数量的长度。
2、安全解锁的等级只能维持一种!!且解锁等级之间独立,且没有从属关系!!!
比如说 10 02 会话中,同时支持01/02解锁和03/04解锁,同一时间内,不存在两种解锁等级同时处于unlock状态。
这里有一些人存在一种基于“实际项目的一种错觉”,即“数字越大好像解锁的权限越高”,给我们造成一种错觉03/04解锁覆盖了01/02解锁。还是以上面的例子为例,1002会话下的0x2F(控制输入输出服务)只有在01/02解锁等级下,才能使用。但是在03/04解锁下,0x2F也能使用,而且还能控制0x31,添加了0x34,0x35,0x36,0x37等服务。
但是,如果项目中规定,01/02解锁状态下,能使用0x2F服务,03/04解锁不能使用0x2F服务,你也不能说他是错误的。但是一般主机厂都不这么干!!
2.3、解锁等级和服务之间的关系
同理那种解锁安全等级下,能使用那些特定的服务,14229中也没有强制规定。需由结合具体的会话确定,这些都是由主机厂规定的。
4、seed产生的随机数?
对seed产生的随机数,测试中有一项测试,就是对随机数进行检测。就是对服务器产生的随机数进行检测。其中一项就是对随机性质进行检测,就是检测产生种子的随机性。
代码如下:
假设诊断ID=0x701,
/*先获取9999次种子*/
qword ArraySeed[99999]={}; //具体看Seed的实际长度,假设是8个byte
byte i_forgetseed;
on message 0x701
{
dword count=0;
qword seed=0;
if(this.byte(1)==0x67&&this.byte(2)==0x01)
{
for(i_forgetseed=0;i_forgetseed<8;i_forgetseed++)
seed =seed + this.byte(i_forgetseed+3)<<(7-i_forgetseed)*8;
}
ArraySeed[count]=seed;
seed=0; //重新初始化为0
}
/*获取完成后,就开始比较*/
byte ComSeedArr(qword Arr_Seed)
{
dword i_max = elcount(Arr_Seed);
dword i=0;
dword i_forcmp=0;
dword Sum_SameSeed;
Sum_SameSeed =0;
for(i=0;i<i_max;i++)
{
for(i_forcmp=i+1;i_forcmp<i_max;i_forcmp++)
{
if(Arr_Seed[i]=if(Arr_Seed[i_forcmp];
{
write("存在两个种子一样,分别为第%d个 Seed=第%d个Seed",i,i_forcmp);
Sum_SameSeed++
}
}
if(Sum_SameSeed==00)
return 0; //表示没有种子相同
else
return 1; //表示存在种子相同
}
//最后,在读取完所有种子后,在合适的地方调用ComSeedArr() 函数即可
ComSeedArr[ArraySeed];
2.5、0x27服务对应的几个特殊的NRC
2.5.1)NRC: 0x35,
这个最简单就是服务端发送的key,和服务器端自己计算的key对不上,就发送这个NRC
2.5.2)NRC: 0x36 错误计数达到阈值
失败的key发送次数,主机厂定义。需要注意的是0x36NRC,存在一个前提,就是请求key的子功能,必须和请求seed的子功能一致。当同一会话下
错误示范如下:假设错误0x36触发条件=错误key被发送4次。
0x 701 02 27 01
0x 7B1 04 67 01 22 33
0x 701 04 67 02 44 55,假设44 55 是计算错误的key ,正确的key是其他值。
0x 7B1 03 7F 27 35, 表示错误key被接收
此步骤连续执行3次后,第4次执行,也就是说,发送错误计数达到=最大计数时,NRC36被触发。
0x 701 02 27 01
0x 7B1 04 67 01 22 33
0x 701 04 67 02 44 55,假设44 55 是计算错误的key ,正确的key是其他值。
0x 7B1 03 7F 27 36
但是如果第四次执行是
0x 701 02 27 01
0x 7B1 04 67 01 22 33
0x 701 04 67 04 44 55,假设44 55 是计算错误的key ,正确的key是其他值。
0x 7B1 03 7F 27 24 ,则会报出请求顺序错误
2.5.3)NRC: 0x37 错误达到阈值后,继续执行解锁服务
如上,第五次执行01/02解锁后,触发37服务。此时会触发代码内部的一个计时器,假设计时器计时为3s,在这3s时间内,再发送27 01 就会返回NRC0x37。
注意:(1)、0x35、0x36、0x37都是基于特定子服务,也就是解锁等级。如下例子说明
**1)01/02解锁中,已经触发了3次NRC0x35,此时在执行第1次错误key的03/04解锁,则会返回NRC0x35,执行第2次错误key的03/04解锁,依然会返回NRC0x35,直到第4次(假设03/04解锁触发0x36的错误次数阈值=4)。
从上面的例子可知,各种不同的解锁之间错误计数是相互独立的。因为错误key引起的拒绝访问的维持时间,也是相互独立的。
2.5.4 重置(解锁错误计数(NRC0x36)和延迟计时(NRC0x37))的方法
严格来说14229规范中只规定了,当错误计数累计到=阈值-1时,来一次正确的解锁流程,才能将“错误解锁次数计数”重置为0。
但是,实际很多项目中,0x11复位服务,也能重置“错误解锁次数计数”。这个主机厂或供应商自行决定。
而延迟计时,14229规范并没有规定重置的方法,也没有规定延时的具体时间。上文说过,具体延时时间由主机厂或零部件供应商自行设定。
那,延时有没有办法重置,了解这个问题之前先看14229规范中的一段描述。
归纳下大意:即ECU启动或者复位的时候也启用这个定时器。可以所有安全等级用同一个定时器,也可以每个安全等级都分配一个定时器。甚至,这个定时器可以是一个可变值,例如可以随着尝试失败的次数增加而增加。
但是以上描述中的“ECU启动或者复位的时候也启用这个定时器”很多实际项目中都没有去实现。测试人员可以尝试使用自动化工具实现测试,如果你能报这个bug。
实际测试中发现,0x11复位后,会重置这个值。
另外按照规范描述,复位或者下电时,错误计数和延时的值,是需要写入ERROR中去
6、种子全0,的特殊状态
6.1 什么状态下,服务器回复的seed全部是0
协议中规定,正常解锁,请求种子时,种子不能全为0。只有一种特殊情况,即“同一会话状态下,同一级别的安全解锁已经解锁过了,第二次解锁后,种子必须全0”。
实际测试时的步骤如下:
**1)先进入 10 03会话,会话状态维持在10 03会话下
**2)执行第一次01/02解锁,观察种子是否全0?全0则报错
**3)保持会话状态不跳转,执行第二次01/02解锁,这次种子必须是全0
热爱思考的同学,这是又会提出疑问 10 01 会话状态下,解锁是不是只能执行一次,就是只有一次请求的种子为非全0?,理论上是这样的,不过存在两个前提:如下
前提1:一直维持默认会话,不进行会话状态跳转,如果默认会话状态,跳转到其他会话,再从其他会话跳转到默认会话,再次请求种子,就不能是全0.
前提2:不执行断电上电操作,重新上下电后,属于再次初始化,请求的种子必须不是全0
6.2 seed全0,与NRC 0x36 NRC 0x24的关系
1、先执行3次,触发NRC35
0x 701 02 27 01
0x 7B1 04 67 01 22 33
0x 701 04 67 02 44 55,假设44 55 是计算错误的key ,正确的key是其他值。
0x 7B1 03 7F 27 35, 表示错误key被接收
2、第四次,执行一次正确的01/02解锁服务
0x 701 02 27 01
0x 7B1 04 67 01 22 33
0x 701 04 67 02 32 5A 这次“ 32 5A ”是正确的NRC
3、第五次,在执行一次错误的01/02解锁
0x 701 02 27 01
0x 7B1 04 67 01 00 00 , 此时因为上一步正确解锁后,服务器返回的种子为全0
0x 701 04 67 02 44 55,假设44 55 是计算错误的key ,正确的key是其他值。
0x 7B1 03 7F 27 24, 此时认为是请求顺序错误
从上面的例子可以看出,解锁一次成功后,是无法继续触发NRC0x36,而NRC0x37也是需要先触发0x36,才能触发NRC0x37,故0x37,在以上情况下,也是无法触发!!
7、另外一个和解锁强相关的NRC 0x33
也就是对应服务,如果在诊断文件中规定,必须要对应的安全解锁等级解锁,但是实际未解锁,就会回NRC0x33