一、Sequence number的作用:
在网络安全中,重放攻击是一种技术,窃听者拦截并捕获一个或多个消息,然后在稍后重新发送它们,目的是欺骗接收者,执行攻击设备没有授权做的事情。一个经常被引用的例子是,汽车的无钥匙进入系统被攻击者破坏,拦截车主和汽车之间的认证序列,然后重播这些信息,以进入汽车并偷走它。
蓝牙mesh有保护功能,可以防止重放攻击。这种保护的基础是使用了两个网络PDU字段,分别称为序列号(SEQ)和IV索引。元素在每次发布消息时都会增加SEQ值(由SRC字段中包含的单播地址标识)。节点从包含SEQ值小于或等于最后一条有效消息中的值的元素接收消息时,将丢弃它,因为它很可能与重放攻击有关。在序列号接近最大值(0x FFFFFF)之前,元素应使用IV update(通过发送SNB的方式来同步)来更新IV index。这样做是为了确保序列号永远不会被环绕起来。
IV索引是一个单独的领域,与SEQ一起考虑。IV来自特定元素的消息中的索引值必须始终等于或大于来自该元素的最后一条有效消息。
二、IV Index
IV索引是一个32位的值,它是通过安全网络信标(SNB)在网络中共享(即网状网络中的所有节点共享相同的IV索引值,并将其用于它们所属的所有子网)。
NetKey支持多个密钥,多密钥可以用来划分网络范围,实现设备间的隔离。Key index为0的是主网络密钥,其余的都是普通的其他子网络密钥。只有主网络中的节点才能参与IV Updata Procedure,并将IV更新信息传递到其他子网中。也就是说,只有主网络节点才能更新IV index网络参数,其他子网的节点只能被动的接收IV index更新。这样不平等的网络密钥设计的目的是约束子网络节点的数据发送频次,防止子网络节点滥用IV index更新而耗尽IV index,从而导致网络安全问题。通常大部分节点在主网络中,部分节点同时处于主网络和某个子网络,少量节点只处于某个子网络,此时这些少量节点只能在子网络内进行局部通信,从而限定这些少量节点的通信范围,例如酒店顾客只能控制自己房间内的灯。
两个mesh设备进行通信时,如果其中一个设备的IV Index值变化了,那么即使appkey和netkey相同,同一个网络的其他mesh设备也无法正确的解析该设备的mesh消息(因为解密时需要network nonce,而network nonce包含了完整的IV index),但其他mesh设备仍然可以解析出它发出的 Mesh SNB消息(AD Type = 0x2B),因为SNB的加密仅仅使用BeaconKey,没有使用Network Nonce”。
三.Mesh网络IV Index更新的方式
IV index更新是通过SNB(Secure Network Beacon)消息来实现的,我们首先回顾SNB的格式:
其中IV Index字段是4字节的,包含了完整的IV Index的值。
NetworkID字段是由NetKey派生而来,标识了当前Mesh网络。
Authentication Value是对SNB整体的校验,使用的是BeaconKey,这个key也是由NetKey直接派生而来。
我们通过一个实例,解释一下IV Index是如何更新的,假设我们的Mesh网络中,有4个设备,其中包括1个Provisioner,3个Mesh node设备(1个Mesh灯,1个Mesh无线开关,1个Mesh门铃)。这四个设备首先工作在Normal Operation状态,各自发送的SNB消息中的IV index均为0x00000000,IV Update Flag为0。工作了一段时间之后,由于Mesh无线开关经常被使用,它的seq number增长的特别快,到达了0xFEFFFF,接近最大值0xFFFFFF,在Mesh无线开关的内部逻辑中,认为0xFEFFFF已经到了IV index更新的触发点了,因此它从Normal Operation状态切换到了IV Update In Process状态,它发送的SNB发生了变化,里面的IV index值变为了0x00000001,IV Update Flag变为了1。但是它仍然使用0x00000000的IV index作为network nonce来对mesh消息进行加密,所使用的seq number也仍然是0xFEFFFF + 1 (2,3,4,5,6...... + n),这样做的目的是让其他还没有来的及更新IV index的设备,也可以正确的解析到这条消息,同时作为接收端,它使用0x00000000和0x00000001来作为network nonce来解析收到的数据,这样做的目的是可以接收已经IV更新的其他设备和尚未进行IV更新的其他设备的Mesh消息。我们把从Normal Operation切换到IV Update In Process状态的时间点记做T1,这时Mesh灯和Provisioner设备收到了IV Update Flag为1,IV index为0x00000001的SNB,了解到Mesh网络中有其他设备触发了IV update,于是也从Normal Operation状态切换到IV Update In Process状态,同样开始发送更新后的SNB(IV Update Flag为1,IV index为0x00000001),接收解密和发送加密时所需要的network nonce的计算逻辑与触发IV Update的Mesh开关相同。这三个设备在经过各自的96个小时之后,从IV Update In Process状态切换回Normal Operation状态,我们标记这个时间为T2,但是SNB中的IV Index已更新到0x00000001,并且使用新的IV index作为发送需要的network nonce,使用旧的IV index和新的IV index作为network nonce来解密接收到的网络中的其他设备,值得一提的是,在T1~T2时间内,设备们使用的seq number还是原来的基础上递增的(Mesh开关在seq number 被设计为了到达了0xFEFFFF时就触发IV Update,而不是到了0xFFFFFF时才触发,根本原因是为了预留(0xFFFFFF - 0xFEFFFF)这一段的seq number给在96个小时的IV Update In Process状态下使用,在这个状态下的Mesh消息,seq number仍然在++),在IV Update结束且切换到Normal Operation之后,seq number才清零,大家从0开始递增seq number。这里面有一个逻辑是,一旦IV Update被触发,那么一定要在IV Update In Process状态下待够96个小时,进入Normal Operation状态时,也要在这个状态待够96个小时,这个时间被称为冷却时间,以上就是IV Update的过程。
下面的表格,汇总了在IV Update的过程中,几个状态的切换,和在各个状态下,所发SNB消息的内容,以及接收/发送Mesh消息所使用的IV index。
细心的读者可能会发现,Mesh门铃没有参与到IV Update的过程,那么它干嘛去了呢?原来这一阵子Mesh门铃正好没电了,错过了IV update的全过程,当它再次更换电池重启启动时,空中已经没有IV Update Flag为1,IV index为0x00000001的SNB了,大家都在使用IV index为0x00000001进行通信了,因此Mesh门铃的已经无法正确解析其他Mesh设备发过来的Mesh消息了,但是它可以解析空中的SNB消息,发现IV index已经增加了,IV Update Flag也是0了,知道自己错过了IV Update的整个过程,于是直接跳过了IV Update In Process状态,直接更换它的IV index为0x00000001,与其他Mesh设备保持了一致,这个过程就是IV Recovery过程。
上面iv index 从0x00000000变为0x00000001的例子来解释IV Recovery过程其实不是特别好,因为IV Recovery在Mesh的官方文档中,主要用在iv index相差2~42,而不是相差1,也就是离线的足够久,才必须IV Recovery。
以上面的Mesh门铃为例,当它发现周围设备SNB消息中的IV Update Flag为0,IV Index为0x00000001时,Spec定义它可以执行三种操作,任选其一:
1.直接进行IV Recovery,与IV index相差2~42相同。
2.切换到IV Update模式,待够96个小时,再切换回normal状态,与正常IV Update过程一样,相当于把欠下的债一点不差的补上,这么设计的原因我猜测是因为SNB不能relay,所以执行IV Update的话,可以把它周边的远端设备也拉过来更新。如果直接IV Recovery而没有执行IV Update的话,对由于距离远的而导致没有条件跟随“Mesh无线开关”进行IV Update的设备不友好。
3.直接忽略掉IV Index + 1的SNB,这个设计让我很不理解了,因为如果忽略掉的话,会导致这个设备只能发送Mesh消息给其他设备,而无法接收其他Mesh设备的消息。很遗憾有一些Mesh协议栈的实现是直接忽略IV Index + 1的SNB,例如zephyr。
IV 更新的相关补充:
1.只有主网络可以触发IV index更新,其他网络和主网络共享IV index。
2.IV Index Update的触发源,可以由seq number即将到期的设备触发,也可以由发现这个设备的seq number即将到期的其他设备来触发。
3.一个Mesh设备,触发IV index更新的周期不能小于192个小时(96小时normal operation状态和96小时IV Update in Process状态)。
4.小于当前IV index值,或者大于IV index + 42,则忽略。
5.一个Mesh设备,触发IV Recovery的周期不能小于192个小时。