doc: extend sm, mention security in gatt client

rename gatt client security diagrams
This commit is contained in:
Matthias Ringwald 2020-12-08 14:32:11 +01:00
parent 9b037397d7
commit 33676bc673
10 changed files with 73 additions and 17 deletions

View File

@ -85,7 +85,7 @@ ENABLE_HFP_WIDE_BAND_SPEECH | Enable support for mSBC codec used in HFP pro
ENBALE_LE_PERIPHERAL | Enable support for LE Peripheral Role in HCI and Security Manager
ENBALE_LE_CENTRAL | Enable support for LE Central Role in HCI and Security Manager
ENABLE_LE_SECURE_CONNECTIONS | Enable LE Secure Connections
ENABLE_LE_CENTRAL_AUTO_ENCRYPTION | Enable automatic encryption for bonded devices on re-connect
ENABLE_LE_PROACTIVE_AUTHENTICATION | Enable automatic encryption for bonded devices on re-connect
ENABLE_GATT_CLIENT_PAIRING | Enable GATT Client to start pairing and retry operation on security error
ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS | Use [micro-ecc library](https://github.com/kmackay/micro-ecc) for ECC operations
ENABLE_LE_DATA_CHANNELS | Enable LE Data Channels in credit-based flow control mode

View File

@ -376,12 +376,41 @@ queries in sequence, or you can check if you can perform a GATT query
on a particular connection right now using
*gatt_client_is_ready*, and retry later if it is not ready.
As a result to a GATT query, zero to many
*le_event*s are returned before a *GATT_EVENT_QUERY_COMPLETE* event
*GATT_EVENT_X*s are returned before a *GATT_EVENT_QUERY_COMPLETE* event
completes the query.
For more details on the available GATT queries, please consult
[GATT Client API](#sec:gattClientAPIAppendix).
#### Authentication
By default, the GATT Server is responsible for security and the GATT Client does not enforce any kind of authentication.
If the GATT Client accesses Characteristic that require encrytion or authentication, the remote GATT Server will return an error,
which is returned in the *att status* of the *GATT_EVENT_QUERY_COMPLETE*.
You can define *ENABLE_GATT_CLIENT_PAIRING* to instruct the GATT Client to trigger pairing in this case and to repeat the request.
This model allows for an attacker to spoof another device, but don't require authentication for the Characteristics.
As a first improvement, you can define *ENABLE_LE_PROACTIVE_AUTHENTICATION* in *btstack_config.h*. When defined, the GATT Client will
request the Security Manager to re-encrypt the connection if there is stored bonding information available.
If this fails, the *GATT_EVENT_QUERY_COMPLETE* will return with the att status *ATT_ERROR_BONDING_INFORMATION_MISSING*.
With *ENABLE_LE_PROACTIVE_AUTHENTICATION* defined and in Central role, you need to delete the local bonding information if the remote
lost its bonding information, e.g. because of a device reset. See *example/sm_pairing_central.c*.
Even with the Proactive Authentication, your device may still connect to an attacker that provides the same advertising data as
your actual device. If the device that you want to connect requires pairing, you can instruct the GATT Client to automatically
request an encrypted connection before sending any GATT Client request by calling *gatt_client_set_required_security_level()*.
If the device provides sufficient IO capabilities, a MITM attack can then be prevented. We call this 'Mandatory Authentication'.
The following diagrams provide a detailed overview about the GATT Client security mechanisms in different configurations:
- [Reactive Authentication as Central](picts/gatt_client_security_reactive_authentication_central.svg)
- [Reactive Authentication as Peripheral](picts/gatt_client_security_reactive_authentication_peripheral.svg)
- [Proactive Authentication as Central](picts/gatt_client_security_proactive_authentication_central.svg)
- [Proactive Authentication as Peripheral](picts/gatt_client_security_proactive_authentication_peripheral.svg)
- [Mandatory Authentication as Central](picts/gatt_client_security_mandatory_authentication_central.svg)
- [Mandatory Authentication as Peripheral](picts/gatt_client_security_mandatory_authentication_peripheral.svg)
### GATT Server {#sec:GATTServerProfiles}

View File

@ -824,9 +824,10 @@ To facilitate the creation of such a keypairs and the calculation of the LTK,
the Bluetooth Core V4.2 specification introduced appropriate commands for the Bluetooth controller.
As an alternative for controllers that don't provide these primitives, BTstack provides the relevant cryptographic functions in software via the BSD-2-Clause licensed [micro-ecc library](https://github.com/kmackay/micro-ecc/tree/static).
When using using LE Secure Connections, the Peripheral must store LTK in non-volatile memory.
To only allow LE Secure Connections, you can call *sm_set_secure_connections_only_mode(true)*.
### Initialization
@ -843,6 +844,7 @@ Bluetooth Core V4.0, Vol 3, Part G, 5.2.2 for more details on deriving
the different keys. The IR key is used to identify a device if private,
resolvable Bluetooth addresses are used.
### Configuration
To receive events from the Security Manager, a callback is necessary.
@ -866,7 +868,7 @@ The default SMP configuration in BTstack is to be as open as possible:
- expect no authentication requirements,
- don't support LE Secure Connections, and
- don't require LE Secure Connections, and
- IO Capabilities set to *IO_CAPABILITY_NO_INPUT_NO_OUTPUT*.
@ -898,37 +900,62 @@ and later:
- *SM_EVENT_IDENTITY_RESOLVING_FAILED* on lookup failure.
### User interaction
### User interaction during Pairing
BTstack will inform the app about pairing via theses events:
- *SM_EVENT_PAIRING_STARTED*: inform user that pairing has started
- *SM_EVENT_PAIRING_COMPLETE*: inform user that pairing is complete, see status
Depending on the authentication requirements, IO capabilities,
available OOB data, and the enabled STK generation methods,
BTstack will request feedback from
the app in the form of an event:
- *SM_EVENT_JUST_WORKS_REQUEST*: request a user to accept a Just Works
pairing
- *SM_EVENT_JUST_WORKS_REQUEST*: request a user to accept a Just Works pairing
- *SM_EVENT_PASSKEY_INPUT_NUMBER*: request user to input a passkey
- *SM_EVENT_PASSKEY_DISPLAY_NUMBER*: show a passkey to the user
- *SM_EVENT_PASSKEY_DISPLAY_CANCEL*: cancel show passkey to user
- *SM_EVENT_NUMERIC_COMPARISON_REQUEST*: show a passkey to the user and request confirmation
- *SM_EVENT_PASSKEY_INPUT_NUMBER*: request user to input a passkey
To accept Just Works/Numeric Comparison, or provide a Passkey, *sm_just_works_confirm* or *sm_passkey_input* can be called respectively.
Othwerise, *sm_bonding_decline* aborts the pairing.
- *SM_EVENT_PASSKEY_DISPLAY_NUMBER*: show a passkey to the user
After the bonding process, *SM_EVENT_PAIRING_COMPLETE*, is emitted. Any active dialog can be closed on this.
- *SM_EVENT_NUMERIC_COMPARISON_REQUEST*: show a passkey to the user and request confirmation
### Connection with Bonded Devices
To stop the bonding process, *sm_bonding_decline* should be called.
Otherwise, *sm_just_works_confirm* or *sm_passkey_input* can be
called.
During pairing, two devices exchange bonding information, notably a Long-Term Key (LTK) and their respective Identity Resolving Key (IRK).
On a subsequent connection, the Securit Manager will use this information to establish an encrypted connection.
To inform about this, the following events are emitted:
- *SM_EVENT_REENCRYPTION_STARTED*: we have stored bonding information and either trigger encryption (as Central), or, sent a security request (as Peripheral).
- *SM_EVENT_REENCRYPTION_COMPLETE*: re-encryption is complete. If the remote device does not have a stored LTK, the status code will be *ERROR_CODE_PIN_OR_KEY_MISSING*.
The *SM_EVENT_REENCRYPTION_COMPLETE* with *ERROR_CODE_PIN_OR_KEY_MISSING* can be caused:
- if the remote device was reset or the bonding was removed, or,
- we're connected to an attacker that uses the Bluetooth address of a bonded device.
In Peripheral role, pairing will start even in case of an re-encryption error. It might be helpful to inform the user about the lost bonding or reject it right away due to security considerations.
After the bonding process, *SM_EVENT_JUST_WORKS_CANCEL*, *SM_EVENT_PASSKEY_DISPLAY_CANCEL*, or *SM_EVENT_NUMERIC_COMPARISON_CANCEL* is emitted to update the user interface if an Just Works request or a passkey has been shown before.
### Keypress Notifications
As part of Bluetooth Core V4.2 specification, a device with a keyboard but no display can send keypress notifications to provide better user feedback. In BTstack, the *sm_keypress_notification()* function is used for sending notifications. Notifications are received by BTstack via the *SM_EVENT_KEYPRESS_NOTIFICATION* event.
### Cross-transport Key Derivation for LE Secure Connections
### Cross-transport Key Derivation (CTKD) for LE Secure Connections
In a dual-mode configuration, BTstack automatically generates an BR/EDR Link Key from the LE LTK via the Link Key Conversion function *h6*. It is then stored in the link key db.
In a dual-mode configuration, BTstack generates an BR/EDR Link Key from the LE LTK via the Link Key Conversion functions *h6* ,
(or *h7* if supported) when *ENABLE_CROSS_TRANSPORT_KEY_DERIVATION* is defined.
The derived key then stored in local LE Device DB.
To derive an LE LTK from a BR/EDR link key, the Bluetooth controller needs to support Secure Connections via NIST P-256 elliptic curves and the LE Secure Connections needs to get established via the LE Transport. BTstack does not support LE Secure Connections via LE Transport currently.
The main use case for this is connections with smartphones. E.g. iOS provides APIs for LE scanning and connection, but none for BR/EDR. This allows an application to connect and pair with
a device and also later setup a BR/EDR connection without the need for the smartphone user to use the system Settings menu.
To derive an LE LTK from a BR/EDR link key, the Bluetooth controller needs to support Secure Connections via NIST P-256 elliptic curves. BTstack does not support LE Secure Connections via LE Transport currently.
### Out-of-Band Data with LE Legacy Pairing