Merge branch 'doc/api-guides_blufi' into 'master'

Doc/api guides blufi

See merge request idf/esp-idf!2376
This commit is contained in:
Angus Gratton 2018-06-07 08:54:27 +08:00
commit d7d559a489
4 changed files with 886 additions and 1 deletions

View file

@ -0,0 +1,431 @@
BluFi
^^^^^
Overview
--------
The BluFi for ESP32 is a Wi-Fi network configuration function via Bluetooth channel. It provides a secure protocol to pass Wi-Fi configuration and credentials to the ESP32. Using this information ESP32 can then e.g. connect to an AP or establish a SoftAP.
Fragmenting, data encryption, checksum verification in the BluFi layer are the key elements of this process.
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.
The BluFi Flow
---------------
The BluFi networking flow includes the configuration of the SoftAP and Station.
The following uses Station as an example to illustrate the core parts of the procedure, including broadcast, connection, service discovery, negotiation of the shared key, data transmission, connection status backhaul.
1. Set the ESP32 into GATT Server mode and then it will send broadcasts with specific *advertising data*. You can customize this broadcast as needed, which is not a part of the BluFi Profile.
2. Use the App installed on the mobile phone to search for this particular broadcast. The mobile phone will connect to ESP32 as the GATT Client once the broadcast is confirmed. The App used during this part is up to you.
3. After the GATT connection is successfully established, the mobile phone will send a data frame for key negotiation to ESP32 (see the section :ref:`frame_formats` for details).
4. After ESP32 receives the data frame of key negotiation, it will parse the content according to the user-defined negotiation method.
5. The mobile phone works with ESP32 for key negotiation using the encryption algorithms such as DH, RSA or ECC.
6. After the negotiation process is completed, the mobile phone will send a control frame for security-mode setup to ESP32.
7. When receiving this control frame, ESP32 will be able to encrypt and decrypt the communication data using the shared key and the security configuration.
8. The mobile phone sends the data frame defined in the section of :ref:`frame_formats`with the Wi-Fi configuration information to ESP32, including SSID, password, etc.
9. The mobile phone sends a control frame of Wi-Fi connection request to ESP32. When receiving this control frame, ESP32 will regard the communication of essential information as done and get ready to connect to the Wi-Fi.
10. After connecting to the Wi-Fi, ESP32 will send a control frame of Wi-Fi connection status report to the mobile phoneto report the connection status. At this point the networking procedure is completed.
.. note::
1. After ESP32 receives the control frame of security-mode configuration, it will execute the operations in accordance with the defined security mode.
2. The data lengths before and after symmetric encryption/decryption must stay the same. It also supports in-place encryption and decryption.
The flow chat of BluFi
-----------------------
.. seqdiag::
:caption: BluFi Flow Chart
:align: center
seqdiag blufi {
activation = none;
node_width = 80;
node_height = 60;
edge_length = 380;
span_height = 10;
default_fontsize = 12;
Phone <- ESP32 [label="Advertising"];
Phone -> ESP32 [label="Create GATT connection"];
Phone <- ESP32 [label="Negotiate key procedure"];
Phone -> ESP32 [label="Negotiate key procedure"];
Phone -> ESP32 [label="CTRL: Set ESP32 to Phone Security mode"];
Phone -> ESP32 [label="DATA: SSID"];
Phone -> ESP32 [label="DATA: Password"];
Phone -> ESP32 [label="DATA: Other information, such as CA certification"];
Phone -> ESP32 [label="CTRL: Connect to AP"];
Phone <- ESP32 [label="DATA: Connection State Report"];
}
.. _frame_formats:
The Frame Formats Defined in BluFi
-----------------------------------
The frame formats for the communication between the mobile phone App and ESP32 are defined as follows:
The frame format with no fragment (8 bit)
+------------+---------------+-----------------+-------------+----------------+----------------+
| LSB - Type | Frame Control | Sequence Number | Data Length | Data | MSB - CheckSum |
+============+===============+=================+=============+================+================+
| 1 | 1 | 1 | 1 | ${Data Length} | 2 |
+------------+---------------+-----------------+-------------+----------------+----------------+
If the **Frame Ctrl** bit is enabled, the **Total length** bit indicates the length of remaining part of the frame. It can tell the remote how much memory needs to be alloced.
The frame format with fragments8 bit
+------------+--------------------+----------------+------------+-------------------------------------------+----------------+
| LSB - Type | FrameControl(Frag) | SequenceNumber | DataLength | Data | MSB - CheckSum |
+ + + + +----------------------+--------------------+ +
| | | | | Total Content Length | Content | |
+============+====================+================+============+======================+====================+================+
| 1 | 1 | 1 | 1 | 2 | ${Data Length} - 2 | 2 |
+------------+--------------------+----------------+------------+----------------------+--------------------+----------------+
Normally, the control frame does not contain data bits, except for Ack Frame.
The format of Ack Frame8 bit
+------------------+----------------+------------------+--------------+-----------------------+----------------+
| LSB - Type (Ack) | Frame Control | SequenceNumber | Data Length | Data | MSB - CheckSum |
+ + + + +-----------------------+ +
| | | | | Acked Sequence Number | |
+==================+================+==================+==============+=======================+================+
| 1 | 1 | 1 | 1 | 1 | 2 |
+------------------+----------------+------------------+--------------+-----------------------+----------------+
1. Type
The **Type** field, taking 1 byte, is divided into **Type** and **Subtype**, that Type uses the lower 2 bits and **Subtype** uses the upper 6 bits.
* The control frame is not encrypted for the time being and supports to be verified;
* The data frame supports to be encrypted and verified.
**1.1 Control Frame (0x0b00)**
+-------------------------+--------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
| Control Frame / 0x0b00 | Implication | Explanation | Note |
+=========================+==============================================================+===============================================================+===============================================================+
| 0x0b000000 | Ack | The data field of the Ack frame uses the same | The data field consumes a byte and its value is |
| | | sequence value of the frame to reply to. | the same as the sequence field of the frame to reply to. |
+-------------------------+--------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
| 0x1b000001 | Set ESP32 to the security mode. | To inform ESP32 of the security mode to use | The data field consumes a byte. |
| | | when sending data, which is allowed to be reset | The higher 4 bits are for the security mode setting |
| | | multiple times during the process. | of the control frame, and the lower 4 bits are for |
| | | Each setting affects the subsequent security mode used. | the security mode setting of the data frame. |
+ + + If it is not set, ESP32 will send the control frame +---------------------------------------------------------------+
| | | and data frame with no checksum and encryption by default. | b0000: no checksum and no encryption; |
+ + + The data transmission from the mobile phone to ESP32 is +---------------------------------------------------------------+
| | | controlled by this control frame. | b0001: with checksum but no encryption; |
+ + + +---------------------------------------------------------------+
| | | | b0010: no checksum but with encryption; |
+ + + +---------------------------------------------------------------+
| | | | b0011: with both checksum and encryption. |
+-------------------------+--------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
| 0x2b000010 | Set the opmode of Wi-Fi. | The frame contains opmode settings for | data[0] is for opmode settings, including: |
+ + + configuring for the Wi-Fi mode of ESP32. +---------------------------------------------------------------+
| | | | 0x00: NULL |
+ + + +---------------------------------------------------------------+
| | | | 0x01: STA; |
+ + + +---------------------------------------------------------------+
| | | | 0x02: SoftAP; |
+ + + +---------------------------------------------------------------+
| | | | 0x03: SoftAP&STA. |
+ + + +---------------------------------------------------------------+
| | | | Please set the SSID/Password/Max Connection Number of |
| | | | the AP mode in the first place if an AP gets involved. |
+-------------------------+--------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
| 0x3b000011 | Connect ESP32 to the AP. | To notify ESP32 that the essential information has been sent | No data field is contained. |
| | | and it is allowed to connect to the AP. | |
+-------------------------+--------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
| 0x4b000100 | Disconnect ESP32 from the AP. | | No data field is contained. |
+-------------------------+--------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
| 0x5b000101 | To get the information of ESP32s Wi-Fi mode and its status. | | No data field is contained. |
| | | | When receiving this control frame, ESP32 will send back |
| | | | a follow-up frame of Wi-Fi connection state report to |
| | | | the mobile phone with the information of the current opmode, |
| | | | connection status, SSID and so on. |
| | | | The types of information sent to the mobile phone is |
| | | | defined by the application installed on the phone. |
+-------------------------+--------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
| 0x6b000110 | Disconnect the STA device from the SoftAP (in SoftAP mode). | | Date[0~5] is taken as the MAC address for the STA device. |
| | | | If there is a second STA device, then it uses data[6-11] |
| | | | and the rest can be done in the same manner. |
+-------------------------+--------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
| 0x7b'000111 | Get the version information. | | |
+-------------------------+--------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
| 0x8b001000 | Disconnect the BLE GATT link. | | ESP32 will disconnect the BLE GATT link |
| | | | after receives this command. |
+-------------------------+--------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
| 0x9b001001 | Get the Wi-Fi list. | To get ESP32 to scan the Wi-Fi access points around. | No data field is contained. |
| | | | When receiving this control frame, |
| | | | ESP32 will send back a follow-up frame of Wi-Fi list |
| | | | report to the mobile phone. |
+-------------------------+--------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
**1.2 Data Frame (0x1b01)**
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| Data Frame | Implication | Explanation | Note |
+==============+====================================================+===============================================================+=======================================================================+
| 0x0b000000 | Send the negotiation data. | The negotiation data will be sent to the callback | The length of the data depends on the length field. |
| | | function registered in the application layer. | |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0x1b000001 | Send the BSSID for STA mode. | To send the BSSID of the AP for the STA device to | The length of the data depends on the length field. |
| | | connect under the condition that the SSID is hidden. | When the transmission direction is ESP32 to the mobile phone, |
| | | | it means to provide the mobile phone with the needed information. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0x2b000010 | Send the SSID for STA mode. | To send the SSID of the AP for the STA device to connect. | The length of the data depends on the length field. |
| | | | When the transmission direction is ESP32 to the mobile phone, |
| | | | it means to provide the mobile phone with the needed information. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0x3b000011 | Send the password for STA mode. | To send the password of the AP for the STA device to connect. | The length of the data depends on the length field. |
| | | | When the transmission direction is ESP32 to the mobile phone, |
| | | | it means to provide the mobile phone with the needed information. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0x4b000100 | Send the SSID for SoftAP mode. | | The length of the data depends on the length field. |
| | | | When the transmission direction is ESP32 to the mobile phone, |
| | | | it means to provide the mobile phone with the needed information. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0x5b000101 | Send the password for SoftAPmode. | | The length of the data depends on the length field. |
| | | | When the transmission direction is ESP32 to the mobile phone, |
| | | | it means to provide the mobile phone with the needed information. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0x6b000110 | Set the maximum connection number for SoftAP mode. | | data[0] represents the value of the connection number, |
| | | | ranging from 1 to 4. When the transmission direction is ESP32 |
| | | | to the mobile phone, it means to provide the mobile phone with |
| | | | the needed information. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0x7b000111 | Set the authentication mode for the SoftAP. | | data[0] |
+ + + +-----------------------------------------------------------------------+
| | | | 0x00: OPEN |
+ + + +-----------------------------------------------------------------------+
| | | | 0x01: WEP |
+ + + +-----------------------------------------------------------------------+
| | | | 0x02: WPA_PSK |
+ + + +-----------------------------------------------------------------------+
| | | | 0x03: WPA2_PSK |
+ + + +-----------------------------------------------------------------------+
| | | | 0x04: WPA_WPA2_PSK |
+ + + +-----------------------------------------------------------------------+
| | | | When the transmission direction is ESP32 to the mobile phone, |
| | | | it means to provide the mobile phone with the needed information. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0x8b001000 | Set the channel amount for SoftAP mode. | | data[0] represents the quantity of the supported channels, |
| | | | ranging from 1 to 14. |
| | | | When the transmission direction is ESP32 to the mobile phone, |
| | | | it means to provide the mobile phone with the needed information. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0x9b001001 | Username | It provides the username of the GATT client when using | The length of the data depends on the length field. |
| | | encryption of enterprise level. | |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0xab001010 | CA Certification | It provides the CA Certification when using encryption | The length of the data depends on the length field. |
| | | of enterprise level. | The frame supports to be fragmented if the data length is not enough. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0xbb001011 | Client Certification | It provides the client certification when | The length of the data depends on the length field. |
| | | using encryption of enterprise level. | The frame supports to be fragmented if the data length is not enough. |
| | | Whether the private key is contained or not | |
| | | depends on the content of the certification. | |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0xcb001100 | Server Certification | It provides the sever certification when using | The length of the data depends on the length field. |
| | | encryption of enterprise level. Whether the private key is | The frame supports to be fragmented if the data length is not enough. |
| | | contained or not depends on the content of the certification. | |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0xdb001101 | ClientPrivate Key | It provides the private key of the client when | The length of the data depends on the length field. |
| | | using encryption of enterprise level. | The frame supports to be fragmented if the data length is not enough. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0xeb001110 | ServerPrivate Key | It provides the private key of the sever when | The length of the data depends on the length field. |
| | | using encryption of enterprise level. | The frame supports to be fragmented if the data length is not enough. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0xfb001111 | Wi-Fi Connection State Report | To notify the phone of the ESP32's Wi-Fi status, | data[0] represents opmode, including: |
+ + + including STA status and SoftAP status. +-----------------------------------------------------------------------+
| | | It is for the STA device to connect to the | 0x00: NULL |
+ + + mobile phone or the SoftAP. +-----------------------------------------------------------------------+
| | | However, when the mobile phone receives the Wi-Fi status, | 0x01: STA |
+ + + it can reply to other frames in addition to this frame. +-----------------------------------------------------------------------+
| | | | 0x02: SoftAP |
+ + + +-----------------------------------------------------------------------+
| | | | 0x03: SoftAP&STA |
+ + + +-----------------------------------------------------------------------+
| | | | data[1]the connection state of the STA device, |
| | | | 0x0 indicates a connection state, |
| | | | and others represent a disconnected state; |
+ + + +-----------------------------------------------------------------------+
| | | | data[2]the connection state of the SoftAP, |
| | | | that is, how many STA devices have been connected. |
+ + + +-----------------------------------------------------------------------+
| | | | data[3] and the subsequent is in accordance with the |
| | | | format of SSID/BSSID information. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0x10b010000 | Version | | data[0]= great versiondata[1]= sub version |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0x11B010001 | Wi-Fi List | To send the Wi-Fi list to ESP32. | The format of the data frame is length + RSSI + SSID |
| | | | and it supports to be sent into fragments |
| | | | if the data length is too long. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0x12B010010 | Report Error | To notify the mobile phone that there is an error with BluFi. | 0x00: sequence error |
+ + + +-----------------------------------------------------------------------+
| | | | 0x01: checksum error |
+ + + +-----------------------------------------------------------------------+
| | | | 0x02: decrypt error |
+ + + +-----------------------------------------------------------------------+
| | | | 0x03: encrypt error |
+ + + +-----------------------------------------------------------------------+
| | | | 0x04: init security error |
+ + + +-----------------------------------------------------------------------+
| | | | 0x05: dh malloc error |
+ + + +-----------------------------------------------------------------------+
| | | | 0x06: dh param error |
+ + + +-----------------------------------------------------------------------+
| | | | 0x07: read param error |
+ + + +-----------------------------------------------------------------------+
| | | | 0x08: make public error |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
| 0x13B010011 | Custom Data | To send or receive custom data. | The data frame supports to be sent into |
| | | | fragments if the data length is too long. |
+--------------+----------------------------------------------------+---------------------------------------------------------------+-----------------------------------------------------------------------+
2. Frame Control
Control field, takes 1 byte and each bit has a different meaning.
+--------------------+------------------------------------------------------------------------------------------------+
| Bit | Meaning |
+====================+================================================================================================+
| 0x01 | Indicates whether the frame is encrypted. |
+ +------------------------------------------------------------------------------------------------+
| | 1 means encryption, and 0 means unencrypted. |
+ +------------------------------------------------------------------------------------------------+
| | The encrypted part of the frame includes |
| | the full clear data before the DATA field is encrypted (no checksum). |
+ +------------------------------------------------------------------------------------------------+
| | Control frame is not encrypted, so this bit is 0. |
+--------------------+------------------------------------------------------------------------------------------------+
| 0x02 | The data field that indicates whether a frame contains |
| | a checksum (such as SHA1,MD5,CRC, etc.) for the end of |
| | the frame data field includes SEQUCNE + data length + clear text. |
| | Both the control frame and the data frame can contain a check bit or not. |
+--------------------+------------------------------------------------------------------------------------------------+
| 0x04 | Represents the data direction. |
+--------------------+------------------------------------------------------------------------------------------------+
| | 0 means the mobile phone to ESP32; |
+--------------------+------------------------------------------------------------------------------------------------+
| | 1 means ESP32 to the mobile phone. |
+--------------------+------------------------------------------------------------------------------------------------+
| 0x08 | Indicates whether the other person is required to reply to an ACK. |
+--------------------+------------------------------------------------------------------------------------------------+
| | 0 indicates no requirement; |
+--------------------+------------------------------------------------------------------------------------------------+
| | 1 indicates to reply Ack. |
+--------------------+------------------------------------------------------------------------------------------------+
| 0x10 | Indicates whether there are subsequent data fragments. |
+--------------------+------------------------------------------------------------------------------------------------+
| | 0 indicates that there are no subsequent data fragments for this frame; |
+--------------------+------------------------------------------------------------------------------------------------+
| | 1 indicates that there are subsequent data fragments and used to transmit longer data. |
+--------------------+------------------------------------------------------------------------------------------------+
| | In the case of a frag frame, |
| | the total length of the current content section + subsequent content section is given, |
| | in the first 2 bytes of the data field (that is, the content data of the maximum support 64K). |
+--------------------+------------------------------------------------------------------------------------------------+
| 0x10~0x80 reserved | |
+--------------------+------------------------------------------------------------------------------------------------+
3. Sequence Control
Sequence control field. When a frame is sent,the value of sequence fied is automatically incremented by 1 regardless of the type of frame, which prevents Replay Attack. The sequence is cleared after each reconnection.
4. Length
The length of the data field that does not include CheckSum.
5. Data
The instruction of the data field is different according to various values of Type or Subtype. Please refer to the table above.
6. CheckSum
This field takes 2 bytes that is used to check "sequence + data length + clear text data".
The Security Implementation of ESP32
-------------------------------------
1. Securing data
To ensure that the transmission of the Wi-Fi SSID and password is secure, the message needs to be encrypted using symmetric encryption algorithms, such as AES, DES and so on. Before using symmetric encryption algorithms, the devices are required to negotiate (or generate) a shared key using an asymmetric encryption algorithm (DH, RSA, ECC, etc).
2. Ensuring data integrity
To ensure data integrity, you need to add a checksum algorithm, such as SHA1, MD5, CRC, etc.
3. Securing identity (signature)
Algorithm like RSA can be used to secure identity. But for DH, it needs other algorithms as an companion for signature.
4. Replay attack prevention
It is added to the Sequence field and used during the checksum verification.
For the coding of ESP32, you can determine and develop the security processing, such as key negotiation. The mobile application sends the negotiation data to ESP32 and then the data will be sent to the application layer for processing. If the application layer does not process it, you can use the DH encryption algorithm provided by BluFi to negotiate the key.
The application layer needs to register several security-related functions to BluFi:
.. 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)
This function is for ESP32 to receive normal data during negotiation, and 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.
Here are two "*", because the length of the data to be emitted is unknown that requires the function to allocate itself (malloc) or point to the global variable, and to inform whether the memory needs to be freed by NEED_FREE.
.. code-block:: c
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int cyprt_len)
The data to be encrypted and decrypted must use the same length. The IV8 is a 8 bit sequence value of frames, which can be used as a 8 bit of IV.
.. code-block:: c
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 use the same length. The IV8 is a 8 bit sequence value of frames, which can be used as a 8 bit of IV.
.. code-block:: c
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.
GATT Related Instructions
-------------------------
UUID
>>>>>
BluFi Service UUID: 0xFFFF16 bit
BluFi (the mobile -> ESP32): 0xFF01, writable
Blufi (ESP32 -> the mobile phone): 0xFF02, readable and callable
.. note::
1. The Ack mechanism is already defined in the profile, but there is no implementation based on the code for the time being.
2. Other parts have been implemented.

View file

@ -23,4 +23,5 @@ API Guides
ROM debug console <romconsole>
WiFi Driver <wifi>
Mesh Stack <mesh>
BluFi <blufi>
External SPI-connected RAM <external-ram>

View file

@ -0,0 +1,427 @@
BluFi
^^^^^
概览
-----
BluFi 是一款基于蓝牙通道的 Wi-Fi 网络配置功能,适用于 ESP32。它通过安全协议将 Wi-Fi 配置和证书传输到 ESP32然后 ESP32 可基于这些信息连接到 AP 或建立 SoftAP。
BluFi 流程的关键部分包括数据的分片、加密、校验和验证。
用户可按需自定义用于对称加密、非对称加密和校验的算法。这里我们采用 DH 算法进行密钥协商、128-AES 算法用于数据加密、CRC16 算法用于校验和验证。
BluFi 流程
----------
BluFi 配网功能包含配置 SoftAP 和 Station 两部分。
下面以配置 Station 为例说明配置步骤。
BluFi 配网的配置 Station 包含广播、连接、服务发现、协商共享密钥、传输数据、回传连接状态等步骤。
ESP32 配网流程
--------------
1. ESP32 开启 GATT Server 功能,发送带有特定 *adv data* 的广播。你可以自定义该广播,该广播不属于 BluFi Profile。
2. 使用手机 APP 搜索到该特定广播,手机作为 GATT Client 连接 ESP32。你可以决定使用哪款手机 APP。
3. GATT 连接建立成功后,手机向 ESP32 发送“协商过程”数据帧(详情见 :ref:`frame_formats` )。
4. ESP32 收到“协商过程”数据帧后,会按照使用者自定义的协商过程来解析。
5. 手机与 ESP32 进行密钥协商。协商过程可使用 DH/RSA/ECC 等加密算法进行。
6. 协商结束后,手机端向 ESP32 发送“设置安全模式”控制帧。
7. ESP32 收到“设置安全模式”控制帧后,使用经过协商的共享密钥以及配置的安全策略对通信数据进行加密和解密。
8. 手机向 ESP32 发送“BluFi 传输格式”定义的 SSID、Password 等用于 Wi-Fi 连接的必要信息。
9. 手机向 ESP32 发送“Wi-Fi 连接请求”控制帧ESP32 收到之后,识别为手机已将必要的信息传输完毕,准备连接 Wi-Fi。
10. ESP32 连接到 Wi-Fi 后发送“Wi-Fi 连接状态报告”控制帧到手机,以报告连接状态。至此配网结束。
.. note::
1. 安全模式设置可在任何时候进行ESP32 收到安全模式的配置后,会根据安全模式指定的模式进行安全相关的操作。
2. 进行对称加密和解密时,加密和解密前后的数据长度必须一致,支持原地加密和解密。
配网流程图
-----------
.. seqdiag::
:caption: BluFi Flow Chart
:align: center
seqdiag blufi {
activation = none;
node_width = 80;
node_height = 60;
edge_length = 380;
span_height = 10;
default_fontsize = 12;
Phone <- ESP32 [label="广播"];
Phone -> ESP32 [label="建立 GATT 链接"];
Phone <- ESP32 [label="协商密钥"];
Phone -> ESP32 [label="协商密钥"];
Phone -> ESP32 [label="CTRL: 设置 ESP32 手机安全模式"];
Phone -> ESP32 [label="DATA: SSID"];
Phone -> ESP32 [label="DATA: Password"];
Phone -> ESP32 [label="DATA: 其他信息,如 CA 认证"];
Phone -> ESP32 [label="CTRL: 连接到 AP"];
Phone <- ESP32 [label="DATA: 连接状态报告"];
}
.. _frame_formats:
BluFi 传输格式
--------------
手机 APP 与 ESP32 之间的 BluFi 通信格式定义如下:
帧不分片情况下的标准格式 (8 bit)
+------------+---------------+-----------------+-------------+----------------+----------------+
| LSB - Type | Frame Control | Sequence Number | Data Length | Data | MSB - CheckSum |
+============+===============+=================+=============+================+================+
| 1 | 1 | 1 | 1 | ${Data Length} | 2 |
+------------+---------------+-----------------+-------------+----------------+----------------+
如果 **Frame Control** 帧中的 **More Frag** 使能,则 **Total Content Length** 为数据帧中剩余部分的总长度,用于报告终端需要分配多少内存。
帧分片格式8 bit
+------------+--------------------+----------------+------------+-------------------------------------------+----------------+
| LSB - Type | FrameControl(Frag) | SequenceNumber | DataLength | Data | MSB - CheckSum |
+ + + + +----------------------+--------------------+ +
| | | | | Total Content Length | Content | |
+============+====================+================+============+======================+====================+================+
| 1 | 1 | 1 | 1 | 2 | ${Data Length} - 2 | 2 |
+------------+--------------------+----------------+------------+----------------------+--------------------+----------------+
通常情况下控制帧不包含数据位Ack 帧类型除外。
Ack 帧格式8 bit
+------------------+---------------+-----------------+-------------+-----------------------+----------------+
| LSB - Type (Ack) | Frame Control | SequenceNumber | Data Length | Data | MSB - CheckSum |
+ + + + +-----------------------+ +
| | | | | Acked Sequence Number | |
+==================+===============+=================+=============+=======================+================+
| 1 | 1 | 1 | 1 | 1 | 2 |
+------------------+---------------+-----------------+-------------+-----------------------+----------------+
1. Type
类型域,占 1 byte。分为 Type 和 Subtype子类型域两部分, Type 占低 2 bitSubtype 占高 6 bit。
* 控制帧,暂不进行加密,可校验;
* 数据帧,可加密,可校验。
**1.1 控制帧 (0x0b00)**
+------------------+-----------------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+
| 控制帧 / 0x0b00 | 含义 | 解释 | 备注 |
+==================+===================================+================================================================+======================================================================+
| 0x0b000000 | Ack | 用来回复对方发的帧, | Data 域使用1 byte Sequence 值, |
| | | Ack 帧的 Data 域使用回复对象帧的 Sequence 值。 | 与恢复对象帧的Sequence 值相同。 |
+------------------+-----------------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+
| 0x1b000001 | Set ESP32 to the security mode. | 通知 ESP32 发送数据时使用的安全模式, | Data 域占用 1 byte。 |
| | | 在该过程中可设置多次,每次设置后影响后续安全模式。 | 高 4 bit 为控制帧的安全模式,低 4bit 为数据帧的安全模式。 |
+ + + 在不设置的情况下ESP32 默认控制帧和数据帧均为无校验、无加密。 +----------------------------------------------------------------------+
| | | 手机到 ESP32 方向依赖于帧 Control 域。 | b0000无校验、无加密 |
+ + + +----------------------------------------------------------------------+
| | | | b0001有校验、无加密 |
+ + + +----------------------------------------------------------------------+
| | | | b0010无校验、有加密 |
+ + + +----------------------------------------------------------------------+
| | | | b0011有校验、有加密。 |
+------------------+-----------------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+
| 0x2b000010 | Set the Wi-Fi opmode of ESP32. | 设置 ESP32 的 Wi-Fi 模式,帧包含 opmode 信息。 | data[0] 用于表示 opmode 类型,包括: |
+ + + +----------------------------------------------------------------------+
| | | | 0x00: NULL; |
+ + + +----------------------------------------------------------------------+
| | | | 0x01: STA; |
+ + + +----------------------------------------------------------------------+
| | | | 0x02: SoftAP; |
+ + + +----------------------------------------------------------------------+
| | | | 0x03: SoftAP&STA. |
+ + + +----------------------------------------------------------------------+
| | | | 如果设置有包含 AP请尽量优先 |
| | | | 设置 AP 模式的SSID/Password/Max Conn Number 等。 |
+------------------+-----------------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+
| 0x3b000011 | Connect ESP32 to the AP. | 通知 ESP32必要的信息已经发送完毕可以连接 AP。 | 不包含 Data 域。 |
+------------------+-----------------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+
| 0x4b000100 | Disconnect ESP32 from the AP. | 通知 ESP32 断开与 AP 的连接 | 不包含 Data 域。 |
+------------------+-----------------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+
| 0x5b000101 | Get the status of Wi-Fi. | 获取 ESP32 的 Wi-Fi 模式和状态等信息。 | 不包含 Data 域。 |
| | | | ESP32 收到此控制帧后,后续会通过 Wi-Fi 连接状态 |
| | | | 报告 (Wi-Fi Connection State Report) 数据帧来回复手机端当前 |
| | | | 所处的 opmode、连接状态、SSID 等信息。提供给手机端的信息由应用决定。 |
+------------------+-----------------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+
| 0x6b000110 | Disconnect the STA device | 处于 SoftAP 模式时,踢掉某个 STA 设备。 | data[0~5] 为 STA 设备的 MAC 地址, |
| | from the SoftAP in SoftAP mode. | | 如有多个 STA则 [6-11] 为第二个,依次类推。 |
+------------------+-----------------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+
| 0x7b'000111 | Get the version. | | |
+------------------+-----------------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+
| 0x8b001000 | Tell ESP32 to disconnect | 通知 ESP32 断开蓝牙连接。 | ESP32 收到该指令后主动断开蓝牙连接。 |
| | the BLE GATT link. | | |
+------------------+-----------------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+
| 0x9b001001 | Tell ESP32 to get the Wi-Fi list. | 通知 ESP32 扫描周围的 Wi-Fi 热点 | 不包含 Data 域。 |
| | | | ESP32 收到此控制帧后,会发送包含 Wi-Fi 热点 |
| | | | 报告 (Wi-Fi List Report) 的数据帧回复 |
| | | | 手机端 ESP32 周围的 Wi-Fi 热点。 |
+------------------+-----------------------------------+----------------------------------------------------------------+----------------------------------------------------------------------+
**1.2 数据帧 (0x1b01)**
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 数据帧 | 含义 | 解释 | 备注 |
+===============+========================================+================================================+======================================================+
| 0x0 b000000 | Negotiation data. | 用来发送协商数据,传输到应用层注册的回调函数。 | 数据长度与 Length 域有关。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0x1 b000001 | BSSID for STA mode. | STA 将要连接的 AP 的 BSSID用于隐藏SSID。 | 数据长度与 Length 域有关。 |
+ + + +------------------------------------------------------+
| | | | 当传输方向为 ESP32 到手机时, |
| | | | 表示向手机端提供信息。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0x2 b000010 | SSID for STA mode. | STA 将要连接的 AP 的 SSID。 | 数据长度与 Length 域有关。 |
+ + + +------------------------------------------------------+
| | | | 当传输方向为 ESP32 到手机时, |
| | | | 表示向手机端提供信息。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0x3 b000011 | Password for STA mode. | STA 将要连接的 AP 的密码。 | 数据长度与 Length 域有关。 |
+ + + +------------------------------------------------------+
| | | | 当传输方向为 ESP32 到手机时, |
| | | | 表示向手机端提供信息。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0x4 b000100 | SSID for SoftAP mode. | SoftAP 模式使用的 SSID。 | 数据长度与 Length 域有关。 |
+ + + +------------------------------------------------------+
| | | | 当传输方向为 ESP32 到手机时, |
| | | | 表示向手机端提供信息。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0x5 b000101 | Password for SoftAPmode. | SoftAP 模式使用的密码。 | 数据长度与 Length 域有关。 |
+ + + +------------------------------------------------------+
| | | | 当传输方向为 ESP32 到手机时, |
| | | | 表示向手机端提供信息。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0x6 b000110 | Max connection number for SoftAP mode. | AP 模式的最大连接数。 | data[0] 表示连接数的值,范围 1~4。 |
+ + + +------------------------------------------------------+
| | | | 当传输方向为 ESP32 到手机时, |
| | | | 表示向手机端提供信息。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0x7b000111 | Authentication mode for SoftAP mode. | AP 模式的认证模式。 | data[0] |
+ + + +------------------------------------------------------+
| | | | 0x00: OPEN; |
+ + + +------------------------------------------------------+
| | | | 0x01: WEP; |
+ + + +------------------------------------------------------+
| | | | 0x02: WPA_PSK; |
+ + + +------------------------------------------------------+
| | | | 0x03: WPA2_PSK; |
+ + + +------------------------------------------------------+
| | | | 0x04: WPA_WPA2_PSK. |
+ + + +------------------------------------------------------+
| | | | 当传输方向为 ESP32 到手机时, |
| | | | 表示向手机端提供信息。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0x8b001000 | Channel for SoftAP mode. | SoftAP 模式的通道数量。 | data[0] 表示通道的数量,范围 1~14。 |
+ + + +------------------------------------------------------+
| | | | 当传输方向为 ESP32 到手机时, |
| | | | 表示向手机端提供信息。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0x9b001001 | Username. | 使用企业级加密时Client 端的用户名。 | 数据长度与 Length 域有关。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0xab001010 | CA certification. | 进行企业级加密时使用的 CA 证书。 | 数据长度与 Length 域有关, |
| | | | 长度不够,可用分片。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0xbb001011 | Client certification. | 进行企业级加密时Client 端的证书。 | 数据长度与 Length 域有关, |
+ + +------------------------------------------------+ 长度不够,可用分片。 +
| | | 可包含或不包含私钥,由证书内容决定。 | |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0xcb001100 | Server certification. | 进行企业级加密时Server 端的证书。 | 数据长度与 Length 域有关, |
+ + +------------------------------------------------+ 长度不够,可用分片。 +
| | | 可包含或不包含私钥,由证书内容决定。 | |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0xdb001101 | Client private key. | 进行企业级加密时Client 端的私钥。 | 数据长度与 Length 域有关, |
| | | | 长度不够,可用分片。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0xeb001110 | Server private key. | 进行企业级加密时Server 端的私钥。 | 数据长度与 Length 域有关, |
| | | | 长度不够,可用分片。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0xf b001111 | Wi-Fi connection state report. | 通知手机 ESP32 的 Wi-Fi 状态, | data[0] 表示 opmode包括 |
| | | 包括 STA状态和 SoftAP 状态, | |
| | | 用于手机配置 STA 连接时的通知, | |
| | | 或有 STA 连接上 SoftAP 时的通知。 | |
+ + +------------------------------------------------+------------------------------------------------------+
| | | 但收到手机询问 Wi-Fi 状态时, | 0x00: NULL |
+ + + 除了回复此帧外,还可回复其他数据帧。 +------------------------------------------------------+
| | | | 0x01: STA; |
+ + + +------------------------------------------------------+
| | | | 0x02: SoftAP; |
+ + + +------------------------------------------------------+
| | | | 0x03: SoftAP&STA |
+ + + +------------------------------------------------------+
| | | | data[1]STA 的连接状态, |
| | | | 0x0 表示处于连接状态, |
| | | | 其他表示处于非连接状态; |
+ + + +------------------------------------------------------+
| | | | data[2]SoftAP 的连接状态, |
| | | | 即表示有多少 STA 已经连接。 |
+ + + +------------------------------------------------------+
| | | | data[3] 及以后:为按照本协议格式 SSID\BSSID 等信息。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0x10 b010000 | Version. | | data[0]= great version |
+ + + +------------------------------------------------------+
| | | | data[1]=sub version |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0x11 B010001 | Wi-Fi list. | 通知手机 ESP32 周围的 Wi-Fi 热点列表。 | 数据帧数据格式为 Length + RSSI + SSID, |
| | | | 数据较长时可分片发送。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0x12 B010010 | Report error. | 通知手机 BluFi 过程出现异常错误。 | 0x00: sequence error; |
+ + + +------------------------------------------------------+
| | | | 0x01: checksum error; |
+ + + +------------------------------------------------------+
| | | | 0x02: decrypt error; |
+ + + +------------------------------------------------------+
| | | | 0x03: encrypt error; |
+ + + +------------------------------------------------------+
| | | | 0x04: init security error; |
+ + + +------------------------------------------------------+
| | | | 0x05: dh malloc error; |
+ + + +------------------------------------------------------+
| | | | 0x06: dh param error; |
+ + + +------------------------------------------------------+
| | | | 0x07: read param error; |
+ + + +------------------------------------------------------+
| | | | 0x08: make public error. |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
| 0x13 B010011 | Custom data. | 用户发送或者接收自定义数据。 | 数据较长时可分片发送。 |
+---------------+----------------------------------------+------------------------------------------------+------------------------------------------------------+
2. Frame Control
帧控制域,占 1 byte每个 bit 表示不同含义。
+----------------+-------------------------------------------------------------------------------------------------------------------------------+
| 位 | 含义 |
+================+===============================================================================================================================+
| 0x01 | 表示帧是否加密。 |
+ +-------------------------------------------------------------------------------------------------------------------------------+
| | 1 表示加密0 表示未加密。 |
+ +-------------------------------------------------------------------------------------------------------------------------------+
| | 加密部分帧括完整的 DATA 域加密之前的明文(不帧含末尾的校验)。 |
+ +-------------------------------------------------------------------------------------------------------------------------------+
| | 控制帧暂不加密,故控制帧此位为 0。 |
+----------------+-------------------------------------------------------------------------------------------------------------------------------+
| 0x02 | 表示帧 Data 域结尾是否帧含校验(例如 SHA1,MD5,CRC等需要校验的数据域包括 sequcne + data length + 明文 data。 |
+ +-------------------------------------------------------------------------------------------------------------------------------+
| | 控制帧和数据帧都可以包含校验位或不包含。 |
+----------------+-------------------------------------------------------------------------------------------------------------------------------+
| 0x04 | 表示数据方向。 |
+ +-------------------------------------------------------------------------------------------------------------------------------+
| | 0 表示手机发向 ESP32 |
+ +-------------------------------------------------------------------------------------------------------------------------------+
| | 1 表示 ESP32 发向手机。 |
+----------------+-------------------------------------------------------------------------------------------------------------------------------+
| 0x08 | 表示是否要求对方回复 ack。 |
+ +-------------------------------------------------------------------------------------------------------------------------------+
| | 0 表示不要求; |
+ +-------------------------------------------------------------------------------------------------------------------------------+
| | 1 表示要求回复 ack。 |
+----------------+-------------------------------------------------------------------------------------------------------------------------------+
| 0x10 | 表示是否有后续的数据分片。 |
+ +-------------------------------------------------------------------------------------------------------------------------------+
| | 0 表示此帧没有后续数据分片; |
+ +-------------------------------------------------------------------------------------------------------------------------------+
| | 1 表示还有后续数据分片,用来传输较长的数据。 |
+ +-------------------------------------------------------------------------------------------------------------------------------+
| | 如果是 Frag 帧,则告知当前 content 部分+后续 content 部分的总长度,位于 Data 域的前 2 字节(即最大支持 64K 的 content 数据)。 |
+----------------+-------------------------------------------------------------------------------------------------------------------------------+
| 0x10~0x80 保留 | |
+----------------+-------------------------------------------------------------------------------------------------------------------------------+
3. Sequence Control
序列控制域。帧发送时,无论帧的类型是什么,序列 (Sequence) 都会自动加 1用来防止重放攻击 (Replay Attack)。每次重现连接后,序列清零。
4. Length
Data 域的长度,不包含 CheckSum。
5. Data
不同的 Type 或 SubtypeData 域的含义均不同。请参考上方表格。
6. CheckSum
此域为 2 byte 的校验,用来校验『序列 + 数据长度 + 明文数据』。
ESP32 端的安全实现
------------------
1. 保证数据安全
为了保证 Wi-Fi SSID 和密码的传输过程是安全的,需要使用对称加密算法(例如 AES、DES等对报文进行加密。在使用对称加密算法之前需要使用非对称加密算法DH、RSA、ECC 等)协商出(或生成出)一个共享密钥。
2. 保证数据完整性
保证数据完整性,需要加入校验算法(例如 SHA1、MD5、CRC 等)。
3. 身份安全(签名)
某些算法如 RSA 可以保证身份安全。有些算法如 DH本身不能保证身份安全需要添加其他算法来签名。
4. 防止重放攻击 (Replay Attack)
加入帧发送序列Sequence并且序列参与数据校验。
在 ESP32 端的代码中,你可以决定和开发密钥协商等安全处理的流程参考上述流程图)。手机应用向 ESP32 发送协商数据,将传送给应用层处理。如果应用层不处理,可使用 BluFi 提供的 DH 加密算法来磋商密钥。应用层需向 BluFi 注册以下几个与安全相关的函数:
.. 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);
该函数用来接收协商期间的正常数据 (normal data),处理完成后,需要将待发送的数据使用 output_data 和 output_len 传出。
BluFi 会在调用完 negotiate_data_handler 后,发送 negotiate_data_handler 传出的 output_data。
这里的两个『*』,因为需要发出去的数据长度未知,所以需要函数自行分配 (malloc) 或者指向全局变量,通过 need_free 通知是否需要释放内存。
.. code-block:: c
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int cyprt_len);
加密和解密的数据长度必须一致。其中 iv8 为帧的 8 bit 序列 (sequence),可作为 iv 的某 8 bit 来使用。
.. code-block:: c
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
加密和解密的数据长度必须一致。其中 iv8 为帧的 8 bit 序列 (sequence),可作为 iv 的某 8 bit 来使用。
.. code-block:: c
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len);
该函数用来计算 CheckSum返回值为 CheckSum 的值。BluFi 会使用该函数返回值与包末尾的 CheckSum 做比较。
GATT 相关说明
-------------
UUID
>>>>>
BluFi Service UUID 0xFFFF16 bit
BluFi (手机 -> ESP32 特性0xFF01主要权限可写
BluFi ESP32 -> 手机) 特性0xFF02主要权限可读可通知
.. note::
1. 目前 Ack 机制已经在该 Profile 协议中定义,但是还没有代码实现。
2. 其他部分均已实现。

View file

@ -1 +1,27 @@
.. include:: ../../en/api-guides/index.rst
API Guides
**********
.. toctree::
:maxdepth: 1
General Notes <general-notes>
Build System <build-system>
Deep Sleep Wake Stubs <deep-sleep-stub>
ESP32 Core Dump <core_dump>
Flash Encryption <../security/flash-encryption>
FreeRTOS SMP Changes <freertos-smp>
Thread Local Storage <thread-local-storage>
High Level Interrupts <hlinterrupts>
JTAG Debugging <jtag-debugging/index>
Bootloader <bootloader>
Partition Tables <partition-tables>
Secure Boot <../security/secure-boot>
ULP Coprocessor <ulp>
Unit Testing <unit-tests>
Application Level Tracing <app_trace>
Console Component <console>
ROM debug console <romconsole>
WiFi Driver <wifi>
Mesh Stack <mesh>
BluFi <blufi>
External SPI-connected RAM <external-ram>