蓝牙mesh规范配网(最全)

配网(Provisioning)是将未配网设备添加到mesh网络的过程,由配置器管理。 配网器为未配网设备提供配网数据(provisioning data),使其成为mesh节点。 供应数据包括网络密钥、当前IV索引和每个元素的单播地址。

配网器(Provisioner) 通常是智能手机或其他移动计算设备。 尽管网络上只需要一个配网器来进行配置,但可以使用多个配网器。 在多个配网器之间共享和协调缓存数据是需要特定的方法实现的。

要配置设备,必须在配网器和设备之间存在一个配网承载器。配网器可以通过设备的UUID和其他可能提供的补充信息来识别设备。

配网承载器建立后,配网器使用椭圆曲线 Diffie-Hellman (ECDH)协议与设备建立密钥。然后,它使用特定于该设备的 OOB 信息对设备进行身份验证。这种OOB信息可以包括设备的公钥、长密码、将值输入设备的要求或在该设备上输出值的要求。此类 OOB 信息还支持对该设备进行身份验证。一旦设备通过身份验证,配置数据就会被传输到使用从该共享密钥派生的密钥加密的设备。设备密钥派生自 ECDHSecretProvisioningSalt

蓝牙mesh配网协议图.png

配网协议使用分层架构,如上图所示。设备的配网是使用配网协议发送配网 PDU 的完成的。配网PDU 使用通用配网层代理协议层传输到未配网设备。这些层定义了如何将配网 PDU 作为可以分段和重组的指令进行传输。这些指令通过配网承载器发送。配网承载器定义了如何建立会话,以便可以将来自通用配网层的指令传送到某个设备。在配网协议架构的底部是承载器。

除非另有说明,否则该层中的所有多字节数值应为“大端”模式

配网承载层

配网承载层支持在配网器和未配网设备之间传输配网 PDU。

  • 蓝牙mesh规范定义了两种承载器:广播承载器(PB-ADV)GATT承载器(PB-GATT)

  • 未配网设备至少支持 PB-ADVPB-GATT 之一。 但强烈建议同时支持 PB-ADVPB-GATT

  • 配网器应至少支持 PB-ADVPB-GATT 之一。 强烈建议支持PB-ADV

广播承载器(PB-ADV)

PB-ADV 是一种配网承载器,通过广播通道方式使用通用配网 PDU给设备配网。供网机制是基于会话的。未配网设备同一时间只能支持一个会话。配网器没有这样的限制。PB-ADV 承载器用于传输通用配网 PDU。PB-ADV 承载器的 MTU(最大传输单元)大小为 24 个字节。

当使用 PB-ADV 时,通用广播PDU应该使用PB-ADV广播类型进行发送,类型定义在«PB-ADV»。

支持 PB-ADV 的设备应以尽可能接近 100% 的占空比执行被动扫描,以避免丢失任何传入的 通用配网 PDU。

PB-ADV AD 类型包含一个 PB-ADV PDU。 该 AD 类型的格式在下表中定义。

字段 长度(字节) 描述
Length 1 Length of the AD Type and Contents
AD Type 1 «PB-ADV»
Contents 变动 PB-ADV PDU

任何使用 PB-ADV AD 类型的广播都应是不可连接和不可扫描的非定向广播事件。如果节点在可连接或可扫描的广播数据中接收到 PB-ADV AD 类型,则应忽略该消息。

下表定义了 PB-ADV PDU 的格式

字段 长度(字节) 描述
Link ID 4 The identifier of a link
Transaction Number 1 The number for identifying a transaction
Generic Provisioning PDU 1-24 Generic Provisioning PDU being transferred

Link ID 用于标识两个设备之间的链路。

Transaction Number 字段包含一个八位字节的值,用于标识设备发送的每个单独的 Generic Provisioning PDU。当一个配网PDU无法通过单个 PB-ADV PDU传输完时,配网PDU 会被分段,并且所有分段都使用相同的事务编号(Transaction Number)字段值发送。当一个供应 PDU 被重传时,事务编号字段不会改变。

定义传输特定消息以建立和终止两个设备之间的链接。

发送 PB-ADV PDU 时应执行以下规则:

  • PB-ADV PDU 包含一个配网承载器控制 PDU 时,Transaction Number 字段应设置为 0 并在接收时忽略。

  • 当配网器第一次通过开放的配网链路发送配网 PDU 时,它应该以 Transaction Number 字段值 0x00 开始。对于在配网链接期间发送的每一个新的配网 PDU,配网器应将其Transaction Number字段值加一。如果该字段值已达到 0x7F,则在发送下一个配网 PDU 时应回到 0x00。

  • 当未配网设备第一次通过开放配网链路发送配网 PDU 时,它应以事务编号字段值 0x80 开始。 设备应在配网链路期间为它发送的每个新配网 PDU 将字段值加一。 如果该字段值已达到 0xFF,则在发送下一个配网 PDU 时应回到 0x80。

  • 当一个设备正在接收一个配网 PDU时,它应该将Transaction Number字段设置为在事务期间接收到的PB-ADV PDUTransaction Number字段的值。

  • 当设备发送事务确认 PDU 时,事务编号字段应设置为传输时已被确认的配网 PDU 的 PB-ADV PDU 的事务编号字段的值。

GATT承载器(PB-GATT)

PB-GATT 是一种配网承载器,用于给使用代理 PDU 的设备配网,以将配网 PDU 封装到 Mesh Provisioning Service 中。

由于应用程序接口的限制,当配网器不支持 PB-ADV 时,PB-GATT可以提供支持。

注意:建议配网器和设备之间的连接间隔在250到1000毫秒之间,以使设备能够以极低的功耗运行并允许设备计算Diffie-Hellman共享密钥而不会浪费维持空闲链路的大量能量。

Mesh Provisioning Server 应该能够在单个写命令 ATT PDU 中接收单个代理 PDU。

Mesh Provisioning Server 应使用单个 Handle 值通知 ATT PDU 将配网 PDU 发送到配网器。

如果协商的 ATT_MTU 小于所需的代理 PDU 大小,则 Mesh Provisioning Data In 和 Mesh Provisioning Out 特性的传输总是需要分段和重组。每个 PDU 应在处理前完成重新组装。

Mesh Provisioning Server 要能够在一个或多个 ATT PDU 中接收代理 PDU。

Mesh Provision Server 应根据消息的大小和协商的 ATT_MTU 使用一个或多个 Handle 值通知 ATT PDU 向 Provision Client 发送代理 PDU。

通用配网层(Generic Provisioning layer)

通用配网层负责通过不可靠的无连接配网承载器传输通用配网 PDU。 该层还定义了通用配网 PDU。

通用配网PDU(Generic Provisioning PDU) 格式由一个 Generic Provisioning Control (GPC) 字段和一个可变长度的 Generic Provisioning Payload 字段组成,如下图所示。

通用配网PDU数据结构模型.png

字段 长度(字节) 描述
Generic Provisioning Control 1–17 通用配网控制字段
Generic Provisioning Payload 0–64 通用配网负载 (配网PDU的某一段)

Generic Provisioning Control 字段的第一个八位字节的两个最低有效位包含一个 Generic Provisioning Control Format (GPCF) 字段,该字段确定 Generic Provisioning Control 字段的格式。GPCF 字段是一个枚举,其值如下表所示。

值(0b/二进制) 描述
0b00 事务开始(Transaction Start )
0b01 事务确认 (Transaction Acknowledgment )
0b10 事务继续(Transaction Continuation)
0b11 配网承载器控制(Provisioning Bearer Control)

通用配网 PDU 类型

1.事务开始PDU (Transaction Start PDU )

Transaction Start PDU 用于启动分段消息的传输。 Transaction Start PDU 的 Generic Provisioning Control 字段如下图和下表所示。


业务开始PDU的字段结构.png

各字段的解释如下:

字段 长度(bit位) 描述
SegN 6 The last segment number
GPCF 2 0b00 = Transaction Start
TotalLength 16 Provisioning PDU 中的字节数
FCS 8 Provisioning PDU的帧校验序列

SegN 字段应设置为该事务的最后一个段号(从零开始)。

GPCF 字段应设置为 0b00。

TotalLength 字段应设置为 Provisioning PDU 中的字节数。

当使用 PB-ADV 传输时,FCS 字段按照 3GPP TS 27.010 的多项式 (x8 + x2 + x1 + 1) 的定义进行计算,并且仅在 Provisioning PDU 上计算。

Generic Provisioning Payload 应包含 Provisioning PDU 的段 0。

2.事务确认PDU (Transaction Acknowledgment )

Transaction Acknowledgement PDU 用于确认 Provisioning PDU。 事务确认 PDU 的通用供应控制字段如下图 和下表所示。

事务确认PDU的控制字段.png
字段 长度(bit位) 描述
Padding 6 0b000000;所有其他值 禁止
GPCF 2 0b01 = Transaction Acknowledgment

Generic Provisioning Payload 的长度为零。事务确认不包含任何负载,Data段为空。

3.事务继续PDU(Transaction Continuation)

Transaction Continuation PDU 用于发送Provisioning PDU 的附加段。 事务继续 PDU 的通用供应控制字段如下图和下表中显示。


事务继续PDU结构.png
字段 长度(bit位) 描述
SegmentIndex 6 事务段号
GPCF 2 0b10 = Transaction Continuation

Generic Provisioning Payload 应包含 Provisioning PDU 的 SegmentIndex。

4.配网承载器控制PDU(Provisioning Bearer Control)

配网承载器控制 PDU 用于管理没有固有会话管理的承载器上的会话。 配置承载控制 PDU 的通用配置控制字段在下图和下表中说明。 配网承载器控制 PDU 在以下部分中定义。

配网承载器控制结构.png
字段 长度(bit位) 描述
BearerOpcode 6 配网承载器控制PDU操作码
GPCF 2 0b11 = Provisioning Bearer Control
Parameters 可变的 每个 BearerOpcode 定义的参数

BearerOpcode 定义的参数如下表

消息 描述
0x00 Link Open 建立一个承载器与设备之间的会话
0x01 Link ACK 确定承载器的会话
0x02 Link Close 关掉承载器的会话
0x03–0x3F 保留(RFU) 保留,供以后使用

Generic Provisioning Payload 的长度为零。
每条消息的参数在以下部分中定义。

4.1链接开启消息(Link Open message)

Link Open 消息用于在配网器 和未配网设备之间建立链接。 设备应使用 Link ACK 消息确认该消息。

Link Open消息格式.png

Device UUID:16字节,这是所选未配网设备的设备 UUID。

4.2链接确认消息(Link ACK)

发送 Link Ack 消息以确认收到 Link Open 消息。 此消息没有参数。


Link Ack消息格式.png
4.3链接关闭消息(Link Close)

Link Close消息用于关闭链接。 如果此消息未被确认,发送者应至少重复此消息 3 次。 链接的双方都可能发送此消息。 无论Reason字段的设置如何,都应接受和处理该消息。

Link Close消息格式.png

Reason:1字节,描述关闭链接的原因。

Reason字段的定义如下:

原因 说明
0x00 Success 配网成功
0x01 Timeout 配网事务超时
0x02 Fail 配网失败
0x03–0xFF Unrecognized 保留值,无法识别

链接建立过程

链路建立过程(Link Establishment procedure)用于为没有固有会话管理的承载器建立会话。 会话通过链路 ID 来标识,链路 ID在会话期间是不变的,并且链路 ID是随机生成以防止会话之间的冲突。

在配网器和未配网设备之间建立链接,用于发送配网消息。 未配网的设备由设备 UUID 标识。

配网器应扫描未配网设备。在收到未配网设备信标后,配网器可以通过设备UUID与设备建立一个链接。

当设备为 Link Open 消息发送 Link ACK 时,该链路对设备打开。 当接收到 Link ACK的 Link ID 与 Link Open 消息中发送的 Link ID 相同时,该 Link 对 Provisioner 开放。 当链路打开并且设备已收到任何 Provisioning PDU 时,设备正在被配网。

当链路未打开,并且设备接收到 Link Open 消息时,设备应通过使用与 PB-ADV PDU 中设置的相同 Link ID 的 Link ACK 消息来回复此消息。

当链路打开且设备未在配网,并且设备接收到具有相同 Link ID 的 Link Open 消息时,设备应通过使用与 PB-ADV PDU 中设置具有相同 Link ID 的 Link ACK 消息进行回复。

当链接打开时,设备应启动链接计时器,设置为 60 秒。 当链接定时器到期时,设备将关闭链接。 当设备收到任何 Provisioning PDU 或 Link Close 消息时,设备应取消链接定时器。

要打开链接,Provisioner 应启动链接建立计时器,设置为 60 秒,然后开始发送 Link Open 消息。 配网器可以随时中止这个过程。 Link Open 消息包含设备的设备 UUID。 在广播承载器 PB-ADV 上,PB-ADV PDU 格式包括一个 Link ID 字段。

链接建立过程.png

通用配网行为

每个通用配网 PDU 应在 20 到 50 毫秒之间的随机延迟后发送。每个 Provisioning PDU 作为单独的事务传输。 一个事务可能由一个或多个段组成。

发送Provisioning PDU 所需的段数由Provisioning PDU 的大小决定。 段的索引从 0 到 63。段 0 应使用事务开始(Transaction Start) PDU 发送。 所有其他段应使用事务继续(Transaction Continuation) PDU 发送。

配网PDU的段号放在通用配网PDU的负载字段中。每个承载器在传输通用配网 PDU时,都有它自己的MTU长度限制。每个通用配网 PDU都应该以最大长度进行传输,事务的最后一段除外。

发送方应按顺序发送事务的所有段。 如果发送方没有收到事务确认(Transaction Acknowledgment)消息,发送方应重新发送事务的所有段。

如果发送方收到事务确认消息,则事务处理完成。

如果发送方收到其他 PDU 类型的消息,则该消息应被忽略。

如果发送方在发送事务中的第一条消息后 30 秒内未收到事务确认消息,则发送方应取消这个事务,取消配置过程并关闭链接。

接收方应根据事务开始 PDU 确定事务的段数。

在 PB-ADV 承载器上,当接收方收到一个事务的所有段时,接收方应对接收到的 Provisioning PDU 计算 FCS,如果与 Transaction Start PDU 中的 FCS 字段匹配,则在 20 到 50 毫秒之间的随机延迟之后,发送 Transaction Acknowledgement PDU 。

当一个给定事务的事务确认 PDU 已被发送并且已接收到同一事务的另一个段时,应发送另一个事务确认 PDU,并且应忽略接收到的段。

注释:当事务确认 PDU已发送 ,说明已经处理了该事务的所有消息,如果再收到这个事务的消息,说明是已经处理过的消息,自然应该忽略。发送了事务确认PDU,发送方依然在发送事务消息,说明发送方没有收到确认,在进行重发操作,所以发送另外一个事务确认PDU,再告诉发送方进行事务确认。

配网协议

本节定义了对配网 PDU、行为和安全性的要求。

配网PDU(Provisioning PDUs)

Provisioning PDU 用于在 Provisioner 和设备之间进行通信。

Provisioning PDU 的第一个字节是 Type 字段,定义了 Provisioning PDU 的参数格式。

Provisioning PDU 格式定义定义如下:

配网PDU格式.png
字段 长度(bit位) 描述
Padding 6 0b00. 其他值是禁止的
Type 2 配网PDU类型值(0x03)
Parameters 可变的 消息参数

配网消息均是以03开头,表示该消息是配网协议消息。

Parameters字段各值的含义如下:

类型 名称 描述
0x00 Provisioning Invite 邀请设备加入mesh网络
0x01 Provisioning Capabilities 表示设备的配网能力
0x02 Provisioning Start 表示配网器根据设备能力选择的配网方式(ECDH)
0x03 Provisioning Public Key 包含设备或配网器的公钥(两端都要发)
0x04 Provisioning Input Complete 表示用户已完成输入值
0x05 Provisioning Confirmation 包含设备或配网器的配网确认值
0x06 Provisioning Random 包含设备或配网器的配网随机值
0x07 Provisioning Data 包括分配的主元素单播地址,网络密钥及索引,
标志和IV索引
0x08 Provisioning Complete 表示配网完成
0x09 Provisioning Failed 表示配网失败
0x0A–0xFF RFU 保留供将来使用

配网邀请(Provisioning Invite)

配网器发送此 PDU 以向设备指示配网过程正式开始。 该 PDU 的参数格式如下。

Attention Duration :1字节,提示时间定时器状态(Attention Timer state)。

配网能力(Provisioning Capabilities)

设备发送此 PDU 以向 Provisioner 指示其支持的配置能力。配网能力PDU参数格式如下:

字段 长度(字节) 注释
Number of Elements 1 设备支持的元素个数
Algorithms 2 支持的算法和其他功能
Public Key Type 1 支持的公钥类型
Static OOB Type 1 支持的静态 OOB 类型
Output OOB Size 1 支持的最大输出 OOB 大小
Output OOB Action 2 支持的输出 OOB 操作
Input OOB Size 1 支持的输入 OOB 的最大字节大小
Input OOB Action 2 支持的输入 OOB 操作

元素个数字段值范围:0x01–0xFF;0x00是禁止的。

支持的算法:FIPS P-256 椭圆曲线。目前仅支持这一种。设备应至少支持一种算法。

支持的公钥类型:仅支持0,代表可用的公钥 OOB 信息。公钥 OOB 信息的大小由所选算法确定。

支持的静态 OOB 类型:仅支持0,代表可用的静态 OOB 信息。

静态 OOB 信息的最大大小为 16 个字节。

  • 当在 Output OOB Action 字段中设置了输出数字并且未设置输出字母时,Output OOB Size 定义了可以输出的位数(例如,屏显示或喇叭说出)。
  • 当在 Output OOB Action 字段中未设置输出数字并且设置了输出字母时,Output OOB Size 定义了可以输出的数字和大写字母的数量。
  • 当在 Output OOB Action 字段中设置了输出数字并且设置了输出字母时,Output OOB Size 定义了可以输出的数字和大写字母的数量。

Output OOB Size的值定义如下:

描述
0x00 设备不支持输出OOB
0x01–0x08 设备支持的最大输出 OOB 大小
0x09–0xFF 保留供以后使用

Output OOB Action的值定义如下:

描述 数据类型
0 Blink(眨眼) 数字
1 Beep(哔哔的声音) 数字
2 Vibrate(震动) 数字
3 Output Numeric(输出数字) 数字
4 Output Alphanumeric(输出字母) 字母
5-15 保留供以后使用 保留供以后使用
  • 当在 Input OOB Action 字段中设置了 Input Numeric 值且未设置 Input Alphanumeric 时,Input OOB Size 定义了可以输入的位数。
  • 当在 Input OOB Action 字段中未设置 Input Numeric 值且设置了 Input Alphanumeric 时,Input OOB Size 定义了可以输入的数字和大写字母的数量。
  • 当在 Input OOB Action 字段中设置了 Input Numeric 值且设置了 Input Alphanumeric 时,Input OOB Size 定义了可以输入的数字和大写字母的数量。

Input OOB Size字段定义如下:

描述
0x00 该设备不支持输入OOB
0x01–0x08 设备支持的最大输入 OOB 大小
0x09–0xFF 保留供将来使用

Input OOB Actions定义如下

描述 数据类型
0 Push(按) 数字
1 Twist(旋转) 数字
2 Input Numeric 数字
3 Input Alphanumeric 字母
4-15 保留供将来使用 保留供将来使用

配网开始(Provisioning Start)

配网器发送此 PDU 以指示它从 Provisioning Capabilities PDU 中选择的配网方式。 该 PDU 的参数格式定义如下。

字段 长度(字节) 注释
Algorithm 1 用于配网的算法
Public Key 1 使用的公钥
Authentication Method 1 使用的认证方法
Authentication Action 1 选择的Output OOB Action或Input OOB Action或 0x00
Authentication Size 1 使用的Output OOB 的大小或Input OOB 的大小或 0x00

算法(Algorithm)值的定义:0x00,FIPS P-256 椭圆曲线;0x01–0xFF,保留供以后使用。

公钥值的定义:

描述
0x00 未使用 OOB 公钥
0x01 使用 OOB 公钥
0x02–0xFF 禁止

认证方法值定义如下:

描述
0x00 未使用 OOB 身份验证
0x01 使用静态 OOB 身份验证
0x02 使用输出 OOB 身份验证
0x03 使用输入 OOB 身份认证
0x04–0xFF 禁止
  • 当认证方法 Authentication Method 使用0x00 (Authentication with No OOB) 方法时,Authentication Action 字段应设置为 0x00,Authentication Size 字段应设置为 0x00。

  • 当使用认证方法 0x01(静态 OOB 认证)方法时,认证大小应设置为 0x00,认证操作字段应设置为 0x00。

  • 当使用认证方法 0x02(Output OOB Authentication)时,应使用下表中定义的值来确定认证动作(Authentication Action)和认证大小(Authentication Size)。

认证方法采用Output OOB Action时,Authentication Action字段的值在下表中定义。

描述
0x00 Blink(眨眼)
0x01 Beep(哔哔的声音)
0x02 Vibrate(震动)
0x03 Output Numeric(输出数字)
0x04 Output Alphanumeric(输出字母)
0x05–0xFF 保留供将来使用

认证方法采用Output OOB Action时,Authentication Size字段的值在下表中定义。

描述
0x00 禁止
0x01–0x08 要使用的 Output OOB Size
0x09–0xFF 保留供将来使用
  • 当使用认证方法 0x03(Input OOB Authentication)时,应使用下表中定义的值来确定认证动作(Authentication Action)和认证大小(Authentication Size)。

认证方法采用Input OOB Action时,Authentication Action字段的值在下表中定义。

描述
0x00 Push(按)
0x01 Twist(旋转)
0x02 Input Numeric(输入数字)
0x03 Input Alphanumeric(输入字母)
0x04–0xFF 保留供将来使用

认证方法采用Input OOB Action时,Authentication Size字段的值在下表中定义。

描述
0x00 禁止
0x01–0x08 要使用的输入 OOB 大小
0x09–0xFF 保留供将来使用

配置公钥(Provisioning Public Key)

配网器发送此 PDU 以传递要在 ECDH 计算中使用的公钥。 该 PDU 的参数格式在下表中定义。

字段 长度(字节) 注释
Public Key X 32 FIPS P-256 算法的公钥的 X 组件
Public Key Y 32 FIPS P-256 算法的公钥的 Y 组件

配网输入数据完成(Provisioning Input Complete)

当用户完成输入操作时,设备会发送此 PDU。此 PDU 没有参数。

配网确认(Provisioning Confirmation)

配网器或者设备将此PDU发送给对方,以确认到目前为止交换的值,包括 OOB Authentication 值和尚未交换的随机数。

Confirmation字段:16字节,到目前为止交换的值,包括 OOB 身份验证值

配网随机数(Provisioning Random)

配网器或者设备将此PDU发送给对方,以判断确认(Confirmation)是否有效。

Random字段:16字节,确认(confirmation)的最终输入。

配网数据(Provisioning Data)

配网器发送此PDU将配网数据发送到设备。

字段 长度(字节) 注释
Encrypted Provisioning Data 25 网络密钥、NetKey 索引、密钥刷新标志、IV 更新标志、IV 索引的当前值和主元素的单播地址
Provisioning Data MIC 8 PDU 完整性校验值

配网完成(Provisioning Complete)

设备发送此 PDU 以表明它已成功接收并处理了配网数据。此 PDU 没有参数。

配网失败(Provisioning Failed)

如果设备未能处理接收到的供应协议 PDU,则设备发送此 PDU。

Error Code:1字节,设备遇到的配网协议中的特定错误。

名称 描述
0x00 Prohibited 禁止
0x01 Invalid PDU 设备无法识别配网协议 PDU
0x02 Invalid Format 协议 PDU 的参数超出预期值或 PDU 的长度与预期不同
0x03 Unexpected PDU 当前配网步骤中不期望收到的 PDU
0x04 Confirmation Failed 计算的确认值未成功验证
0x05 Out of Resources 由于设备资源不足,无法继续配网协议
0x06 Decryption Failed 数据块未成功解密
0x07 Unexpected Error 发生了可能无法恢复的意外错误
0x08 Cannot AssignAddresses 设备无法为所有元素分配连续的单播地址
0x09–0xFF RFU 保留供将来使用

配网行为(Provisioning behavior)

配网使用五个步骤执行:信标、邀请、交换公钥、身份验证和供应数据的分发。

配网行为流程图.png

信标阶段(Beaconing)

支持 PB-ADV、尚未配网且不在配网过程中的设备应广播未配置设备信标。当设备尚未被配置时,建议使用匿名广告、不可解析的私有地址或可解析的私有地址。 该信标可以指示 OOB 数据的可用性,允许配网器在下一步之前提示用户收集该 OOB 数据。

邀请阶段(Invitation)

在建立配网承载器后,配网器应该发送配网邀请PDU,设备在收到配网邀请PDU后,要回复配网能力PDU进行响应。配网邀请PDU包含一个Attention Duration字段,用于确定设备主元素使用Attention计时器识别自己的配网时间。如果配网配网承载器被丢弃,则设备应将主元素的Attention定时器状态设置为 0x00(关闭)。配网能力 PDU 包括设备支持的元素数量、支持的安全算法集、使用 OOB 技术的公钥的可用性、设备向用户输出值的能力、 该设备允许用户输入值的能力,并且该设备是否具有可用于身份验证的 OOB 数据块。

配网邀请阶段.png

交换公钥阶段(Exchanging public keys)

根据未配网设备公钥的可用性,此步骤在配网器端有两种可能性。结合身份验证步骤的三种可能性,有六种可能的交换/身份验证路径。

一旦配网器确定了使用六种路径中的哪一种来给设备配网,配网器将发送一个配网开始PDU。

在收到来自配网器的配网开始(Provisioning Start) PDU 后,设备应将 Attention Timer 设置为 0x00。

配网器应从新设备在配网能力 PDU 中提供给它的算法中选择一个算法。如果配网器无法识别PDU中算法字段位代表的含义,则应忽略该位并仅从其支持的算法中进行选择。配网器应该选健壮性最强的算法。如果使用 OOB 技术无法获得公钥,则在配网器和未配网设备之间交换公钥。对于每次交换,配网器和未配网的设备都应生成一个新的密钥对。

如果OOB技术未传输密钥 ,则设备应发送其公钥。

当未配网设备的公钥未知时,公钥交换的消息序列如下图所示。

交换公钥.png

另外,如果公钥是通过OOB机制获得的,则配网器将生成一个新的密钥对,密钥对的公钥应该由配网器发送给设备,并使用适当的 OOB 技术从设备中读取静态公钥。

当未配网设备的公钥为 OOB 时,公钥交换的消息序列如下图所示。

OOB技术交换公钥.png

OOB技术获取公钥

配网器和设备应该相互检查对方提供的公钥或者OOB获取的公钥是否有效。当配网器或者设备收到无效的公钥,配网失败。

在已知公钥并经过验证后,(ECDHSecret) 应使用以下公式计算:

ECDHSecret = P-256(私钥,对方公钥)

计算完 ECDHSecret 后,配网器和未配网的设备将删除其在此步骤中生成的私钥-公钥对。

身份认证阶段(Authentication)

如果使用Output OOB authentication(输出 OOB 身份验证),则设备在收到配网器的Provisioning Start PDU后,作出响应,将使用某种方式在设备上输出单个数字或多个数字值。 输出动作的示例可以包括发出噪音、闪烁灯光、发出声音或在显示器上显示符号。
例如,如果设备是包含 LED 的门锁,则可以让该 LED 闪烁的方式使用Output OOB authentication(输出 OOB 身份验证)。

  1. 当使用 Authentication Method 0x02(Authentication with Output OOB)并且当 Authentication Action 的 Output OOB Action 值等于 Blink、Beep 或 Vibrate 时,设备应选择一个介于 0 和 10 之间的随机整数,即身份验证大小专有。该随机数应作为事件序列输出(例如,通过闪烁、哔哔声或以 500 毫秒开启和 500 毫秒关闭的占空比振动),序列之间的间隔至少为 3 秒,以允许用户确定序列的结尾。
  2. 当 Authentication Action 的 Output OOB Action 值等于 Output Numeric 时,使用由 Authentication Size 值确定的多个数字(即 ASCII 字符代码 0x30-0x39)输出(例如,显示或说出)该值。
  3. 当 Authentication Action 的 Output OOB Action 值等于 Output Alphanumeric 时,则使用由 Authentication Size 值确定的多个 ASCII 数字和大写字母(即 ASCII 字符代码 0x30-0x39 和 0x41-0x5A)输出该值。

配网操作者应该输入观察到的数字来验证该设备。

一旦输入了数字,就会进行确认交换,然后进行随机数字交换。 确认值是当前为止交换的所有值的加密哈希、尚未公开的随机数和输入的数字。 一旦交换了随机数,每个设备就可以验证对方。

来自输出 OOB、输入 OOB 或静态 OOB 的验证值在 AuthValue 中用于计算确认值,如下所述。

配网器的确认(confirmation)值通过以下方式计算:

设备的确认值通过以下方式计算:

其中:

ConfirmationKey = k1(ECDHSecret, ConfirmationSalt, “prck”)

ConfirmationSalt = s1(ConfirmationInputs)

ConfirmationInputs = ProvisioningInvitePDUValue || ProvisioningCapabilitiesPDUValue || ProvisioningStartPDUValue || PublicKeyProvisioner || PublicKeyDevice

ProvisioningInvitePDUValue 是发送或接收的 Provisioning Invite PDU 字段(不包括操作码)的值。

ProvisioningCapabilitiesPDUValue 是已发送或接收的 Provisioning Capabilities PDU 字段(不包括操作码)的值。

ProvisioningStartPDUValue 是已发送或接收的 Provisioning Start PDU 字段(不包括操作码)的值。

PublicKeyProvisioner 是由 Provisioner 发送的 Public Key PDU 中的 Public Key X 和 Public Key Y 字段的值。

PublicKeyDevice 是来自设备发送的公钥 PDU 或交付的 OOB 公钥的公钥 X 和公钥 Y 字段的值。

  • RandomProvisioner 是由 Provisioner 的随机数生成器生成的一串随机位。

  • RandomDevice 是由设备的随机数生成器生成的一串随机位。

  • AuthValue 是一个 128 位的值。 AuthValue 的计算取决于所使用的输出 OOB 操作、输入 OOB 操作或静态 OOB 类型的数据类型。

  • 如果数据类型是二进制,则 AuthValue 是一个字节数组。 如果该值小于 128 位,则其余位应设置为 0。

例如,如果值为 [0x12, 0x34, 0x56],则 AuthValue 是一个由 [0x12, 0x34, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00, 0x00]。

如果数据类型是 Numeric,则该数字应表示为无符号的 128 位值。

如果数据类型是字母数字,则 AuthValue 应该是字符的 ASCII 代码的串联。

  1. 例如,如果Authentication是 Output OOB 方法与 Output OOB Action 中的 Blink 一起使用,并且输出值为 5,则 AuthValue 应为 0x000000000000000000000000000000005。 然后按照大端定义对 AuthValue 进行编码,以计算确认值,从而生成一个由 [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00、0x00、0x05]。

  2. 例如,如果 Authentication 是 Output OOB 方法与 Output OOB Action 中的 Display Number 一起使用,并且显示的数字为 019655,则 AuthValue 应为 0x00000000000000000000000000004CC7。然后按照大端定义对 AuthValue 进行编码,以计算确认值,从而生成一个由 [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00、0x4C、0xC7]。

  3. 例如,如果 Authentication 是 Output OOB 方法与 Output OOB Action 中的 Display String 一起使用,并且显示的字符串是“123ABC”,则 AuthValue 应为 0x313233414243000000000000000000000,从而得到一个由 [0x31, 0x32, 0x33, 0x41, 0x42、0x43、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00]。

  4. 例如,如果使用 Authentication 是 No OOB 方法,则 AuthValue 应设置为 0x00000000000000000000000000000000,表示未通过身份验证,导致数组由 [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]。

配网器在收到 Provisioning Confirmation PDU 后应发送 Provisioning Random PDU。 设备应在根据收到的随机数验证确认值后发送 Provisioning Random。

使用 Output OOB 进行身份验证的消息时序图如下所示。

Output OOB认证时序图.png

当使用的 Authentication Method是 0x03 (Authentication with Input OOB) 方法并且

  • 当 Authentication Action 的 Input OOB Action 值等于 Push 时,配网器应选择 0 到 10 的 Authentication Size 的幂次方之间的随机整数。该随机数应按按压动作的数量输入。
  • 当 Authentication Action 的 Input OOB Action 值等于 Twist 时,配网器应选择 0 到 10 的 Authentication Size 次方的随机整数。该随机数应输入扭转动作的次数,直到输入控件上的值。
  • 当 Authentication Action 的 Input OOB Action 值等于 Input Numeric 时,通过输入由 Authentication Size 值确定的多个数字(可能使用数字键盘)来输入该值。
  • 当 Authentication Action 的 Input OOB Action 值等于 Input Alphanumeric 时,通过输入由 Authentication Size 值确定的多个 ASCII 数字和大写字母(可能使用字母数字键盘)来输入该值。

当 Authentication Action 的 Input OOB Action 值等于 Push 或 Twist 时,超过 5 秒没有检测到进一步的输入动作后,该值被认为已输入。当 Authentication Action 值的 Input OOB Action 等于 Input Numeric 或 Input Alphanumeric 时,该值被认为是在该设备上本地输入的(例如,通过按下 Enter 键)。

例如,灯开关可以允许用户通过按适当次数的按钮来输入随机数。

一旦执行了数字输入,设备将向配网器发送 Provisioning Input Complete PDU 以确认设备具有输入值。执行确认交换,然后执行随机数交换。确认值是当前为止交换的所有值的加密哈希、尚未公开的随机数和已输入的数字。一旦交换了随机数,每个设备就可以验证对方。

使用 Input OOB 进行身份验证的消息时序图如下所示。

Input OOB 认证时序图.png

如果使用static OOB 身份验证,或者 No OOB 身份验证,则配网器应使用确认和随机数交换。如果静态 OOB 值可用,则该值应包含在确认值中。 如果没有可用的静态 OOB 值,则该值应为零。

使用静态 OOB 或无 OOB 进行身份验证的消息时序图如下所示。

Static OOB或No OOB认证模式.png

分发配网数据(Distribution of provisioning data)

一旦设备通过身份验证,配网器和设备将使用计算出的 Diffie-Hellman 共享密钥 ECDHSecret ,并从该共享密钥生成会话密钥。 然后,该会话密钥将用于加密和验证配网数据。 然后,配网器应向设备发送包含加密和验证的配网数据的 Provisioning Data PDU。

配网数据格式如下表定义:

字段 长度(字节) 注释
Network Key 16 NetKey
Key Index 2 Index of the NetKey
Flags 1 Flags bitmask
IV Index 4 Current value of the IV Index
Unicast Address 2 Unicast address of the primary element

网络密钥Network Key应包含网络密钥NetKey

Key Index字段应标识 Network Key 的全局 NetKey Index。

Flags字段定义如下:

Bit位 定义
0 Key Refresh Flag
0: Key Refresh Phase 0
1: Key Refresh Phase 2
1 IV Update Flag
0: Normal operation
1: IV Update active
2-7 保留供将来使用

IV 索引字段应包含网络中当前的 IV 索引值。

Unicast Address应包含被添加到网络的节点的主要元素的单播地址。

Session key 应使用以下公式得出:

ProvisioningSalt = s1(ConfirmationSalt || RandomProvisioner || RandomDevice)

SessionKey = k1(ECDHSecret, ProvisioningSalt, “prsk”)

nonce应该是最低13个字节

SessionNonce = k1(ECDHSecret, ProvisioningSalt, “prsn”)

配网数据应该使用下面公司加密和验证

Provisioning Data = Network Key || Key Index || Flags || IV Index || Unicast Address

Encrypted Provisioning Data, Provisioning Data MIC = AES-CCM (SessionKey, SessionNonce, Provisioning Data)

配网数据的MIC值长度是8字节。

加密的配网数据和配网数据 MIC应用作Provisioning Data PDU 中的字段。配网器应将Provisioning Data PDU 发送到设备。

设备应该计算 device key。

分发配网数据的流程如下图:


分发配网数据流程.png

配网器和设备根据已建立的 Diffie-Hellman 共享密钥 ECDHSecret 使用 k1 密钥推导函数计算设备密钥。

在接收到来自配网器的 Provisioning Data PDU 后,设备应解密和验证配网数据。 在成功验证配网数据后,设备应设置网络密钥(由密钥索引标识),设置 IV 索引,根据 IV 更新标志设置 IV 更新过程状态,根据密钥刷新标志设置密钥刷新阶段 ,并使用从网络中得到的单播地址值的连续地址范围,将单播地址分配给从主元素开始的所有设备元素。成功完成地址分配过程后,设备应以 Provisioning Complete PDU 进行响应,以确认其已被配网。 如果地址分配无法成功完成,则设备应假定配置失败,并以错误代码参数设置为无法分配地址的 Provisioning Failed PDU 进行响应。

在处理来自配网器的 Provisioning Data PDU 之后,在 IV 更新过程中定义的用于更改 IV 更新过程状态的 96 小时时间限制不适用。

在接收到来自设备的 Provisioning Complete PDU 后,配网器应假定配网过程已成功完成,并且设备正在使用从单播地址的值开始的连续地址范围。地址范围的长度在 Provisioning Capabilities PDU 中报告给配网器。

作为程序的最后一步,配网器应断开配网承载器。 该设备现在是网状网络中的一个节点。

配网器不得重复使用已分配给设备的单播地址,并在 Provisioning Data PDU 中发送单播地址,直到配网器从同一设备 收到 Unprovisioned Device 信标 或 收到来自Mesh Provisioning Service 的标识设备用的Device UUID服务数据 。

配网安全性(Provisioning security)

所有设备和配网器都应支持 FIPS P-256 椭圆曲线算法。

配网可能是安全的或不安全的。安全配网需要以下方法:

  • FIPS P-256 椭圆曲线算法,不带内传输的公钥类型(即选择“使用 OOB 公钥”),以及任意大小的静态 OOB。
  • FIPS P-256 椭圆曲线算法; 输入数字、输入字母数字、输出数字或输出字母数字的 OOB 操作; 和 OOB 大小至少为 6 个字节。

建议设备和配网器支持 安全配网(Secure Provisioning)。 配网器可能仅支持安全配网来配置设备。 不支持安全配网的设备将无法由仅支持安全配网的配网器进行配网。

FIPS P-256 椭圆曲线定义

椭圆曲线由 p、a 和 b 指定,形式为:

对于 b 的每个值,可以开发出一条唯一的曲线。 在 NIST P-256 中:

b 已定义,其生成方法可以使用 SHA-1 验证。使用给定的种子 s 并使用

给出以下参数:

  • 素数模p,阶r,基点x-坐标Gx,基点y-坐标Gy。
  • 整数 p 和 r 以十进制形式给出; 位串和字段元素以十六进制给出。

p = 115792089210356248762697446949407573530086143415290314195533631308867097853951

r = 115792089210356248762697446949407573529996955224135760342422259061068512044369

b = 5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b

Gx = 6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296

Gy = 4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5

函数 P-256 定义如下。 给定一个整数 u,0 < u < r,以及曲线 E 上的一个点 V,值 P-256(u, V) 被计算为点 V 的第 u 个倍数 uV 的 x 坐标。

私钥应介于 1 和 r/2 之间,其中 r 是椭圆曲线上阿贝尔群的阶数(即介于 1 和 2256/2 之间)。
有效的公钥 Q=(X_Q,Y_Q),其中 X_Q 和 Y_Q 都在 0到top-1 范围,并且在相关曲线的有限域中满足方程(Y_Q)^2=(X_Q)^3+aX_Q+b\ (mod \ P) 的公钥。

配网密钥派生(Provisioning key derivation)

ConfirmationKey的派生过程


ConfirmationKey派生过程.png

SessionKeySessionNonce的派生过程

SessionKey和SessionNonce的派生过程.png

配网错误

无论配网协议因何原因失败,设备应永久删除所有存储的细节信息。没有恢复过程,配网器必须从头开始整个配网过程。

在处理协议错误时,配网协议是不对称的。

  • 当配网器遇到配网协议错误时,应立即断开配网承载器。在意外情况导致配网承载器关闭时,配网协议失败。

  • 当设备在配网协议中遇到除超时以外的错误时,它应发送带有适当错误代码的配网失败 PDU,并等待配网承载器关闭。 此时,从配网器接收到的任何配网协议 PDU 都被认为是非法的。

  • 配网器收到配网失败PDU 后,应假定配网失败并立即断开配网承载器。

  • 配网协议应具有 60 秒的最小超时,每次发送或接收配网协议 PDU 时都会重置该超时。当设备收到第一个配网 PDU 和配网器发送第一个配网PDU 时,超时计时开始。如果在超时到期之前没有收到 PDU,则协议失败。 在协议超时的情况下,设备不应发送配网失败 PDU。

你可能感兴趣的:(蓝牙mesh规范配网(最全))