組網過程(provisioning)是ble mesh 核心流程,先從宏觀上了解整個組網過程,再深入到協議的算法,個人認爲更加容易接受一些。
請尊重原創,引用請標明出處https://editor.csdn.net/md/?articleId=104375184
組網流程圖
總結爲五個步驟:
- beaconing 信標
- 邀請入網,交換設備能力信息(support feature,io cap)
- 交換public key
- 加密,
- 分發組網數據
初步印象,整個過程跟ble smp 流程非常相似。
Beaconning
一個全新的設備,沒有加入過任何網絡
如果需要加入到mesh 網絡,需要向porvisioner 發送ADV
要告訴周圍的設備,希望加入mesh 網絡,並且現存網絡中的設備處於scan 模式,能夠收聽到這個訊息,注意兩點
- provisioner 需要處於scan 模式
- new device 發送Unprovisioned Device beacon
Note:如果一個設備以及配對過,有加入到網絡,需要發送匿名廣播,或者私有地址廣播,區別於Unprovisioned Device beacon
Invitation
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
- the number of elements the device supports,
- the set of security algorithms supported,
- the availability of its public key using an OOB technology,
- the ability for this device to output a value to the user,
- the ability for this device to allow a value to be input by the
user, - and if the device has a block of OOB data that can be used for
authentication
*這些信息,決定後後面加密採用的哪種方式,加密的參數,用戶交互的方式等等,
如果熟悉ble smp 過程,這個步驟異常熟悉
Exchange public keys
這步根據provisioner 是否有新設備的public key,分爲有兩種可能
另外涉及到的加密方式又有三種可能
所有交換和加密總共有6種可能實現的方法
provisioner 根據信息,會決定用6 種方法中哪一種方法,這些信息攜帶在
Provisioning Start PDU
new device 收到之後,會設置Attention Timer =0,流程正式開始
情況一: 不支持OOB,
兩端設備沒有其他途徑獲得public key,所以需要在加密計算之前,交換public
情況二:支持OOB
在計算之前,兩個設備通過wifi或者其他非藍牙的方式,獲得了對端設備的public key,只需要把自己的key 告訴新設備,然後開始加密計算
ECDHSecret = P-256(private key, peer public key)
交換public key 之後,會用上述算法,計算出宇哥ECDH值,並且刪除產生的public-priviate key
這一步跟smp 過程exchange public key 一樣
Authentication
如果設備輸出OOB支持,provisioner 用戶需要輸入觀察到的數字
obb 能力大概分爲下面幾類:
- Blink, Beep, or Vibrate
- Output Numeric
- Alphanumeric,
根據設備支持能力,加密分爲三種情況
Output OOB, Input OOB, or Static OOB
情況一:Output OOB
Authentication Method 0x02
加密過程中需要的參數:
ConfirmationInputs = ProvisioningInvitePDUValue || ProvisioningCapabilitiesPDUValue ||
ProvisioningStartPDUValue || PublicKeyProvisioner || PublicKeyDevice
情況二:Input OOB
Authentication Method 0x03
新設備具備輸入能力, 獲取到provisioner 設備顯示的隨機數字
新設備需要輸入該數字。
情況三:static OOB
該設備不具備輸入輸出能力,使用這種方式。
如果無法獲得到oob數據,則全部設置爲0,類似ble smp justwork模式
總結
三個不同情況,都會經過下面兩個步驟:
provisioning confirmation
provisioning random
涉及到算法如下:
ConfirmationProvisioner = AES-CMAC(RandomProvisioner || AuthValue)
ConfirmationDevice = AES-CMAC (RandomDevice || AuthValue)
ConfirmationKey = k1(ECDHSecret, ConfirmationSalt, “prck”)
ConfirmationSalt = s1(ConfirmationInputs)
ConfirmationInputs = ProvisioningInvitePDUValue || ProvisioningCapabilitiesPDUValue ||
ProvisioningStartPDUValue || PublicKeyProvisioner || PublicKeyDevice
所計算的這些參數,都是爲最終計算provision data做準備。
兩端設備都會使用相同且一致的參數計算,計算結果最後會校驗。
校驗通過後,加密過程結束,計入到下一步
Distribution of 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)
加密過程如下: