预配置
配置是将设备添加到网状网络的过程。它需要两个设备以下角色运行:
供应器 表示网络所有者,并负责将新节点添加到网状网络。
被调配者是通过调配过程添加到网络的设备。在配置过程开始之前,被调配者是未配置的设备。
WM IoT SDK Bluetooth Mesh 堆栈中的 资源调配模块既支持被供应者角色的广告和 GATT 设置承载器,也支持供应器角色的高级配置承载。
资源调配过程
必须先配置所有 Bluetooth Mesh 节点,然后才能参与 Bluetooth Mesh 网络。配置 API 提供设备成为配置的 Mesh 节点所需的所有功能。资源调配是一个五步过程,涉及以下步骤:
信标
邀请
公钥交换
身份验证
预配置数据传输
信标
要启动配置过程,未配置的设备必须首先开始广播未配置的信标。这使得它对附近的供应器可见,
可以启动供应。要指示需要配置设备,请调用 bt_mesh_prov_enable()
。设备使用设备 UUID 和
OOB information
字段开始广播未配置的 prov
,如传递给 bt_mesh_init()
的 prov 参数中所指定的那样。
此外,可以指定统一资源标识符(URI),其可以将配置器指向某些带外信息的位置,例如设备的公钥或认证值数据库。
URI 在单独的信标中进行公告,未配置的信标包含 URI 哈希,以将两者绑定在一起。
统一资源标识符
统一资源标识符应遵循蓝牙核心规范补充中规定的格式。URI 必须以 URI 方案开始,该方案编码为单个 utf-8 数据点,或者以特殊的 none
方案开始,编码为 0x01
。可用方案列在 Bluetooth website.
编码 URI 的示例:
URI |
Encoded |
|
|
|
|
|
|
正在设置邀请
调配器通过发送调配邀请来启动调配过程。邀请会提示被调配者使用 Health Server 注意力状态 (如果可用)提醒自己注意。
未配置的设备通过提供其功能的列表(包括支持的带外身份验证方法和算法)来自动响应邀请。
公钥交换
在供应过程开始之前,供应器和未经验证的设备交换带内或带外(OOB)公钥。
带内公钥交换是配置过程的一部分,始终由未配置的设备和配置程序支持。
如果应用程序希望通过 OOB 支持公钥交换,则需要为网格堆栈提供公钥和私钥。 未配置的设备将在其功能中反映这一点。供应器通过任何可用的 OOB 机制获得公钥(例如,设备可以公布包含公钥的分组, 或者可以将其编码为打印在设备包装上的 QR 码)。请注意,即使未配置的设备已为带外交换指定公钥, 如果配置程序无法通过 OOB 机制检索公钥,则它也可以选择在带内交换公钥。在这种情况下,网格堆栈将为每个配置过程生成一个新的密钥对。
要在未配置的设备端启用 OOB 公钥支持,需要启用 CONFIG_BT_MESH_PROV_OOB_public_key
。
在启动配置过程之前,应用程序必须通过初始化指向 bt_mesh_prov.public_key_be
和 bt_mesh_prov.private_key_be
的指针来提供公钥和私钥。密钥需要以大端字节顺序提供。
要提供通过 OOB 获得的设备公钥,请在供应器端调用 bt_mesh_prov_remote_pub_key_set()
。
身份验证
在初始交换之后,供应器选择带外(OOB)身份验证方法。这允许用户确认供应器连接到的设备实际上是他们想要的设备,而不是恶意的第三方。
Provisioning API 支持被调配者的以下身份验证方法:
静态OOB: 将身份验证值分配给生产中的设备,供应器可以以特定于应用程序的方式查询该值。
输入OOB: 用户输入身份验证值。中列出了可用的输入操作
bt_mesh_input_action_t
.输出OOB: 向用户显示身份验证值。中列出了可用的输出操作
bt_mesh_output_action_t
.
应用程序必须为 bt_mesh_prov
中支持的身份验证方法提供回调,并在 bt_mesh_prov.output_actions
和 bt_mesh_prov.input_actions
中启用支持的操作。
选择输出 OOB 操作时,应在调用输出回调时向用户提供身份验证值,并保持该值,直到调用 bt_mesh_prov.input_complete
或 bt_mesh_prov.complete
回调。
如果 blink
, beep
或者 vibrate
,则应在延迟三秒或更长时间后重复该序列。
选择输入 OOB 操作时,当应用程序收到 bt_mesh_prov.Input
回调时,应提示用户。应通过 bt_mesh_input_string ()
或 bt_mesh_input_number()
将用户响应反馈给配置 API。如果在60秒内未记录用户响应,则中止配置过程。
如果供应者希望强制 OOB 身份验证,则必须使用 BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM
算法
数据传输
成功验证设备后,配置程序传输配置数据:
单播地址
网络密钥
IV 指数
网络标志
密钥更新
IV 更新
此外,为节点生成设备密钥。所有这些数据都由网格堆栈存储,并调用配置 bt_mesh_prov.complete
回调。
设置安全性
根据公钥交换机制和身份验证方法的选择,配置过程可以是安全的,也可以是不安全的。
2021年5月24日,ANSI disclosed Bluetooth Mesh 配置协议中的一组漏洞, 展示了如何在模拟和MITM攻击中利用闪烁、振动、推送、扭曲和输入/输出数字 OOB 方法提供的低熵。 作为响应,Bluetooth SIG 在 BluetoothMesh Profile Specification v1.0.1 erratum 16350 中将这些OOB方法重新分类为不安全的, 因为 AuthValue 可能是实时强制的。为了确保安全配置,应用程序应该使用静态 OOB 值和 OOB 公钥传输。
API 参考
- group bt_mesh_prov
Provisioning.
Typedefs
-
typedef enum bt_mesh_output_auth_action bt_mesh_output_action_t
Available Provisioning output authentication actions.
-
typedef enum bt_mesh_input_auth_action bt_mesh_input_action_t
Available Provisioning input authentication actions.
-
typedef enum bt_mesh_prov_bearer bt_mesh_prov_bearer_t
Available Provisioning bearers.
-
typedef enum bt_mesh_prov_oob_info_location bt_mesh_prov_oob_info_t
Out of Band information location.
Enums
-
enum bt_mesh_prov_authentication_alg
Available authentication algorithms.
Values:
-
enumerator BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM
-
enumerator BT_MESH_PROV_AUTH_HMAC_SHA256_AES_CCM
-
enumerator BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM
-
enum bt_mesh_oob_type
OOB Type field values.
Values:
-
enumerator BT_MESH_STATIC_OOB_AVAILABLE
Static OOB information available
-
enumerator BT_MESH_OOB_AUTH_REQUIRED
OOB authentication required
-
enumerator BT_MESH_STATIC_OOB_AVAILABLE
-
enum bt_mesh_output_auth_action
Available Provisioning output authentication actions.
Values:
-
enumerator BT_MESH_NO_OUTPUT
-
enumerator BT_MESH_BLINK
Blink
-
enumerator BT_MESH_BEEP
Beep
-
enumerator BT_MESH_VIBRATE
Vibrate
-
enumerator BT_MESH_DISPLAY_NUMBER
Output numeric
-
enumerator BT_MESH_DISPLAY_STRING
Output alphanumeric
-
enumerator BT_MESH_NO_OUTPUT
-
enum bt_mesh_input_auth_action
Available Provisioning input authentication actions.
Values:
-
enumerator BT_MESH_NO_INPUT
-
enumerator BT_MESH_PUSH
Push
-
enumerator BT_MESH_TWIST
Twist
-
enumerator BT_MESH_ENTER_NUMBER
Input number
-
enumerator BT_MESH_ENTER_STRING
Input alphanumeric
-
enumerator BT_MESH_NO_INPUT
-
enum bt_mesh_prov_bearer
Available Provisioning bearers.
Values:
-
enumerator BT_MESH_PROV_ADV
PB-ADV bearer
-
enumerator BT_MESH_PROV_GATT
PB-GATT bearer
-
enumerator BT_MESH_PROV_REMOTE
PB-Remote bearer
-
enumerator BT_MESH_PROV_ADV
-
enum bt_mesh_prov_oob_info_location
Out of Band information location.
Values:
-
enumerator BT_MESH_PROV_OOB_OTHER
Other
-
enumerator BT_MESH_PROV_OOB_URI
Electronic / URI
-
enumerator BT_MESH_PROV_OOB_2D_CODE
2D machine-readable code
-
enumerator BT_MESH_PROV_OOB_BAR_CODE
Bar Code
-
enumerator BT_MESH_PROV_OOB_NFC
Near Field Communication (NFC)
-
enumerator BT_MESH_PROV_OOB_NUMBER
Number
-
enumerator BT_MESH_PROV_OOB_STRING
String
-
enumerator BT_MESH_PROV_OOB_CERTIFICATE
Support for certificate-based provisioning
-
enumerator BT_MESH_PROV_OOB_RECORDS
Support for provisioning records
-
enumerator BT_MESH_PROV_OOB_ON_BOX
On box
-
enumerator BT_MESH_PROV_OOB_IN_BOX
Inside box
-
enumerator BT_MESH_PROV_OOB_ON_PAPER
On piece of paper
-
enumerator BT_MESH_PROV_OOB_IN_MANUAL
Inside manual
-
enumerator BT_MESH_PROV_OOB_ON_DEV
On device
-
enumerator BT_MESH_PROV_OOB_OTHER
Functions
-
int bt_mesh_input_string(const char *str)
Provide provisioning input OOB string.
This is intended to be called after the bt_mesh_prov input callback has been called with BT_MESH_ENTER_STRING as the action.
- 参数:
str – String.
- 返回:
Zero on success or (negative) error code otherwise.
-
int bt_mesh_input_number(uint32_t num)
Provide provisioning input OOB number.
This is intended to be called after the bt_mesh_prov input callback has been called with BT_MESH_ENTER_NUMBER as the action.
- 参数:
num – Number.
- 返回:
Zero on success or (negative) error code otherwise.
-
int bt_mesh_prov_remote_pub_key_set(const uint8_t public_key[64])
Provide Device public key.
- 参数:
public_key – Device public key in big-endian.
- 返回:
Zero on success or (negative) error code otherwise.
-
int bt_mesh_auth_method_set_input(bt_mesh_input_action_t action, uint8_t size)
Use Input OOB authentication.
Provisioner only.
Instruct the unprovisioned device to use the specified Input OOB authentication action. When using BT_MESH_PUSH, BT_MESH_TWIST or BT_MESH_ENTER_NUMBER, the bt_mesh_prov::output_number callback is called with a random number that has to be entered on the unprovisioned device.
When using BT_MESH_ENTER_STRING, the bt_mesh_prov::output_string callback is called with a random string that has to be entered on the unprovisioned device.
- 参数:
action – Authentication action used by the unprovisioned device.
size – Authentication size.
- 返回:
Zero on success or (negative) error code otherwise.
-
int bt_mesh_auth_method_set_output(bt_mesh_output_action_t action, uint8_t size)
Use Output OOB authentication.
Provisioner only.
Instruct the unprovisioned device to use the specified Output OOB authentication action. The bt_mesh_prov::input callback will be called.
When using BT_MESH_BLINK, BT_MESH_BEEP, BT_MESH_VIBRATE or BT_MESH_DISPLAY_NUMBER, and the application has to call bt_mesh_input_number with the random number indicated by the unprovisioned device.
When using BT_MESH_DISPLAY_STRING, the application has to call bt_mesh_input_string with the random string displayed by the unprovisioned device.
- 参数:
action – Authentication action used by the unprovisioned device.
size – Authentication size.
- 返回:
Zero on success or (negative) error code otherwise.
-
int bt_mesh_auth_method_set_static(const uint8_t *static_val, uint8_t size)
Use static OOB authentication.
Provisioner only.
Instruct the unprovisioned device to use static OOB authentication, and use the given static authentication value when provisioning.
- 参数:
static_val – Static OOB value.
size – Static OOB value size.
- 返回:
Zero on success or (negative) error code otherwise.
-
int bt_mesh_auth_method_set_none(void)
Don’t use OOB authentication.
Provisioner only.
Don’t use any authentication when provisioning new devices. This is the default behavior.
警告
Not using any authentication exposes the mesh network to impersonation attacks, where attackers can pretend to be the unprovisioned device to gain access to the network. Authentication is strongly encouraged.
- 返回:
Zero on success or (negative) error code otherwise.
-
int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers)
Enable specific provisioning bearers.
Enable one or more provisioning bearers.
- 参数:
bearers – Bit-wise or of provisioning bearers.
- 返回:
Zero on success or (negative) error code otherwise.
-
int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers)
Disable specific provisioning bearers.
Disable one or more provisioning bearers.
- 参数:
bearers – Bit-wise or of provisioning bearers.
- 返回:
Zero on success or (negative) error code otherwise.
-
int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, uint8_t flags, uint32_t iv_index, uint16_t addr, const uint8_t dev_key[16])
Provision the local Mesh Node.
This API should normally not be used directly by the application. The only exception is for testing purposes where manual provisioning is desired without an actual external provisioner.
- 参数:
net_key – Network Key
net_idx – Network Key Index
flags – Provisioning Flags
iv_index – IV Index
addr – Primary element address
dev_key – Device Key
- 返回:
Zero on success or (negative) error code otherwise.
-
int bt_mesh_provision_adv(const uint8_t uuid[16], uint16_t net_idx, uint16_t addr, uint8_t attention_duration)
Provision a Mesh Node using PB-ADV.
- 参数:
uuid – UUID
net_idx – Network Key Index
addr – Address to assign to remote device. If addr is 0, the lowest available address will be chosen.
attention_duration – The attention duration to be send to remote device
- 返回:
Zero on success or (negative) error code otherwise.
-
int bt_mesh_provision_gatt(const uint8_t uuid[16], uint16_t net_idx, uint16_t addr, uint8_t attention_duration)
Provision a Mesh Node using PB-GATT.
- 参数:
uuid – UUID
net_idx – Network Key Index
addr – Address to assign to remote device. If addr is 0, the lowest available address will be chosen.
attention_duration – The attention duration to be send to remote device
- 返回:
Zero on success or (negative) error code otherwise.
-
int bt_mesh_provision_remote(struct bt_mesh_rpr_cli *cli, const struct bt_mesh_rpr_node *srv, const uint8_t uuid[16], uint16_t net_idx, uint16_t addr)
Provision a Mesh Node using PB-Remote.
- 参数:
cli – Remote Provisioning Client Model to provision with.
srv – Remote Provisioning Server that should be used to tunnel the provisioning.
uuid – UUID of the unprovisioned node
net_idx – Network Key Index to give to the unprovisioned node.
addr – Address to assign to remote device. If addr is 0, the lowest available address will be chosen.
- 返回:
Zero on success or (negative) error code otherwise.
-
int bt_mesh_reprovision_remote(struct bt_mesh_rpr_cli *cli, struct bt_mesh_rpr_node *srv, uint16_t addr, bool comp_change)
Reprovision a Mesh Node using PB-Remote.
Reprovisioning can be used to change the device key, unicast address and composition data of another device. The reprovisioning procedure uses the same protocol as normal provisioning, with the same level of security.
There are three tiers of reprovisioning: 1. Refreshing the device key 2. Refreshing the device key and node address. Composition data may change, including the number of elements. 3. Refreshing the device key and composition data, in case the composition data of the target node changed due to a firmware update or a similar procedure.
The target node indicates that its composition data changed by instantiating its composition data page 128. If the number of elements have changed, it may be necessary to move the unicast address of the target node as well, to avoid overlapping addresses.
备注
Changing the unicast addresses of the target node requires changes to all nodes that publish directly to any of the target node’s models.
- 参数:
cli – Remote Provisioning Client Model to provision on
srv – Remote Provisioning Server to reprovision
addr – Address to assign to remote device. If addr is 0, the lowest available address will be chosen.
comp_change – The target node has indicated that its composition data has changed. Note that the target node will reject the update if this isn’t true.
- 返回:
Zero on success or (negative) error code otherwise.
-
bool bt_mesh_is_provisioned(void)
Check if the local node has been provisioned.
This API can be used to check if the local node has been provisioned or not. It can e.g. be helpful to determine if there was a stored network in flash, i.e. if the network was restored after calling settings_load().
- 返回:
True if the node is provisioned. False otherwise.
-
struct bt_mesh_dev_capabilities
Device Capabilities.
-
struct bt_mesh_prov
Provisioning properties & capabilities.
-
typedef enum bt_mesh_output_auth_action bt_mesh_output_action_t