diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b413a57b..bc2e07483 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - GAP: gap_set_security_level sets required security level for incoming and outgoing connections - cc256x: allow to specify power vector for each modulation type - FreeRTOS: btstack_run_loop_freertos_trigger_exit allows to request run loop exit +- sm: support LE Secure Connections Only mode with sm_set_secure_connections_only_mode ### Changed - L2CAP ERTM: send extended features request only once per HCI connection diff --git a/example/sm_pairing_central.c b/example/sm_pairing_central.c index baffd3593..82c8e0968 100644 --- a/example/sm_pairing_central.c +++ b/example/sm_pairing_central.c @@ -100,7 +100,9 @@ static void sm_pairing_central_setup(void){ /** * Choose ONE of the following configurations - * Bonding is disabled to allow for repeated testing. It can be enabled with SM_AUTHREQ_BONDING + * Bonding is disabled to allow for repeated testing. It can be enabled by or'ing + * SM_AUTHREQ_BONDING to the authentication requirements like this: + * sm_set_authentication_requirements( X | SM_AUTHREQ_BONDING) */ // register handler @@ -112,7 +114,7 @@ static void sm_pairing_central_setup(void){ // LE Legacy Pairing, Just Works // sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_YES_NO); - // sm_set_authentication_requirements(SM_AUTHREQ_ NO_BONDING); + // sm_set_authentication_requirements(0); // LE Legacy Pairing, Passkey entry initiator enter, responder (us) displays // sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY); @@ -120,12 +122,15 @@ static void sm_pairing_central_setup(void){ // sm_use_fixed_passkey_in_display_role(FIXED_PASSKEY); #ifdef ENABLE_LE_SECURE_CONNECTIONS - // LE Secure Connetions, Just Works + + // enable LE Secure Connections Only mode - disables Legacy pairing + // sm_set_secure_connections_only_mode(true); + + // LE Secure Connections, Just Works // sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_YES_NO); // sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION); // LE Secure Connections, Numeric Comparison - // sm_set_io_capabilities(IO_CAPABILITY_KEYBOARD_ONLY); sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_YES_NO); sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); @@ -237,7 +242,7 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa printf("Pairing failed, timeout\n"); break; case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: - printf("Pairing faileed, disconnected\n"); + printf("Pairing failed, disconnected\n"); break; case ERROR_CODE_AUTHENTICATION_FAILURE: printf("Pairing failed, reason = %u\n", sm_event_pairing_complete_get_reason(packet)); diff --git a/example/sm_pairing_peripheral.c b/example/sm_pairing_peripheral.c index 0aa815daa..d8d29257f 100644 --- a/example/sm_pairing_peripheral.c +++ b/example/sm_pairing_peripheral.c @@ -93,12 +93,14 @@ static void sm_peripheral_setup(void){ /** * Choose ONE of the following configurations - * Bonding is disabled to allow for repeated testing. It can be enabled with SM_AUTHREQ_BONDING + * Bonding is disabled to allow for repeated testing. It can be enabled by or'ing + * SM_AUTHREQ_BONDING to the authentication requirements like this: + * sm_set_authentication_requirements( X | SM_AUTHREQ_BONDING) */ // LE Legacy Pairing, Just Works // sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT); - // sm_set_authentication_requirements(SM_AUTHREQ_BONDING); + // sm_set_authentication_requirements(0); // LE Legacy Pairing, Passkey entry initiator enter, responder (us) displays // sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY); @@ -106,12 +108,16 @@ static void sm_peripheral_setup(void){ // sm_use_fixed_passkey_in_display_role(123456); #ifdef ENABLE_LE_SECURE_CONNECTIONS - // LE Secure Connetions, Just Works + + // enable LE Secure Connections Only mode - disables Legacy pairing + sm_set_secure_connections_only_mode(true); + + // LE Secure Connections, Just Works // sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_YES_NO); // sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION); // LE Secure Connections, Numeric Comparison - sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY); + sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_YES_NO); sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); // LE Legacy Pairing, Passkey entry initiator enter, responder (us) displays @@ -207,7 +213,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack printf("Pairing failed, timeout\n"); break; case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: - printf("Pairing faileed, disconnected\n"); + printf("Pairing failed, disconnected\n"); break; case ERROR_CODE_AUTHENTICATION_FAILURE: printf("Pairing failed, reason = %u\n", sm_event_pairing_complete_get_reason(packet)); diff --git a/src/ble/sm.c b/src/ble/sm.c index 3c25bd466..5c71c1b6b 100644 --- a/src/ble/sm.c +++ b/src/ble/sm.c @@ -191,6 +191,7 @@ static uint8_t sm_io_capabilities = IO_CAPABILITY_NO_INPUT_NO_OUTPUT; static uint8_t sm_slave_request_security; static uint32_t sm_fixed_passkey_in_display_role; static uint8_t sm_reconstruct_ltk_without_le_device_db_entry; +static bool sm_sc_only_mode; #ifdef ENABLE_LE_SECURE_CONNECTIONS static uint8_t sm_sc_oob_random[16]; @@ -1130,6 +1131,12 @@ static int sm_stk_generation_init(sm_connection_t * sm_conn){ if (!sm_validate_stk_generation_method()) return SM_REASON_AUTHENTHICATION_REQUIREMENTS; #ifdef ENABLE_LE_SECURE_CONNECTIONS + // check LE SC Only mode + if (sm_sc_only_mode && (setup->sm_use_secure_connections == false)){ + log_info("SC Only mode active but SC not possible"); + return SM_REASON_AUTHENTHICATION_REQUIREMENTS; + } + // LTK (= encyrption information & master identification) only used exchanged for LE Legacy Connection if (setup->sm_use_secure_connections){ remote_key_request &= ~SM_KEYDIST_ENC_KEY; @@ -4455,3 +4462,12 @@ int gap_reconnect_security_setup_active(hci_con_handle_t con_handle){ // IRK Lookup Succeeded, re-encryption should be initiated. When done, state gets reset return sm_conn->sm_engine_state != SM_INITIATOR_CONNECTED; } + +void sm_set_secure_connections_only_mode(bool enable){ +#ifdef ENABLE_LE_SECURE_CONNECTIONS + sm_sc_only_mode = enable; +#else + // SC Only mode not possible without support for SC + btstack_assert(enable == false); +#endif +} diff --git a/src/ble/sm.h b/src/ble/sm.h index 82bc15068..c11ded343 100644 --- a/src/ble/sm.h +++ b/src/ble/sm.h @@ -110,6 +110,12 @@ void sm_set_authentication_requirements(uint8_t auth_req); */ void sm_set_io_capabilities(io_capability_t io_capability); +/** + * @brief Enable/disable Secure Connections Mode only + * @param enable secure connections only mode + */ +void sm_set_secure_connections_only_mode(bool enable); + /** * @brief Let Peripheral request an encrypted connection right after connecting * @note Not used normally. Bonding is triggered by access to protected attributes in ATT Server