綜述
啟動配置(配網)是將一個沒有被配網的設備增加到一個mesh網絡中,由配網者(provisioner)管理。
provisioner將配網信息提供給未配網者。配網數據包含網絡秘鑰,當前的IV索引以及每一個元素的單播地址。(疑問:是該未配置節點分配的元素單播地址,還是整個網絡中各個元素的單播地址)
provisioner通常是智能手機或者其他可移動的計算設備。盡管配網過程只需要一個provisioner,但是網絡中可以有多個provisioner。共享數據的方法和協調多個provisioner的實現是特定的。(mesh規范中不給出)
配網承載層建立之后,provisioner和設備之間通過ECDH(Elliptic Curve Diffie-Hellman,橢圓曲線算法)協議建立了共享秘鑰。
然后使用設備特定的OOB信息(Out Of Bound,帶外數據)完成認證。這里OOB信息可以包含一個設備公鑰,一個長秘密(long secret),向設備輸入一個值,或者由設備輸出一個值。
一旦設備完成認證,配網數據就通過之前建立的共享秘鑰生成的秘鑰加密后發送給設備。設備秘鑰由ECDHSecret和ProvisioningSalt求出。
配網協議有一個層次結構。設配通過發送配網PDU的配網協議完成配網。配網PDU通過通用配網層發送給未配網設備。這個通用配網層定義了配網PDU如果被發送,分片和重組。
這里的通信交換建立在配網承載層。配網承載層定義了如何建立會話(session),這樣就可以使由通用配網層遞交的數據可以被分發到一個單獨的設備上。
最后,配網協議的架構最低是承載層。
啟動配置承載層
廣播方式(PB-ADV)
GATT方式(PB-GATT)
通用啟動配置層
通用啟動配置PDU類型
鏈路建立過程
鏈路建立過程用於給承載層建立起會話(session)。一個會話由鏈路ID唯一標識。鏈路ID在會話時間內是靜態不變的。而且為了防止不同會話間的沖突,鏈路ID是隨機生成的。
一個鏈路建立在provisioner和被配網設備之間,用於發送配網消息。未配網設備有設備UUID做標識區分。
provisioner掃描未配網設備。當收到一個未配網設備發出的beacon時,provisioner將於設備建立一個鏈路,通過設備UUID做標識。
鏈路建立開始於provisioner發送一個LinkOpen消息。LinkOpen消息中包含了設備UUID。對於廣播方式的配網,PB-ADV PDU中包含了LinkID字段。
除非已經被配網(設備已經接受到一個Provisioning Invite PDU),設備在收到LinkOpen消息時應該接受並且使用相同的LinkID回復一個LinkACK消息。
鏈路建立后,可以通過發送LinkClose消息在任何時間關閉鏈路。鏈路的任何一側都可以發送LinkClose消息。
通用啟動配置行為
啟動配置協議
啟動配置PDU
啟動配置行為
配網過程包含5個步驟:0.beacon,1.invitation(邀請),2.exchange public keys(交換秘鑰),3.authentication(認證),4.distribution of the provisioning data(發送配網數據)。
Beacon
一個支持PB-ADV的未配網而且沒有處於配網過程的設備,可以廣播Unprovisioned Device Beacon。
當一個設備沒有被配網,建議使用匿名的廣播,不可解析的私有地址或者可解析的私有地址。
該Beacon可以指示OOB數據的能力,這樣便可以使provisioner要求用戶在下一步操作前收集OOB數據。
Invitation
在建立了配網承載層后,provisioner會發送一個配網邀請包(Provisioning Invite PDU),設備將使用配網能力包(Provisioning Capability PDU)回應。
配網邀請包包含一個額外的持續時間字段,用於確定設備的主元素有多長時間使用Attention Timer識別自身。
如果配網承載層停止(be dropped),設備應該設置主元素的Attention Timer狀態為0x00(off)。
配網能力包包含設備支持的元素個數信息,支持的安全算法集,公鑰使用OOB技術的能力,設備輸出一個值給用戶的能力(output OOB),設備允許用戶輸入一個值的能力(input OOB),設備是否有一塊OOB數據用於認證(static OOB)。
當使用來自Output OOB Action字段的值(閃燈,蜂鳴,或者震動)時,設備要隨機選擇一個大於1的整形數字,這個數字將以連續事件的方式輸出(比如,閃燈,蜂鳴或者整棟以一個500ms開,500ms關的循環)。並且在允許用戶決定事件結束要有3秒鍾時間。(output OOB 應該至少持續3秒?)。當使用數值(Numeric, 純數字)方式輸出時,輸出值用數字表示(例如,ASCII字符編碼0x30-0x39)。當使用文字數字(Alphanumeric,含有字母的數字)時,輸出的值使用ASCII數字和大寫字母(例如,ASCII字符編碼0x30-0x39和0x41-0x5A)。
input OOB(沒有看懂。。。個人理解: the number of push action && the number of twist action.被配網設備的配網能力input,所以應該向為配網設備輸入OOB信息,可以是純數字,也可以是數字加字母形式,因此對被配網設備要求了輸入能力。)
Exchanging public keys
對於provisioner該步驟由於未配網設備提供公鑰能力的不同有兩種可能性。隨之,認證步驟將有三種不同可能性。因此有六種可能的叫交換/認證路徑。
一旦provisioner確定自己可以為設備配網,它將發出一個Provisioning Start PDU,該PDU中詳細描述了使用六種路徑中的那一條路徑。
設備收到Provisioning Start PDU后,需要設置Attention Timer為0x00。
Provisioner需要從被配網設備發送的Provisioning Capability PDU中選擇一種算法。如果Provisioner不理解算法位字段中的位集(bit set),那么它可以忽略該bit,並且選擇它理解的算法。Provisioner應該選擇最健壯的算法。
如果公鑰不能使用OOB技術,那么該公鑰將在所有設備間交換。
如果不同OOB下發,設備需要發送公鑰。
當未配網設備公鑰未知時公鑰交換的消息序列如下圖說明:
如果通過OOB機制的公鑰可用,那么臨時的公鑰應該從Provisioner傳輸給設備,並且應該從設備使用的合適OOB技術上讀出一個靜態的公鑰。
當未配網設備通過OOB方式完成公鑰交換時,消息序列如下圖說明:
一旦對側設備的公鑰已知,ECDHSecret可以如下計算出:
ECDHSecret = P-256(private key, peer public key)
Authentication
如果使用Output OOB認證,那么Provisioning Start PDU應該包含一個對於設備按規定動作輸出一個或多個數字只的請求。輸出的動作可以包括發出聲音,閃爍燈,或者在屏幕顯示符號。
例如,如果一個含有一個LED燈的門鎖設備,那么它可以通過閃爍LED的方式來使用Output OOB認證。
設備需要選擇一個隨機數,然后輸出該數字。provisioner的用戶可以輸入觀察到的用於認證的數字。一旦數字被輸入,一個隨着隨機數字交換而交換的確認動作將被執行。
確認值是所有到目前的交換值,明文形式的隨機數,和被輸入的數字的hash加密值。一旦隨機數被交換,每個設備都可以認證對側。
來自Output OOB,Input OOB或者static OOB的認證值將在AuthValue中使用,用於計算上面說的確認值。
Provisioner的確認計算:
ConfirmationProvisioner = AES-CMACconfirmationKey(RandomProvisioner || AuthValue)
設備的確認計算:
ConfirmationDevice = AES-CMACconfirmationKey(RandomDevice || AuthValue)
其中,
ConfirmationKey = k1(ECDH_Secret, ConfirmationSalt, "prck")
ConfirmationSalt = s1(ConfirmationInputs)
ConfirmationInputs = ProvisioningInvitePDUValue || ProvisingCapabilitiesPDUValue || ProvisionStartPDUValue || PublicKeyProvisioner || PublicKeyDevice
這其中,
ProvisioningInvitePDUValue是Provisioning Invite PDU字段除去操作碼后的值。
ProvisioningCapabilitiesPDUValue是Provisioning Capabilities PDU字段去除操作碼后的值。
ProvisioningStartPDUValue是Provisioning Start PDU字段去除操作碼后的值。
PublicKeyProvisoner是由Provisioner發送的公鑰PDU中PbulicKeyX和PublicKeyY的值。
PbulicKeyDevice是有設備發送的公鑰PDU中的PublicKeyX和PublicKeyY字段的值(或者分發出來的OOB公鑰)
RandomProvisioner是一個隨機bit數的字符串,由provisioner的隨機數生成器生成。
RandomDevice是一個隨機bit數的字符串,由設備的隨機數生成器生成。
AuthValue是128bit的值。它的計算依賴與OOB動作的數據類型。
如果數據類型是二進制,那么AuthValue是一個octet的數組。如果該值比128bit少,那么剩余的bit用0填充。
如果數據類型是純數字,那么該數字應該是一個無符號128bit值。
如果數據類型是數字和文本,那么AuthValue應該對字符和ASCII碼相關連。
5->0x05
019655->0x4CC7
"123ABC"->
如果沒有使用Output OOB方式認證,AuthValue應該被設置為全0。
Provisioner在收到Provisioning Confirmation PDU后會發送Provisioning Random PDU。設備在驗證了確認值后會發送Provisioning Random。
使用OutPut OOB方式認證的消息序列如下圖:
如果使用Input OOB方式認證,那么Provisioner需要生成一個隨機數,並且展示給用戶。用戶用一種合適的方式將該值輸入到設備。
例如,一個燈的開關可以讓用戶通過按壓開關一定次數來輸入隨機數。
一旦隨機數被輸入,設備將發送Provisioning Input Complete PDU給Provisioner確認。一個伴隨隨機數交換的確認交換被執行。
Input OOB方式認證的消息序列如下圖:
使用靜態OOB或者沒有OOB使用時,Provisioner會按上述立即(無其他操作)進行確認和隨機數交換。如果靜態OOB值可用,那么該值將作為確認值的一部分。如果沒有可用的靜態OOB值,那么該值應該全為0。
靜態OOB或者沒有OOB時的消息序列如下圖: