1 /*
2  * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef _ESP_BLE_MESH_PROVISIONING_API_H_
8 #define _ESP_BLE_MESH_PROVISIONING_API_H_
9 
10 #include "esp_ble_mesh_defs.h"
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 /** @brief: event, event code of provisioning events; param, parameters of provisioning events */
17 typedef void (* esp_ble_mesh_prov_cb_t)(esp_ble_mesh_prov_cb_event_t event,
18                                         esp_ble_mesh_prov_cb_param_t *param);
19 
20 /**
21  * @brief         Register BLE Mesh provisioning callback.
22  *
23  * @param[in]     callback: Pointer to the callback function.
24  *
25  * @return        ESP_OK on success or error code otherwise.
26  *
27  */
28 esp_err_t esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb_t callback);
29 
30 /**
31  * @brief         Check if a device has been provisioned.
32  *
33  * @return        TRUE if the device is provisioned, FALSE if the device is unprovisioned.
34  *
35  */
36 bool esp_ble_mesh_node_is_provisioned(void);
37 
38 /**
39  * @brief         Enable specific provisioning bearers to get the device ready for provisioning.
40  *
41  * @note          PB-ADV: send unprovisioned device beacon.
42  *                PB-GATT: send connectable advertising packets.
43  *
44  * @param         bearers: Bit-wise OR of provisioning bearers.
45  *
46  * @return        ESP_OK on success or error code otherwise.
47  *
48  */
49 esp_err_t esp_ble_mesh_node_prov_enable(esp_ble_mesh_prov_bearer_t bearers);
50 
51 /**
52  * @brief         Disable specific provisioning bearers to make a device inaccessible for provisioning.
53  *
54  * @param         bearers: Bit-wise OR of provisioning bearers.
55  *
56  * @return        ESP_OK on success or error code otherwise.
57  *
58  */
59 esp_err_t esp_ble_mesh_node_prov_disable(esp_ble_mesh_prov_bearer_t bearers);
60 
61 /**
62  * @brief        Unprovisioned device set own oob public key & private key pair.
63  *
64  * @note         In order to avoid suffering brute-forcing attack (CVE-2020-26559).
65  *               The Bluetooth SIG recommends that potentially vulnerable mesh provisioners
66  *               use an out-of-band mechanism to exchange the public keys.
67  *               So as an unprovisioned device, it should use this function to input
68  *               the Public Key exchanged through the out-of-band mechanism.
69  *
70  * @param[in]    pub_key_x:   Unprovisioned device's Public Key X
71  * @param[in]    pub_key_y:   Unprovisioned device's Public Key Y
72  * @param[in]    private_key: Unprovisioned device's Private Key
73  *
74  * @return       ESP_OK on success or error code otherwise.
75  */
76 esp_err_t esp_ble_mesh_node_set_oob_pub_key(uint8_t pub_key_x[32], uint8_t pub_key_y[32],
77                                             uint8_t private_key[32]);
78 
79 /**
80  * @brief        Provide provisioning input OOB number.
81  *
82  * @note         This is intended to be called if the user has received ESP_BLE_MESH_NODE_PROV_INPUT_EVT
83  *               with ESP_BLE_MESH_ENTER_NUMBER as the action.
84  *
85  * @param[in]    number: Number input by device.
86  *
87  * @return       ESP_OK on success or error code otherwise.
88  *
89  */
90 esp_err_t esp_ble_mesh_node_input_number(uint32_t number);
91 
92 /**
93  * @brief        Provide provisioning input OOB string.
94  *
95  * @note         This is intended to be called if the user has received ESP_BLE_MESH_NODE_PROV_INPUT_EVT
96  *               with ESP_BLE_MESH_ENTER_STRING as the action.
97  *
98  * @param[in]    string: String input by device.
99  *
100  * @return       ESP_OK on success or error code otherwise.
101  *
102  */
103 esp_err_t esp_ble_mesh_node_input_string(const char *string);
104 
105 /**
106  * @brief        Using this function, an unprovisioned device can set its own device name,
107  *               which will be broadcasted in its advertising data.
108  *
109  * @param[in]    name: Unprovisioned device name
110  *
111  * @note         This API applicable to PB-GATT mode only by setting the name to the scan response data,
112  *               it doesn't apply to PB-ADV mode.
113  *
114  * @return       ESP_OK on success or error code otherwise.
115  *
116  */
117 esp_err_t esp_ble_mesh_set_unprovisioned_device_name(const char *name);
118 
119 /**
120  * @brief        Provisioner inputs unprovisioned device's oob public key.
121  *
122  * @note         In order to avoid suffering brute-forcing attack (CVE-2020-26559).
123  *               The Bluetooth SIG recommends that potentially vulnerable mesh provisioners
124  *               use an out-of-band mechanism to exchange the public keys.
125  *
126  * @param[in]    link_idx:   The provisioning link index
127  * @param[in]    pub_key_x:  Unprovisioned device's Public Key X
128  * @param[in]    pub_key_y:  Unprovisioned device's Public Key Y
129  *
130  * @return       ESP_OK on success or error code otherwise.
131  */
132 esp_err_t esp_ble_mesh_provisioner_read_oob_pub_key(uint8_t link_idx, uint8_t pub_key_x[32],
133                                                     uint8_t pub_key_y[32]);
134 
135 /**
136  * @brief        Provide provisioning input OOB string.
137  *
138  *               This is intended to be called after the esp_ble_mesh_prov_t prov_input_num
139  *               callback has been called with ESP_BLE_MESH_ENTER_STRING as the action.
140  *
141  * @param[in]    string:   String input by Provisioner.
142  * @param[in]    link_idx: The provisioning link index.
143  *
144  * @return       ESP_OK on success or error code otherwise.
145  *
146  */
147 esp_err_t esp_ble_mesh_provisioner_input_string(const char *string, uint8_t link_idx);
148 
149 /**
150  * @brief        Provide provisioning input OOB number.
151  *
152  *               This is intended to be called after the esp_ble_mesh_prov_t prov_input_num
153  *               callback has been called with ESP_BLE_MESH_ENTER_NUMBER as the action.
154  *
155  * @param[in]    number:   Number input by Provisioner.
156  * @param[in]    link_idx: The provisioning link index.
157  *
158  * @return       ESP_OK on success or error code otherwise.
159  *
160  */
161 esp_err_t esp_ble_mesh_provisioner_input_number(uint32_t number, uint8_t link_idx);
162 
163 /**
164  * @brief        Enable one or more provisioning bearers.
165  *
166  * @param[in]    bearers: Bit-wise OR of provisioning bearers.
167  *
168  * @note         PB-ADV: Enable BLE scan.
169  *               PB-GATT: Initialize corresponding BLE Mesh Proxy info.
170  *
171  * @return       ESP_OK on success or error code otherwise.
172  *
173  */
174 esp_err_t esp_ble_mesh_provisioner_prov_enable(esp_ble_mesh_prov_bearer_t bearers);
175 
176 /**
177  * @brief        Disable one or more provisioning bearers.
178  *
179  * @param[in]    bearers: Bit-wise OR of provisioning bearers.
180  *
181  * @note         PB-ADV: Disable BLE scan.
182  *               PB-GATT: Break any existing BLE Mesh Provisioning connections.
183  *
184  * @return       ESP_OK on success or error code otherwise.
185  *
186  */
187 esp_err_t esp_ble_mesh_provisioner_prov_disable(esp_ble_mesh_prov_bearer_t bearers);
188 
189 /**
190  * @brief        Add unprovisioned device info to the unprov_dev queue.
191  *
192  * @param[in]    add_dev: Pointer to a struct containing the device information
193  * @param[in]    flags: Flags indicate several operations on the device information
194  *                      - Remove device information from queue after device has been provisioned (BIT0)
195  *                      - Start provisioning immediately after device is added to queue (BIT1)
196  *                      - Device can be removed if device queue is full (BIT2)
197  *
198  * @return       ESP_OK on success or error code otherwise.
199  *
200  * @note:        1. Currently address type only supports public address and static random address.
201  *               2. If device UUID and/or device address as well as address type already exist in the
202  *                  device queue, but the bearer is different from the existing one, add operation
203  *                  will also be successful and it will update the provision bearer supported by
204  *                  the device.
205  *               3. For example, if the Provisioner wants to add an unprovisioned device info before
206  *                  receiving its unprovisioned device beacon or Mesh Provisioning advertising packets,
207  *                  the Provisioner can use this API to add the device info with each one or both of
208  *                  device UUID and device address added. When the Provisioner gets the device's
209  *                  advertising packets, it will start provisioning the device internally.
210  *                  - In this situation, the Provisioner can set bearers with each one or both of
211  *                    ESP_BLE_MESH_PROV_ADV and ESP_BLE_MESH_PROV_GATT enabled, and cannot set flags
212  *                    with ADD_DEV_START_PROV_NOW_FLAG enabled.
213  *               4. Another example is when the Provisioner receives the unprovisioned device's beacon or
214  *                  Mesh Provisioning advertising packets, the advertising packets will be reported on to
215  *                  the application layer using the callback registered by the function
216  *                  esp_ble_mesh_register_prov_callback. And in the callback, the Provisioner
217  *                  can call this API to start provisioning the device.
218  *                  - If the Provisioner uses PB-ADV to provision, either one or both of device UUID and
219  *                    device address can be added, bearers shall be set with ESP_BLE_MESH_PROV_ADV
220  *                    enabled and the flags shall be set with ADD_DEV_START_PROV_NOW_FLAG enabled.
221  *                  - If the Provisioner uses PB-GATT to provision, both the device UUID and device
222  *                    address need to be added, bearers shall be set with ESP_BLE_MESH_PROV_GATT enabled,
223  *                    and the flags shall be set with ADD_DEV_START_PROV_NOW_FLAG enabled.
224  *                  - If the Provisioner just wants to store the unprovisioned device info when receiving
225  *                    its advertising packets and start to provision it the next time (e.g. after receiving
226  *                    its advertising packets again), then it can add the device info with either one or both
227  *                    of device UUID and device address included. Bearers can be set with either one or both
228  *                    of ESP_BLE_MESH_PROV_ADV and ESP_BLE_MESH_PROV_GATT enabled (recommend to enable the
229  *                    bearer which will receive its advertising packets, because if the other bearer is
230  *                    enabled, the Provisioner is not aware if the device supports the bearer), and flags
231  *                    cannot be set with ADD_DEV_START_PROV_NOW_FLAG enabled.
232  *                  - Note: ESP_BLE_MESH_PROV_ADV, ESP_BLE_MESH_PROV_GATT and ADD_DEV_START_PROV_NOW_FLAG
233  *                          can not be enabled at the same time.
234  *
235  */
236 esp_err_t esp_ble_mesh_provisioner_add_unprov_dev(esp_ble_mesh_unprov_dev_add_t *add_dev,
237                                                   esp_ble_mesh_dev_add_flag_t flags);
238 
239 /** @brief Provision an unprovisioned device and assign a fixed unicast address for it in advance.
240  *
241  *  @param[in] uuid:         Device UUID of the unprovisioned device
242  *  @param[in] addr:         Device address of the unprovisioned device
243  *  @param[in] addr_type:    Device address type of the unprovisioned device
244  *  @param[in] bearer:       Provisioning bearer going to be used by Provisioner
245  *  @param[in] oob_info:     OOB info of the unprovisioned device
246  *  @param[in] unicast_addr: Unicast address going to be allocated for the unprovisioned device
247  *
248  *  @return Zero on success or (negative) error code otherwise.
249  *
250  *  @note: 1. Currently address type only supports public address and static random address.
251  *         2. Bearer must be equal to ESP_BLE_MESH_PROV_ADV or ESP_BLE_MESH_PROV_GATT, since
252  *            Provisioner will start to provision a device immediately once this function is
253  *            invoked. And the input bearer must be identical with the one within the parameters
254  *            of the ESP_BLE_MESH_PROVISIONER_RECV_UNPROV_ADV_PKT_EVT event.
255  *         3. If this function is used by a Provisioner to provision devices, the application
256  *            should take care of the assigned unicast address and avoid overlap of the unicast
257  *            addresses of different nodes.
258  *         4. Recommend to use only one of the functions "esp_ble_mesh_provisioner_add_unprov_dev"
259  *            and "esp_ble_mesh_provisioner_prov_device_with_addr" by a Provisioner.
260  */
261 esp_err_t esp_ble_mesh_provisioner_prov_device_with_addr(const uint8_t uuid[16],
262                                                          esp_ble_mesh_bd_addr_t addr,
263                                                          esp_ble_mesh_addr_type_t addr_type,
264                                                          esp_ble_mesh_prov_bearer_t bearer,
265                                                          uint16_t oob_info, uint16_t unicast_addr);
266 
267 /**
268  * @brief        Delete device from queue, and reset current provisioning link with the device.
269  *
270  * @note         If the device is in the queue, remove it from the queue; if the device is
271  *               being provisioned, terminate the provisioning procedure. Either one of the
272  *               device address or device UUID can be used as input.
273  *
274  * @param[in]    del_dev: Pointer to a struct containing the device information.
275  *
276  * @return       ESP_OK on success or error code otherwise.
277  *
278  */
279 esp_err_t esp_ble_mesh_provisioner_delete_dev(esp_ble_mesh_device_delete_t *del_dev);
280 
281 /**
282  * @brief        Callback for Provisioner that received advertising packets from unprovisioned devices which are
283  *               not in the unprovisioned device queue.
284  *
285  *               Report on the unprovisioned device beacon and mesh provisioning service adv data to application.
286  *
287  * @param[in]    addr: Pointer to the unprovisioned device address.
288  * @param[in]    addr_type: Unprovisioned device address type.
289  * @param[in]    adv_type: Adv packet type(ADV_IND or ADV_NONCONN_IND).
290  * @param[in]    dev_uuid: Unprovisioned device UUID pointer.
291  * @param[in]    oob_info: OOB information of the unprovisioned device.
292  * @param[in]    bearer: Adv packet received from PB-GATT or PB-ADV bearer.
293  *
294  */
295 typedef void (*esp_ble_mesh_prov_adv_cb_t)(const esp_ble_mesh_bd_addr_t addr, const esp_ble_mesh_addr_type_t addr_type,
296                                            const uint8_t adv_type, const uint8_t *dev_uuid,
297                                            uint16_t oob_info, esp_ble_mesh_prov_bearer_t bearer);
298 
299 /**
300  * @brief         This function is called by Provisioner to set the part of the device UUID
301  *                to be compared before starting to provision.
302  *
303  * @param[in]     match_val: Value to be compared with the part of the device UUID.
304  * @param[in]     match_len: Length of the compared match value.
305  * @param[in]     offset: Offset of the device UUID to be compared (based on zero).
306  * @param[in]     prov_after_match: Flag used to indicate whether provisioner should start to provision
307  *                                  the device immediately if the part of the UUID matches.
308  *
309  * @return        ESP_OK on success or error code otherwise.
310  *
311  */
312 esp_err_t esp_ble_mesh_provisioner_set_dev_uuid_match(const uint8_t *match_val, uint8_t match_len,
313                                                       uint8_t offset, bool prov_after_match);
314 
315 /**
316  * @brief         This function is called by Provisioner to set provisioning data information
317  *                before starting to provision.
318  *
319  * @param[in]     prov_data_info: Pointer to a struct containing net_idx or flags or iv_index.
320  *
321  * @return        ESP_OK on success or error code otherwise.
322  *
323  */
324 esp_err_t esp_ble_mesh_provisioner_set_prov_data_info(esp_ble_mesh_prov_data_info_t *prov_data_info);
325 
326 /**
327  * @brief         This function is called by Provisioner to set static oob value used for provisioning.
328  *
329  * @note          The Bluetooth SIG recommends that mesh implementations enforce a randomly selected
330  *                AuthValue using all of the available bits, where permitted by the implementation.
331  *                A large entropy helps ensure that a brute-force of the AuthValue, even a static
332  *                AuthValue, cannot normally be completed in a reasonable time (CVE-2020-26557).
333  *
334  *                AuthValues selected using a cryptographically secure random or pseudorandom number
335  *                generator and having the maximum permitted entropy (128-bits) will be most difficult
336  *                to brute-force. AuthValues with reduced entropy or generated in a predictable manner
337  *                will not grant the same level of protection against this vulnerability. Selecting a
338  *                new AuthValue with each provisioning attempt can also make it more difficult to launch
339  *                a brute-force attack by requiring the attacker to restart the search with each
340  *                provisioning attempt (CVE-2020-26556).
341  *
342  * @param[in]     value:  Pointer to the static oob value.
343  * @param[in]     length: Length of the static oob value.
344  *
345  * @return        ESP_OK on success or error code otherwise.
346  *
347  */
348 esp_err_t esp_ble_mesh_provisioner_set_static_oob_value(const uint8_t *value, uint8_t length);
349 
350 /**
351  * @brief         This function is called by Provisioner to set own Primary element address.
352  *
353  * @note          This API must be invoked when BLE Mesh initialization is completed successfully,
354  *                and can be invoked before Provisioner functionality is enabled.
355  *                Once this API is invoked successfully, the prov_unicast_addr value in the struct
356  *                esp_ble_mesh_prov_t will be ignored, and Provisioner will use this address as its
357  *                own primary element address.
358  *                And if the unicast address going to assigned for the next unprovisioned device is
359  *                smaller than the input address + element number of Provisioner, then the address
360  *                for the next unprovisioned device will be recalculated internally.
361  *
362  * @param[in]     addr: Unicast address of the Primary element of Provisioner.
363  *
364  * @return        ESP_OK on success or error code otherwise.
365  *
366  */
367 esp_err_t esp_ble_mesh_provisioner_set_primary_elem_addr(uint16_t addr);
368 
369 /**
370  * @brief         This function is called to set provisioning data information before starting
371  *                fast provisioning.
372  *
373  * @param[in]     fast_prov_info: Pointer to a struct containing unicast address range, net_idx, etc.
374  *
375  * @return        ESP_OK on success or error code otherwise.
376  *
377  */
378 esp_err_t esp_ble_mesh_set_fast_prov_info(esp_ble_mesh_fast_prov_info_t *fast_prov_info);
379 
380 /**
381  * @brief         This function is called to start/suspend/exit fast provisioning.
382  *
383  * @param[in]     action: fast provisioning action (i.e. enter, suspend, exit).
384  *
385  * @return        ESP_OK on success or error code otherwise.
386  *
387  */
388 esp_err_t esp_ble_mesh_set_fast_prov_action(esp_ble_mesh_fast_prov_action_t action);
389 
390 #ifdef __cplusplus
391 }
392 #endif
393 
394 #endif /* _ESP_BLE_MESH_PROVISIONING_API_H_ */
395