From 95f2edde0729fa03fec4870aca346cb1b4f0d1ad Mon Sep 17 00:00:00 2001 From: liqigan Date: Mon, 16 Aug 2021 10:38:46 +0800 Subject: [PATCH] add FAQ in SPP demo README --- .../bluedroid/stack/include/stack/hcidefs.h | 2 +- .../classic_bt/bt_spp_acceptor/ESP32_SSP.md | 179 ++++++++++++++++++ .../classic_bt/bt_spp_acceptor/README.md | 52 +++++ .../classic_bt/bt_spp_acceptor/README.rst | 16 -- .../classic_bt/bt_spp_initiator/README.md | 54 ++++++ .../classic_bt/bt_spp_initiator/README.rst | 16 -- 6 files changed, 286 insertions(+), 33 deletions(-) create mode 100644 examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/ESP32_SSP.md create mode 100644 examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/README.md delete mode 100644 examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/README.rst create mode 100644 examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/README.md delete mode 100644 examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/README.rst diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index fdce44d804..8d27ed7dd7 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -800,7 +800,7 @@ #define HCI_ERR_SCO_AIR_MODE 0x1D #define HCI_ERR_INVALID_LMP_PARAM 0x1E #define HCI_ERR_UNSPECIFIED 0x1F -#define HCI_ERR_UNSUPPORTED_LMP_FEATURE 0x20 +#define HCI_ERR_UNSUPPORTED_LMP_PARAMETERS 0x20 #define HCI_ERR_ROLE_CHANGE_NOT_ALLOWED 0x21 #define HCI_ERR_LMP_RESPONSE_TIMEOUT 0x22 #define HCI_ERR_LMP_ERR_TRANS_COLLISION 0x23 diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/ESP32_SSP.md b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/ESP32_SSP.md new file mode 100644 index 0000000000..68a168a599 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/ESP32_SSP.md @@ -0,0 +1,179 @@ +# ESP32 Classic Bluetooth Security - Secure Simple Pairing + +This document briefly describes how the device io capability and security mask affect the process of the Secure Simple Pairing. It will help you figure out how to set the parameter when calling `esp_bt_gap_set_security_param`, or the parameter `sec_mask` when you want to establish a connection associate a certain profile, for example, an SPP connection. + +## IO Capability +Input and output capabilities of a device are combined to generate its IO capabilities. The input capabilities are described in Table 1 The output capabilities are described in Table 2. Table 3 shows the combination of Input and Output Capability, which are defined as `ESP_BT_IO_CAP_OUT`, `ESP_BT_IO_CAP_IO`, `ESP_BT_IO_CAP_IN` and `ESP_BT_IO_CAP_NONE` in `esp_gap_bt_api.h`. + +| Input Capability | Description | +| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| No input | Device does not have the ability to indicate 'yes' or 'no' | +| Yes / No | Device has at least two buttons that can be easily mapped to 'yes' and 'no' or the device has a mechanism whereby the user can indicate either 'yes' or 'no' (see note below). | +| Keyboard | Device has a numeric keyboard that can input the numbers '0' through '9' and a confirmation. Device also has two buttons that can be easily mapped to 'yes' and 'no' or the device has a mechanism whereby the user can indicate either 'yes' or 'no' (see Note below). | +*Table 1 User Input Capability* +**Note**: 'yes' could be indicated by pressing a button within a certain time limit otherwise 'no' would be assumed. + +| Output Capability | Description | +| ----------------- | ----------------------------------------------------------------------------------- | +| No output | Device does not have the ability to display or communicate a 6 digit decimal number | +| Numeric output | Device has the ability to display or communicate a 6 digit decimal number | +*Table 2 User Output Capability* + +| | No Output | Numeric Output | +| -------- | -------------------------------------- | --------------------------------- | +| No input | NoInputNoOutput (`ESP_BT_IO_CAP_NONE`) | DisplayOnly (`ESP_BT_IO_CAP_OUT`) | +| Yes / No | NoInputNoOutput (`ESP_BT_IO_CAP_NONE`) | DisplayYesNo (`ESP_BT_IO_CAP_IO`) | +| Keyboard | KeyboardOnly (`ESP_BT_IO_CAP_IN`) | DisplayYesNo (`ESP_BT_IO_CAP_IO`) | +*Table 3 IO Capability Mapping* + +## Secure Simple Pairing +The primary goal of Secure Simple Pairing is to simplify the pairing procedure for the user. Secondary goals are to protect against passive eavesdropping and man-in-the-middle (MITM) attacks (active eavesdropping). It uses four association models referred to as Numeric Comparison, Just Works, Out Of Band, and Passkey Entry. +* Numeric Comparison: both devices are capable of displaying a six digit number and both are capable of having the user enter "yes" or "no" +* Just Works: at least one of the devices does not have a display capable of displaying a six digit number nor does it have a keyboard capable of entering six decimal digits +* Out Of Band: use Out of Band mechanism to discover the devices and transfer cryptographic numbers +* Passkey Entry: one device has input capability but does not have the capability to display six digits and the other device has output capabilities. + +**Note**: Just Works can be considered as a special kind of Numeric Comparison with automatic accept allowed. + +There are four stages defined in the Secure Simple Pairing LM process: +* IO Capability exchange +* Public key exchange +* Authentication stage 1 +* Authentication stage 2 + +### IO Capability Exchange +The IO_Capability_Request_Reply command is used to reply to an IO Capability Request event from the controller, and specifies the current I/O capabilities of the host. The content of this command is shown as Table 4. +| Command | OCF | Command Parameters | Return Parameters | +| ------------------------------- | ------ | ------------------------------------------------------------------------------ | ------------------ | +| HCI_IO_Capability_Request_Reply | 0x002B | BD_ADDR,
IO_Capability,
OOB_Data_Present,
Authentication_Requirements | Status,
BD_ADDR | +*Table 4 IO_Capability_Request_Reply command* + +### Authentication Requirements +If an authenticated link key is not required by the Host, the Authentication Requirements parameter may be set to one of the following: +* MITM Protection Not Required – No Bonding +* MITM Protection Not Required – Dedicated Bonding +* MITM Protection Not Required – General Bonding + +**Note**: If both Hosts set the Authentication_Requirements parameter to one of the above values, the Link Managers shall use the numeric comparison authentication procedure and the hosts shall use the Just Works Association Model. + +If an authenticated link key is required by the Host, the Authentication Requirements parameter shall be set to one of the following: +* MITM Protection Required – No Bonding +* MITM Protection Required – Dedicated Bonding +* MITM Protection Required – General Bonding + +**Note**: In addition, the following requirements apply: +1. If one or both hosts set the Authentication Requirements parameter to one of the above values, the Link Managers shall use the IO_Capability parameter to determine the authentication procedure. +2. A Host that sets the Authentication_Requirements parameter to one of the above values shall verify that the resulting Link Key type meets the security requirements requested. + +### IO Capability and Authentication Procedure Mapping +If one or both devices have set the Authentication_Requirements parameter to one of the MITM Protection Required options, the IO capabilities are mapped to the authentication method as defined in the following table. A host has set the MITM Protection Required options shall verify that the resulting Link Key is an Authenticated Combination Key. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Responder
InitiatorDisplayOnlyDisplayYesNoKeyboardOnlyNoInputNoOutput
DisplayOnlyJust Works

Unauthenticated
Just Works

Unauthenticated
Passkey Entry

Authenticated
Just Works

Unauthenticated
DisplayYesNoJust Works

Unauthenticated
Numeric Comparison

Authenticated
Passkey Entry

Authenticated
Just Works

Unauthenticated
KeyboardOnlyPasskey Entry

Authenticated
Passkey Entry

Authenticated
Passkey Entry(both need enter)

Authenticated
Just Works

Unauthenticated
NoInputNoOutputJust Works

Unauthenticated
Just Works

Unauthenticated
Just Works

Unauthenticated
Just Works

Unauthenticated
+ +*Table 5 IO Capability and Authentication Procedure Mapping* + +## Security Mask +Security Mask has two function. First, to decide whether or not required MITM protection for Authentication_Requirements parameter. Second, to set the security level for authentication stage. On ESP32, the Security Masks for A2DP and HFP are hard coded with `BTA_SEC_AUTHENTICATE` and `(BTA_SEC_AUTHENTICATE|BTA_SEC_ENCRYPT)`. The following table shows `sec_mask` value for SPP and its definition in BTA layer of ESP32 Bluetooth stack. + +| SPP sec_mask | BTA layer sec_mask | value | Description | +| -------------------------- | ---------------------- | ------ | ----------------------------------------------------------------------------------------- | +| `ESP_SPP_SEC_NONE` | `BTA_SEC_NONE` | 0x0000 | No security | +| `ESP_SPP_SEC_AUTHORIZE` | `BTA_SEC_AUTHORIZE` | 0x0001 | Authorization required (only needed for out going connection)
(not support) | +| `ESP_SPP_SEC_AUTHENTICATE` | `BTA_SEC_AUTHENTICATE` | 0x0012 | Authentication required | +| `ESP_SPP_SEC_ENCRYPT` | `BTA_SEC_ENCRYPT` | 0x0024 | Encryption required | +| `ESP_SPP_SEC_MODE4_LEVEL4` | `BTA_SEC_MODE4_LEVEL4` | 0x0040 | Mode 4 level 4 service, i.e. incoming/outgoing MITM and P-256 encryption
(not support) | +| `ESP_SPP_SEC_MITM` | `BTA_SEC_MITM` | 0x3000 | Man-In-The_Middle protection | +| `ESP_SPP_SEC_IN_16_DIGITS` | `BTA_SEC_IN_16_DIGITS` | 0x4000 | Min 16 digit for pin code | +*Table 6 ESP32 SPP Security Mask* + +**Note**: +1. When `ESP_SPP_SEC_AUTHENTICATE` is set, then Security Manager set `ESP_SPP_SEC_MITM` automatically. +2. When `ESP_SPP_SEC_ENCRYPT` is set, then Security Manager set `ESP_SPP_SEC_AUTHENTICATE` automatically. + +## Security Mode 4 +The ESP32 Security Manager supports Security Mode 4 which means that it enforces security requirements before it attempts to access services offered by a remote device and before it grants access to services it offers to remote devices. Security Mode 4 has 4 level of security. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Security Level Required for ServiceLink Key type required for remote devicesCommentsIO Capability & Security Mask Setting
Level 4(not support)
* MITM protection required
* Encryption required
* User interaction acceptable
Authenticated (P-256 based Secure Simple Pairing and Secure Authentication)Highest Security Only possible when both devices support Secure Connections/
Level 3
* MITM protection required
* Encryption required
* User interaction acceptable
AuthenticatedHigh SecurityIO: >= DisplayYesNo
Mask: ESP_SPP_SEC_MITM | BTA_SEC_ENCRYPT
Level 2
* MITM protection not necessary
* Encryption desired
UnauthenticatedMedium SecurityIO: >= DisplayYesNo
Mask: BTA_SEC_ENCRYPT
Level 1
* MITM protection not necessary
* Encryption desired
* Minimal user interaction desired
UnauthenticatedLow SecurityIO: >= NoInputNoOutput
Mask: BTA_SEC_ENCRYPT
Level 0
* MITM protection not necessary
* Encryption not necessary
* No user interaction desired
NonePermitted only for SDP and service data sent via either L2CAP fixed signaling channels or the L2CAP connectionless channel to PSMs that correspond to service class UUIDs which are allowed to utilize Level 0./
+ +*Table 7 Security Mode 4 Security Level mapping to link key requirements* + +**Note**: Security Mode 4 always requires **authentication** and **encryption** over establishment of L2CAP connection on ESP32. + + +ESP32 Secure Simple Pairing performs legacy authentication which means mutual authentication is achieved by first performing the authentication procedure in one direction and then immediately performing the authentication procedure in the opposite direction. So, when the initiator does not require MITM protection, the generated link key type in this direction is unauthenticated. In other direction, if the responder need MITM protection and have the `sec_mask` of `ESP_SPP_SEC_AUTHENTICATE`, then the unauthenticated link key will be regenerated and upgraded to an authenticated one. Each time the link key is regenerated, user will receive a `ESP_BT_GAP_AUTH_CMPL_EVT` event. diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/README.md b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/README.md new file mode 100644 index 0000000000..5bc9621305 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/README.md @@ -0,0 +1,52 @@ +| Supported Targets | ESP32 | +| ----------------- | ----- | + +## ESP-IDF BT-SPP-ACCEPTOR demo + +This is the demo for user to use ESP_APIs to create a **Serial Port Protocol** (**SPP**) acceptor and we aggregate **Secure Simple Pair** (**SSP**) into this demo to show how to use SPP when creating your own APPs. + +## How to use example + +### Hardware Required + +This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC. + +To operate it should be connected to an SPP Initiator running on a smartphone or on another ESP32 development board. + +### Configure the project + +``` +idf.py menuconfig +``` + +In `menuconfig` path: `Coponent config --> Bluetooth--> Bluedroid Options --> SPP` and `Coponent config --> Bluetooth--> Bluedroid Options --> Secure Simple Pair`. + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Example Description + +After the program started, `bt_spp_initator` will connect it and send data. + +## Trouble shooting + +- Acceptor is expected to start before `bt_spp_initator` start. + +- To see the information of data, users shall set `SPP_SHOW_MODE` as `SPP_SHOW_DATA` or `SPP_SHOW_SPEED` in code(should be same with `bt_spp_initator`). + +- We also show the Security Simple Pair in this SPP demo. Users can set the IO Capability and Security Mode for their device (security level is fixed level 4). The default security mode of this demo is `ESP_SPP_SEC_AUTHENTICATE` which support MITM (Man In The Middle) protection. For more information about Security Simple Pair on ESP32, please refer to [ESP32_SSP](./ESP32_SSP.md). + +## FAQ +Q: How many SPP servers does ESP32 support? +A: For now, the maximum number of SPP servers is 6, which is limited by the maximum number of SDP records. When the SPP server is successfully started, the unique SCN (Server Channel Number) will be mapped to the SPP server. diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/README.rst b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/README.rst deleted file mode 100644 index d33e353672..0000000000 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/README.rst +++ /dev/null @@ -1,16 +0,0 @@ -ESP-IDF BT-SPP-ACCEPTOR demo -====================== - -Demo of SPP acceptor role - -This is the demo for user to use ESP_APIs to create a SPP acceptor. - -Options choose step: - 1. idf.py menuconfig. - 2. enter menuconfig "Component config", choose "Bluetooth" - 3. enter menu Bluetooth, choose "Classic Bluetooth" and "SPP Profile" - 4. choose your options. - -Then set SPP_SHOW_MODE as SPP_SHOW_DATA or SPP_SHOW_SPEED in code(should be same with bt_spp_initator). - -After the program started, bt_spp_initator will connect it and send data. diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/README.md b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/README.md new file mode 100644 index 0000000000..34dcbbf59e --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/README.md @@ -0,0 +1,54 @@ +| Supported Targets | ESP32 | +| ----------------- | ----- | + +# ESP-IDF BT-SPP-INITATOR demo + +This is the demo for user to use ESP_APIs to create a **Serial Port Protocol** (**SPP**) initiator and we aggregate **Secure Simple Pair** (**SSP**) into this demo to show how to use SPP when creating your own APPs. + +## How to use example + +### Hardware Required + +This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC. To operate it should be connected to an SPP Acceptor running on another device. + +### Configure the project + +``` +idf.py menuconfig +``` + +In `menuconfig` path: `Coponent config --> Bluetooth--> Bluedroid Options --> SPP` and `Coponent config --> Bluetooth--> Bluedroid Options --> Secure Simple Pair`. + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Troubleshouting + +- Set `SPP_SHOW_MODE` as `SPP_SHOW_DATA` or `SPP_SHOW_SPEED` in code (should be same with bt_spp_acceptor). + +- After the program started, It will connect to bt_spp_acceptor and send data. + +- We haven't do the same update to `bt_acceptor_demo` for the sake of reducing the size of ESP_IDF, but transplanting of input module is supported. + +- We also show the Security Simple Pair in this SPP demo. Users can set the IO Capability and Security Mode for their device (security level is fixed level 4). The default security mode of this demo is `ESP_SPP_SEC_AUTHENTICATE` which support MITM (Man In The Middle) protection. For more information about Security Simple Pair on ESP32, please refer to [ESP32_SSP](../bt_spp_acceptor/ESP32_SSP.md). + +## FAQ +Q: How can we reach the maximum throughput when using SPP? +A: The default MTU size of classic Bluetooth SPP on ESP32 is 990 bytes, and higher throughput can be achieved in the case that data chunck size is close to the MTU size or multiple of MTU size. For example, sending 100 bytes data per second is much better than sending 10 bytes every 100 milliseconds. + +Q: What is the difference between the event `ESP_SPP_CONG_EVT` and the parameter `cong` of the event `ESP_SPP_WRITE_EVT`? +A: The event `ESP_SPP_CONG_EVT` shows the changing status from `congest` to `uncongest`, or form `uncongest` to `congest`. Congestion can have many causes, such as using out of the credit which is sent by peer, reaching the high watermark of the Tx buffer, the congestion at Bluetooth L2CAP layer and so on. The parameter `cong` of the event `ESP_SPP_WRITE_EVT` shows a snapshot of the state of the flow control manager after the write operation is completed. The user needs to carefully consider retransmitting or continuing to write according to these two events. The ESP32 offers an VFS mode of SPP which hides the details of retransmitting, but it will block the caller and is not more efficient than the callback mode. + +Q: How many SPP clients does ESP32 support? +A: The ESP32 supports maximum 8 SPP clients, which including virtual SPP connections. Virtual SPP connection means that SPP clients can connect to the different SPP servers running on the same peer device. However the number of SPP clients (excluding virtual connections) shall not exceed the number of Bluetooth ACL connections. diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/README.rst b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/README.rst deleted file mode 100644 index 07bf513a1c..0000000000 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/README.rst +++ /dev/null @@ -1,16 +0,0 @@ -ESP-IDF BT-SPP-INITATOR demo -====================== - -Demo of SPP initator role - -This is the demo for user to use ESP_APIs to create a SPP initator. - -Options choose step: - 1. idf.py menuconfig. - 2. enter menuconfig "Component config", choose "Bluetooth" - 3. enter menu Bluetooth, choose "Classic Bluetooth" and "SPP Profile" - 4. choose your options. - -Then set SPP_SHOW_MODE as SPP_SHOW_DATA or SPP_SHOW_SPEED in code(should be same with bt_spp_acceptor). - -After the program started, It will connect to bt_spp_acceptor and send data.