当读者读到该章节的内容时,这也意味着红旭的SIG Mesh的文字教程也要接近尾声,但这同样也表示新的视频教程将会很快到来;
其实,类似的内容,小编在Configuration Model浅析.Key Refresh Phase也有所提及,接下来让小编带着读者们看看SIG MESH是如何基于现有的密钥进行NetKey以及AppKey更新的;
在开始讲解密钥更新流程,读者们是不是有这样的疑问?
密钥更新的发起者是谁?普通的节点能不能发起密钥更新流程?
关于这一点,Mesh Spec中已经明文规定:
Key Refresh Phase的发起者必须是Configuration Client,而具备此模型的大多是Provisioner,至于什么是Configuration Client?则可以参考Configuration Model浅析的内容
至于,密钥更新的流程如下图所示:
从上图可知,它们的转换关系如下所示:
Old State | Transition | New State | Description |
---|---|---|---|
0x00 | 0x03 | 0x00 | Transition 3 from Key Refresh Phase 0x00 does not cause any state change |
0x01 | 0x02 | 0x02 | Transition 2 from Key Refresh Phase 0x01 moves to Key Refresh Phase 0x02 |
0x01 | 0x03 | 0x00 | Transition 3 from Key Refresh Phase 0x01 invokes Key Refresh Phase 3 and then moves to Key Refresh Phase 0x00 |
0x02 | 0x02 | 0x02 | Transition 2 from Key Refresh Phase 0x02 does not cause any state change |
0x02 | 0x03 | 0x00 | Transition 3 from Key Refresh Phase 0x02 invokes Key Refresh Phase 3 and then moves to Key Refresh Phase 0x00 |
除此之外,上图所示的阶段过渡以及触发条件而言,这个是相对比较好理解的;但是,读者们是不是仍然有很多下述的疑问:
在密钥更新中,各个阶段所做的事情又有哪些呢?具体如下:
Phase 0
此时表示密钥更新已经完成或者密钥更新流程还没有被激活,这是一个正常工作的阶段
Phase 1
分发新的密钥,包括NetKey和AppKey;需要注意的是:
NetKey
AppKey
Phase2
所有的Mesh数据包切换至新的密钥加密并发送出去
Phase3
摒弃旧的密钥,此时所有数据的收发均采用新的密钥,然后回归到Phase0
上述的内容,可以浓缩成下述的图:
至于如何判断当前处于哪个阶段,从上面的图示可知,密钥更新的各阶段对于发起者和接收者的判断如下:
Phase 1
发起者
当NetKey Update命令发送成功了,就处于阶段1
接收者
当NetKey Update命令接收成功了,就处于阶段1
Phase2
发起者
当Config Key Refresh Phase2 Set命令发送成功或者Key Refresh flag为1的Secure Network Beacon发送成功,就处于阶段2
接收者
当Config Key Refresh Phase2 Set命令或者Key Refresh flag为1的Secure Network Beacon或者Friend Update接收成功,就处于阶段2
Phase3
发起者
当Config Key Refresh Phase3 Set命令发送成功或者将Key Refresh flag从1变成0的Secure Network Beacon发送成功,就处于阶段3
接收者
当Config Key Refresh Phase3 Set命令或者Key Refresh flag为0的Secure Network Beacon和Friend Update接收成功,就处于阶段3
但是阶段3是瞬态的,当旧的密钥被清除时,就又回到阶段0;这也就是说,阶段3只是一个临时的阶段,换句话说当读取当前的阶段值时,只能是Phase1和Phase2以及Phase0,具体的如下表所示:
Value | Description |
---|---|
0x00 | Normal operation; Key Refresh procedure is not active |
0x01 | First phase of Key Refresh procedure |
0x02 | Second phase of Key Refresh procedure |
0x03–0xFF | Prohibited |
与小编在上述提及到的内容那样,密钥的更新请求是由Configuration Client发起的,那么它又是如何决定其可以切换至下一个阶段的呢?接下来就让大家瞧瞧:
当旧的密钥从Client中删除之后,其直接从Phase3回到Phase0,不需要专门的命令或者Secure Network Beacon
当Client发送完Config NetKey Update命令时,就从Phase0进入Phase1了,得益于Config NetKey Update是一个带应答的命令,所以当Client向未在黑名单的目标地址,发送该条命令之后,如果均得到了正确的回应,那么CLient端就认为Phase1完成,随时可以切换到Phase2
当Client发送Key Refresh Flag为1的Secure Network Beacon或者Config Key Refresh Phase2 Set出去时,其已经从Phase1切换至Phase2;问题的难点在于:其中“Secure Network Beacon不是一个带应答的消息,Client没有办法知道Server是不是已经收到Secure Network Beacon”;那么这个时候,Client应该何时切换至Phase3呢?解决的方法很简单:既然没办法知道,那就无须知道;当Client接收到Key Refresh Flag为0的Secure Network Beacon时,即可随时切换到Phase3;那么这个时候有读者就会问:这么随便?难道这样不会出问题吗?
读者们先不要慌,至于为什么可以这样,小编会在如何处理节点掉电的问题中徐徐道来
从上述的Phase2可知,此阶段只是一个暂时的阶段,一旦其自身将旧的密钥删除之后,就立即恢复到Phase0;因此,Client过渡到下一阶段的条件就是旧的密钥的删除
从上述的这些内容可知,当NetKey Update命令从Configuration Client发出来之后,密钥更新阶段的过渡有两种方式:
Config Key Refresh Phase Set
一个带应答的消息,如果SIG Mesh网络中的节点数据较少,则可以使用该命令;采用这种类型消息的好处就是:“稳定可靠”,但是缺点就是:“密钥更新会比较耗时,节点数量过多的话,容易产生网络阻塞”
Secure Network Beacon
如果SIG Mesh网络中的节点较多的话,那么可以使用该类型的消息,因为其不是一个带应答的消息,所以不会引起 “网络风暴”;这种方式的好处是:“密钥更新的时间会比较短,很快就能完成,适用于节点较多的SIG Mesh网络”,缺点就是:“由于该消息不带应答,所以在可靠性以及阶段预知方面会相对差一点”;既然,这里讲到Secure Network Beacon,那这里就顺道穿插一下:Secure Network Beacon的发送频率,Spec是有明文规定的,不是你想怎么发就怎么发的:
Beacon Interval = Observation Period * (Observed Number of Beacons + 1) / Expected Number of Beacon
其中:
这里举一个实际捉包图(SIG Mesh网络中仅有一个节点):
由上图可知,Beacon Interval = 20*1/2 = 10 秒;接着小编再举一个捉包图(SIG Mesh网络中仅有两个节点):
由上图可知,Beacon Interval = 20x(1+1)/2 = 20 秒
但是,即便节点的数量很多的时候,从Phase0切换至Phase1仍然需要Configuration Client向Configuration Server一个一个地发送NetKey Update命令
在密钥刷新的过程中,肯定有可能会出现下述的这种情况:
如果在密钥更新的过程中,SIG Mesh网络中的某个或者某些节点发生掉电了,这个时候应该怎么办?会不会因此导致某个或者某些节点被踢出网络?首先,这个时候肯定是已经接收到NetKey Update命令,并处于密钥更新的阶段1,在分析这个问题之前,我们先看看掉电然后再上电时,会出现哪种情况:
如果节点重新恢复上电后,此时整个SIG Mesh网络仍然处于Phase2,那么这个时候又分两种情况:
Config Key Refresh Phase Set
接收到Configuration Client的Config Key Refresh Phase2 Set命令,然后进入到Phase2
Secure Network Beacon
接收到Secure Network Beacon (Key Refresh Flag = 1),然后进入到Phase2
如果节点重新恢复上电之后,整个SIG Mesh网络已经处于Phase0,那么当收到使用新的密钥的Secure Network Beacon (Key Refresh Flag = 0) 时,直接进入到Phase0
这也是为什么小编在Phase2中提及到:“当使用Secure Network Beacon时,处于Phase1的Configuration Client无须知道Configuration Server当前处于哪个阶段,这是因为所有的步骤都是围绕着上述的密钥刷新步骤合法合理地进行”
有查阅过SIG Mesh Spec的读者,可能会有这样的一个疑问:“AppKey是在哪里更新的?在上述的密钥刷新步骤也没有看到啊,是不是不能更新?” 针对这一问题,显然AppKey是可以更新的,至于在哪个阶段更新,让我们看看Spec原文中的描述:
The Config AppKey Update message shall generate an error when node is in normal operation, Phase 2, or Phase 3 or in Phase 1 when the Config AppKey Update message on a valid AppKeyIndex when the AppKey value is different.
我们可以看到,AppKey不但可以更新,而且只能在Phase1中更新,至于后半句的意思是说:“在Phase1,如果已经接收到Config AppKey Update命令,但是下一个Config AppKey Update命令所携带的AppKey与上一个的不一样,则报错”;我们也可以从Nordic SIG Mesh的源码一窥究竟:
xuint32_t dsm_appkey_update(dsm_handle_t app_handle, const uint8_t * p_key)
{
if (NULL == p_key)
{
return NRF_ERROR_NULL;
}
else if (app_handle >= DSM_APP_MAX || !bitfield_get(m_appkey_allocated, app_handle))
{
return NRF_ERROR_NOT_FOUND;
}
else if (m_subnets[m_appkeys[app_handle].subnet_handle].key_refresh_phase != NRF_MESH_KEY_REFRESH_PHASE_1)
{
return NRF_ERROR_INVALID_STATE;
}
else
{
if (m_appkeys[app_handle].key_updated)
{
return 0 == memcmp(m_appkeys[app_handle].secmat_updated.key, p_key, NRF_MESH_KEY_SIZE) ?
NRF_SUCCESS : NRF_ERROR_INVALID_STATE;
}
m_appkeys[app_handle].key_updated = true;
memcpy(m_appkeys[app_handle].secmat_updated.key, p_key, NRF_MESH_KEY_SIZE);
NRF_MESH_ASSERT(nrf_mesh_keygen_aid(p_key, &m_appkeys[app_handle].secmat_updated.aid) == NRF_SUCCESS);
m_appkeys[app_handle].secmat_updated.is_device_key = m_appkeys[app_handle].secmat.is_device_key;
dsm_entry_store(MESH_OPT_DSM_APPKEYS_RECORD, app_handle, m_appkey_allocated);
}
return NRF_SUCCESS;
}
基于上述的内容,目前的密钥刷新有如下几种组合:
从Phase0切换至Phase1这一过渡,基本上都是一样的,即发送带应答的Network Update命令;唯一不同的就是Phase2/3的切换是采用带应答的Config Key Refresh Phase Set还是不带应答的Secure Network Beacon;
该组合的工作流程如下图所示:
从上图我们可以知道,Configuration Model Client与白名单中的不同的节点发送Config命令时,则需要不同的DevKey;如果是使用这种组合的话,最好就不要与Secure Network Beacon混用,否则会增加Configuration Model Client处理的复杂度,导致是否要发送Config Key Refresh Phase Set命令之前,均要对每个节点进行判断当前处于阶段几。下图是一幅该组合的实际捉包图 (新的NetKey为0x0102030405060708090A0B0C0D0E0F10)
这里采用Secure Network Beacon的方式来进行密钥刷新阶段地刷新,其工作流程如下图所示:
从上图可知,Config Client发送NetKey Update的命令以及方式都是一样的,由于Secure Network Beacon是没有应答的,所以采用这种方式就比较爽了,发完就完事,接下来只要监听同一个网络中的Secure Network Beacon的内容并做要对应地处理就可以了,还是老规矩先上图:
网络密钥的更新命令跟上述Netkey Update + Config Key Refresh Phase Set的内容是一样的
当Config Client收到所有节点的Config NetKey Update应答命令之后,率先发送Key Refresh Flag等于1的Secure Network Beacon并进入Phase2,至于什么时候发?怎么发?发送的频率是多少?则可以参考上述的Secure Network Beacon内容,接下来啥也不管,只需要监听Secure Network Beacon的内容即可
当SIG Mesh网络中的其他节点收到带Key Refresh Flag等于1的Secure Network Beacon后,它摇身一变也发出同样带Key Refresh Flag等于1的Secure Network Beacon,并进入Phase2
当Config Client接收到其他节点发送带Key Refresh Flag等于1的Secure Network Beacon时,就直接进入Phase3,删除掉旧的网络密钥之后就马上Phase0,尽管这个时候可能其他的节点还处于Phase2
至于为什么这个节点,发出的是Key Refresh Flag等于0的Secure Network Beacon呢?那是因为其在发出Key Refresh Flag等于1的Secure Network Beacon之前,就已经收到了其他节点的Key Refresh Flag等于0的Secure Network Beacon,其实它经历过Phase3到Phase0的切换过程
该组合增加了朋友节点和低功耗节点,由于低功耗节点大部分时间都处于睡眠状态,所以这个时候要对低功耗节点更新密钥的话,会相对比较麻烦,具体的工作流程如下图所示:
从上图可知,当发送给LPN的密钥,会先暂时缓存在朋友节点的缓存区中,当LPN醒来向朋友节点索取数据时,朋友节点会LPN提供新的密钥;所以Config Client发送应答的消息的时候,需要发送几次,也就是说要在Polltimeout内尽可能的多发,下图是该组合的实际捉包图:
阶段1
由上述的图可知,Config Client对LPN总共发了4次Config NetKey Update,然后LPN向朋友节点Poll之后,才应答Config Client
阶段2
这里我们可以看到有4条Config NetKey Status消息,这也间隔地说明朋友节点帮LPN缓存了4条Config NetKey Update消息,因此LPN向Friend节点Poll的时候,给LPN回了4条Config NetKey Update消息;同理,Config Client给LPN发送Config Key Refresh Phase Set消息时,Config Client同样也是发送了几次之后,LPN才应答该消息 (如图中的2的C所示)
阶段3
该阶段的切换内容如上述的阶段2所示
该组合的密钥刷新流程如下图所示:
由上图可知,Config NetKey Update的流程跟上述的NetKey Update + Config Key Refresh Phase Set(LPN+FN)基本上是一致的;这里比较爽的就是发完Secure Network Beacon之后就完事了,然后接下来根据接收到的Secure Network Beacon的内容进行相对应的阶段切换;接下来大家可以看看该组合的实际捉包图:
上图的捉包图已经完整展示了该组合的整个密钥刷新过程,阶段1的流程跟上述的NetKey Update + Config Key Refresh Phase Set(LPN+FN)基本上是一致的;而对于阶段2:
Config Client
只要接收到所有白名单节点的Config NetKey Update应答消息,则马上发出Key Refresh Flag等于1的Secure Network Beacon
Config Server(Friend Node)
当接收到Key Refresh Flag等于1的Secure Network Beacon时,然后其也发出Key Refresh Flag等于1的Secure Network Beacon
Config Server(LPN)
当向朋友节点发送Friend Poll消息之后,收到Key Refresh Flag等于1的Friend Update的应答,则LPN也相对应的进入Phase2
同样的,对于阶段3而言:
Config Client
当收到Key Refresh Flag等于1的Secure Network Beacon时,其马上进入Phase3,紧接着将旧的密钥删除,然后进入Phase0;最后发出Key Refresh Flag等于0的Secure Network Beacon就不管了
Config Server(Friend Node)
当接收到Key Refresh Flag等于0的Secure Network Beacon时,其马上进入Phase3,紧接着将旧的密钥删除,然后进入Phase0;最后发出Key Refresh Flag等于0的Secure Network Beacon就不管了
Config Server(LPN)
当向朋友节点发送Friend Poll消息之后,收到Key Refresh Flag等于0的Friend Update的应答,则LPN也相对应地进入Phase3,紧接着将旧的密钥删除,最后进入Phase0
通过上述的不同组合的密钥刷新流程,我们可以看到还是使用Config NetKey Update + Secure Network Beacon的方式对应用层比较友好且简单方便;