Merge branch 'feat/show_how_to_use_smp_in_blufi_example_v5.5' into 'release/v5.5'

feat(ble/blufi): Support setting BLE encryption for blufi (v5.5)

See merge request espressif/esp-idf!44143
This commit is contained in:
Island
2025-12-29 12:11:21 +08:00
10 changed files with 322 additions and 44 deletions
+30 -18
View File
@@ -12,6 +12,12 @@ Fragmenting, data encryption, and checksum verification in the BluFi layer are t
You can customize symmetric encryption, asymmetric encryption, and checksum support customization. Here we use the DH algorithm for key negotiation, 128-AES algorithm for data encryption, and CRC16 algorithm for checksum verification.
.. note::
**BluFi is currently in maintenance mode, and no new features are planned.**
For new projects or when adding Wi-Fi provisioning, we recommend using the `network_provisioning`_ component, which offers a modern, secure, and actively maintained solution.
Getting Started
-----------------
@@ -665,43 +671,46 @@ The Security Implementation of {IDF_TARGET_NAME}
The application layer needs to register several security-related functions to BluFi:
.. code-block:: c
.. code-block:: c
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free)
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free)
This function is for {IDF_TARGET_NAME} to receive normal data during negotiation. After processing is completed, the data will be transmitted using Output_data and Output_len.
This function is for {IDF_TARGET_NAME} to receive normal data during negotiation. After processing is completed, the data will be transmitted using Output_data and Output_len.
BluFi will send output_data from Negotiate_data_handler after Negotiate_data_handler is called.
BluFi will send output_data from Negotiate_data_handler after Negotiate_data_handler is called.
Here are two "*", which means the length of the data to be emitted is unknown. Therefore, it requires the function to allocate itself (malloc) or point to the global variable to inform whether the memory needs to be freed by NEED_FREE.
Here are two ``*``, which means the length of the data to be emitted is unknown. Therefore, it requires the function to allocate itself (malloc) or point to the global variable to inform whether the memory needs to be freed by NEED_FREE.
.. code-block:: c
.. code-block:: c
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
The data to be encrypted and decrypted must be in the same length. The IV8 is an 8-bit sequence value of frames, which can be used as a 8-bit of IV.
The data to be encrypted and decrypted must be in the same length. The IV8 is an 8-bit sequence value of frames, which can be used as a 8-bit of IV.
.. code-block:: c
.. code-block:: c
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
The data to be encrypted and decrypted must be in the same length. The IV8 is an 8-bit sequence value of frames, which can be used as an 8-bit of IV.
The data to be encrypted and decrypted must be in the same length. The IV8 is an 8-bit sequence value of frames, which can be used as an 8-bit of IV.
.. code-block:: c
.. code-block:: c
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len)
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len)
This function is used to compute CheckSum and return a value of CheckSum. BluFi uses the returned value to compare the CheckSum of the frame.
This function is used to compute CheckSum and return a value of CheckSum. BluFi uses the returned value to compare the CheckSum of the frame.
5. Implementing Stronger Security
The default encryption/decryption logic in this example is intended for demonstration purposes only.
The default encryption and decryption logic in this example is intended for demonstration purposes only. If your application requires stronger security guarantees, consider one of the following approaches:
If you require a higher level of security, it is recommended to implement your own encryption, decryption, authentication, and checksum algorithms by customizing the security callbacks in the BluFi framework.
- **Custom Security Callbacks**: Implement your own encryption, decryption, authentication, and checksum algorithms by defining custom security callbacks in the Blufi framework:
.. code-block:: c
.. code-block:: c
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks)
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks);
- **Network Provisioning Component (recommended)**: For a more robust, secure, and production-ready provisioning solution, consider using the `network_provisioning`_ component.
GATT Related Instructions
----------------------------
@@ -714,3 +723,6 @@ BluFi Service UUID: 0xFFFF, 16 bit
BluFi (the mobile > {IDF_TARGET_NAME}): 0xFF01, writable
Blufi ({IDF_TARGET_NAME} > the mobile phone): 0xFF02, readable and callable
.. _network_provisioning: https://github.com/espressif/idf-extra-components/tree/master/network_provisioning
+30 -18
View File
@@ -12,6 +12,12 @@ BluFi 流程的关键部分包括数据的分片、加密以及校验和验证
用户可按需自定义用于对称加密、非对称加密以及校验的算法。此处,我们采用 DH 算法进行密钥协商,128-AES 算法用于数据加密,CRC16 算法用于校验和验证。
.. note::
**BluFi 目前处于维护模式,暂不计划增加新功能。**
对于新项目或需要添加 Wi-Fi 配网功能的场景,建议使用 `network_provisioning`_ 组件。该组件更加现代、安全,并且仍在积极维护中。
快速入门
--------
@@ -665,43 +671,46 @@ ACK 帧格式 (8 bit)
应用层需向 BluFi 注册以下几个与安全相关的函数:
.. code-block:: c
.. code-block:: c
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free)
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free)
该函数用来接收协商期间的正常数据 (normal data)。数据处理完成后,需要将待发送的数据使用 output_data 和 output_len 传出。
该函数用来接收协商期间的正常数据 (normal data)。数据处理完成后,需要将待发送的数据使用 output_data 和 output_len 传出。
BluFi 会在调用完 Negotiate_data_handler 后,发送 Negotiate_data_handler 传出的 output_data。
BluFi 会在调用完 Negotiate_data_handler 后,发送 Negotiate_data_handler 传出的 output_data。
这里的两个 “*” 是因为需要发出去的数据长度未知,所以需要函数自行分配 (malloc) 或者指向全局变量,并告知是否需要通过 NEED_FREE 释放内存。
这里的两个 ``*`` 是因为需要发出去的数据长度未知,所以需要函数自行分配 (malloc) 或者指向全局变量,并告知是否需要通过 NEED_FREE 释放内存。
.. code-block:: c
.. code-block:: c
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
加密和解密的数据长度必须一致。其中 IV8 为帧的 8 位序列,可作为 IV 的某 8 个位来使用。
加密和解密的数据长度必须一致。其中 IV8 为帧的 8 位序列,可作为 IV 的某 8 个位来使用。
.. code-block:: c
.. code-block:: c
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
加密和解密的数据长度必须一致。其中 IV8 为帧的 8 位序列,可作为 IV 的某 8 个位来使用。
加密和解密的数据长度必须一致。其中 IV8 为帧的 8 位序列,可作为 IV 的某 8 个位来使用。
.. code-block:: c
.. code-block:: c
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len)
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len)
该函数用来进行校验,返回值为校验的值。BluFi 会使用该函数返回值与帧的校验值进行比较。
该函数用来进行校验,返回值为校验的值。BluFi 会使用该函数返回值与帧的校验值进行比较。
5. 实现更强的安全性
示例中默认加密/解密逻辑仅用于演示目的。
示例中默认加密解密逻辑仅用于演示目的。如果你的应用需要更高的安全保障,可选择以下任一方法:
如果需要更高等级的安全性,建议通过自定义 BluFi 框架中的安全回调函数,实现您自己的加密、解密、认证以及校验算法
- **自定义安全回调**:通过改写 BluFi 框架中的安全回调函数,自定义加密、解密、认证以及校验算法
.. code-block:: c
.. code-block:: c
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks)
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks);
- **网络配网组件(推荐使用)**:使用 ESP-IDF 提供的 `network_provisioning`_ 组件,实现安全、可直接使用的配网解决方案。
GATT 相关说明
@@ -715,3 +724,6 @@ BluFi Service UUID 0xFFFF16 bit
BluFi(手机 > {IDF_TARGET_NAME})特性:0xFF01,主要权限:可写
BluFi{IDF_TARGET_NAME} > 手机)特性:0xFF02,主要权限:可读可通知
.. _network_provisioning: https://github.com/espressif/idf-extra-components/tree/master/network_provisioning