组网过程(provisioning)是ble mesh 核心流程,先从宏观上了解整个组网过程,再深入到协议的算法,个人认为更加容易接受一些。
请尊重原创,引用请标明出处https://editor.csdn.net/md/?articleId=104375184
总结为五个步骤:
初步印象,整个过程跟ble smp 流程非常相似。
一个全新的设备,没有加入过任何网络
如果需要加入到mesh 网络,需要向porvisioner 发送ADV
要告诉周围的设备,希望加入mesh 网络,并且现存网络中的设备处于scan 模式,能够收听到这个讯息,注意两点
Note:如果一个设备以及配对过,有加入到网络,需要发送匿名广播,或者私有地址广播,区别于Unprovisioned Device beacon
provisioner 接收到beacon 之后,会邀请该设备入网,并且会交换一些必要的设备信息,为后续步骤做准备。
这个过程中有一些特殊的数据帧格式需要特别留意:
Provisioning Invite PDU
an Attention Duration field, used to determine how long the primary element of the device identifies itself using the Attention Timer,
告诉新设备,我会等你多久
Provisioning Capabilities PDU
*这些信息,决定后后面加密采用的哪种方式,加密的参数,用户交互的方式等等,
如果熟悉ble smp 过程,这个步骤异常熟悉
这步根据provisioner 是否有新设备的public key,分为有两种可能
另外涉及到的加密方式又有三种可能
所有交换和加密总共有4种可能实现的方法
provisioner 根据信息,会决定用4种方法中哪一种方法,这些信息携带在
Provisioning Start PDU
new device 收到之后,会设置Attention Timer =0,流程正式开始
两端设备没有其他途径获得public key,所以需要在加密计算之前,交换public
在计算之前,两个设备通过wifi或者其他非蓝牙的方式,获得了对端设备的public key,只需要把自己的key 告诉新设备,然后开始加密计算
ECDHSecret = P-256(private key, peer public key)
交换public key 之后,会用上述算法,计算出宇哥ECDH值,并且删除产生的public-priviate key
这一步跟smp 过程exchange public key 一样
如果设备输出OOB支持,provisioner 用户需要输入观察到的数字
obb 能力大概分为下面几类:
根据设备支持能力,加密分为三种情况
Output OOB, Input OOB, or Static OOB
Authentication Method 0x02
加密过程中需要的参数:
ConfirmationInputs = ProvisioningInvitePDUValue || ProvisioningCapabilitiesPDUValue ||
ProvisioningStartPDUValue || PublicKeyProvisioner || PublicKeyDevice
Authentication Method 0x03
新设备具备输入能力, 获取到provisioner 设备显示的随机数字
新设备需要输入该数字。
该设备不具备输入输出能力,使用这种方式。
如果无法获得到oob数据,则全部设置为0,类似ble smp justwork模式
三个不同情况,都会经过下面两个步骤:
provisioning confirmation
provisioning random
涉及到算法如下:
ConfirmationProvisioner = AES-CMAC C o n f i r m a t i o n K e y _{ConfirmationKey} ConfirmationKey(RandomProvisioner || AuthValue)
ConfirmationDevice = AES-CMAC C o n f i r m a t i o n K e y _{ConfirmationKey} ConfirmationKey (RandomDevice || AuthValue)
ConfirmationKey = k1(ECDHSecret, ConfirmationSalt, “prck”)
ConfirmationSalt = s1(ConfirmationInputs)
ConfirmationInputs = ProvisioningInvitePDUValue || ProvisioningCapabilitiesPDUValue ||
ProvisioningStartPDUValue || PublicKeyProvisioner || PublicKeyDevice
所计算的这些参数,都是为最终计算provision data做准备。
两端设备都会使用相同且一致的参数计算,计算结果最后会校验。
校验通过后,加密过程结束,计入到下一步
Provisioner and device shall use the calculated DiffieHellman shared secret ECDHSecret .
根据上一步参数,会完成DHKey check。
最终生成的Provisioning Data PDU 包含如下信息
Field | size(octotes) | Notes |
---|---|---|
Network Key | 16 | NetKey |
Key Index | 2 | Index of NetKey |
Flag | 1 | Flags bitmask |
IV Index | 4 | Current value of the IV index |
Unicast Address | 2 | Unicast address of the primary element |
这个过程会产生一个session key,使用到如下算法
ProvisioningSalt = s1(ConfirmationSalt || RandomProvisioner || RandomDevice)
SessionKey = k1(ECDHSecret, ProvisioningSalt, “prsk”)
仅使用一次的session key:
SessionNonce = k1(ECDHSecret, ProvisioningSalt, “prsn”)
分发过程中,provisioning data 使用如下算法加密:
Provisioning Data = Network Key || Key Index || Flags || IV Index || Unicast Address Encrypted Provisioning Data, Provisioning Data MIC = AES-CCM (SessionKey, SessionNonce,Provisioning Data)
加密过程如下: