From c245ca32b5fab86802edc8bc7205c3c3404a2af9 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Tue, 27 Nov 2018 11:25:13 +0100 Subject: [PATCH] sm: ENABLE_LE_CENTRAL_AUTO_ENCRYPTION triggers automatic encryption on connect to bonded devices --- doc/manual/docs/how_to.md | 3 ++- src/ble/sm.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/doc/manual/docs/how_to.md b/doc/manual/docs/how_to.md index ac1ea4bd5..594ee828c 100644 --- a/doc/manual/docs/how_to.md +++ b/doc/manual/docs/how_to.md @@ -80,6 +80,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_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 @@ -91,7 +92,7 @@ ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL | Enable HCI Controller to Host Flow ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND | Enable workaround for bug in CC256x Flow Control during baud rate change, see chipset docs. Notes: -- ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS: Only some Bluetooth 4.2+ controllers (e.g., EM9304, ESP32) support the necessary HCI commands. Others reasons to enable the ECC software implementations are if the Host is much faster or if the micro-ecc library is already provided (e.g., ESP32, WICED) +- ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS: Only some Bluetooth 4.2+ controllers (e.g., EM9304, ESP32) support the necessary HCI commands for ECC. Other reason to enable the ECC software implementations are if the Host is much faster or if the micro-ecc library is already provided (e.g., ESP32, WICED, or if the ECC HCI Commands are unreliable. ### HCI Controller to Host Flow Control In general, BTstack relies on flow control of the HCI transport, either via Hardware CTS/RTS flow control for UART or regular USB flow control. If this is not possible, e.g on an SoC, BTstack can use HCI Controller to Host Flow Control by defining ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL. If enabled, the HCI Transport implementation must be able to buffer the specified packets. In addition, it also need to be able to buffer a few HCI Events. Using a low number of host buffers might result in less throughput. diff --git a/src/ble/sm.c b/src/ble/sm.c index bfeed8023..9d04828c8 100644 --- a/src/ble/sm.c +++ b/src/ble/sm.c @@ -1151,10 +1151,18 @@ static void sm_address_resolution_handle_event(address_resolution_event_t event) // reset requests sm_connection->sm_security_request_received = 0; sm_connection->sm_pairing_requested = 0; + // have ltk -> start encryption + // Core 5, Vol 3, Part C, 10.3.2 Initiating a Service Request + // "When a bond has been created between two devices, any reconnection should result in the local device + // enabling or requesting encryption with the remote device before initiating any service request." if (have_ltk){ +#ifdef ENABLE_LE_CENTRAL_AUTO_ENCRYPTION sm_connection->sm_engine_state = SM_INITIATOR_PH0_HAS_LTK; break; +#else + log_info("central: defer enabling encryption for bonded device"); +#endif } // pairint_request -> send pairing request if (pairing_need){ @@ -3021,6 +3029,15 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint // encryption change event concludes re-encryption for bonded devices (even if it fails) if (sm_conn->sm_engine_state == SM_INITIATOR_PH0_W4_CONNECTION_ENCRYPTED){ sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; + // notify client, if pairing was requested before + if (sm_conn->sm_pairing_requested){ + sm_conn->sm_pairing_requested = 0; + if (sm_conn->sm_connection_encrypted){ + sm_notify_client_status_reason(sm_conn, ERROR_CODE_SUCCESS, 0); + } else { + sm_notify_client_status_reason(sm_conn, ERROR_CODE_AUTHENTICATION_FAILURE, 0); + } + } sm_done_for_handle(sm_conn->sm_handle); break; } @@ -3849,8 +3866,20 @@ void sm_request_pairing(hci_con_handle_t con_handle){ } else { // used as a trigger to start central/master/initiator security procedures if (sm_conn->sm_engine_state == SM_INITIATOR_CONNECTED){ + uint8_t ltk[16]; switch (sm_conn->sm_irk_lookup_state){ case IRK_LOOKUP_SUCCEEDED: +#ifndef ENABLE_LE_CENTRAL_AUTO_ENCRYPTION + le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL); + int have_ltk = !sm_is_null_key(ltk); + log_info("have ltk %u", have_ltk); + // trigger 'pairing complete' event on encryption change + sm_conn->sm_pairing_requested = 1; + sm_conn->sm_engine_state = SM_INITIATOR_PH0_HAS_LTK; + break; +#endif + /* explicit fall-through */ + case IRK_LOOKUP_FAILED: sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; break;