13deb3ec6SMatthias Ringwald /* 23deb3ec6SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 33deb3ec6SMatthias Ringwald * 43deb3ec6SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 53deb3ec6SMatthias Ringwald * modification, are permitted provided that the following conditions 63deb3ec6SMatthias Ringwald * are met: 73deb3ec6SMatthias Ringwald * 83deb3ec6SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 93deb3ec6SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 103deb3ec6SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 113deb3ec6SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 123deb3ec6SMatthias Ringwald * documentation and/or other materials provided with the distribution. 133deb3ec6SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 143deb3ec6SMatthias Ringwald * contributors may be used to endorse or promote products derived 153deb3ec6SMatthias Ringwald * from this software without specific prior written permission. 163deb3ec6SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 173deb3ec6SMatthias Ringwald * personal benefit and not for any commercial purpose or for 183deb3ec6SMatthias Ringwald * monetary gain. 193deb3ec6SMatthias Ringwald * 203deb3ec6SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 213deb3ec6SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 223deb3ec6SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 232fca4dadSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 242fca4dadSMilanka Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 253deb3ec6SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 263deb3ec6SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 273deb3ec6SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 283deb3ec6SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 293deb3ec6SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 303deb3ec6SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 313deb3ec6SMatthias Ringwald * SUCH DAMAGE. 323deb3ec6SMatthias Ringwald * 333deb3ec6SMatthias Ringwald * Please inquire about commercial licensing options at 343deb3ec6SMatthias Ringwald * [email protected] 353deb3ec6SMatthias Ringwald * 363deb3ec6SMatthias Ringwald */ 37ab2c6ae4SMatthias Ringwald 38e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "sm.c" 393deb3ec6SMatthias Ringwald 403deb3ec6SMatthias Ringwald #include <string.h> 413deb3ec6SMatthias Ringwald #include <inttypes.h> 423deb3ec6SMatthias Ringwald 433edc84c5SMatthias Ringwald #include "ble/le_device_db.h" 4459c6af15SMatthias Ringwald #include "ble/core.h" 453edc84c5SMatthias Ringwald #include "ble/sm.h" 4661f37892SMatthias Ringwald #include "bluetooth_company_id.h" 47d7f1c72eSMatthias Ringwald #include "btstack_bool.h" 48d1a1f6a4SMatthias Ringwald #include "btstack_crypto.h" 490e2df43fSMatthias Ringwald #include "btstack_debug.h" 500e2df43fSMatthias Ringwald #include "btstack_event.h" 510e2df43fSMatthias Ringwald #include "btstack_linked_list.h" 520e2df43fSMatthias Ringwald #include "btstack_memory.h" 53899e6e02SMatthias Ringwald #include "btstack_tlv.h" 54f7a05cdaSMatthias Ringwald #include "gap.h" 550e2df43fSMatthias Ringwald #include "hci.h" 5613377825SMatthias Ringwald #include "hci_dump.h" 570e2df43fSMatthias Ringwald #include "l2cap.h" 583deb3ec6SMatthias Ringwald 591a682202SMatthias Ringwald #if !defined(ENABLE_LE_PERIPHERAL) && !defined(ENABLE_LE_CENTRAL) 601a682202SMatthias Ringwald #error "LE Security Manager used, but neither ENABLE_LE_PERIPHERAL nor ENABLE_LE_CENTRAL defined. Please add at least one to btstack_config.h." 611a682202SMatthias Ringwald #endif 621a682202SMatthias Ringwald 637ece0eaaSMatthias Ringwald #if defined(ENABLE_CROSS_TRANSPORT_KEY_DERIVATION) && (!defined(ENABLE_CLASSIC) || !defined(ENABLE_LE_SECURE_CONNECTIONS)) 647ece0eaaSMatthias Ringwald #error "Cross Transport Key Derivation requires support for LE Secure Connections and BR/EDR (Classic)" 656857ad8fSMatthias Ringwald #endif 666857ad8fSMatthias Ringwald 67d1a1f6a4SMatthias Ringwald // assert SM Public Key can be sent/received 68d1a1f6a4SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 69d1a1f6a4SMatthias Ringwald #if HCI_ACL_PAYLOAD_SIZE < 69 70d1a1f6a4SMatthias Ringwald #error "HCI_ACL_PAYLOAD_SIZE must be at least 69 bytes when using LE Secure Conection. Please increase HCI_ACL_PAYLOAD_SIZE or disable ENABLE_LE_SECURE_CONNECTIONS" 71d1a1f6a4SMatthias Ringwald #endif 72d1a1f6a4SMatthias Ringwald #endif 73d1a1f6a4SMatthias Ringwald 7442134bc6SMatthias Ringwald #if defined(ENABLE_LE_PERIPHERAL) && defined(ENABLE_LE_CENTRAL) 75cd1176f5SMatthias Ringwald #define IS_RESPONDER(role) ((role) == HCI_ROLE_SLAVE) 7642134bc6SMatthias Ringwald #else 7742134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 7842134bc6SMatthias Ringwald // only central - never responder (avoid 'unused variable' warnings) 79cd1176f5SMatthias Ringwald #define IS_RESPONDER(role) (0 && ((role) == HCI_ROLE_SLAVE)) 8042134bc6SMatthias Ringwald #else 8142134bc6SMatthias Ringwald // only peripheral - always responder (avoid 'unused variable' warnings) 82cd1176f5SMatthias Ringwald #define IS_RESPONDER(role) (1 || ((role) == HCI_ROLE_SLAVE)) 8342134bc6SMatthias Ringwald #endif 8442134bc6SMatthias Ringwald #endif 8542134bc6SMatthias Ringwald 867a766ebfSMatthias Ringwald #if defined(ENABLE_LE_SIGNED_WRITE) || defined(ENABLE_LE_SECURE_CONNECTIONS) 87d1a1f6a4SMatthias Ringwald #define USE_CMAC_ENGINE 887a766ebfSMatthias Ringwald #endif 897a766ebfSMatthias Ringwald 906857ad8fSMatthias Ringwald 91968b2eafSMatthias Ringwald #define BTSTACK_TAG32(A,B,C,D) (((A) << 24) | ((B) << 16) | ((C) << 8) | (D)) 92899e6e02SMatthias Ringwald 933deb3ec6SMatthias Ringwald // 943deb3ec6SMatthias Ringwald // SM internal types and globals 953deb3ec6SMatthias Ringwald // 963deb3ec6SMatthias Ringwald 973deb3ec6SMatthias Ringwald typedef enum { 983deb3ec6SMatthias Ringwald DKG_W4_WORKING, 993deb3ec6SMatthias Ringwald DKG_CALC_IRK, 1003deb3ec6SMatthias Ringwald DKG_CALC_DHK, 1013deb3ec6SMatthias Ringwald DKG_READY 1023deb3ec6SMatthias Ringwald } derived_key_generation_t; 1033deb3ec6SMatthias Ringwald 1043deb3ec6SMatthias Ringwald typedef enum { 1053deb3ec6SMatthias Ringwald RAU_IDLE, 106fbd4e238SMatthias Ringwald RAU_GET_RANDOM, 1073deb3ec6SMatthias Ringwald RAU_W4_RANDOM, 1083deb3ec6SMatthias Ringwald RAU_GET_ENC, 1093deb3ec6SMatthias Ringwald RAU_W4_ENC, 1103deb3ec6SMatthias Ringwald } random_address_update_t; 1113deb3ec6SMatthias Ringwald 1123deb3ec6SMatthias Ringwald typedef enum { 1133deb3ec6SMatthias Ringwald CMAC_IDLE, 1143deb3ec6SMatthias Ringwald CMAC_CALC_SUBKEYS, 1153deb3ec6SMatthias Ringwald CMAC_W4_SUBKEYS, 1163deb3ec6SMatthias Ringwald CMAC_CALC_MI, 1173deb3ec6SMatthias Ringwald CMAC_W4_MI, 1183deb3ec6SMatthias Ringwald CMAC_CALC_MLAST, 1193deb3ec6SMatthias Ringwald CMAC_W4_MLAST 1203deb3ec6SMatthias Ringwald } cmac_state_t; 1213deb3ec6SMatthias Ringwald 1223deb3ec6SMatthias Ringwald typedef enum { 1233deb3ec6SMatthias Ringwald JUST_WORKS, 12427c32905SMatthias Ringwald PK_RESP_INPUT, // Initiator displays PK, responder inputs PK 12527c32905SMatthias Ringwald PK_INIT_INPUT, // Responder displays PK, initiator inputs PK 12647fb4255SMatthias Ringwald PK_BOTH_INPUT, // Only input on both, both input PK 12747fb4255SMatthias Ringwald NUMERIC_COMPARISON, // Only numerical compparison (yes/no) on on both sides 12847fb4255SMatthias Ringwald OOB // OOB available on one (SC) or both sides (legacy) 1293deb3ec6SMatthias Ringwald } stk_generation_method_t; 1303deb3ec6SMatthias Ringwald 1313deb3ec6SMatthias Ringwald typedef enum { 1323deb3ec6SMatthias Ringwald SM_USER_RESPONSE_IDLE, 1333deb3ec6SMatthias Ringwald SM_USER_RESPONSE_PENDING, 1343deb3ec6SMatthias Ringwald SM_USER_RESPONSE_CONFIRM, 1353deb3ec6SMatthias Ringwald SM_USER_RESPONSE_PASSKEY, 1363deb3ec6SMatthias Ringwald SM_USER_RESPONSE_DECLINE 1373deb3ec6SMatthias Ringwald } sm_user_response_t; 1383deb3ec6SMatthias Ringwald 1393deb3ec6SMatthias Ringwald typedef enum { 1403deb3ec6SMatthias Ringwald SM_AES128_IDLE, 1413deb3ec6SMatthias Ringwald SM_AES128_ACTIVE 1423deb3ec6SMatthias Ringwald } sm_aes128_state_t; 1433deb3ec6SMatthias Ringwald 1443deb3ec6SMatthias Ringwald typedef enum { 1453deb3ec6SMatthias Ringwald ADDRESS_RESOLUTION_IDLE, 1463deb3ec6SMatthias Ringwald ADDRESS_RESOLUTION_GENERAL, 1473deb3ec6SMatthias Ringwald ADDRESS_RESOLUTION_FOR_CONNECTION, 1483deb3ec6SMatthias Ringwald } address_resolution_mode_t; 1493deb3ec6SMatthias Ringwald 1503deb3ec6SMatthias Ringwald typedef enum { 151a66b030fSMatthias Ringwald ADDRESS_RESOLUTION_SUCCEEDED, 1523deb3ec6SMatthias Ringwald ADDRESS_RESOLUTION_FAILED, 1533deb3ec6SMatthias Ringwald } address_resolution_event_t; 154901c000fSMatthias Ringwald 155901c000fSMatthias Ringwald typedef enum { 15634b6528fSMatthias Ringwald EC_KEY_GENERATION_IDLE, 1577df18c15SMatthias Ringwald EC_KEY_GENERATION_ACTIVE, 1587df18c15SMatthias Ringwald EC_KEY_GENERATION_DONE, 1597df18c15SMatthias Ringwald } ec_key_generation_state_t; 1607df18c15SMatthias Ringwald 1617df18c15SMatthias Ringwald typedef enum { 1623cf37b8cSMatthias Ringwald SM_STATE_VAR_DHKEY_NEEDED = 1 << 0, 1633cf37b8cSMatthias Ringwald SM_STATE_VAR_DHKEY_CALCULATED = 1 << 1, 1643cf37b8cSMatthias Ringwald SM_STATE_VAR_DHKEY_COMMAND_RECEIVED = 1 << 2, 165901c000fSMatthias Ringwald } sm_state_var_t; 166901c000fSMatthias Ringwald 167c59d0c92SMatthias Ringwald typedef enum { 168c59d0c92SMatthias Ringwald SM_SC_OOB_IDLE, 169d1a1f6a4SMatthias Ringwald SM_SC_OOB_W4_RANDOM, 170c59d0c92SMatthias Ringwald SM_SC_OOB_W2_CALC_CONFIRM, 171c59d0c92SMatthias Ringwald SM_SC_OOB_W4_CONFIRM, 172c59d0c92SMatthias Ringwald } sm_sc_oob_state_t; 173c59d0c92SMatthias Ringwald 1746420f61eSMatthias Ringwald typedef uint8_t sm_key24_t[3]; 1756420f61eSMatthias Ringwald typedef uint8_t sm_key56_t[7]; 1766420f61eSMatthias Ringwald typedef uint8_t sm_key256_t[32]; 1776420f61eSMatthias Ringwald 1783deb3ec6SMatthias Ringwald // 1793deb3ec6SMatthias Ringwald // GLOBAL DATA 1803deb3ec6SMatthias Ringwald // 1813deb3ec6SMatthias Ringwald 1822d2d4d3cSMatthias Ringwald static bool sm_initialized; 1832d2d4d3cSMatthias Ringwald 184841468bbSMatthias Ringwald static bool test_use_fixed_local_csrk; 185841468bbSMatthias Ringwald static bool test_use_fixed_local_irk; 1863deb3ec6SMatthias Ringwald 187192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 188192365feSMatthias Ringwald static uint8_t test_pairing_failure; 189192365feSMatthias Ringwald #endif 190192365feSMatthias Ringwald 1913deb3ec6SMatthias Ringwald // configuration 1923deb3ec6SMatthias Ringwald static uint8_t sm_accepted_stk_generation_methods; 1933deb3ec6SMatthias Ringwald static uint8_t sm_max_encryption_key_size; 1943deb3ec6SMatthias Ringwald static uint8_t sm_min_encryption_key_size; 1953deb3ec6SMatthias Ringwald static uint8_t sm_auth_req = 0; 1963deb3ec6SMatthias Ringwald static uint8_t sm_io_capabilities = IO_CAPABILITY_NO_INPUT_NO_OUTPUT; 1974b8c611fSMatthias Ringwald static uint32_t sm_fixed_passkey_in_display_role; 1981979f09cSMatthias Ringwald static bool sm_reconstruct_ltk_without_le_device_db_entry; 1993deb3ec6SMatthias Ringwald 200b6f39a74SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 201728f6757SMatthias Ringwald static bool sm_slave_request_security; 202b6f39a74SMatthias Ringwald #endif 203b6f39a74SMatthias Ringwald 204c59d0c92SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 205c123d999SMatthias Ringwald static bool sm_sc_only_mode; 206c59d0c92SMatthias Ringwald static uint8_t sm_sc_oob_random[16]; 207c59d0c92SMatthias Ringwald static void (*sm_sc_oob_callback)(const uint8_t * confirm_value, const uint8_t * random_value); 208c59d0c92SMatthias Ringwald static sm_sc_oob_state_t sm_sc_oob_state; 209db88441fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS_DEBUG_KEY 210db88441fSMatthias Ringwald static bool sm_sc_debug_keys_enabled; 211db88441fSMatthias Ringwald #endif 212c59d0c92SMatthias Ringwald #endif 213c59d0c92SMatthias Ringwald 214899e6e02SMatthias Ringwald 2151979f09cSMatthias Ringwald static bool sm_persistent_keys_random_active; 216899e6e02SMatthias Ringwald static const btstack_tlv_t * sm_tlv_impl; 217899e6e02SMatthias Ringwald static void * sm_tlv_context; 218899e6e02SMatthias Ringwald 2193deb3ec6SMatthias Ringwald // Security Manager Master Keys, please use sm_set_er(er) and sm_set_ir(ir) with your own 128 bit random values 2203deb3ec6SMatthias Ringwald static sm_key_t sm_persistent_er; 2213deb3ec6SMatthias Ringwald static sm_key_t sm_persistent_ir; 2223deb3ec6SMatthias Ringwald 2233deb3ec6SMatthias Ringwald // derived from sm_persistent_ir 2243deb3ec6SMatthias Ringwald static sm_key_t sm_persistent_dhk; 2253deb3ec6SMatthias Ringwald static sm_key_t sm_persistent_irk; 2263deb3ec6SMatthias Ringwald static derived_key_generation_t dkg_state; 2273deb3ec6SMatthias Ringwald 2283deb3ec6SMatthias Ringwald // derived from sm_persistent_er 2293deb3ec6SMatthias Ringwald // .. 2303deb3ec6SMatthias Ringwald 2313deb3ec6SMatthias Ringwald // random address update 2323deb3ec6SMatthias Ringwald static random_address_update_t rau_state; 2333deb3ec6SMatthias Ringwald static bd_addr_t sm_random_address; 2343deb3ec6SMatthias Ringwald 235d1a1f6a4SMatthias Ringwald #ifdef USE_CMAC_ENGINE 236514d35fcSMatthias Ringwald // CMAC Calculation: General 237d1a1f6a4SMatthias Ringwald static btstack_crypto_aes128_cmac_t sm_cmac_request; 238d1a1f6a4SMatthias Ringwald static void (*sm_cmac_done_callback)(uint8_t hash[8]); 239d1a1f6a4SMatthias Ringwald static uint8_t sm_cmac_active; 240d1a1f6a4SMatthias Ringwald static uint8_t sm_cmac_hash[16]; 2417a766ebfSMatthias Ringwald #endif 242514d35fcSMatthias Ringwald 243514d35fcSMatthias Ringwald // CMAC for ATT Signed Writes 2447a766ebfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 245d1a1f6a4SMatthias Ringwald static uint16_t sm_cmac_signed_write_message_len; 246d1a1f6a4SMatthias Ringwald static uint8_t sm_cmac_signed_write_header[3]; 247d1a1f6a4SMatthias Ringwald static const uint8_t * sm_cmac_signed_write_message; 248d1a1f6a4SMatthias Ringwald static uint8_t sm_cmac_signed_write_sign_counter[4]; 2497a766ebfSMatthias Ringwald #endif 250514d35fcSMatthias Ringwald 251514d35fcSMatthias Ringwald // CMAC for Secure Connection functions 252514d35fcSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 253aec94140SMatthias Ringwald static sm_connection_t * sm_cmac_connection; 254514d35fcSMatthias Ringwald static uint8_t sm_cmac_sc_buffer[80]; 255514d35fcSMatthias Ringwald #endif 2563deb3ec6SMatthias Ringwald 2573deb3ec6SMatthias Ringwald // resolvable private address lookup / CSRK calculation 2583deb3ec6SMatthias Ringwald static int sm_address_resolution_test; 2593deb3ec6SMatthias Ringwald static uint8_t sm_address_resolution_addr_type; 2603deb3ec6SMatthias Ringwald static bd_addr_t sm_address_resolution_address; 2613deb3ec6SMatthias Ringwald static void * sm_address_resolution_context; 2623deb3ec6SMatthias Ringwald static address_resolution_mode_t sm_address_resolution_mode; 2638f2a52f4SMatthias Ringwald static btstack_linked_list_t sm_address_resolution_general_queue; 2643deb3ec6SMatthias Ringwald 265d1a1f6a4SMatthias Ringwald // aes128 crypto engine. 2663deb3ec6SMatthias Ringwald static sm_aes128_state_t sm_aes128_state; 2673deb3ec6SMatthias Ringwald 268d1a1f6a4SMatthias Ringwald // crypto 269d1a1f6a4SMatthias Ringwald static btstack_crypto_random_t sm_crypto_random_request; 270d1a1f6a4SMatthias Ringwald static btstack_crypto_aes128_t sm_crypto_aes128_request; 271d1a1f6a4SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 272d1a1f6a4SMatthias Ringwald static btstack_crypto_ecc_p256_t sm_crypto_ecc_p256_request; 2737df1ef2fSMatthias Ringwald #endif 2747df1ef2fSMatthias Ringwald 275d1a1f6a4SMatthias Ringwald // temp storage for random data 276d1a1f6a4SMatthias Ringwald static uint8_t sm_random_data[8]; 277d1a1f6a4SMatthias Ringwald static uint8_t sm_aes128_key[16]; 278d1a1f6a4SMatthias Ringwald static uint8_t sm_aes128_plaintext[16]; 279d1a1f6a4SMatthias Ringwald static uint8_t sm_aes128_ciphertext[16]; 2803deb3ec6SMatthias Ringwald 281a036ae12SMatthias Ringwald // to receive events 282e03e489aSMatthias Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration; 283c5b6ce22SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 284a036ae12SMatthias Ringwald static btstack_packet_callback_registration_t l2cap_event_callback_registration; 285c5b6ce22SMatthias Ringwald #endif 286e03e489aSMatthias Ringwald 28789a78d34SMatthias Ringwald /* to dispatch sm event */ 28889a78d34SMatthias Ringwald static btstack_linked_list_t sm_event_handlers; 28989a78d34SMatthias Ringwald 290ece00d2dSMatthias Ringwald /* to schedule calls to sm_run */ 291ece00d2dSMatthias Ringwald static btstack_timer_source_t sm_run_timer; 292ece00d2dSMatthias Ringwald 29309e4d397SMatthias Ringwald // LE Secure Connections 29409e4d397SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 29509e4d397SMatthias Ringwald static ec_key_generation_state_t ec_key_generation_state; 296fc5bff5fSMatthias Ringwald static uint8_t ec_q[64]; 29709e4d397SMatthias Ringwald #endif 298df86eb96SMatthias Ringwald 2993deb3ec6SMatthias Ringwald // 3003deb3ec6SMatthias Ringwald // Volume 3, Part H, Chapter 24 3013deb3ec6SMatthias Ringwald // "Security shall be initiated by the Security Manager in the device in the master role. 3023deb3ec6SMatthias Ringwald // The device in the slave role shall be the responding device." 3033deb3ec6SMatthias Ringwald // -> master := initiator, slave := responder 3043deb3ec6SMatthias Ringwald // 3053deb3ec6SMatthias Ringwald 3063deb3ec6SMatthias Ringwald // data needed for security setup 3073deb3ec6SMatthias Ringwald typedef struct sm_setup_context { 3083deb3ec6SMatthias Ringwald 309ec820d77SMatthias Ringwald btstack_timer_source_t sm_timeout; 3103deb3ec6SMatthias Ringwald 3113deb3ec6SMatthias Ringwald // user response, (Phase 1 and/or 2) 3123deb3ec6SMatthias Ringwald uint8_t sm_user_response; 313dd4a08fbSMatthias Ringwald uint8_t sm_keypress_notification; // bitmap: passkey started, digit entered, digit erased, passkey cleared, passkey complete, 3 bit count 3143deb3ec6SMatthias Ringwald 3153deb3ec6SMatthias Ringwald // defines which keys will be send after connection is encrypted - calculated during Phase 1, used Phase 3 316715a43d1SMatthias Ringwald uint8_t sm_key_distribution_send_set; 317715a43d1SMatthias Ringwald uint8_t sm_key_distribution_sent_set; 3189a90d41aSMatthias Ringwald uint8_t sm_key_distribution_expected_set; 319715a43d1SMatthias Ringwald uint8_t sm_key_distribution_received_set; 3203deb3ec6SMatthias Ringwald 3213deb3ec6SMatthias Ringwald // Phase 2 (Pairing over SMP) 3223deb3ec6SMatthias Ringwald stk_generation_method_t sm_stk_generation_method; 3233deb3ec6SMatthias Ringwald sm_key_t sm_tk; 324a680ba6bSMatthias Ringwald uint8_t sm_have_oob_data; 3256777d8fdSMatthias Ringwald bool sm_use_secure_connections; 3263deb3ec6SMatthias Ringwald 3273deb3ec6SMatthias Ringwald sm_key_t sm_c1_t3_value; // c1 calculation 3283deb3ec6SMatthias Ringwald sm_pairing_packet_t sm_m_preq; // pairing request - needed only for c1 3293deb3ec6SMatthias Ringwald sm_pairing_packet_t sm_s_pres; // pairing response - needed only for c1 3303deb3ec6SMatthias Ringwald sm_key_t sm_local_random; 3313deb3ec6SMatthias Ringwald sm_key_t sm_local_confirm; 3323deb3ec6SMatthias Ringwald sm_key_t sm_peer_random; 3333deb3ec6SMatthias Ringwald sm_key_t sm_peer_confirm; 3343deb3ec6SMatthias Ringwald uint8_t sm_m_addr_type; // address and type can be removed 3353deb3ec6SMatthias Ringwald uint8_t sm_s_addr_type; // '' 3363deb3ec6SMatthias Ringwald bd_addr_t sm_m_address; // '' 3373deb3ec6SMatthias Ringwald bd_addr_t sm_s_address; // '' 3383deb3ec6SMatthias Ringwald sm_key_t sm_ltk; 3393deb3ec6SMatthias Ringwald 34068437d83SMatthias Ringwald uint8_t sm_state_vars; 341e53be891SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 342fc5bff5fSMatthias Ringwald uint8_t sm_peer_q[64]; // also stores random for EC key generation during init 343446a8c36SMatthias Ringwald sm_key_t sm_peer_nonce; // might be combined with sm_peer_random 344446a8c36SMatthias Ringwald sm_key_t sm_local_nonce; // might be combined with sm_local_random 345d08147dfSMatthias Ringwald uint8_t sm_dhkey[32]; 346e53be891SMatthias Ringwald sm_key_t sm_peer_dhkey_check; 347e53be891SMatthias Ringwald sm_key_t sm_local_dhkey_check; 348446a8c36SMatthias Ringwald sm_key_t sm_ra; 349446a8c36SMatthias Ringwald sm_key_t sm_rb; 3502bacf595SMatthias Ringwald sm_key_t sm_t; // used for f5 and h6 351a9f29768SMatthias Ringwald sm_key_t sm_mackey; 3527df18c15SMatthias Ringwald uint8_t sm_passkey_bit; // also stores number of generated random bytes for EC key generation 353e53be891SMatthias Ringwald #endif 35427c32905SMatthias Ringwald 3553deb3ec6SMatthias Ringwald // Phase 3 3563deb3ec6SMatthias Ringwald 3573deb3ec6SMatthias Ringwald // key distribution, we generate 3583deb3ec6SMatthias Ringwald uint16_t sm_local_y; 3593deb3ec6SMatthias Ringwald uint16_t sm_local_div; 3603deb3ec6SMatthias Ringwald uint16_t sm_local_ediv; 3613deb3ec6SMatthias Ringwald uint8_t sm_local_rand[8]; 3623deb3ec6SMatthias Ringwald sm_key_t sm_local_ltk; 3633deb3ec6SMatthias Ringwald sm_key_t sm_local_csrk; 3643deb3ec6SMatthias Ringwald sm_key_t sm_local_irk; 3653deb3ec6SMatthias Ringwald // sm_local_address/addr_type not needed 3663deb3ec6SMatthias Ringwald 3673deb3ec6SMatthias Ringwald // key distribution, received from peer 3683deb3ec6SMatthias Ringwald uint16_t sm_peer_y; 3693deb3ec6SMatthias Ringwald uint16_t sm_peer_div; 3703deb3ec6SMatthias Ringwald uint16_t sm_peer_ediv; 3713deb3ec6SMatthias Ringwald uint8_t sm_peer_rand[8]; 3723deb3ec6SMatthias Ringwald sm_key_t sm_peer_ltk; 3733deb3ec6SMatthias Ringwald sm_key_t sm_peer_irk; 3743deb3ec6SMatthias Ringwald sm_key_t sm_peer_csrk; 3753deb3ec6SMatthias Ringwald uint8_t sm_peer_addr_type; 3763deb3ec6SMatthias Ringwald bd_addr_t sm_peer_address; 377715a43d1SMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 378715a43d1SMatthias Ringwald int sm_le_device_index; 379715a43d1SMatthias Ringwald #endif 380e0a03c85SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 381e0a03c85SMatthias Ringwald link_key_t sm_link_key; 382e0a03c85SMatthias Ringwald link_key_type_t sm_link_key_type; 383e0a03c85SMatthias Ringwald #endif 3843deb3ec6SMatthias Ringwald } sm_setup_context_t; 3853deb3ec6SMatthias Ringwald 3863deb3ec6SMatthias Ringwald // 3873deb3ec6SMatthias Ringwald static sm_setup_context_t the_setup; 3883deb3ec6SMatthias Ringwald static sm_setup_context_t * setup = &the_setup; 3893deb3ec6SMatthias Ringwald 3903deb3ec6SMatthias Ringwald // active connection - the one for which the_setup is used for 3917149bde5SMatthias Ringwald static uint16_t sm_active_connection_handle = HCI_CON_HANDLE_INVALID; 3923deb3ec6SMatthias Ringwald 3936b65794dSMilanka Ringwald // @return 1 if oob data is available 3943deb3ec6SMatthias Ringwald // stores oob data in provided 16 byte buffer if not null 3953deb3ec6SMatthias Ringwald static int (*sm_get_oob_data)(uint8_t addres_type, bd_addr_t addr, uint8_t * oob_data) = NULL; 3964acf7b7bSMatthias Ringwald static int (*sm_get_sc_oob_data)(uint8_t addres_type, bd_addr_t addr, uint8_t * oob_sc_peer_confirm, uint8_t * oob_sc_peer_random); 397b96d60a6SMatthias Ringwald static bool (*sm_get_ltk_callback)(hci_con_handle_t con_handle, uint8_t addres_type, bd_addr_t addr, uint8_t * ltk); 3983deb3ec6SMatthias Ringwald 3993deb3ec6SMatthias Ringwald static void sm_run(void); 4007887cd92SMatthias Ringwald static void sm_state_reset(void); 401711e6c80SMatthias Ringwald static void sm_done_for_handle(hci_con_handle_t con_handle); 402711e6c80SMatthias Ringwald static sm_connection_t * sm_get_connection_for_handle(hci_con_handle_t con_handle); 403916ea5b2SMatthias Ringwald static void sm_cache_ltk(sm_connection_t * connection, const sm_key_t ltk); 40477e2e5edSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 40577e2e5edSMatthias Ringwald static sm_connection_t * sm_get_connection_for_bd_addr_and_type(bd_addr_t address, bd_addr_type_t addr_type); 40677e2e5edSMatthias Ringwald #endif 4073deb3ec6SMatthias Ringwald static inline int sm_calc_actual_encryption_key_size(int other); 4083deb3ec6SMatthias Ringwald static int sm_validate_stk_generation_method(void); 409d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_address_resolution(void *arg); 410d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_dkg_dhk(void *arg); 411d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_dkg_irk(void *arg); 412d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_a(void *arg); 413d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_b(void *arg); 414d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_c(void *arg); 415d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_csrk(void *arg); 416d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_d(void * arg); 417d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph3_ltk(void *arg); 418d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph3_y(void *arg); 4192a526f21SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 420d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph4_ltk(void *arg); 421d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph4_y(void *arg); 4222a526f21SMatthias Ringwald #endif 423d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_stk(void *arg); 424d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_rau(void *arg); 425d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph2_tk(void * arg); 426d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_rau(void * arg); 427d1a1f6a4SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4286d80b495SMatthias Ringwald static void sm_cmac_message_start(const sm_key_t key, uint16_t message_len, const uint8_t * message, void (*done_callback)(uint8_t * hash)); 42934b6528fSMatthias Ringwald static void sm_ec_generate_new_key(void); 4306ca80073SMatthias Ringwald static void sm_handle_random_result_sc_next_w2_cmac_for_confirmation(void * arg); 4316ca80073SMatthias Ringwald static void sm_handle_random_result_sc_next_send_pairing_random(void * arg); 4326777d8fdSMatthias Ringwald static bool sm_passkey_entry(stk_generation_method_t method); 433d1a1f6a4SMatthias Ringwald #endif 4340ccf6c9cSMatthias Ringwald static void sm_pairing_complete(sm_connection_t * sm_conn, uint8_t status, uint8_t reason); 4353deb3ec6SMatthias Ringwald 4363deb3ec6SMatthias Ringwald static void log_info_hex16(const char * name, uint16_t value){ 4373deb3ec6SMatthias Ringwald log_info("%-6s 0x%04x", name, value); 4383deb3ec6SMatthias Ringwald } 4393deb3ec6SMatthias Ringwald 4401fbd72c5SMatthias Ringwald // static inline uint8_t sm_pairing_packet_get_code(sm_pairing_packet_t packet){ 4411fbd72c5SMatthias Ringwald // return packet[0]; 4421fbd72c5SMatthias Ringwald // } 4431fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_io_capability(sm_pairing_packet_t packet){ 4441fbd72c5SMatthias Ringwald return packet[1]; 4451fbd72c5SMatthias Ringwald } 4461fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_oob_data_flag(sm_pairing_packet_t packet){ 4471fbd72c5SMatthias Ringwald return packet[2]; 4481fbd72c5SMatthias Ringwald } 4491fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_auth_req(sm_pairing_packet_t packet){ 4501fbd72c5SMatthias Ringwald return packet[3]; 4511fbd72c5SMatthias Ringwald } 4521fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_max_encryption_key_size(sm_pairing_packet_t packet){ 4531fbd72c5SMatthias Ringwald return packet[4]; 4541fbd72c5SMatthias Ringwald } 4551fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_initiator_key_distribution(sm_pairing_packet_t packet){ 4561fbd72c5SMatthias Ringwald return packet[5]; 4571fbd72c5SMatthias Ringwald } 4581fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_responder_key_distribution(sm_pairing_packet_t packet){ 4591fbd72c5SMatthias Ringwald return packet[6]; 4601fbd72c5SMatthias Ringwald } 4611fbd72c5SMatthias Ringwald 4621fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_code(sm_pairing_packet_t packet, uint8_t code){ 4631fbd72c5SMatthias Ringwald packet[0] = code; 4641fbd72c5SMatthias Ringwald } 4651fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_io_capability(sm_pairing_packet_t packet, uint8_t io_capability){ 4661fbd72c5SMatthias Ringwald packet[1] = io_capability; 4671fbd72c5SMatthias Ringwald } 4681fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_oob_data_flag(sm_pairing_packet_t packet, uint8_t oob_data_flag){ 4691fbd72c5SMatthias Ringwald packet[2] = oob_data_flag; 4701fbd72c5SMatthias Ringwald } 4711fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_auth_req(sm_pairing_packet_t packet, uint8_t auth_req){ 4721fbd72c5SMatthias Ringwald packet[3] = auth_req; 4731fbd72c5SMatthias Ringwald } 4741fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_max_encryption_key_size(sm_pairing_packet_t packet, uint8_t max_encryption_key_size){ 4751fbd72c5SMatthias Ringwald packet[4] = max_encryption_key_size; 4761fbd72c5SMatthias Ringwald } 4771fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_initiator_key_distribution(sm_pairing_packet_t packet, uint8_t initiator_key_distribution){ 4781fbd72c5SMatthias Ringwald packet[5] = initiator_key_distribution; 4791fbd72c5SMatthias Ringwald } 4801fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_responder_key_distribution(sm_pairing_packet_t packet, uint8_t responder_key_distribution){ 4811fbd72c5SMatthias Ringwald packet[6] = responder_key_distribution; 4821fbd72c5SMatthias Ringwald } 4831fbd72c5SMatthias Ringwald 4841979f09cSMatthias Ringwald static bool sm_is_null_random(uint8_t random[8]){ 48524c4191dSMatthias Ringwald return btstack_is_null(random, 8); 4863764b551SMatthias Ringwald } 4873764b551SMatthias Ringwald 4881979f09cSMatthias Ringwald static bool sm_is_null_key(uint8_t * key){ 48924c4191dSMatthias Ringwald return btstack_is_null(key, 16); 4903764b551SMatthias Ringwald } 4913764b551SMatthias Ringwald 4921c34405fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4931c34405fSMatthias Ringwald static bool sm_is_ff(const uint8_t * buffer, uint16_t size){ 4941c34405fSMatthias Ringwald uint16_t i; 4951c34405fSMatthias Ringwald for (i=0; i < size ; i++){ 4961c34405fSMatthias Ringwald if (buffer[i] != 0xff) { 4971c34405fSMatthias Ringwald return false; 4981c34405fSMatthias Ringwald } 4991c34405fSMatthias Ringwald } 5001c34405fSMatthias Ringwald return true; 5011c34405fSMatthias Ringwald } 5021c34405fSMatthias Ringwald #endif 5031c34405fSMatthias Ringwald 50470b44dd4SMatthias Ringwald // sm_trigger_run allows to schedule callback from main run loop // reduces stack depth 50570b44dd4SMatthias Ringwald static void sm_run_timer_handler(btstack_timer_source_t * ts){ 50670b44dd4SMatthias Ringwald UNUSED(ts); 50770b44dd4SMatthias Ringwald sm_run(); 50870b44dd4SMatthias Ringwald } 50970b44dd4SMatthias Ringwald static void sm_trigger_run(void){ 5102d2d4d3cSMatthias Ringwald if (!sm_initialized) return; 51184c0c5c7SMatthias Ringwald (void)btstack_run_loop_remove_timer(&sm_run_timer); 51270b44dd4SMatthias Ringwald btstack_run_loop_set_timer(&sm_run_timer, 0); 51370b44dd4SMatthias Ringwald btstack_run_loop_add_timer(&sm_run_timer); 51470b44dd4SMatthias Ringwald } 51570b44dd4SMatthias Ringwald 5163deb3ec6SMatthias Ringwald // Key utils 5173deb3ec6SMatthias Ringwald static void sm_reset_tk(void){ 5183deb3ec6SMatthias Ringwald int i; 5193deb3ec6SMatthias Ringwald for (i=0;i<16;i++){ 5203deb3ec6SMatthias Ringwald setup->sm_tk[i] = 0; 5213deb3ec6SMatthias Ringwald } 5223deb3ec6SMatthias Ringwald } 5233deb3ec6SMatthias Ringwald 5243deb3ec6SMatthias Ringwald // "For example, if a 128-bit encryption key is 0x123456789ABCDEF0123456789ABCDEF0 5253deb3ec6SMatthias Ringwald // and it is reduced to 7 octets (56 bits), then the resulting key is 0x0000000000000000003456789ABCDEF0."" 5263deb3ec6SMatthias Ringwald static void sm_truncate_key(sm_key_t key, int max_encryption_size){ 5273deb3ec6SMatthias Ringwald int i; 5283deb3ec6SMatthias Ringwald for (i = max_encryption_size ; i < 16 ; i++){ 5293deb3ec6SMatthias Ringwald key[15-i] = 0; 5303deb3ec6SMatthias Ringwald } 5313deb3ec6SMatthias Ringwald } 5323deb3ec6SMatthias Ringwald 533899e6e02SMatthias Ringwald // ER / IR checks 53421045273SMatthias Ringwald static void sm_er_ir_set_default(void){ 535899e6e02SMatthias Ringwald int i; 536899e6e02SMatthias Ringwald for (i=0;i<16;i++){ 537899e6e02SMatthias Ringwald sm_persistent_er[i] = 0x30 + i; 538899e6e02SMatthias Ringwald sm_persistent_ir[i] = 0x90 + i; 539899e6e02SMatthias Ringwald } 540899e6e02SMatthias Ringwald } 541899e6e02SMatthias Ringwald 5421d80f1e6SMatthias Ringwald static bool sm_er_is_default(void){ 543899e6e02SMatthias Ringwald int i; 544899e6e02SMatthias Ringwald for (i=0;i<16;i++){ 5451d80f1e6SMatthias Ringwald if (sm_persistent_er[i] != (0x30+i)) return true; 546899e6e02SMatthias Ringwald } 5471d80f1e6SMatthias Ringwald return false; 548899e6e02SMatthias Ringwald } 549899e6e02SMatthias Ringwald 5501d80f1e6SMatthias Ringwald static bool sm_ir_is_default(void){ 551899e6e02SMatthias Ringwald int i; 552899e6e02SMatthias Ringwald for (i=0;i<16;i++){ 5531d80f1e6SMatthias Ringwald if (sm_persistent_ir[i] != (0x90+i)) return true; 554899e6e02SMatthias Ringwald } 5551d80f1e6SMatthias Ringwald return false; 556899e6e02SMatthias Ringwald } 557899e6e02SMatthias Ringwald 55873102768SMatthias Ringwald static void sm_dispatch_event(uint8_t packet_type, uint16_t channel, uint8_t * packet, uint16_t size){ 55973102768SMatthias Ringwald UNUSED(channel); 56073102768SMatthias Ringwald 56173102768SMatthias Ringwald // log event 56273102768SMatthias Ringwald hci_dump_packet(packet_type, 1, packet, size); 56373102768SMatthias Ringwald // dispatch to all event handlers 56473102768SMatthias Ringwald btstack_linked_list_iterator_t it; 56573102768SMatthias Ringwald btstack_linked_list_iterator_init(&it, &sm_event_handlers); 56673102768SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&it)){ 56773102768SMatthias Ringwald btstack_packet_callback_registration_t * entry = (btstack_packet_callback_registration_t*) btstack_linked_list_iterator_next(&it); 56873102768SMatthias Ringwald entry->callback(packet_type, 0, packet, size); 56973102768SMatthias Ringwald } 57073102768SMatthias Ringwald } 57173102768SMatthias Ringwald 57273102768SMatthias Ringwald static void sm_setup_event_base(uint8_t * event, int event_size, uint8_t type, hci_con_handle_t con_handle, uint8_t addr_type, bd_addr_t address){ 57373102768SMatthias Ringwald event[0] = type; 57473102768SMatthias Ringwald event[1] = event_size - 2; 57573102768SMatthias Ringwald little_endian_store_16(event, 2, con_handle); 57673102768SMatthias Ringwald event[4] = addr_type; 57773102768SMatthias Ringwald reverse_bd_addr(address, &event[5]); 57873102768SMatthias Ringwald } 57973102768SMatthias Ringwald 58073102768SMatthias Ringwald static void sm_notify_client_base(uint8_t type, hci_con_handle_t con_handle, uint8_t addr_type, bd_addr_t address){ 58173102768SMatthias Ringwald uint8_t event[11]; 58273102768SMatthias Ringwald sm_setup_event_base(event, sizeof(event), type, con_handle, addr_type, address); 58373102768SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, event, sizeof(event)); 58473102768SMatthias Ringwald } 58573102768SMatthias Ringwald 58673102768SMatthias Ringwald static void sm_notify_client_index(uint8_t type, hci_con_handle_t con_handle, uint8_t addr_type, bd_addr_t address, uint16_t index){ 58773102768SMatthias Ringwald // fetch addr and addr type from db, only called for valid entries 58873102768SMatthias Ringwald bd_addr_t identity_address; 58973102768SMatthias Ringwald int identity_address_type; 59073102768SMatthias Ringwald le_device_db_info(index, &identity_address_type, identity_address, NULL); 59173102768SMatthias Ringwald 59273102768SMatthias Ringwald uint8_t event[20]; 59373102768SMatthias Ringwald sm_setup_event_base(event, sizeof(event), type, con_handle, addr_type, address); 59473102768SMatthias Ringwald event[11] = identity_address_type; 59573102768SMatthias Ringwald reverse_bd_addr(identity_address, &event[12]); 59673102768SMatthias Ringwald little_endian_store_16(event, 18, index); 59773102768SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, event, sizeof(event)); 59873102768SMatthias Ringwald } 59973102768SMatthias Ringwald 60073102768SMatthias Ringwald static void sm_notify_client_status(uint8_t type, hci_con_handle_t con_handle, uint8_t addr_type, bd_addr_t address, uint8_t status){ 60173102768SMatthias Ringwald uint8_t event[12]; 60273102768SMatthias Ringwald sm_setup_event_base(event, sizeof(event), type, con_handle, addr_type, address); 60373102768SMatthias Ringwald event[11] = status; 60473102768SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, (uint8_t*) &event, sizeof(event)); 60573102768SMatthias Ringwald } 60673102768SMatthias Ringwald 60773102768SMatthias Ringwald 60873102768SMatthias Ringwald static void sm_reencryption_started(sm_connection_t * sm_conn){ 60973102768SMatthias Ringwald 6103ab61f77SMatthias Ringwald if (sm_conn->sm_reencryption_active) return; 6113ab61f77SMatthias Ringwald 6127b001f4eSMatthias Ringwald sm_conn->sm_reencryption_active = true; 61373102768SMatthias Ringwald 61473102768SMatthias Ringwald int identity_addr_type; 61573102768SMatthias Ringwald bd_addr_t identity_addr; 6163c0e26deSMatthias Ringwald if (sm_conn->sm_le_db_index >= 0){ 6173c0e26deSMatthias Ringwald // fetch addr and addr type from db, only called for valid entries 61873102768SMatthias Ringwald le_device_db_info(sm_conn->sm_le_db_index, &identity_addr_type, identity_addr, NULL); 6193c0e26deSMatthias Ringwald } else { 6203c0e26deSMatthias Ringwald // for legacy pairing with LTK re-construction, use current peer addr 6213c0e26deSMatthias Ringwald identity_addr_type = sm_conn->sm_peer_addr_type; 622d5529700SMatthias Ringwald // cppcheck-suppress uninitvar ; identity_addr is reported as uninitialized although it's the destination of the memcpy 6233c0e26deSMatthias Ringwald memcpy(identity_addr, sm_conn->sm_peer_address, 6); 6243c0e26deSMatthias Ringwald } 62573102768SMatthias Ringwald 62673102768SMatthias Ringwald sm_notify_client_base(SM_EVENT_REENCRYPTION_STARTED, sm_conn->sm_handle, identity_addr_type, identity_addr); 62773102768SMatthias Ringwald } 62873102768SMatthias Ringwald 62973102768SMatthias Ringwald static void sm_reencryption_complete(sm_connection_t * sm_conn, uint8_t status){ 63073102768SMatthias Ringwald 63160be5b21SMatthias Ringwald if (!sm_conn->sm_reencryption_active) return; 63260be5b21SMatthias Ringwald 6337b001f4eSMatthias Ringwald sm_conn->sm_reencryption_active = false; 63473102768SMatthias Ringwald 63573102768SMatthias Ringwald int identity_addr_type; 63673102768SMatthias Ringwald bd_addr_t identity_addr; 6373c0e26deSMatthias Ringwald if (sm_conn->sm_le_db_index >= 0){ 6383c0e26deSMatthias Ringwald // fetch addr and addr type from db, only called for valid entries 63973102768SMatthias Ringwald le_device_db_info(sm_conn->sm_le_db_index, &identity_addr_type, identity_addr, NULL); 6403c0e26deSMatthias Ringwald } else { 6413c0e26deSMatthias Ringwald // for legacy pairing with LTK re-construction, use current peer addr 6423c0e26deSMatthias Ringwald identity_addr_type = sm_conn->sm_peer_addr_type; 643d5529700SMatthias Ringwald // cppcheck-suppress uninitvar ; identity_addr is reported as uninitialized although it's the destination of the memcpy 6443c0e26deSMatthias Ringwald memcpy(identity_addr, sm_conn->sm_peer_address, 6); 6453c0e26deSMatthias Ringwald } 64673102768SMatthias Ringwald 64773102768SMatthias Ringwald sm_notify_client_status(SM_EVENT_REENCRYPTION_COMPLETE, sm_conn->sm_handle, identity_addr_type, identity_addr, status); 64873102768SMatthias Ringwald } 64973102768SMatthias Ringwald 650d3c12277SMatthias Ringwald static void sm_pairing_started(sm_connection_t * sm_conn){ 651d3c12277SMatthias Ringwald 652d3c12277SMatthias Ringwald if (sm_conn->sm_pairing_active) return; 653d3c12277SMatthias Ringwald 654d3c12277SMatthias Ringwald sm_conn->sm_pairing_active = true; 655d3c12277SMatthias Ringwald 656d3c12277SMatthias Ringwald uint8_t event[11]; 657d3c12277SMatthias Ringwald sm_setup_event_base(event, sizeof(event), SM_EVENT_PAIRING_STARTED, sm_conn->sm_handle, setup->sm_peer_addr_type, setup->sm_peer_address); 658d3c12277SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, (uint8_t*) &event, sizeof(event)); 659d3c12277SMatthias Ringwald } 660d3c12277SMatthias Ringwald 6610ccf6c9cSMatthias Ringwald static void sm_pairing_complete(sm_connection_t * sm_conn, uint8_t status, uint8_t reason){ 662f61072f5SMatthias Ringwald 663d77906ffSMatthias Ringwald if (!sm_conn->sm_pairing_active) return; 664d77906ffSMatthias Ringwald 66569f82ad8SMatthias Ringwald sm_conn->sm_pairing_active = false; 66669f82ad8SMatthias Ringwald 6670ccf6c9cSMatthias Ringwald uint8_t event[13]; 6680ccf6c9cSMatthias Ringwald sm_setup_event_base(event, sizeof(event), SM_EVENT_PAIRING_COMPLETE, sm_conn->sm_handle, setup->sm_peer_addr_type, setup->sm_peer_address); 6690ccf6c9cSMatthias Ringwald event[11] = status; 6700ccf6c9cSMatthias Ringwald event[12] = reason; 6710ccf6c9cSMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, (uint8_t*) &event, sizeof(event)); 6720ccf6c9cSMatthias Ringwald } 6730ccf6c9cSMatthias Ringwald 6743deb3ec6SMatthias Ringwald // SMP Timeout implementation 6753deb3ec6SMatthias Ringwald 6763deb3ec6SMatthias Ringwald // Upon transmission of the Pairing Request command or reception of the Pairing Request command, 6773deb3ec6SMatthias Ringwald // the Security Manager Timer shall be reset and started. 6783deb3ec6SMatthias Ringwald // 6793deb3ec6SMatthias Ringwald // The Security Manager Timer shall be reset when an L2CAP SMP command is queued for transmission. 6803deb3ec6SMatthias Ringwald // 6813deb3ec6SMatthias Ringwald // If the Security Manager Timer reaches 30 seconds, the procedure shall be considered to have failed, 6823deb3ec6SMatthias Ringwald // and the local higher layer shall be notified. No further SMP commands shall be sent over the L2CAP 6833deb3ec6SMatthias Ringwald // Security Manager Channel. A new SM procedure shall only be performed when a new physical link has been 6843deb3ec6SMatthias Ringwald // established. 6853deb3ec6SMatthias Ringwald 686ec820d77SMatthias Ringwald static void sm_timeout_handler(btstack_timer_source_t * timer){ 6873deb3ec6SMatthias Ringwald log_info("SM timeout"); 688c5b64319SMatthias Ringwald sm_connection_t * sm_conn = (sm_connection_t*) btstack_run_loop_get_timer_context(timer); 6893deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_TIMEOUT; 69068a18fb9SMatthias Ringwald sm_reencryption_complete(sm_conn, ERROR_CODE_CONNECTION_TIMEOUT); 6910ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_CONNECTION_TIMEOUT, 0); 6923deb3ec6SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 6933deb3ec6SMatthias Ringwald 6943deb3ec6SMatthias Ringwald // trigger handling of next ready connection 6953deb3ec6SMatthias Ringwald sm_run(); 6963deb3ec6SMatthias Ringwald } 6973deb3ec6SMatthias Ringwald static void sm_timeout_start(sm_connection_t * sm_conn){ 698528a4a3bSMatthias Ringwald btstack_run_loop_remove_timer(&setup->sm_timeout); 69991a977e8SMatthias Ringwald btstack_run_loop_set_timer_context(&setup->sm_timeout, sm_conn); 700528a4a3bSMatthias Ringwald btstack_run_loop_set_timer_handler(&setup->sm_timeout, sm_timeout_handler); 701528a4a3bSMatthias Ringwald btstack_run_loop_set_timer(&setup->sm_timeout, 30000); // 30 seconds sm timeout 702528a4a3bSMatthias Ringwald btstack_run_loop_add_timer(&setup->sm_timeout); 7033deb3ec6SMatthias Ringwald } 7043deb3ec6SMatthias Ringwald static void sm_timeout_stop(void){ 705528a4a3bSMatthias Ringwald btstack_run_loop_remove_timer(&setup->sm_timeout); 7063deb3ec6SMatthias Ringwald } 7073deb3ec6SMatthias Ringwald static void sm_timeout_reset(sm_connection_t * sm_conn){ 7083deb3ec6SMatthias Ringwald sm_timeout_stop(); 7093deb3ec6SMatthias Ringwald sm_timeout_start(sm_conn); 7103deb3ec6SMatthias Ringwald } 7113deb3ec6SMatthias Ringwald 7123deb3ec6SMatthias Ringwald // end of sm timeout 7133deb3ec6SMatthias Ringwald 7143deb3ec6SMatthias Ringwald // GAP Random Address updates 7153deb3ec6SMatthias Ringwald static gap_random_address_type_t gap_random_adress_type; 716ec820d77SMatthias Ringwald static btstack_timer_source_t gap_random_address_update_timer; 7173deb3ec6SMatthias Ringwald static uint32_t gap_random_adress_update_period; 7183deb3ec6SMatthias Ringwald 7193deb3ec6SMatthias Ringwald static void gap_random_address_trigger(void){ 720899e6e02SMatthias Ringwald log_info("gap_random_address_trigger, state %u", rau_state); 721d1a1f6a4SMatthias Ringwald if (rau_state != RAU_IDLE) return; 722fbd4e238SMatthias Ringwald rau_state = RAU_GET_RANDOM; 72370b44dd4SMatthias Ringwald sm_trigger_run(); 7243deb3ec6SMatthias Ringwald } 7253deb3ec6SMatthias Ringwald 726ec820d77SMatthias Ringwald static void gap_random_address_update_handler(btstack_timer_source_t * timer){ 7279ec2630cSMatthias Ringwald UNUSED(timer); 7289ec2630cSMatthias Ringwald 7293deb3ec6SMatthias Ringwald log_info("GAP Random Address Update due"); 730528a4a3bSMatthias Ringwald btstack_run_loop_set_timer(&gap_random_address_update_timer, gap_random_adress_update_period); 731528a4a3bSMatthias Ringwald btstack_run_loop_add_timer(&gap_random_address_update_timer); 7323deb3ec6SMatthias Ringwald gap_random_address_trigger(); 7333deb3ec6SMatthias Ringwald } 7343deb3ec6SMatthias Ringwald 7353deb3ec6SMatthias Ringwald static void gap_random_address_update_start(void){ 736528a4a3bSMatthias Ringwald btstack_run_loop_set_timer_handler(&gap_random_address_update_timer, gap_random_address_update_handler); 737528a4a3bSMatthias Ringwald btstack_run_loop_set_timer(&gap_random_address_update_timer, gap_random_adress_update_period); 738528a4a3bSMatthias Ringwald btstack_run_loop_add_timer(&gap_random_address_update_timer); 7393deb3ec6SMatthias Ringwald } 7403deb3ec6SMatthias Ringwald 7413deb3ec6SMatthias Ringwald static void gap_random_address_update_stop(void){ 742528a4a3bSMatthias Ringwald btstack_run_loop_remove_timer(&gap_random_address_update_timer); 7433deb3ec6SMatthias Ringwald } 7443deb3ec6SMatthias Ringwald 7453deb3ec6SMatthias Ringwald // ah(k,r) helper 7463deb3ec6SMatthias Ringwald // r = padding || r 7473deb3ec6SMatthias Ringwald // r - 24 bit value 7484a6806f3SMatthias Ringwald static void sm_ah_r_prime(uint8_t r[3], uint8_t * r_prime){ 7493deb3ec6SMatthias Ringwald // r'= padding || r 7503deb3ec6SMatthias Ringwald memset(r_prime, 0, 16); 7516535961aSMatthias Ringwald (void)memcpy(&r_prime[13], r, 3); 7523deb3ec6SMatthias Ringwald } 7533deb3ec6SMatthias Ringwald 7543deb3ec6SMatthias Ringwald // d1 helper 7553deb3ec6SMatthias Ringwald // d' = padding || r || d 7563deb3ec6SMatthias Ringwald // d,r - 16 bit values 7574a6806f3SMatthias Ringwald static void sm_d1_d_prime(uint16_t d, uint16_t r, uint8_t * d1_prime){ 7583deb3ec6SMatthias Ringwald // d'= padding || r || d 7593deb3ec6SMatthias Ringwald memset(d1_prime, 0, 16); 760f8fbdce0SMatthias Ringwald big_endian_store_16(d1_prime, 12, r); 761f8fbdce0SMatthias Ringwald big_endian_store_16(d1_prime, 14, d); 7623deb3ec6SMatthias Ringwald } 7633deb3ec6SMatthias Ringwald 7643deb3ec6SMatthias Ringwald // calculate arguments for first AES128 operation in C1 function 7654a6806f3SMatthias Ringwald static void sm_c1_t1(sm_key_t r, uint8_t preq[7], uint8_t pres[7], uint8_t iat, uint8_t rat, uint8_t * t1){ 7663deb3ec6SMatthias Ringwald 7673deb3ec6SMatthias Ringwald // p1 = pres || preq || rat’ || iat’ 7683deb3ec6SMatthias Ringwald // "The octet of iat’ becomes the least significant octet of p1 and the most signifi- 7693deb3ec6SMatthias Ringwald // cant octet of pres becomes the most significant octet of p1. 7703deb3ec6SMatthias Ringwald // For example, if the 8-bit iat’ is 0x01, the 8-bit rat’ is 0x00, the 56-bit preq 7713deb3ec6SMatthias Ringwald // is 0x07071000000101 and the 56 bit pres is 0x05000800000302 then 7723deb3ec6SMatthias Ringwald // p1 is 0x05000800000302070710000001010001." 7733deb3ec6SMatthias Ringwald 7743deb3ec6SMatthias Ringwald sm_key_t p1; 7759c80e4ccSMatthias Ringwald reverse_56(pres, &p1[0]); 7769c80e4ccSMatthias Ringwald reverse_56(preq, &p1[7]); 7773deb3ec6SMatthias Ringwald p1[14] = rat; 7783deb3ec6SMatthias Ringwald p1[15] = iat; 7798314c363SMatthias Ringwald log_info_key("p1", p1); 7808314c363SMatthias Ringwald log_info_key("r", r); 7813deb3ec6SMatthias Ringwald 7823deb3ec6SMatthias Ringwald // t1 = r xor p1 7833deb3ec6SMatthias Ringwald int i; 7843deb3ec6SMatthias Ringwald for (i=0;i<16;i++){ 7853deb3ec6SMatthias Ringwald t1[i] = r[i] ^ p1[i]; 7863deb3ec6SMatthias Ringwald } 7878314c363SMatthias Ringwald log_info_key("t1", t1); 7883deb3ec6SMatthias Ringwald } 7893deb3ec6SMatthias Ringwald 7903deb3ec6SMatthias Ringwald // calculate arguments for second AES128 operation in C1 function 7914a6806f3SMatthias Ringwald static void sm_c1_t3(sm_key_t t2, bd_addr_t ia, bd_addr_t ra, uint8_t * t3){ 7923deb3ec6SMatthias Ringwald // p2 = padding || ia || ra 7933deb3ec6SMatthias Ringwald // "The least significant octet of ra becomes the least significant octet of p2 and 7943deb3ec6SMatthias Ringwald // the most significant octet of padding becomes the most significant octet of p2. 7953deb3ec6SMatthias Ringwald // For example, if 48-bit ia is 0xA1A2A3A4A5A6 and the 48-bit ra is 7963deb3ec6SMatthias Ringwald // 0xB1B2B3B4B5B6 then p2 is 0x00000000A1A2A3A4A5A6B1B2B3B4B5B6. 7973deb3ec6SMatthias Ringwald 7983deb3ec6SMatthias Ringwald sm_key_t p2; 799d5529700SMatthias Ringwald // cppcheck-suppress uninitvar ; p2 is reported as uninitialized 8003deb3ec6SMatthias Ringwald memset(p2, 0, 16); 8016535961aSMatthias Ringwald (void)memcpy(&p2[4], ia, 6); 8026535961aSMatthias Ringwald (void)memcpy(&p2[10], ra, 6); 8038314c363SMatthias Ringwald log_info_key("p2", p2); 8043deb3ec6SMatthias Ringwald 8053deb3ec6SMatthias Ringwald // c1 = e(k, t2_xor_p2) 8063deb3ec6SMatthias Ringwald int i; 8073deb3ec6SMatthias Ringwald for (i=0;i<16;i++){ 8083deb3ec6SMatthias Ringwald t3[i] = t2[i] ^ p2[i]; 8093deb3ec6SMatthias Ringwald } 8108314c363SMatthias Ringwald log_info_key("t3", t3); 8113deb3ec6SMatthias Ringwald } 8123deb3ec6SMatthias Ringwald 8134a6806f3SMatthias Ringwald static void sm_s1_r_prime(sm_key_t r1, sm_key_t r2, uint8_t * r_prime){ 8148314c363SMatthias Ringwald log_info_key("r1", r1); 8158314c363SMatthias Ringwald log_info_key("r2", r2); 8166535961aSMatthias Ringwald (void)memcpy(&r_prime[8], &r2[8], 8); 8176535961aSMatthias Ringwald (void)memcpy(&r_prime[0], &r1[8], 8); 8183deb3ec6SMatthias Ringwald } 8193deb3ec6SMatthias Ringwald 820fbe050beSMatthias Ringwald 8213deb3ec6SMatthias Ringwald // decide on stk generation based on 8223deb3ec6SMatthias Ringwald // - pairing request 8233deb3ec6SMatthias Ringwald // - io capabilities 8243deb3ec6SMatthias Ringwald // - OOB data availability 8253deb3ec6SMatthias Ringwald static void sm_setup_tk(void){ 8263deb3ec6SMatthias Ringwald 8278334d3d8SMatthias Ringwald // horizontal: initiator capabilities 8288334d3d8SMatthias Ringwald // vertial: responder capabilities 8298334d3d8SMatthias Ringwald static const stk_generation_method_t stk_generation_method [5] [5] = { 8308334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, PK_INIT_INPUT, JUST_WORKS, PK_INIT_INPUT }, 8318334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, PK_INIT_INPUT, JUST_WORKS, PK_INIT_INPUT }, 8328334d3d8SMatthias Ringwald { PK_RESP_INPUT, PK_RESP_INPUT, PK_BOTH_INPUT, JUST_WORKS, PK_RESP_INPUT }, 8338334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS }, 8348334d3d8SMatthias Ringwald { PK_RESP_INPUT, PK_RESP_INPUT, PK_INIT_INPUT, JUST_WORKS, PK_RESP_INPUT }, 8358334d3d8SMatthias Ringwald }; 8368334d3d8SMatthias Ringwald 8378334d3d8SMatthias Ringwald // uses numeric comparison if one side has DisplayYesNo and KeyboardDisplay combinations 8388334d3d8SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 8398334d3d8SMatthias Ringwald static const stk_generation_method_t stk_generation_method_with_secure_connection[5][5] = { 8408334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, PK_INIT_INPUT, JUST_WORKS, PK_INIT_INPUT }, 8418334d3d8SMatthias Ringwald { JUST_WORKS, NUMERIC_COMPARISON, PK_INIT_INPUT, JUST_WORKS, NUMERIC_COMPARISON }, 8428334d3d8SMatthias Ringwald { PK_RESP_INPUT, PK_RESP_INPUT, PK_BOTH_INPUT, JUST_WORKS, PK_RESP_INPUT }, 8438334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS }, 8448334d3d8SMatthias Ringwald { PK_RESP_INPUT, NUMERIC_COMPARISON, PK_INIT_INPUT, JUST_WORKS, NUMERIC_COMPARISON }, 8458334d3d8SMatthias Ringwald }; 8468334d3d8SMatthias Ringwald #endif 8478334d3d8SMatthias Ringwald 8483deb3ec6SMatthias Ringwald // default: just works 8493deb3ec6SMatthias Ringwald setup->sm_stk_generation_method = JUST_WORKS; 8503deb3ec6SMatthias Ringwald 85127c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 85227c32905SMatthias Ringwald setup->sm_use_secure_connections = ( sm_pairing_packet_get_auth_req(setup->sm_m_preq) 85327c32905SMatthias Ringwald & sm_pairing_packet_get_auth_req(setup->sm_s_pres) 8544ea43905SMatthias Ringwald & SM_AUTHREQ_SECURE_CONNECTION ) != 0u; 85527c32905SMatthias Ringwald #else 8566777d8fdSMatthias Ringwald setup->sm_use_secure_connections = false; 85727c32905SMatthias Ringwald #endif 85898d95509SMatthias Ringwald log_info("Secure pairing: %u", setup->sm_use_secure_connections); 85927c32905SMatthias Ringwald 86065a9a04eSMatthias Ringwald 86165a9a04eSMatthias Ringwald // decide if OOB will be used based on SC vs. Legacy and oob flags 8621979f09cSMatthias Ringwald bool use_oob; 86365a9a04eSMatthias Ringwald if (setup->sm_use_secure_connections){ 86465a9a04eSMatthias Ringwald // In LE Secure Connections pairing, the out of band method is used if at least 86565a9a04eSMatthias Ringwald // one device has the peer device's out of band authentication data available. 8661979f09cSMatthias Ringwald use_oob = (sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq) | sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres)) != 0; 86765a9a04eSMatthias Ringwald } else { 86865a9a04eSMatthias Ringwald // In LE legacy pairing, the out of band method is used if both the devices have 86965a9a04eSMatthias Ringwald // the other device's out of band authentication data available. 8701979f09cSMatthias Ringwald use_oob = (sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq) & sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres)) != 0; 87165a9a04eSMatthias Ringwald } 87265a9a04eSMatthias Ringwald if (use_oob){ 87365a9a04eSMatthias Ringwald log_info("SM: have OOB data"); 87465a9a04eSMatthias Ringwald log_info_key("OOB", setup->sm_tk); 87565a9a04eSMatthias Ringwald setup->sm_stk_generation_method = OOB; 87665a9a04eSMatthias Ringwald return; 87765a9a04eSMatthias Ringwald } 87865a9a04eSMatthias Ringwald 87927c32905SMatthias Ringwald // If both devices have not set the MITM option in the Authentication Requirements 88027c32905SMatthias Ringwald // Flags, then the IO capabilities shall be ignored and the Just Works association 88127c32905SMatthias Ringwald // model shall be used. 8824ea43905SMatthias Ringwald if (((sm_pairing_packet_get_auth_req(setup->sm_m_preq) & SM_AUTHREQ_MITM_PROTECTION) == 0u) 8834ea43905SMatthias Ringwald && ((sm_pairing_packet_get_auth_req(setup->sm_s_pres) & SM_AUTHREQ_MITM_PROTECTION) == 0u)){ 88427c32905SMatthias Ringwald log_info("SM: MITM not required by both -> JUST WORKS"); 88527c32905SMatthias Ringwald return; 88627c32905SMatthias Ringwald } 88727c32905SMatthias Ringwald 8883deb3ec6SMatthias Ringwald // Reset TK as it has been setup in sm_init_setup 8893deb3ec6SMatthias Ringwald sm_reset_tk(); 8903deb3ec6SMatthias Ringwald 8913deb3ec6SMatthias Ringwald // Also use just works if unknown io capabilites 8928da2e96dSMatthias Ringwald if ((sm_pairing_packet_get_io_capability(setup->sm_m_preq) > IO_CAPABILITY_KEYBOARD_DISPLAY) || (sm_pairing_packet_get_io_capability(setup->sm_s_pres) > IO_CAPABILITY_KEYBOARD_DISPLAY)){ 8933deb3ec6SMatthias Ringwald return; 8943deb3ec6SMatthias Ringwald } 8953deb3ec6SMatthias Ringwald 8963deb3ec6SMatthias Ringwald // Otherwise the IO capabilities of the devices shall be used to determine the 8973deb3ec6SMatthias Ringwald // pairing method as defined in Table 2.4. 89827c32905SMatthias Ringwald // see http://stackoverflow.com/a/1052837/393697 for how to specify pointer to 2-dimensional array 89927c32905SMatthias Ringwald const stk_generation_method_t (*generation_method)[5] = stk_generation_method; 90027c32905SMatthias Ringwald 90127c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 902c6b7cbd9SMatthias Ringwald // table not define by default 90327c32905SMatthias Ringwald if (setup->sm_use_secure_connections){ 90427c32905SMatthias Ringwald generation_method = stk_generation_method_with_secure_connection; 90527c32905SMatthias Ringwald } 90627c32905SMatthias Ringwald #endif 90727c32905SMatthias Ringwald setup->sm_stk_generation_method = generation_method[sm_pairing_packet_get_io_capability(setup->sm_s_pres)][sm_pairing_packet_get_io_capability(setup->sm_m_preq)]; 90827c32905SMatthias Ringwald 9093deb3ec6SMatthias Ringwald log_info("sm_setup_tk: master io cap: %u, slave io cap: %u -> method %u", 9101ad129beSMatthias Ringwald sm_pairing_packet_get_io_capability(setup->sm_m_preq), sm_pairing_packet_get_io_capability(setup->sm_s_pres), setup->sm_stk_generation_method); 9113deb3ec6SMatthias Ringwald } 9123deb3ec6SMatthias Ringwald 9133deb3ec6SMatthias Ringwald static int sm_key_distribution_flags_for_set(uint8_t key_set){ 9143deb3ec6SMatthias Ringwald int flags = 0; 915f688bdb8SMatthias Ringwald if ((key_set & SM_KEYDIST_ENC_KEY) != 0u){ 9163deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 9173deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 9183deb3ec6SMatthias Ringwald } 919f688bdb8SMatthias Ringwald if ((key_set & SM_KEYDIST_ID_KEY) != 0u){ 9203deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 9213deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 9223deb3ec6SMatthias Ringwald } 923f688bdb8SMatthias Ringwald if ((key_set & SM_KEYDIST_SIGN) != 0u){ 9243deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 9253deb3ec6SMatthias Ringwald } 9263deb3ec6SMatthias Ringwald return flags; 9273deb3ec6SMatthias Ringwald } 9283deb3ec6SMatthias Ringwald 9299a90d41aSMatthias Ringwald static void sm_setup_key_distribution(uint8_t keys_to_send, uint8_t keys_to_receive){ 9303deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set = 0; 9319a90d41aSMatthias Ringwald setup->sm_key_distribution_expected_set = sm_key_distribution_flags_for_set(keys_to_receive); 9329a90d41aSMatthias Ringwald setup->sm_key_distribution_send_set = sm_key_distribution_flags_for_set(keys_to_send); 933715a43d1SMatthias Ringwald setup->sm_key_distribution_sent_set = 0; 9349790be5fSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 935715a43d1SMatthias Ringwald setup->sm_le_device_index = -1; 9369790be5fSMatthias Ringwald #endif 9373deb3ec6SMatthias Ringwald } 9383deb3ec6SMatthias Ringwald 9393deb3ec6SMatthias Ringwald // CSRK Key Lookup 9403deb3ec6SMatthias Ringwald 9413deb3ec6SMatthias Ringwald 9421d80f1e6SMatthias Ringwald static bool sm_address_resolution_idle(void){ 9433deb3ec6SMatthias Ringwald return sm_address_resolution_mode == ADDRESS_RESOLUTION_IDLE; 9443deb3ec6SMatthias Ringwald } 9453deb3ec6SMatthias Ringwald 946711e6c80SMatthias Ringwald static void sm_address_resolution_start_lookup(uint8_t addr_type, hci_con_handle_t con_handle, bd_addr_t addr, address_resolution_mode_t mode, void * context){ 9476535961aSMatthias Ringwald (void)memcpy(sm_address_resolution_address, addr, 6); 9483deb3ec6SMatthias Ringwald sm_address_resolution_addr_type = addr_type; 9493deb3ec6SMatthias Ringwald sm_address_resolution_test = 0; 9503deb3ec6SMatthias Ringwald sm_address_resolution_mode = mode; 9513deb3ec6SMatthias Ringwald sm_address_resolution_context = context; 952711e6c80SMatthias Ringwald sm_notify_client_base(SM_EVENT_IDENTITY_RESOLVING_STARTED, con_handle, addr_type, addr); 9533deb3ec6SMatthias Ringwald } 9543deb3ec6SMatthias Ringwald 9553deb3ec6SMatthias Ringwald int sm_address_resolution_lookup(uint8_t address_type, bd_addr_t address){ 9563deb3ec6SMatthias Ringwald // check if already in list 957665d90f2SMatthias Ringwald btstack_linked_list_iterator_t it; 9583deb3ec6SMatthias Ringwald sm_lookup_entry_t * entry; 959665d90f2SMatthias Ringwald btstack_linked_list_iterator_init(&it, &sm_address_resolution_general_queue); 960665d90f2SMatthias Ringwald while(btstack_linked_list_iterator_has_next(&it)){ 961665d90f2SMatthias Ringwald entry = (sm_lookup_entry_t *) btstack_linked_list_iterator_next(&it); 9623deb3ec6SMatthias Ringwald if (entry->address_type != address_type) continue; 963f688bdb8SMatthias Ringwald if (memcmp(entry->address, address, 6) != 0) continue; 9643deb3ec6SMatthias Ringwald // already in list 9653deb3ec6SMatthias Ringwald return BTSTACK_BUSY; 9663deb3ec6SMatthias Ringwald } 9673deb3ec6SMatthias Ringwald entry = btstack_memory_sm_lookup_entry_get(); 9683deb3ec6SMatthias Ringwald if (!entry) return BTSTACK_MEMORY_ALLOC_FAILED; 9693deb3ec6SMatthias Ringwald entry->address_type = (bd_addr_type_t) address_type; 9706535961aSMatthias Ringwald (void)memcpy(entry->address, address, 6); 971665d90f2SMatthias Ringwald btstack_linked_list_add(&sm_address_resolution_general_queue, (btstack_linked_item_t *) entry); 97270b44dd4SMatthias Ringwald sm_trigger_run(); 9733deb3ec6SMatthias Ringwald return 0; 9743deb3ec6SMatthias Ringwald } 9753deb3ec6SMatthias Ringwald 976d1a1f6a4SMatthias Ringwald // CMAC calculation using AES Engineq 977d1a1f6a4SMatthias Ringwald #ifdef USE_CMAC_ENGINE 978514d35fcSMatthias Ringwald 979d1a1f6a4SMatthias Ringwald static void sm_cmac_done_trampoline(void * arg){ 980d1a1f6a4SMatthias Ringwald UNUSED(arg); 981d1a1f6a4SMatthias Ringwald sm_cmac_active = 0; 982d1a1f6a4SMatthias Ringwald (*sm_cmac_done_callback)(sm_cmac_hash); 98370b44dd4SMatthias Ringwald sm_trigger_run(); 9843deb3ec6SMatthias Ringwald } 985514d35fcSMatthias Ringwald 9864dfd504aSMatthias Ringwald int sm_cmac_ready(void){ 9874ea43905SMatthias Ringwald return sm_cmac_active == 0u; 9883deb3ec6SMatthias Ringwald } 9896d80b495SMatthias Ringwald #endif 9903deb3ec6SMatthias Ringwald 9916d80b495SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 992514d35fcSMatthias Ringwald // generic cmac calculation 993d1a1f6a4SMatthias Ringwald static void sm_cmac_message_start(const sm_key_t key, uint16_t message_len, const uint8_t * message, void (*done_callback)(uint8_t * hash)){ 994d1a1f6a4SMatthias Ringwald sm_cmac_active = 1; 995d1a1f6a4SMatthias Ringwald sm_cmac_done_callback = done_callback; 996d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_cmac_message(&sm_cmac_request, key, message_len, message, sm_cmac_hash, sm_cmac_done_trampoline, NULL); 9973deb3ec6SMatthias Ringwald } 9987a766ebfSMatthias Ringwald #endif 9993deb3ec6SMatthias Ringwald 1000514d35fcSMatthias Ringwald // cmac for ATT Message signing 10017a766ebfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 1002d1a1f6a4SMatthias Ringwald 1003d1a1f6a4SMatthias Ringwald static void sm_cmac_generator_start(const sm_key_t key, uint16_t message_len, uint8_t (*get_byte_callback)(uint16_t offset), void (*done_callback)(uint8_t * hash)){ 1004d1a1f6a4SMatthias Ringwald sm_cmac_active = 1; 1005d1a1f6a4SMatthias Ringwald sm_cmac_done_callback = done_callback; 1006d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_cmac_generator(&sm_cmac_request, key, message_len, get_byte_callback, sm_cmac_hash, sm_cmac_done_trampoline, NULL); 1007d1a1f6a4SMatthias Ringwald } 1008d1a1f6a4SMatthias Ringwald 10094dfd504aSMatthias Ringwald static uint8_t sm_cmac_signed_write_message_get_byte(uint16_t offset){ 1010d1a1f6a4SMatthias Ringwald if (offset >= sm_cmac_signed_write_message_len) { 1011d1a1f6a4SMatthias Ringwald log_error("sm_cmac_signed_write_message_get_byte. out of bounds, access %u, len %u", offset, sm_cmac_signed_write_message_len); 10124dfd504aSMatthias Ringwald return 0; 10134dfd504aSMatthias Ringwald } 10144dfd504aSMatthias Ringwald 1015d1a1f6a4SMatthias Ringwald offset = sm_cmac_signed_write_message_len - 1 - offset; 10164dfd504aSMatthias Ringwald 1017d1a1f6a4SMatthias Ringwald // sm_cmac_signed_write_header[3] | message[] | sm_cmac_signed_write_sign_counter[4] 10184dfd504aSMatthias Ringwald if (offset < 3){ 1019d1a1f6a4SMatthias Ringwald return sm_cmac_signed_write_header[offset]; 10204dfd504aSMatthias Ringwald } 1021d1a1f6a4SMatthias Ringwald int actual_message_len_incl_header = sm_cmac_signed_write_message_len - 4; 10224dfd504aSMatthias Ringwald if (offset < actual_message_len_incl_header){ 1023d1a1f6a4SMatthias Ringwald return sm_cmac_signed_write_message[offset - 3]; 10244dfd504aSMatthias Ringwald } 1025d1a1f6a4SMatthias Ringwald return sm_cmac_signed_write_sign_counter[offset - actual_message_len_incl_header]; 10264dfd504aSMatthias Ringwald } 10274dfd504aSMatthias Ringwald 10284dfd504aSMatthias Ringwald void sm_cmac_signed_write_start(const sm_key_t k, uint8_t opcode, hci_con_handle_t con_handle, uint16_t message_len, const uint8_t * message, uint32_t sign_counter, void (*done_handler)(uint8_t * hash)){ 1029514d35fcSMatthias Ringwald // ATT Message Signing 1030d1a1f6a4SMatthias Ringwald sm_cmac_signed_write_header[0] = opcode; 1031d1a1f6a4SMatthias Ringwald little_endian_store_16(sm_cmac_signed_write_header, 1, con_handle); 1032d1a1f6a4SMatthias Ringwald little_endian_store_32(sm_cmac_signed_write_sign_counter, 0, sign_counter); 1033514d35fcSMatthias Ringwald uint16_t total_message_len = 3 + message_len + 4; // incl. virtually prepended att opcode, handle and appended sign_counter in LE 1034d1a1f6a4SMatthias Ringwald sm_cmac_signed_write_message = message; 1035d1a1f6a4SMatthias Ringwald sm_cmac_signed_write_message_len = total_message_len; 1036d1a1f6a4SMatthias Ringwald sm_cmac_generator_start(k, total_message_len, &sm_cmac_signed_write_message_get_byte, done_handler); 10373deb3ec6SMatthias Ringwald } 10387a766ebfSMatthias Ringwald #endif 10393deb3ec6SMatthias Ringwald 1040ea9b6796SMatthias Ringwald static void sm_trigger_user_response_basic(sm_connection_t * sm_conn, uint8_t event_type){ 1041ea9b6796SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_PENDING; 10425baa755bSMatthias Ringwald uint8_t event[12]; 1043f6a153d5SMatthias Ringwald sm_setup_event_base(event, sizeof(event), event_type, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address); 10445baa755bSMatthias Ringwald event[11] = setup->sm_use_secure_connections ? 1 : 0; 1045f6a153d5SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, event, sizeof(event)); 1046ea9b6796SMatthias Ringwald } 1047ea9b6796SMatthias Ringwald 104874b4d42aSMatthias Ringwald static void sm_trigger_user_response_passkey(sm_connection_t * sm_conn, uint8_t event_type){ 10495baa755bSMatthias Ringwald uint8_t event[16]; 1050f6a153d5SMatthias Ringwald uint32_t passkey = big_endian_read_32(setup->sm_tk, 12); 105174b4d42aSMatthias Ringwald sm_setup_event_base(event, sizeof(event), event_type, sm_conn->sm_handle, 1052f6a153d5SMatthias Ringwald sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address); 10535baa755bSMatthias Ringwald event[11] = setup->sm_use_secure_connections ? 1 : 0; 10545baa755bSMatthias Ringwald little_endian_store_32(event, 12, passkey); 1055f6a153d5SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, event, sizeof(event)); 1056ea9b6796SMatthias Ringwald } 1057ea9b6796SMatthias Ringwald 10583deb3ec6SMatthias Ringwald static void sm_trigger_user_response(sm_connection_t * sm_conn){ 1059446a8c36SMatthias Ringwald // notify client for: JUST WORKS confirm, Numeric comparison confirm, PASSKEY display or input 10603deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_IDLE; 1061d77906ffSMatthias Ringwald sm_conn->sm_pairing_active = true; 10623deb3ec6SMatthias Ringwald switch (setup->sm_stk_generation_method){ 10633deb3ec6SMatthias Ringwald case PK_RESP_INPUT: 106442134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1065ea9b6796SMatthias Ringwald sm_trigger_user_response_basic(sm_conn, SM_EVENT_PASSKEY_INPUT_NUMBER); 10663deb3ec6SMatthias Ringwald } else { 106774b4d42aSMatthias Ringwald sm_trigger_user_response_passkey(sm_conn, SM_EVENT_PASSKEY_DISPLAY_NUMBER); 10683deb3ec6SMatthias Ringwald } 10693deb3ec6SMatthias Ringwald break; 10703deb3ec6SMatthias Ringwald case PK_INIT_INPUT: 107142134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 107274b4d42aSMatthias Ringwald sm_trigger_user_response_passkey(sm_conn, SM_EVENT_PASSKEY_DISPLAY_NUMBER); 10733deb3ec6SMatthias Ringwald } else { 1074ea9b6796SMatthias Ringwald sm_trigger_user_response_basic(sm_conn, SM_EVENT_PASSKEY_INPUT_NUMBER); 10753deb3ec6SMatthias Ringwald } 10763deb3ec6SMatthias Ringwald break; 107747fb4255SMatthias Ringwald case PK_BOTH_INPUT: 1078ea9b6796SMatthias Ringwald sm_trigger_user_response_basic(sm_conn, SM_EVENT_PASSKEY_INPUT_NUMBER); 10793deb3ec6SMatthias Ringwald break; 108047fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 108174b4d42aSMatthias Ringwald sm_trigger_user_response_passkey(sm_conn, SM_EVENT_NUMERIC_COMPARISON_REQUEST); 108227c32905SMatthias Ringwald break; 10833deb3ec6SMatthias Ringwald case JUST_WORKS: 1084ea9b6796SMatthias Ringwald sm_trigger_user_response_basic(sm_conn, SM_EVENT_JUST_WORKS_REQUEST); 10853deb3ec6SMatthias Ringwald break; 10863deb3ec6SMatthias Ringwald case OOB: 10873deb3ec6SMatthias Ringwald // client already provided OOB data, let's skip notification. 10883deb3ec6SMatthias Ringwald break; 10897bbeb3adSMilanka Ringwald default: 10907bbeb3adSMilanka Ringwald btstack_assert(false); 10917bbeb3adSMilanka Ringwald break; 10923deb3ec6SMatthias Ringwald } 10933deb3ec6SMatthias Ringwald } 10943deb3ec6SMatthias Ringwald 109561d1a45eSMatthias Ringwald static bool sm_key_distribution_all_received(void) { 10965fa700b1SMatthias Ringwald log_debug("sm_key_distribution_all_received: received 0x%02x, expecting 0x%02x", setup->sm_key_distribution_received_set, setup->sm_key_distribution_expected_set); 1097b2296177SMatthias Ringwald return (setup->sm_key_distribution_expected_set & setup->sm_key_distribution_received_set) == setup->sm_key_distribution_expected_set; 10983deb3ec6SMatthias Ringwald } 10993deb3ec6SMatthias Ringwald 1100711e6c80SMatthias Ringwald static void sm_done_for_handle(hci_con_handle_t con_handle){ 11017149bde5SMatthias Ringwald if (sm_active_connection_handle == con_handle){ 11023deb3ec6SMatthias Ringwald sm_timeout_stop(); 11037149bde5SMatthias Ringwald sm_active_connection_handle = HCI_CON_HANDLE_INVALID; 1104711e6c80SMatthias Ringwald log_info("sm: connection 0x%x released setup context", con_handle); 1105c085d9ffSMatthias Ringwald 1106c085d9ffSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 1107c085d9ffSMatthias Ringwald // generate new ec key after each pairing (that used it) 1108c085d9ffSMatthias Ringwald if (setup->sm_use_secure_connections){ 1109c085d9ffSMatthias Ringwald sm_ec_generate_new_key(); 1110c085d9ffSMatthias Ringwald } 1111c085d9ffSMatthias Ringwald #endif 11123deb3ec6SMatthias Ringwald } 11133deb3ec6SMatthias Ringwald } 11143deb3ec6SMatthias Ringwald 11157d1c0c3aSMatthias Ringwald static void sm_master_pairing_success(sm_connection_t *connection) {// master -> all done 11161dca9d8aSMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_CONNECTED; 11170ccf6c9cSMatthias Ringwald sm_pairing_complete(connection, ERROR_CODE_SUCCESS, 0); 11181dca9d8aSMatthias Ringwald sm_done_for_handle(connection->sm_handle); 11191dca9d8aSMatthias Ringwald } 11201dca9d8aSMatthias Ringwald 11213deb3ec6SMatthias Ringwald static int sm_key_distribution_flags_for_auth_req(void){ 1122bb09604fSMatthias Ringwald 1123bb09604fSMatthias Ringwald int flags = SM_KEYDIST_ID_KEY; 1124f688bdb8SMatthias Ringwald if ((sm_auth_req & SM_AUTHREQ_BONDING) != 0u){ 1125bb09604fSMatthias Ringwald // encryption and signing information only if bonding requested 11263deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_ENC_KEY; 1127bb09604fSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 1128bb09604fSMatthias Ringwald flags |= SM_KEYDIST_SIGN; 1129bb09604fSMatthias Ringwald #endif 11307ece0eaaSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 1131b2072c76SMatthias Ringwald // LinkKey for CTKD requires SC and BR/EDR Support 1132b2072c76SMatthias Ringwald if (hci_classic_supported() && ((sm_auth_req & SM_AUTHREQ_SECURE_CONNECTION) != 0)){ 11337ece0eaaSMatthias Ringwald flags |= SM_KEYDIST_LINK_KEY; 11347ece0eaaSMatthias Ringwald } 11357ece0eaaSMatthias Ringwald #endif 11363deb3ec6SMatthias Ringwald } 11373deb3ec6SMatthias Ringwald return flags; 11383deb3ec6SMatthias Ringwald } 11393deb3ec6SMatthias Ringwald 1140d7471931SMatthias Ringwald static void sm_reset_setup(void){ 11413deb3ec6SMatthias Ringwald // fill in sm setup 1142901c000fSMatthias Ringwald setup->sm_state_vars = 0; 1143dd4a08fbSMatthias Ringwald setup->sm_keypress_notification = 0; 1144d0ea782aSMatthias Ringwald setup->sm_have_oob_data = 0; 11453deb3ec6SMatthias Ringwald sm_reset_tk(); 1146d7471931SMatthias Ringwald } 1147d7471931SMatthias Ringwald 1148d7471931SMatthias Ringwald static void sm_init_setup(sm_connection_t * sm_conn){ 1149d7471931SMatthias Ringwald // fill in sm setup 11503deb3ec6SMatthias Ringwald setup->sm_peer_addr_type = sm_conn->sm_peer_addr_type; 11516535961aSMatthias Ringwald (void)memcpy(setup->sm_peer_address, sm_conn->sm_peer_address, 6); 11523deb3ec6SMatthias Ringwald 1153a680ba6bSMatthias Ringwald // query client for Legacy Pairing OOB data 11549305033eSMatthias Ringwald if (sm_get_oob_data != NULL) { 1155a680ba6bSMatthias Ringwald setup->sm_have_oob_data = (*sm_get_oob_data)(sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address, setup->sm_tk); 11563deb3ec6SMatthias Ringwald } 11573deb3ec6SMatthias Ringwald 1158a680ba6bSMatthias Ringwald // if available and SC supported, also ask for SC OOB Data 1159a680ba6bSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 11604acf7b7bSMatthias Ringwald memset(setup->sm_ra, 0, 16); 11614acf7b7bSMatthias Ringwald memset(setup->sm_rb, 0, 16); 1162a680ba6bSMatthias Ringwald if (setup->sm_have_oob_data && (sm_auth_req & SM_AUTHREQ_SECURE_CONNECTION)){ 11639305033eSMatthias Ringwald if (sm_get_sc_oob_data != NULL){ 11644acf7b7bSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1165a680ba6bSMatthias Ringwald setup->sm_have_oob_data = (*sm_get_sc_oob_data)( 1166a680ba6bSMatthias Ringwald sm_conn->sm_peer_addr_type, 1167a680ba6bSMatthias Ringwald sm_conn->sm_peer_address, 1168a680ba6bSMatthias Ringwald setup->sm_peer_confirm, 11694acf7b7bSMatthias Ringwald setup->sm_ra); 11704acf7b7bSMatthias Ringwald } else { 11714acf7b7bSMatthias Ringwald setup->sm_have_oob_data = (*sm_get_sc_oob_data)( 11724acf7b7bSMatthias Ringwald sm_conn->sm_peer_addr_type, 11734acf7b7bSMatthias Ringwald sm_conn->sm_peer_address, 11744acf7b7bSMatthias Ringwald setup->sm_peer_confirm, 11754acf7b7bSMatthias Ringwald setup->sm_rb); 11764acf7b7bSMatthias Ringwald } 1177a680ba6bSMatthias Ringwald } else { 1178a680ba6bSMatthias Ringwald setup->sm_have_oob_data = 0; 1179a680ba6bSMatthias Ringwald } 1180a680ba6bSMatthias Ringwald } 1181a680ba6bSMatthias Ringwald #endif 1182a680ba6bSMatthias Ringwald 11833deb3ec6SMatthias Ringwald sm_pairing_packet_t * local_packet; 118442134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 11853deb3ec6SMatthias Ringwald // slave 11863deb3ec6SMatthias Ringwald local_packet = &setup->sm_s_pres; 11873deb3ec6SMatthias Ringwald setup->sm_m_addr_type = sm_conn->sm_peer_addr_type; 1188d5314cbeSMatthias Ringwald setup->sm_s_addr_type = sm_conn->sm_own_addr_type; 11896535961aSMatthias Ringwald (void)memcpy(setup->sm_m_address, sm_conn->sm_peer_address, 6); 1190d5314cbeSMatthias Ringwald (void)memcpy(setup->sm_s_address, sm_conn->sm_own_address, 6); 11913deb3ec6SMatthias Ringwald } else { 11923deb3ec6SMatthias Ringwald // master 11933deb3ec6SMatthias Ringwald local_packet = &setup->sm_m_preq; 11943deb3ec6SMatthias Ringwald setup->sm_s_addr_type = sm_conn->sm_peer_addr_type; 1195d5314cbeSMatthias Ringwald setup->sm_m_addr_type = sm_conn->sm_own_addr_type; 11966535961aSMatthias Ringwald (void)memcpy(setup->sm_s_address, sm_conn->sm_peer_address, 6); 1197d5314cbeSMatthias Ringwald (void)memcpy(setup->sm_m_address, sm_conn->sm_own_address, 6); 11983deb3ec6SMatthias Ringwald 1199d0ea782aSMatthias Ringwald uint8_t key_distribution_flags = sm_key_distribution_flags_for_auth_req(); 12001ad129beSMatthias Ringwald sm_pairing_packet_set_initiator_key_distribution(setup->sm_m_preq, key_distribution_flags); 12011ad129beSMatthias Ringwald sm_pairing_packet_set_responder_key_distribution(setup->sm_m_preq, key_distribution_flags); 12023deb3ec6SMatthias Ringwald } 12033deb3ec6SMatthias Ringwald 120457132f12SMatthias Ringwald uint8_t auth_req = sm_auth_req & ~SM_AUTHREQ_CT2; 1205d0ea782aSMatthias Ringwald uint8_t max_encryption_key_size = sm_max_encryption_key_size; 12062c041b42SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 12072c041b42SMatthias Ringwald // enable SC for SC only mode 12082c041b42SMatthias Ringwald if (sm_sc_only_mode){ 12092c041b42SMatthias Ringwald auth_req |= SM_AUTHREQ_SECURE_CONNECTION; 1210d0ea782aSMatthias Ringwald max_encryption_key_size = 16; 12112c041b42SMatthias Ringwald } 12122c041b42SMatthias Ringwald #endif 121357132f12SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 121457132f12SMatthias Ringwald // set CT2 if SC + Bonding + CTKD 121557132f12SMatthias Ringwald const uint8_t auth_req_for_ct2 = SM_AUTHREQ_SECURE_CONNECTION | SM_AUTHREQ_BONDING; 121657132f12SMatthias Ringwald if ((auth_req & auth_req_for_ct2) == auth_req_for_ct2){ 121757132f12SMatthias Ringwald auth_req |= SM_AUTHREQ_CT2; 121857132f12SMatthias Ringwald } 121957132f12SMatthias Ringwald #endif 12201ad129beSMatthias Ringwald sm_pairing_packet_set_io_capability(*local_packet, sm_io_capabilities); 1221a680ba6bSMatthias Ringwald sm_pairing_packet_set_oob_data_flag(*local_packet, setup->sm_have_oob_data); 1222df86eb96SMatthias Ringwald sm_pairing_packet_set_auth_req(*local_packet, auth_req); 1223d0ea782aSMatthias Ringwald sm_pairing_packet_set_max_encryption_key_size(*local_packet, max_encryption_key_size); 12243deb3ec6SMatthias Ringwald } 12253deb3ec6SMatthias Ringwald 12263deb3ec6SMatthias Ringwald static int sm_stk_generation_init(sm_connection_t * sm_conn){ 12273deb3ec6SMatthias Ringwald 12283deb3ec6SMatthias Ringwald sm_pairing_packet_t * remote_packet; 12299a90d41aSMatthias Ringwald uint8_t keys_to_send; 12309a90d41aSMatthias Ringwald uint8_t keys_to_receive; 123142134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 123252f9cf63SMatthias Ringwald // slave / responder 12333deb3ec6SMatthias Ringwald remote_packet = &setup->sm_m_preq; 12349a90d41aSMatthias Ringwald keys_to_send = sm_pairing_packet_get_responder_key_distribution(setup->sm_m_preq); 12359a90d41aSMatthias Ringwald keys_to_receive = sm_pairing_packet_get_initiator_key_distribution(setup->sm_m_preq); 12363deb3ec6SMatthias Ringwald } else { 12373deb3ec6SMatthias Ringwald // master / initiator 12383deb3ec6SMatthias Ringwald remote_packet = &setup->sm_s_pres; 12399a90d41aSMatthias Ringwald keys_to_send = sm_pairing_packet_get_initiator_key_distribution(setup->sm_s_pres); 12409a90d41aSMatthias Ringwald keys_to_receive = sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres); 12413deb3ec6SMatthias Ringwald } 12423deb3ec6SMatthias Ringwald 12433deb3ec6SMatthias Ringwald // check key size 12442c041b42SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 12452c041b42SMatthias Ringwald // SC Only mandates 128 bit key size 12462c041b42SMatthias Ringwald if (sm_sc_only_mode && (sm_pairing_packet_get_max_encryption_key_size(*remote_packet) < 16)) { 12472c041b42SMatthias Ringwald return SM_REASON_ENCRYPTION_KEY_SIZE; 12482c041b42SMatthias Ringwald } 12492c041b42SMatthias Ringwald #endif 12501ad129beSMatthias Ringwald sm_conn->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(sm_pairing_packet_get_max_encryption_key_size(*remote_packet)); 12514ea43905SMatthias Ringwald if (sm_conn->sm_actual_encryption_key_size == 0u) return SM_REASON_ENCRYPTION_KEY_SIZE; 12523deb3ec6SMatthias Ringwald 1253eddc894fSMatthias Ringwald // decide on STK generation method / SC 12543deb3ec6SMatthias Ringwald sm_setup_tk(); 12553deb3ec6SMatthias Ringwald log_info("SMP: generation method %u", setup->sm_stk_generation_method); 12563deb3ec6SMatthias Ringwald 12573deb3ec6SMatthias Ringwald // check if STK generation method is acceptable by client 12583deb3ec6SMatthias Ringwald if (!sm_validate_stk_generation_method()) return SM_REASON_AUTHENTHICATION_REQUIREMENTS; 12593deb3ec6SMatthias Ringwald 1260eddc894fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 12612c041b42SMatthias Ringwald // Check LE SC Only mode 12623cdbe9dbSMatthias Ringwald if (sm_sc_only_mode && (setup->sm_use_secure_connections == false)){ 12633cdbe9dbSMatthias Ringwald log_info("SC Only mode active but SC not possible"); 12643cdbe9dbSMatthias Ringwald return SM_REASON_AUTHENTHICATION_REQUIREMENTS; 12653cdbe9dbSMatthias Ringwald } 12663cdbe9dbSMatthias Ringwald 12679a90d41aSMatthias Ringwald // LTK (= encryption information & master identification) only used exchanged for LE Legacy Connection 1268eddc894fSMatthias Ringwald if (setup->sm_use_secure_connections){ 12699a90d41aSMatthias Ringwald keys_to_send &= ~SM_KEYDIST_ENC_KEY; 12709a90d41aSMatthias Ringwald keys_to_receive &= ~SM_KEYDIST_ENC_KEY; 1271eddc894fSMatthias Ringwald } 1272eddc894fSMatthias Ringwald #endif 1273eddc894fSMatthias Ringwald 127452f9cf63SMatthias Ringwald // identical to responder 12759a90d41aSMatthias Ringwald sm_setup_key_distribution(keys_to_send, keys_to_receive); 127652f9cf63SMatthias Ringwald 12773deb3ec6SMatthias Ringwald // JUST WORKS doens't provide authentication 1278c1ab6cc1SMatthias Ringwald sm_conn->sm_connection_authenticated = (setup->sm_stk_generation_method == JUST_WORKS) ? 0 : 1; 12793deb3ec6SMatthias Ringwald 12803deb3ec6SMatthias Ringwald return 0; 12813deb3ec6SMatthias Ringwald } 12823deb3ec6SMatthias Ringwald 12833deb3ec6SMatthias Ringwald static void sm_address_resolution_handle_event(address_resolution_event_t event){ 12843deb3ec6SMatthias Ringwald 12853deb3ec6SMatthias Ringwald // cache and reset context 12863deb3ec6SMatthias Ringwald int matched_device_id = sm_address_resolution_test; 12873deb3ec6SMatthias Ringwald address_resolution_mode_t mode = sm_address_resolution_mode; 12883deb3ec6SMatthias Ringwald void * context = sm_address_resolution_context; 12893deb3ec6SMatthias Ringwald 12903deb3ec6SMatthias Ringwald // reset context 12913deb3ec6SMatthias Ringwald sm_address_resolution_mode = ADDRESS_RESOLUTION_IDLE; 12923deb3ec6SMatthias Ringwald sm_address_resolution_context = NULL; 12933deb3ec6SMatthias Ringwald sm_address_resolution_test = -1; 12943deb3ec6SMatthias Ringwald 1295*45d80b08SMatthias Ringwald hci_con_handle_t con_handle = HCI_CON_HANDLE_INVALID; 12963deb3ec6SMatthias Ringwald sm_connection_t * sm_connection; 1297d2e90122SMatthias Ringwald sm_key_t ltk; 12981979f09cSMatthias Ringwald bool have_ltk; 1299*45d80b08SMatthias Ringwald int authenticated; 13006c44b759SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 13011979f09cSMatthias Ringwald bool trigger_pairing; 130242134bc6SMatthias Ringwald #endif 1303*45d80b08SMatthias Ringwald 13043deb3ec6SMatthias Ringwald switch (mode){ 13053deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_GENERAL: 13063deb3ec6SMatthias Ringwald break; 13073deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_FOR_CONNECTION: 13083deb3ec6SMatthias Ringwald sm_connection = (sm_connection_t *) context; 1309711e6c80SMatthias Ringwald con_handle = sm_connection->sm_handle; 13106c44b759SMatthias Ringwald 13116c44b759SMatthias Ringwald // have ltk -> start encryption / send security request 13126c44b759SMatthias Ringwald // Core 5, Vol 3, Part C, 10.3.2 Initiating a Service Request 13136c44b759SMatthias Ringwald // "When a bond has been created between two devices, any reconnection should result in the local device 13146c44b759SMatthias Ringwald // enabling or requesting encryption with the remote device before initiating any service request." 13156c44b759SMatthias Ringwald 13163deb3ec6SMatthias Ringwald switch (event){ 1317a66b030fSMatthias Ringwald case ADDRESS_RESOLUTION_SUCCEEDED: 13183deb3ec6SMatthias Ringwald sm_connection->sm_irk_lookup_state = IRK_LOOKUP_SUCCEEDED; 13193deb3ec6SMatthias Ringwald sm_connection->sm_le_db_index = matched_device_id; 1320a66b030fSMatthias Ringwald log_info("ADDRESS_RESOLUTION_SUCCEEDED, index %d", sm_connection->sm_le_db_index); 13216c44b759SMatthias Ringwald 13222d68601cSMatthias Ringwald le_device_db_encryption_get(sm_connection->sm_le_db_index, NULL, NULL, ltk, NULL, &authenticated, NULL, NULL); 13236c44b759SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 13246c44b759SMatthias Ringwald 1325f688bdb8SMatthias Ringwald if (IS_RESPONDER(sm_connection->sm_role)) { 13266c44b759SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 1327212d735eSMatthias Ringwald // IRK required before, continue 13286c39055aSMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK){ 13296c39055aSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST; 13306c39055aSMatthias Ringwald break; 13316c39055aSMatthias Ringwald } 1332212d735eSMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED_W4_IRK){ 1333212d735eSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED; 1334212d735eSMatthias Ringwald break; 1335212d735eSMatthias Ringwald } 1336728f6757SMatthias Ringwald bool trigger_security_request = sm_connection->sm_pairing_requested || sm_slave_request_security; 13375f3874afSMatthias Ringwald sm_connection->sm_pairing_requested = false; 13386c44b759SMatthias Ringwald #ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 13397af5dcd5SMatthias Ringwald // trigger security request for Proactive Authentication if LTK available 13407af5dcd5SMatthias Ringwald trigger_security_request = trigger_security_request || have_ltk; 13416c44b759SMatthias Ringwald #endif 13427af5dcd5SMatthias Ringwald 13437af5dcd5SMatthias Ringwald log_info("peripheral: pairing request local %u, have_ltk %u => trigger_security_request %u", 13445f3874afSMatthias Ringwald (int) sm_connection->sm_pairing_requested, (int) have_ltk, trigger_security_request); 13457af5dcd5SMatthias Ringwald 13467af5dcd5SMatthias Ringwald if (trigger_security_request){ 13477af5dcd5SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 13487af5dcd5SMatthias Ringwald if (have_ltk){ 13497af5dcd5SMatthias Ringwald sm_reencryption_started(sm_connection); 13507af5dcd5SMatthias Ringwald } else { 13517af5dcd5SMatthias Ringwald sm_pairing_started(sm_connection); 13527af5dcd5SMatthias Ringwald } 13537af5dcd5SMatthias Ringwald sm_trigger_run(); 13546c44b759SMatthias Ringwald } 13556c44b759SMatthias Ringwald #endif 13566c44b759SMatthias Ringwald } else { 13576c44b759SMatthias Ringwald 135842134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 13596c44b759SMatthias Ringwald // check if pairing already requested and reset requests 13606c44b759SMatthias Ringwald trigger_pairing = sm_connection->sm_pairing_requested || sm_connection->sm_security_request_received; 13612d68601cSMatthias Ringwald bool auth_required = sm_auth_req & SM_AUTHREQ_MITM_PROTECTION; 13622d68601cSMatthias Ringwald 13636c44b759SMatthias Ringwald log_info("central: pairing request local %u, remote %u => trigger_pairing %u. have_ltk %u", 13645f3874afSMatthias Ringwald (int) sm_connection->sm_pairing_requested, (int) sm_connection->sm_security_request_received, (int) trigger_pairing, (int) have_ltk); 13650dcaa15fSMatthias Ringwald sm_connection->sm_security_request_received = false; 13665f3874afSMatthias Ringwald sm_connection->sm_pairing_requested = false; 136732bc5d65SMatthias Ringwald bool trigger_reencryption = false; 1368c245ca32SMatthias Ringwald 1369d4af1595SMatthias Ringwald if (have_ltk){ 13702d68601cSMatthias Ringwald if (trigger_pairing){ 13712d68601cSMatthias Ringwald // if pairing is requested, re-encryption is sufficient, if ltk is already authenticated or we don't require authentication 13722d68601cSMatthias Ringwald trigger_reencryption = (authenticated != 0) || (auth_required == false); 13732d68601cSMatthias Ringwald } else { 13746a43f611SMatthias Ringwald #ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 1375b187cc61SMatthias Ringwald trigger_reencryption = true; 137632bc5d65SMatthias Ringwald #else 137732bc5d65SMatthias Ringwald log_info("central: defer enabling encryption for bonded device"); 137832bc5d65SMatthias Ringwald #endif 137932bc5d65SMatthias Ringwald } 13802d68601cSMatthias Ringwald } 138132bc5d65SMatthias Ringwald 138232bc5d65SMatthias Ringwald if (trigger_reencryption){ 13836c44b759SMatthias Ringwald log_info("central: enable encryption for bonded device"); 13845567aa60SMatthias Ringwald sm_connection->sm_engine_state = SM_INITIATOR_PH4_HAS_LTK; 1385d4af1595SMatthias Ringwald break; 1386d4af1595SMatthias Ringwald } 13876c44b759SMatthias Ringwald 13886c44b759SMatthias Ringwald // pairing_request -> send pairing request 13896c44b759SMatthias Ringwald if (trigger_pairing){ 13903deb3ec6SMatthias Ringwald sm_connection->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 1391d4af1595SMatthias Ringwald break; 13923deb3ec6SMatthias Ringwald } 139342134bc6SMatthias Ringwald #endif 1394298ab52bSMatthias Ringwald } 13953deb3ec6SMatthias Ringwald break; 13963deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_FAILED: 13973deb3ec6SMatthias Ringwald sm_connection->sm_irk_lookup_state = IRK_LOOKUP_FAILED; 1398f688bdb8SMatthias Ringwald if (IS_RESPONDER(sm_connection->sm_role)) { 13997af5dcd5SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 14006c39055aSMatthias Ringwald // LTK request received before, IRK required -> negative LTK reply 14016c39055aSMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK){ 14026c39055aSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY; 14036c39055aSMatthias Ringwald } 14047af5dcd5SMatthias Ringwald // send security request if requested 1405728f6757SMatthias Ringwald bool trigger_security_request = sm_connection->sm_pairing_requested || sm_slave_request_security; 14065f3874afSMatthias Ringwald sm_connection->sm_pairing_requested = false; 14077af5dcd5SMatthias Ringwald if (trigger_security_request){ 14087af5dcd5SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 14097af5dcd5SMatthias Ringwald sm_pairing_started(sm_connection); 14107af5dcd5SMatthias Ringwald } 14116c39055aSMatthias Ringwald break; 14127af5dcd5SMatthias Ringwald #endif 14136c39055aSMatthias Ringwald } 141442134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 14155f3874afSMatthias Ringwald if ((sm_connection->sm_pairing_requested == false) && (sm_connection->sm_security_request_received == false)) break; 14160dcaa15fSMatthias Ringwald sm_connection->sm_security_request_received = false; 14175f3874afSMatthias Ringwald sm_connection->sm_pairing_requested = false; 14183deb3ec6SMatthias Ringwald sm_connection->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 141942134bc6SMatthias Ringwald #endif 14203deb3ec6SMatthias Ringwald break; 14217bbeb3adSMilanka Ringwald 14227bbeb3adSMilanka Ringwald default: 14237bbeb3adSMilanka Ringwald btstack_assert(false); 14247bbeb3adSMilanka Ringwald break; 14253deb3ec6SMatthias Ringwald } 14263deb3ec6SMatthias Ringwald break; 14273deb3ec6SMatthias Ringwald default: 14283deb3ec6SMatthias Ringwald break; 14293deb3ec6SMatthias Ringwald } 14303deb3ec6SMatthias Ringwald 14313deb3ec6SMatthias Ringwald switch (event){ 1432a66b030fSMatthias Ringwald case ADDRESS_RESOLUTION_SUCCEEDED: 1433711e6c80SMatthias Ringwald sm_notify_client_index(SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED, con_handle, sm_address_resolution_addr_type, sm_address_resolution_address, matched_device_id); 14343deb3ec6SMatthias Ringwald break; 14353deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_FAILED: 1436711e6c80SMatthias Ringwald sm_notify_client_base(SM_EVENT_IDENTITY_RESOLVING_FAILED, con_handle, sm_address_resolution_addr_type, sm_address_resolution_address); 14373deb3ec6SMatthias Ringwald break; 14387bbeb3adSMilanka Ringwald default: 14397bbeb3adSMilanka Ringwald btstack_assert(false); 14407bbeb3adSMilanka Ringwald break; 14413deb3ec6SMatthias Ringwald } 14423deb3ec6SMatthias Ringwald } 14433deb3ec6SMatthias Ringwald 144455f09f49SMatthias Ringwald static void sm_store_bonding_information(sm_connection_t * sm_conn){ 14453deb3ec6SMatthias Ringwald int le_db_index = -1; 14463deb3ec6SMatthias Ringwald 14473deb3ec6SMatthias Ringwald // lookup device based on IRK 1448f688bdb8SMatthias Ringwald if ((setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION) != 0u){ 14493deb3ec6SMatthias Ringwald int i; 1450092ec58eSMatthias Ringwald for (i=0; i < le_device_db_max_count(); i++){ 14513deb3ec6SMatthias Ringwald sm_key_t irk; 14523deb3ec6SMatthias Ringwald bd_addr_t address; 1453c7e2c1a5SMatthias Ringwald int address_type = BD_ADDR_TYPE_UNKNOWN; 14543deb3ec6SMatthias Ringwald le_device_db_info(i, &address_type, address, irk); 1455adf5eaa9SMatthias Ringwald // skip unused entries 1456c7e2c1a5SMatthias Ringwald if (address_type == BD_ADDR_TYPE_UNKNOWN) continue; 145711d10bdaSMatthias Ringwald // compare Identity Address 145811d10bdaSMatthias Ringwald if (memcmp(address, setup->sm_peer_address, 6) != 0) continue; 145911d10bdaSMatthias Ringwald // compare Identity Resolving Key 1460c7e2c1a5SMatthias Ringwald if (memcmp(irk, setup->sm_peer_irk, 16) != 0) continue; 1461c7e2c1a5SMatthias Ringwald 14623deb3ec6SMatthias Ringwald log_info("sm: device found for IRK, updating"); 14633deb3ec6SMatthias Ringwald le_db_index = i; 14643deb3ec6SMatthias Ringwald break; 14653deb3ec6SMatthias Ringwald } 1466c7e2c1a5SMatthias Ringwald } else { 1467c7e2c1a5SMatthias Ringwald // assert IRK is set to zero 1468c7e2c1a5SMatthias Ringwald memset(setup->sm_peer_irk, 0, 16); 14693deb3ec6SMatthias Ringwald } 14703deb3ec6SMatthias Ringwald 14713deb3ec6SMatthias Ringwald // if not found, lookup via public address if possible 14723deb3ec6SMatthias Ringwald log_info("sm peer addr type %u, peer addres %s", setup->sm_peer_addr_type, bd_addr_to_str(setup->sm_peer_address)); 1473c1ab6cc1SMatthias Ringwald if ((le_db_index < 0) && (setup->sm_peer_addr_type == BD_ADDR_TYPE_LE_PUBLIC)){ 14743deb3ec6SMatthias Ringwald int i; 1475092ec58eSMatthias Ringwald for (i=0; i < le_device_db_max_count(); i++){ 14763deb3ec6SMatthias Ringwald bd_addr_t address; 1477adf5eaa9SMatthias Ringwald int address_type = BD_ADDR_TYPE_UNKNOWN; 14783deb3ec6SMatthias Ringwald le_device_db_info(i, &address_type, address, NULL); 1479adf5eaa9SMatthias Ringwald // skip unused entries 1480adf5eaa9SMatthias Ringwald if (address_type == BD_ADDR_TYPE_UNKNOWN) continue; 14813deb3ec6SMatthias Ringwald log_info("device %u, sm peer addr type %u, peer addres %s", i, address_type, bd_addr_to_str(address)); 14825df9dc78SMatthias Ringwald if ((address_type == BD_ADDR_TYPE_LE_PUBLIC) && (memcmp(address, setup->sm_peer_address, 6) == 0)){ 14833deb3ec6SMatthias Ringwald log_info("sm: device found for public address, updating"); 14843deb3ec6SMatthias Ringwald le_db_index = i; 14853deb3ec6SMatthias Ringwald break; 14863deb3ec6SMatthias Ringwald } 14873deb3ec6SMatthias Ringwald } 14883deb3ec6SMatthias Ringwald } 14893deb3ec6SMatthias Ringwald 14903deb3ec6SMatthias Ringwald // if not found, add to db 149102b02cffSMatthias Ringwald bool new_to_le_device_db = false; 14923deb3ec6SMatthias Ringwald if (le_db_index < 0) { 14933deb3ec6SMatthias Ringwald le_db_index = le_device_db_add(setup->sm_peer_addr_type, setup->sm_peer_address, setup->sm_peer_irk); 149402b02cffSMatthias Ringwald new_to_le_device_db = true; 14953deb3ec6SMatthias Ringwald } 14963deb3ec6SMatthias Ringwald 14973deb3ec6SMatthias Ringwald if (le_db_index >= 0){ 14983deb3ec6SMatthias Ringwald 149902b02cffSMatthias Ringwald #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION 150002b02cffSMatthias Ringwald if (!new_to_le_device_db){ 150102b02cffSMatthias Ringwald hci_remove_le_device_db_entry_from_resolving_list(le_db_index); 150202b02cffSMatthias Ringwald } 150302b02cffSMatthias Ringwald hci_load_le_device_db_entry_into_resolving_list(le_db_index); 150402b02cffSMatthias Ringwald #else 150502b02cffSMatthias Ringwald UNUSED(new_to_le_device_db); 150602b02cffSMatthias Ringwald #endif 150702b02cffSMatthias Ringwald 150848163929SMatthias Ringwald sm_notify_client_index(SM_EVENT_IDENTITY_CREATED, sm_conn->sm_handle, setup->sm_peer_addr_type, setup->sm_peer_address, le_db_index); 1509e1086030SMatthias Ringwald sm_conn->sm_irk_lookup_state = IRK_LOOKUP_SUCCEEDED; 15107710ebd2SMatthias Ringwald sm_conn->sm_le_db_index = le_db_index; 151148163929SMatthias Ringwald 1512eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 15133deb3ec6SMatthias Ringwald // store local CSRK 1514715a43d1SMatthias Ringwald setup->sm_le_device_index = le_db_index; 1515715a43d1SMatthias Ringwald if ((setup->sm_key_distribution_sent_set) & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION){ 15163deb3ec6SMatthias Ringwald log_info("sm: store local CSRK"); 15173deb3ec6SMatthias Ringwald le_device_db_local_csrk_set(le_db_index, setup->sm_local_csrk); 15183deb3ec6SMatthias Ringwald le_device_db_local_counter_set(le_db_index, 0); 15193deb3ec6SMatthias Ringwald } 15203deb3ec6SMatthias Ringwald 15213deb3ec6SMatthias Ringwald // store remote CSRK 15223deb3ec6SMatthias Ringwald if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION){ 15233deb3ec6SMatthias Ringwald log_info("sm: store remote CSRK"); 15243deb3ec6SMatthias Ringwald le_device_db_remote_csrk_set(le_db_index, setup->sm_peer_csrk); 15253deb3ec6SMatthias Ringwald le_device_db_remote_counter_set(le_db_index, 0); 15263deb3ec6SMatthias Ringwald } 1527eda85fbfSMatthias Ringwald #endif 152878f44163SMatthias Ringwald // store encryption information for secure connections: LTK generated by ECDH 152978f44163SMatthias Ringwald if (setup->sm_use_secure_connections){ 1530e6343eb6SMatthias Ringwald log_info("sm: store SC LTK (key size %u, authenticated %u)", sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated); 153178f44163SMatthias Ringwald uint8_t zero_rand[8]; 153278f44163SMatthias Ringwald memset(zero_rand, 0, 8); 153378f44163SMatthias Ringwald le_device_db_encryption_set(le_db_index, 0, zero_rand, setup->sm_ltk, sm_conn->sm_actual_encryption_key_size, 15343dc3a67dSMatthias Ringwald sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED, 1); 153578f44163SMatthias Ringwald } 153678f44163SMatthias Ringwald 1537e6343eb6SMatthias Ringwald // store encryption information for legacy pairing: peer LTK, EDIV, RAND 153878f44163SMatthias Ringwald else if ( (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION) 153978f44163SMatthias Ringwald && (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_MASTER_IDENTIFICATION )){ 1540e6343eb6SMatthias Ringwald log_info("sm: set encryption information (key size %u, authenticated %u)", sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated); 15413deb3ec6SMatthias Ringwald le_device_db_encryption_set(le_db_index, setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk, 15423dc3a67dSMatthias Ringwald sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED, 0); 154378f44163SMatthias Ringwald 15443deb3ec6SMatthias Ringwald } 15453deb3ec6SMatthias Ringwald } 154655f09f49SMatthias Ringwald } 154755f09f49SMatthias Ringwald 15488980298aSMatthias Ringwald static void sm_pairing_error(sm_connection_t * sm_conn, uint8_t reason){ 15498980298aSMatthias Ringwald sm_conn->sm_pairing_failed_reason = reason; 15508980298aSMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_SEND_PAIRING_FAILED; 15518980298aSMatthias Ringwald } 15528980298aSMatthias Ringwald 155322cb578bSMatthias Ringwald static int sm_le_device_db_index_lookup(bd_addr_type_t address_type, bd_addr_t address){ 15541a55487aSMatthias Ringwald int i; 15551a55487aSMatthias Ringwald for (i=0; i < le_device_db_max_count(); i++){ 155622cb578bSMatthias Ringwald bd_addr_t db_address; 155722cb578bSMatthias Ringwald int db_address_type = BD_ADDR_TYPE_UNKNOWN; 155822cb578bSMatthias Ringwald le_device_db_info(i, &db_address_type, db_address, NULL); 15591a55487aSMatthias Ringwald // skip unused entries 15601a55487aSMatthias Ringwald if (address_type == BD_ADDR_TYPE_UNKNOWN) continue; 15613548b7cbSDirk Helbig if ((address_type == (unsigned int)db_address_type) && (memcmp(address, db_address, 6) == 0)){ 15621a55487aSMatthias Ringwald return i; 15631a55487aSMatthias Ringwald } 15641a55487aSMatthias Ringwald } 15651a55487aSMatthias Ringwald return -1; 15661a55487aSMatthias Ringwald } 15671a55487aSMatthias Ringwald 15682e08b70bSMatthias Ringwald static void sm_remove_le_device_db_entry(uint16_t i) { 15692e08b70bSMatthias Ringwald le_device_db_remove(i); 1570672dc582SMatthias Ringwald #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION 1571672dc582SMatthias Ringwald // to remove an entry from the resolving list requires its identity address, which was already deleted 1572672dc582SMatthias Ringwald // fully reload resolving list instead 1573672dc582SMatthias Ringwald gap_load_resolving_list_from_le_device_db(); 1574672dc582SMatthias Ringwald #endif 15752e08b70bSMatthias Ringwald } 15762e08b70bSMatthias Ringwald 15778980298aSMatthias Ringwald static uint8_t sm_key_distribution_validate_received(sm_connection_t * sm_conn){ 15781a55487aSMatthias Ringwald // if identity is provided, abort if we have bonding with same address but different irk 1579f688bdb8SMatthias Ringwald if ((setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION) != 0u){ 158022cb578bSMatthias Ringwald int index = sm_le_device_db_index_lookup(BD_ADDR_TYPE_LE_PUBLIC, setup->sm_peer_address); 15811a55487aSMatthias Ringwald if (index >= 0){ 15821a55487aSMatthias Ringwald sm_key_t irk; 15831a55487aSMatthias Ringwald le_device_db_info(index, NULL, NULL, irk); 15841a55487aSMatthias Ringwald if (memcmp(irk, setup->sm_peer_irk, 16) != 0){ 15851a55487aSMatthias Ringwald // IRK doesn't match, delete bonding information 15861a55487aSMatthias Ringwald log_info("New IRK for %s (type %u) does not match stored IRK -> delete bonding information", bd_addr_to_str(sm_conn->sm_peer_address), sm_conn->sm_peer_addr_type); 15879202d845SMatthias Ringwald sm_remove_le_device_db_entry(index); 15881a55487aSMatthias Ringwald } 15891a55487aSMatthias Ringwald } 15901a55487aSMatthias Ringwald } 15918980298aSMatthias Ringwald return 0; 15928980298aSMatthias Ringwald } 15938980298aSMatthias Ringwald 159455f09f49SMatthias Ringwald static void sm_key_distribution_handle_all_received(sm_connection_t * sm_conn){ 159555f09f49SMatthias Ringwald 15968980298aSMatthias Ringwald // abort pairing if received keys are not valid 15978980298aSMatthias Ringwald uint8_t reason = sm_key_distribution_validate_received(sm_conn); 15988980298aSMatthias Ringwald if (reason != 0){ 15998980298aSMatthias Ringwald sm_pairing_error(sm_conn, reason); 16008980298aSMatthias Ringwald return; 16018980298aSMatthias Ringwald } 16028980298aSMatthias Ringwald 160355f09f49SMatthias Ringwald // only store pairing information if both sides are bondable, i.e., the bonadble flag is set 160455f09f49SMatthias Ringwald bool bonding_enabled = (sm_pairing_packet_get_auth_req(setup->sm_m_preq) 160555f09f49SMatthias Ringwald & sm_pairing_packet_get_auth_req(setup->sm_s_pres) 160655f09f49SMatthias Ringwald & SM_AUTHREQ_BONDING ) != 0u; 160755f09f49SMatthias Ringwald 160855f09f49SMatthias Ringwald if (bonding_enabled){ 160955f09f49SMatthias Ringwald sm_store_bonding_information(sm_conn); 161027ef8bc8SMatthias Ringwald } else { 161127ef8bc8SMatthias Ringwald log_info("Ignoring received keys, bonding not enabled"); 161227ef8bc8SMatthias Ringwald } 16133deb3ec6SMatthias Ringwald } 16143deb3ec6SMatthias Ringwald 1615688a08f9SMatthias Ringwald static inline void sm_pdu_received_in_wrong_state(sm_connection_t * sm_conn){ 1616688a08f9SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_UNSPECIFIED_REASON); 1617688a08f9SMatthias Ringwald } 1618688a08f9SMatthias Ringwald 16199af0f475SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 1620688a08f9SMatthias Ringwald 1621dc300847SMatthias Ringwald static void sm_sc_prepare_dhkey_check(sm_connection_t * sm_conn); 16221d80f1e6SMatthias Ringwald static bool sm_passkey_used(stk_generation_method_t method); 16231d80f1e6SMatthias Ringwald static bool sm_just_works_or_numeric_comparison(stk_generation_method_t method); 1624dc300847SMatthias Ringwald 1625b35a3de2SMatthias Ringwald static void sm_sc_start_calculating_local_confirm(sm_connection_t * sm_conn){ 1626b90c4e75SMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 16271f9d84e9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CONFIRMATION; 1628b90c4e75SMatthias Ringwald } else { 1629b90c4e75SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_nonce, 16, &sm_handle_random_result_sc_next_w2_cmac_for_confirmation, (void *)(uintptr_t) sm_conn->sm_handle); 1630b35a3de2SMatthias Ringwald } 1631b35a3de2SMatthias Ringwald } 1632b35a3de2SMatthias Ringwald 1633688a08f9SMatthias Ringwald static void sm_sc_state_after_receiving_random(sm_connection_t * sm_conn){ 163442134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1635688a08f9SMatthias Ringwald // Responder 16364acf7b7bSMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 16374acf7b7bSMatthias Ringwald // generate Nb 16384acf7b7bSMatthias Ringwald log_info("Generate Nb"); 16396ca80073SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_nonce, 16, &sm_handle_random_result_sc_next_send_pairing_random, (void *)(uintptr_t) sm_conn->sm_handle); 16404acf7b7bSMatthias Ringwald } else { 1641688a08f9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM; 16424acf7b7bSMatthias Ringwald } 1643688a08f9SMatthias Ringwald } else { 1644688a08f9SMatthias Ringwald // Initiator role 1645688a08f9SMatthias Ringwald switch (setup->sm_stk_generation_method){ 1646688a08f9SMatthias Ringwald case JUST_WORKS: 1647dc300847SMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 1648688a08f9SMatthias Ringwald break; 1649688a08f9SMatthias Ringwald 165047fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 1651bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_G2; 1652688a08f9SMatthias Ringwald break; 1653688a08f9SMatthias Ringwald case PK_INIT_INPUT: 1654688a08f9SMatthias Ringwald case PK_RESP_INPUT: 165547fb4255SMatthias Ringwald case PK_BOTH_INPUT: 16564ea43905SMatthias Ringwald if (setup->sm_passkey_bit < 20u) { 1657b35a3de2SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 1658688a08f9SMatthias Ringwald } else { 1659dc300847SMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 1660688a08f9SMatthias Ringwald } 1661688a08f9SMatthias Ringwald break; 1662688a08f9SMatthias Ringwald case OOB: 166365a9a04eSMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 1664688a08f9SMatthias Ringwald break; 16657bbeb3adSMilanka Ringwald default: 16667bbeb3adSMilanka Ringwald btstack_assert(false); 16677bbeb3adSMilanka Ringwald break; 1668688a08f9SMatthias Ringwald } 1669688a08f9SMatthias Ringwald } 1670688a08f9SMatthias Ringwald } 1671688a08f9SMatthias Ringwald 1672aec94140SMatthias Ringwald static void sm_sc_cmac_done(uint8_t * hash){ 1673688a08f9SMatthias Ringwald log_info("sm_sc_cmac_done: "); 1674688a08f9SMatthias Ringwald log_info_hexdump(hash, 16); 1675688a08f9SMatthias Ringwald 1676c59d0c92SMatthias Ringwald if (sm_sc_oob_state == SM_SC_OOB_W4_CONFIRM){ 1677c59d0c92SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_IDLE; 1678a680ba6bSMatthias Ringwald (*sm_sc_oob_callback)(hash, sm_sc_oob_random); 1679c59d0c92SMatthias Ringwald return; 1680c59d0c92SMatthias Ringwald } 1681c59d0c92SMatthias Ringwald 1682bd57ffebSMatthias Ringwald sm_connection_t * sm_conn = sm_cmac_connection; 1683bd57ffebSMatthias Ringwald sm_cmac_connection = NULL; 16846857ad8fSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 16852bacf595SMatthias Ringwald link_key_type_t link_key_type; 1686b4f65634SMatthias Ringwald #endif 1687bd57ffebSMatthias Ringwald 1688bd57ffebSMatthias Ringwald switch (sm_conn->sm_engine_state){ 1689aec94140SMatthias Ringwald case SM_SC_W4_CMAC_FOR_CONFIRMATION: 16906535961aSMatthias Ringwald (void)memcpy(setup->sm_local_confirm, hash, 16); 1691bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_CONFIRMATION; 1692aec94140SMatthias Ringwald break; 1693688a08f9SMatthias Ringwald case SM_SC_W4_CMAC_FOR_CHECK_CONFIRMATION: 1694688a08f9SMatthias Ringwald // check 1695688a08f9SMatthias Ringwald if (0 != memcmp(hash, setup->sm_peer_confirm, 16)){ 1696bd57ffebSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_CONFIRM_VALUE_FAILED); 1697688a08f9SMatthias Ringwald break; 1698688a08f9SMatthias Ringwald } 1699bd57ffebSMatthias Ringwald sm_sc_state_after_receiving_random(sm_conn); 1700688a08f9SMatthias Ringwald break; 1701901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_G2: { 1702901c000fSMatthias Ringwald uint32_t vab = big_endian_read_32(hash, 12) % 1000000; 1703901c000fSMatthias Ringwald big_endian_store_32(setup->sm_tk, 12, vab); 1704901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_USER_RESPONSE; 1705901c000fSMatthias Ringwald sm_trigger_user_response(sm_conn); 1706019005a0SMatthias Ringwald break; 1707019005a0SMatthias Ringwald } 17080346c37cSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_SALT: 17096535961aSMatthias Ringwald (void)memcpy(setup->sm_t, hash, 16); 1710bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_MACKEY; 17110346c37cSMatthias Ringwald break; 17120346c37cSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_MACKEY: 17136535961aSMatthias Ringwald (void)memcpy(setup->sm_mackey, hash, 16); 1714bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_LTK; 17150346c37cSMatthias Ringwald break; 17160346c37cSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_LTK: 1717b18300a6SMatthias Ringwald // truncate sm_ltk, but keep full LTK for cross-transport key derivation in sm_local_ltk 1718b18300a6SMatthias Ringwald // Errata Service Release to the Bluetooth Specification: ESR09 1719b18300a6SMatthias Ringwald // E6405 – Cross transport key derivation from a key of size less than 128 bits 1720b18300a6SMatthias Ringwald // Note: When the BR/EDR link key is being derived from the LTK, the derivation is done before the LTK gets masked." 17216535961aSMatthias Ringwald (void)memcpy(setup->sm_ltk, hash, 16); 17226535961aSMatthias Ringwald (void)memcpy(setup->sm_local_ltk, hash, 16); 1723893e9333SMatthias Ringwald sm_truncate_key(setup->sm_ltk, sm_conn->sm_actual_encryption_key_size); 1724bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F6_FOR_DHKEY_CHECK; 1725019005a0SMatthias Ringwald break; 1726901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F6_FOR_DHKEY_CHECK: 17276535961aSMatthias Ringwald (void)memcpy(setup->sm_local_dhkey_check, hash, 16); 172842134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1729901c000fSMatthias Ringwald // responder 1730f688bdb8SMatthias Ringwald if ((setup->sm_state_vars & SM_STATE_VAR_DHKEY_COMMAND_RECEIVED) != 0u){ 1731901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK; 1732901c000fSMatthias Ringwald } else { 1733901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_DHKEY_CHECK_COMMAND; 1734901c000fSMatthias Ringwald } 1735901c000fSMatthias Ringwald } else { 1736901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_DHKEY_CHECK_COMMAND; 1737901c000fSMatthias Ringwald } 1738901c000fSMatthias Ringwald break; 1739901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK: 1740901c000fSMatthias Ringwald if (0 != memcmp(hash, setup->sm_peer_dhkey_check, 16) ){ 1741901c000fSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 1742aec94140SMatthias Ringwald break; 1743aec94140SMatthias Ringwald } 174442134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1745901c000fSMatthias Ringwald // responder 1746901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_DHKEY_CHECK_COMMAND; 1747901c000fSMatthias Ringwald } else { 1748901c000fSMatthias Ringwald // initiator 1749901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH3_SEND_START_ENCRYPTION; 1750bd57ffebSMatthias Ringwald } 1751901c000fSMatthias Ringwald break; 17526857ad8fSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 175357132f12SMatthias Ringwald case SM_SC_W4_CALCULATE_ILK: 17546535961aSMatthias Ringwald (void)memcpy(setup->sm_t, hash, 16); 175557132f12SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_BR_EDR_LINK_KEY; 17562bacf595SMatthias Ringwald break; 175757132f12SMatthias Ringwald case SM_SC_W4_CALCULATE_BR_EDR_LINK_KEY: 17582bacf595SMatthias Ringwald reverse_128(hash, setup->sm_t); 17592bacf595SMatthias Ringwald link_key_type = sm_conn->sm_connection_authenticated ? 17602bacf595SMatthias Ringwald AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256 : UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256; 17618974e43fSMatthias Ringwald log_info("Derived classic link key from LE using h6, type %u", (int) link_key_type); 176255160b1cSMatthias Ringwald gap_store_link_key_for_bd_addr(setup->sm_peer_address, setup->sm_t, link_key_type); 17638974e43fSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 17642bacf595SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 17652bacf595SMatthias Ringwald } else { 17662bacf595SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 17672bacf595SMatthias Ringwald } 17680ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_SUCCESS, 0); 17692bacf595SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 17702bacf595SMatthias Ringwald break; 1771e0a03c85SMatthias Ringwald case SM_BR_EDR_W4_CALCULATE_ILK: 1772e0a03c85SMatthias Ringwald (void)memcpy(setup->sm_t, hash, 16); 1773e0a03c85SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_W2_CALCULATE_LE_LTK; 1774e0a03c85SMatthias Ringwald break; 1775e0a03c85SMatthias Ringwald case SM_BR_EDR_W4_CALCULATE_LE_LTK: 1776e0a03c85SMatthias Ringwald log_info("Derived LE LTK from BR/EDR Link Key"); 1777e0a03c85SMatthias Ringwald log_info_key("Link Key", hash); 1778e0a03c85SMatthias Ringwald (void)memcpy(setup->sm_ltk, hash, 16); 1779e0a03c85SMatthias Ringwald sm_truncate_key(setup->sm_ltk, sm_conn->sm_actual_encryption_key_size); 1780e0a03c85SMatthias Ringwald sm_conn->sm_connection_authenticated = setup->sm_link_key_type == AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256; 1781e0a03c85SMatthias Ringwald sm_store_bonding_information(sm_conn); 1782c18be159SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 1783e0a03c85SMatthias Ringwald break; 1784bdb14b0eSMatthias Ringwald #endif 1785bd57ffebSMatthias Ringwald default: 1786bd57ffebSMatthias Ringwald log_error("sm_sc_cmac_done in state %u", sm_conn->sm_engine_state); 1787bd57ffebSMatthias Ringwald break; 1788bd57ffebSMatthias Ringwald } 178970b44dd4SMatthias Ringwald sm_trigger_run(); 1790aec94140SMatthias Ringwald } 1791aec94140SMatthias Ringwald 1792688a08f9SMatthias Ringwald static void f4_engine(sm_connection_t * sm_conn, const sm_key256_t u, const sm_key256_t v, const sm_key_t x, uint8_t z){ 1793dc300847SMatthias Ringwald const uint16_t message_len = 65; 1794aec94140SMatthias Ringwald sm_cmac_connection = sm_conn; 17956535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, u, 32); 17966535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 32, v, 32); 1797aec94140SMatthias Ringwald sm_cmac_sc_buffer[64] = z; 1798aec94140SMatthias Ringwald log_info("f4 key"); 1799aec94140SMatthias Ringwald log_info_hexdump(x, 16); 1800aec94140SMatthias Ringwald log_info("f4 message"); 1801dc300847SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1802d1a1f6a4SMatthias Ringwald sm_cmac_message_start(x, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 1803aec94140SMatthias Ringwald } 1804aec94140SMatthias Ringwald 18050346c37cSMatthias Ringwald static const uint8_t f5_key_id[] = { 0x62, 0x74, 0x6c, 0x65 }; 18060346c37cSMatthias Ringwald static const uint8_t f5_length[] = { 0x01, 0x00}; 18070346c37cSMatthias Ringwald 18080346c37cSMatthias Ringwald static void f5_calculate_salt(sm_connection_t * sm_conn){ 18098334d3d8SMatthias Ringwald 18108334d3d8SMatthias Ringwald static const sm_key_t f5_salt = { 0x6C ,0x88, 0x83, 0x91, 0xAA, 0xF5, 0xA5, 0x38, 0x60, 0x37, 0x0B, 0xDB, 0x5A, 0x60, 0x83, 0xBE}; 18118334d3d8SMatthias Ringwald 181240c5d850SMatthias Ringwald log_info("f5_calculate_salt"); 18130346c37cSMatthias Ringwald // calculate salt for f5 18140346c37cSMatthias Ringwald const uint16_t message_len = 32; 18150346c37cSMatthias Ringwald sm_cmac_connection = sm_conn; 18166535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, setup->sm_dhkey, message_len); 1817d1a1f6a4SMatthias Ringwald sm_cmac_message_start(f5_salt, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 18180346c37cSMatthias Ringwald } 18190346c37cSMatthias Ringwald 18200346c37cSMatthias Ringwald static inline void f5_mackkey(sm_connection_t * sm_conn, sm_key_t t, const sm_key_t n1, const sm_key_t n2, const sm_key56_t a1, const sm_key56_t a2){ 18210346c37cSMatthias Ringwald const uint16_t message_len = 53; 18220346c37cSMatthias Ringwald sm_cmac_connection = sm_conn; 18230346c37cSMatthias Ringwald 18240346c37cSMatthias Ringwald // f5(W, N1, N2, A1, A2) = AES-CMACT (Counter = 0 || keyID || N1 || N2|| A1|| A2 || Length = 256) -- this is the MacKey 18250346c37cSMatthias Ringwald sm_cmac_sc_buffer[0] = 0; 18266535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 01, f5_key_id, 4); 18276535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 05, n1, 16); 18286535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 21, n2, 16); 18296535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 37, a1, 7); 18306535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 44, a2, 7); 18316535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 51, f5_length, 2); 18320346c37cSMatthias Ringwald log_info("f5 key"); 18330346c37cSMatthias Ringwald log_info_hexdump(t, 16); 18340346c37cSMatthias Ringwald log_info("f5 message for MacKey"); 18350346c37cSMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1836d1a1f6a4SMatthias Ringwald sm_cmac_message_start(t, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 18370346c37cSMatthias Ringwald } 18380346c37cSMatthias Ringwald 18390346c37cSMatthias Ringwald static void f5_calculate_mackey(sm_connection_t * sm_conn){ 18400346c37cSMatthias Ringwald sm_key56_t bd_addr_master, bd_addr_slave; 18410346c37cSMatthias Ringwald bd_addr_master[0] = setup->sm_m_addr_type; 18420346c37cSMatthias Ringwald bd_addr_slave[0] = setup->sm_s_addr_type; 18436535961aSMatthias Ringwald (void)memcpy(&bd_addr_master[1], setup->sm_m_address, 6); 18446535961aSMatthias Ringwald (void)memcpy(&bd_addr_slave[1], setup->sm_s_address, 6); 184542134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 18460346c37cSMatthias Ringwald // responder 18470346c37cSMatthias Ringwald f5_mackkey(sm_conn, setup->sm_t, setup->sm_peer_nonce, setup->sm_local_nonce, bd_addr_master, bd_addr_slave); 18480346c37cSMatthias Ringwald } else { 18490346c37cSMatthias Ringwald // initiator 18500346c37cSMatthias Ringwald f5_mackkey(sm_conn, setup->sm_t, setup->sm_local_nonce, setup->sm_peer_nonce, bd_addr_master, bd_addr_slave); 18510346c37cSMatthias Ringwald } 18520346c37cSMatthias Ringwald } 18530346c37cSMatthias Ringwald 18540346c37cSMatthias Ringwald // note: must be called right after f5_mackey, as sm_cmac_buffer[1..52] will be reused 18550346c37cSMatthias Ringwald static inline void f5_ltk(sm_connection_t * sm_conn, sm_key_t t){ 18560346c37cSMatthias Ringwald const uint16_t message_len = 53; 18570346c37cSMatthias Ringwald sm_cmac_connection = sm_conn; 18580346c37cSMatthias Ringwald sm_cmac_sc_buffer[0] = 1; 18590346c37cSMatthias Ringwald // 1..52 setup before 18600346c37cSMatthias Ringwald log_info("f5 key"); 18610346c37cSMatthias Ringwald log_info_hexdump(t, 16); 18620346c37cSMatthias Ringwald log_info("f5 message for LTK"); 18630346c37cSMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1864d1a1f6a4SMatthias Ringwald sm_cmac_message_start(t, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 18650346c37cSMatthias Ringwald } 1866f92edc8eSMatthias Ringwald 18670346c37cSMatthias Ringwald static void f5_calculate_ltk(sm_connection_t * sm_conn){ 18680346c37cSMatthias Ringwald f5_ltk(sm_conn, setup->sm_t); 18690346c37cSMatthias Ringwald } 18700346c37cSMatthias Ringwald 187131f061fbSMatthias Ringwald static void f6_setup(const sm_key_t n1, const sm_key_t n2, const sm_key_t r, const sm_key24_t io_cap, const sm_key56_t a1, const sm_key56_t a2){ 18726535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, n1, 16); 18736535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 16, n2, 16); 18746535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 32, r, 16); 18756535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 48, io_cap, 3); 18766535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 51, a1, 7); 18776535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 58, a2, 7); 187831f061fbSMatthias Ringwald } 187931f061fbSMatthias Ringwald 188031f061fbSMatthias Ringwald static void f6_engine(sm_connection_t * sm_conn, const sm_key_t w){ 188131f061fbSMatthias Ringwald const uint16_t message_len = 65; 188231f061fbSMatthias Ringwald sm_cmac_connection = sm_conn; 1883dc300847SMatthias Ringwald log_info("f6 key"); 1884dc300847SMatthias Ringwald log_info_hexdump(w, 16); 1885dc300847SMatthias Ringwald log_info("f6 message"); 1886dc300847SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1887d1a1f6a4SMatthias Ringwald sm_cmac_message_start(w, 65, sm_cmac_sc_buffer, &sm_sc_cmac_done); 1888dc300847SMatthias Ringwald } 1889dc300847SMatthias Ringwald 1890f92edc8eSMatthias Ringwald // g2(U, V, X, Y) = AES-CMACX(U || V || Y) mod 2^32 1891f92edc8eSMatthias Ringwald // - U is 256 bits 1892f92edc8eSMatthias Ringwald // - V is 256 bits 1893f92edc8eSMatthias Ringwald // - X is 128 bits 1894f92edc8eSMatthias Ringwald // - Y is 128 bits 1895bd57ffebSMatthias Ringwald static void g2_engine(sm_connection_t * sm_conn, const sm_key256_t u, const sm_key256_t v, const sm_key_t x, const sm_key_t y){ 1896bd57ffebSMatthias Ringwald const uint16_t message_len = 80; 1897bd57ffebSMatthias Ringwald sm_cmac_connection = sm_conn; 18986535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, u, 32); 18996535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 32, v, 32); 19006535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 64, y, 16); 1901f92edc8eSMatthias Ringwald log_info("g2 key"); 1902f92edc8eSMatthias Ringwald log_info_hexdump(x, 16); 1903f92edc8eSMatthias Ringwald log_info("g2 message"); 19042bacf595SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1905d1a1f6a4SMatthias Ringwald sm_cmac_message_start(x, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 1906f92edc8eSMatthias Ringwald } 1907f92edc8eSMatthias Ringwald 1908b35a3de2SMatthias Ringwald static void g2_calculate(sm_connection_t * sm_conn) { 1909f92edc8eSMatthias Ringwald // calc Va if numeric comparison 191042134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1911f92edc8eSMatthias Ringwald // responder 1912fc5bff5fSMatthias Ringwald g2_engine(sm_conn, setup->sm_peer_q, ec_q, setup->sm_peer_nonce, setup->sm_local_nonce);; 1913f92edc8eSMatthias Ringwald } else { 1914f92edc8eSMatthias Ringwald // initiator 1915fc5bff5fSMatthias Ringwald g2_engine(sm_conn, ec_q, setup->sm_peer_q, setup->sm_local_nonce, setup->sm_peer_nonce); 1916f92edc8eSMatthias Ringwald } 1917f92edc8eSMatthias Ringwald } 1918f92edc8eSMatthias Ringwald 1919945888f5SMatthias Ringwald static void sm_sc_calculate_local_confirm(sm_connection_t * sm_conn){ 19209af0f475SMatthias Ringwald uint8_t z = 0; 192140c5d850SMatthias Ringwald if (sm_passkey_entry(setup->sm_stk_generation_method)){ 19229af0f475SMatthias Ringwald // some form of passkey 19239af0f475SMatthias Ringwald uint32_t pk = big_endian_read_32(setup->sm_tk, 12); 19244ea43905SMatthias Ringwald z = 0x80u | ((pk >> setup->sm_passkey_bit) & 1u); 19259af0f475SMatthias Ringwald setup->sm_passkey_bit++; 19269af0f475SMatthias Ringwald } 1927fc5bff5fSMatthias Ringwald f4_engine(sm_conn, ec_q, setup->sm_peer_q, setup->sm_local_nonce, z); 19289af0f475SMatthias Ringwald } 1929688a08f9SMatthias Ringwald 1930688a08f9SMatthias Ringwald static void sm_sc_calculate_remote_confirm(sm_connection_t * sm_conn){ 1931a680ba6bSMatthias Ringwald // OOB 1932a680ba6bSMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 19334acf7b7bSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 19344acf7b7bSMatthias Ringwald f4_engine(sm_conn, setup->sm_peer_q, setup->sm_peer_q, setup->sm_ra, 0); 19354acf7b7bSMatthias Ringwald } else { 19364acf7b7bSMatthias Ringwald f4_engine(sm_conn, setup->sm_peer_q, setup->sm_peer_q, setup->sm_rb, 0); 19374acf7b7bSMatthias Ringwald } 1938a680ba6bSMatthias Ringwald return; 1939a680ba6bSMatthias Ringwald } 1940a680ba6bSMatthias Ringwald 1941688a08f9SMatthias Ringwald uint8_t z = 0; 194240c5d850SMatthias Ringwald if (sm_passkey_entry(setup->sm_stk_generation_method)){ 1943688a08f9SMatthias Ringwald // some form of passkey 1944688a08f9SMatthias Ringwald uint32_t pk = big_endian_read_32(setup->sm_tk, 12); 1945688a08f9SMatthias Ringwald // sm_passkey_bit was increased before sending confirm value 19464ea43905SMatthias Ringwald z = 0x80u | ((pk >> (setup->sm_passkey_bit-1u)) & 1u); 1947688a08f9SMatthias Ringwald } 1948fc5bff5fSMatthias Ringwald f4_engine(sm_conn, setup->sm_peer_q, ec_q, setup->sm_peer_nonce, z); 1949688a08f9SMatthias Ringwald } 1950688a08f9SMatthias Ringwald 19510346c37cSMatthias Ringwald static void sm_sc_prepare_dhkey_check(sm_connection_t * sm_conn){ 1952f688bdb8SMatthias Ringwald log_info("sm_sc_prepare_dhkey_check, DHKEY calculated %u", (setup->sm_state_vars & SM_STATE_VAR_DHKEY_CALCULATED) != 0 ? 1 : 0); 19533cf37b8cSMatthias Ringwald 1954f688bdb8SMatthias Ringwald if ((setup->sm_state_vars & SM_STATE_VAR_DHKEY_CALCULATED) != 0u){ 19553cf37b8cSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_SALT; 19563cf37b8cSMatthias Ringwald } else { 19573cf37b8cSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_CALCULATE_DHKEY; 19583cf37b8cSMatthias Ringwald } 1959d1a1f6a4SMatthias Ringwald } 19603cf37b8cSMatthias Ringwald 1961d1a1f6a4SMatthias Ringwald static void sm_sc_dhkey_calculated(void * arg){ 1962f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 1963f3582630SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 1964f3582630SMatthias Ringwald if (sm_conn == NULL) return; 1965f3582630SMatthias Ringwald 19661c34405fSMatthias Ringwald // check for invalid public key detected by Controller 19671c34405fSMatthias Ringwald if (sm_is_ff(setup->sm_dhkey, 32)){ 19681c34405fSMatthias Ringwald log_info("sm: peer public key invalid"); 19691c34405fSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 19701c34405fSMatthias Ringwald return; 19711c34405fSMatthias Ringwald } 19721c34405fSMatthias Ringwald 1973d1a1f6a4SMatthias Ringwald log_info("dhkey"); 1974d1a1f6a4SMatthias Ringwald log_info_hexdump(&setup->sm_dhkey[0], 32); 1975d1a1f6a4SMatthias Ringwald setup->sm_state_vars |= SM_STATE_VAR_DHKEY_CALCULATED; 1976d1a1f6a4SMatthias Ringwald // trigger next step 1977d1a1f6a4SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_CALCULATE_DHKEY){ 1978d1a1f6a4SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_SALT; 1979d1a1f6a4SMatthias Ringwald } 198070b44dd4SMatthias Ringwald sm_trigger_run(); 1981dc300847SMatthias Ringwald } 1982dc300847SMatthias Ringwald 1983dc300847SMatthias Ringwald static void sm_sc_calculate_f6_for_dhkey_check(sm_connection_t * sm_conn){ 1984dc300847SMatthias Ringwald // calculate DHKCheck 1985dc300847SMatthias Ringwald sm_key56_t bd_addr_master, bd_addr_slave; 1986dc300847SMatthias Ringwald bd_addr_master[0] = setup->sm_m_addr_type; 1987dc300847SMatthias Ringwald bd_addr_slave[0] = setup->sm_s_addr_type; 19886535961aSMatthias Ringwald (void)memcpy(&bd_addr_master[1], setup->sm_m_address, 6); 19896535961aSMatthias Ringwald (void)memcpy(&bd_addr_slave[1], setup->sm_s_address, 6); 1990dc300847SMatthias Ringwald uint8_t iocap_a[3]; 1991dc300847SMatthias Ringwald iocap_a[0] = sm_pairing_packet_get_auth_req(setup->sm_m_preq); 1992dc300847SMatthias Ringwald iocap_a[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq); 1993dc300847SMatthias Ringwald iocap_a[2] = sm_pairing_packet_get_io_capability(setup->sm_m_preq); 1994dc300847SMatthias Ringwald uint8_t iocap_b[3]; 1995dc300847SMatthias Ringwald iocap_b[0] = sm_pairing_packet_get_auth_req(setup->sm_s_pres); 1996dc300847SMatthias Ringwald iocap_b[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres); 1997dc300847SMatthias Ringwald iocap_b[2] = sm_pairing_packet_get_io_capability(setup->sm_s_pres); 199842134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1999dc300847SMatthias Ringwald // responder 200031f061fbSMatthias Ringwald f6_setup(setup->sm_local_nonce, setup->sm_peer_nonce, setup->sm_ra, iocap_b, bd_addr_slave, bd_addr_master); 200131f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2002dc300847SMatthias Ringwald } else { 2003dc300847SMatthias Ringwald // initiator 200431f061fbSMatthias Ringwald f6_setup( setup->sm_local_nonce, setup->sm_peer_nonce, setup->sm_rb, iocap_a, bd_addr_master, bd_addr_slave); 200531f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2006dc300847SMatthias Ringwald } 2007dc300847SMatthias Ringwald } 2008dc300847SMatthias Ringwald 2009019005a0SMatthias Ringwald static void sm_sc_calculate_f6_to_verify_dhkey_check(sm_connection_t * sm_conn){ 2010019005a0SMatthias Ringwald // validate E = f6() 2011019005a0SMatthias Ringwald sm_key56_t bd_addr_master, bd_addr_slave; 2012019005a0SMatthias Ringwald bd_addr_master[0] = setup->sm_m_addr_type; 2013019005a0SMatthias Ringwald bd_addr_slave[0] = setup->sm_s_addr_type; 20146535961aSMatthias Ringwald (void)memcpy(&bd_addr_master[1], setup->sm_m_address, 6); 20156535961aSMatthias Ringwald (void)memcpy(&bd_addr_slave[1], setup->sm_s_address, 6); 2016019005a0SMatthias Ringwald 2017019005a0SMatthias Ringwald uint8_t iocap_a[3]; 2018019005a0SMatthias Ringwald iocap_a[0] = sm_pairing_packet_get_auth_req(setup->sm_m_preq); 2019019005a0SMatthias Ringwald iocap_a[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq); 2020019005a0SMatthias Ringwald iocap_a[2] = sm_pairing_packet_get_io_capability(setup->sm_m_preq); 2021019005a0SMatthias Ringwald uint8_t iocap_b[3]; 2022019005a0SMatthias Ringwald iocap_b[0] = sm_pairing_packet_get_auth_req(setup->sm_s_pres); 2023019005a0SMatthias Ringwald iocap_b[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres); 2024019005a0SMatthias Ringwald iocap_b[2] = sm_pairing_packet_get_io_capability(setup->sm_s_pres); 202542134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 2026019005a0SMatthias Ringwald // responder 202731f061fbSMatthias Ringwald f6_setup(setup->sm_peer_nonce, setup->sm_local_nonce, setup->sm_rb, iocap_a, bd_addr_master, bd_addr_slave); 202831f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2029019005a0SMatthias Ringwald } else { 2030019005a0SMatthias Ringwald // initiator 203131f061fbSMatthias Ringwald f6_setup(setup->sm_peer_nonce, setup->sm_local_nonce, setup->sm_ra, iocap_b, bd_addr_slave, bd_addr_master); 203231f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2033019005a0SMatthias Ringwald } 2034019005a0SMatthias Ringwald } 20352bacf595SMatthias Ringwald 203655c62cf5SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 20372bacf595SMatthias Ringwald 20382bacf595SMatthias Ringwald // 20392bacf595SMatthias Ringwald // Link Key Conversion Function h6 20402bacf595SMatthias Ringwald // 204157132f12SMatthias Ringwald // h6(W, keyID) = AES-CMAC_W(keyID) 20422bacf595SMatthias Ringwald // - W is 128 bits 20432bacf595SMatthias Ringwald // - keyID is 32 bits 20442bacf595SMatthias Ringwald static void h6_engine(sm_connection_t * sm_conn, const sm_key_t w, const uint32_t key_id){ 20452bacf595SMatthias Ringwald const uint16_t message_len = 4; 20462bacf595SMatthias Ringwald sm_cmac_connection = sm_conn; 20472bacf595SMatthias Ringwald big_endian_store_32(sm_cmac_sc_buffer, 0, key_id); 20482bacf595SMatthias Ringwald log_info("h6 key"); 20492bacf595SMatthias Ringwald log_info_hexdump(w, 16); 20502bacf595SMatthias Ringwald log_info("h6 message"); 20512bacf595SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 2052d1a1f6a4SMatthias Ringwald sm_cmac_message_start(w, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 20532bacf595SMatthias Ringwald } 205457132f12SMatthias Ringwald // 205557132f12SMatthias Ringwald // Link Key Conversion Function h7 205657132f12SMatthias Ringwald // 205757132f12SMatthias Ringwald // h7(SALT, W) = AES-CMAC_SALT(W) 205857132f12SMatthias Ringwald // - SALT is 128 bits 205957132f12SMatthias Ringwald // - W is 128 bits 206057132f12SMatthias Ringwald static void h7_engine(sm_connection_t * sm_conn, const sm_key_t salt, const sm_key_t w) { 206157132f12SMatthias Ringwald const uint16_t message_len = 16; 206257132f12SMatthias Ringwald sm_cmac_connection = sm_conn; 206357132f12SMatthias Ringwald log_info("h7 key"); 206457132f12SMatthias Ringwald log_info_hexdump(salt, 16); 206557132f12SMatthias Ringwald log_info("h7 message"); 206657132f12SMatthias Ringwald log_info_hexdump(w, 16); 206757132f12SMatthias Ringwald sm_cmac_message_start(salt, message_len, w, &sm_sc_cmac_done); 206857132f12SMatthias Ringwald } 20692bacf595SMatthias Ringwald 2070b18300a6SMatthias Ringwald // For SC, setup->sm_local_ltk holds full LTK (sm_ltk is already truncated) 2071b18300a6SMatthias Ringwald // Errata Service Release to the Bluetooth Specification: ESR09 2072b18300a6SMatthias Ringwald // E6405 – Cross transport key derivation from a key of size less than 128 bits 2073b18300a6SMatthias Ringwald // "Note: When the BR/EDR link key is being derived from the LTK, the derivation is done before the LTK gets masked." 207457132f12SMatthias Ringwald 2075c82679c3SMatthias Ringwald static void h6_calculate_ilk_from_le_ltk(sm_connection_t * sm_conn){ 2076b18300a6SMatthias Ringwald h6_engine(sm_conn, setup->sm_local_ltk, 0x746D7031); // "tmp1" 20772bacf595SMatthias Ringwald } 20782bacf595SMatthias Ringwald 2079e0a03c85SMatthias Ringwald static void h6_calculate_ilk_from_br_edr(sm_connection_t * sm_conn){ 2080e0a03c85SMatthias Ringwald h6_engine(sm_conn, setup->sm_link_key, 0x746D7032); // "tmp2" 2081e0a03c85SMatthias Ringwald } 2082e0a03c85SMatthias Ringwald 20832bacf595SMatthias Ringwald static void h6_calculate_br_edr_link_key(sm_connection_t * sm_conn){ 20842bacf595SMatthias Ringwald h6_engine(sm_conn, setup->sm_t, 0x6c656272); // "lebr" 20852bacf595SMatthias Ringwald } 20862bacf595SMatthias Ringwald 2087e0a03c85SMatthias Ringwald static void h6_calculate_le_ltk(sm_connection_t * sm_conn){ 2088e0a03c85SMatthias Ringwald h6_engine(sm_conn, setup->sm_t, 0x62726C65); // "brle" 2089e0a03c85SMatthias Ringwald } 2090e0a03c85SMatthias Ringwald 2091c82679c3SMatthias Ringwald static void h7_calculate_ilk_from_le_ltk(sm_connection_t * sm_conn){ 209257132f12SMatthias Ringwald const uint8_t salt[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x6D, 0x70, 0x31}; // "tmp1" 209357132f12SMatthias Ringwald h7_engine(sm_conn, salt, setup->sm_local_ltk); 209457132f12SMatthias Ringwald } 2095e0a03c85SMatthias Ringwald 2096e0a03c85SMatthias Ringwald static void h7_calculate_ilk_from_br_edr(sm_connection_t * sm_conn){ 2097e0a03c85SMatthias Ringwald const uint8_t salt[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x6D, 0x70, 0x32}; // "tmp2" 2098e0a03c85SMatthias Ringwald h7_engine(sm_conn, salt, setup->sm_link_key); 2099e0a03c85SMatthias Ringwald } 2100e0a03c85SMatthias Ringwald 2101c18be159SMatthias Ringwald static void sm_ctkd_fetch_br_edr_link_key(sm_connection_t * sm_conn){ 2102e0a03c85SMatthias Ringwald hci_connection_t * hci_connection = hci_connection_for_handle(sm_conn->sm_handle); 2103e0a03c85SMatthias Ringwald btstack_assert(hci_connection != NULL); 2104e0a03c85SMatthias Ringwald reverse_128(hci_connection->link_key, setup->sm_link_key); 2105e0a03c85SMatthias Ringwald setup->sm_link_key_type = hci_connection->link_key_type; 2106e0a03c85SMatthias Ringwald } 2107e0a03c85SMatthias Ringwald 210813aed524SMatthias Ringwald static void sm_ctkd_start_from_br_edr(sm_connection_t * sm_conn){ 210913aed524SMatthias Ringwald // only derive LTK if EncKey is set by both 211013aed524SMatthias Ringwald bool derive_ltk = (sm_pairing_packet_get_initiator_key_distribution(setup->sm_s_pres) & 211113aed524SMatthias Ringwald sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres) & SM_KEYDIST_ENC_KEY) != 0; 211213aed524SMatthias Ringwald if (derive_ltk){ 2113c18be159SMatthias Ringwald bool use_h7 = (sm_pairing_packet_get_auth_req(setup->sm_m_preq) & sm_pairing_packet_get_auth_req(setup->sm_s_pres) & SM_AUTHREQ_CT2) != 0; 211413aed524SMatthias Ringwald sm_conn->sm_engine_state = use_h7 ? SM_BR_EDR_W2_CALCULATE_ILK_USING_H7 : SM_BR_EDR_W2_CALCULATE_ILK_USING_H6; 211513aed524SMatthias Ringwald } else { 211613aed524SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 211713aed524SMatthias Ringwald } 2118c18be159SMatthias Ringwald } 2119c18be159SMatthias Ringwald 21209af0f475SMatthias Ringwald #endif 21219af0f475SMatthias Ringwald 212255c62cf5SMatthias Ringwald #endif 212355c62cf5SMatthias Ringwald 2124613da3deSMatthias Ringwald // key management legacy connections: 2125613da3deSMatthias Ringwald // - potentially two different LTKs based on direction. each device stores LTK provided by peer 2126613da3deSMatthias Ringwald // - master stores LTK, EDIV, RAND. responder optionally stored master LTK (only if it needs to reconnect) 2127613da3deSMatthias Ringwald // - initiators reconnects: initiator uses stored LTK, EDIV, RAND generated by responder 2128613da3deSMatthias Ringwald // - responder reconnects: responder uses LTK receveived from master 2129613da3deSMatthias Ringwald 2130613da3deSMatthias Ringwald // key management secure connections: 2131613da3deSMatthias Ringwald // - both devices store same LTK from ECDH key exchange. 2132613da3deSMatthias Ringwald 213342134bc6SMatthias Ringwald #if defined(ENABLE_LE_SECURE_CONNECTIONS) || defined(ENABLE_LE_CENTRAL) 21345829ebe2SMatthias Ringwald static void sm_load_security_info(sm_connection_t * sm_connection){ 21355829ebe2SMatthias Ringwald int encryption_key_size; 21365829ebe2SMatthias Ringwald int authenticated; 21375829ebe2SMatthias Ringwald int authorized; 21383dc3a67dSMatthias Ringwald int secure_connection; 21395829ebe2SMatthias Ringwald 21405829ebe2SMatthias Ringwald // fetch data from device db - incl. authenticated/authorized/key size. Note all sm_connection_X require encryption enabled 21415829ebe2SMatthias Ringwald le_device_db_encryption_get(sm_connection->sm_le_db_index, &setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk, 21423dc3a67dSMatthias Ringwald &encryption_key_size, &authenticated, &authorized, &secure_connection); 21433dc3a67dSMatthias Ringwald log_info("db index %u, key size %u, authenticated %u, authorized %u, secure connetion %u", sm_connection->sm_le_db_index, encryption_key_size, authenticated, authorized, secure_connection); 21445829ebe2SMatthias Ringwald sm_connection->sm_actual_encryption_key_size = encryption_key_size; 21455829ebe2SMatthias Ringwald sm_connection->sm_connection_authenticated = authenticated; 21465829ebe2SMatthias Ringwald sm_connection->sm_connection_authorization_state = authorized ? AUTHORIZATION_GRANTED : AUTHORIZATION_UNKNOWN; 2147d7dbf891SMatthias Ringwald sm_connection->sm_connection_sc = secure_connection != 0; 21485829ebe2SMatthias Ringwald } 214942134bc6SMatthias Ringwald #endif 2150bd57ffebSMatthias Ringwald 215142134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 215259066796SMatthias Ringwald static void sm_start_calculating_ltk_from_ediv_and_rand(sm_connection_t * sm_connection){ 21536535961aSMatthias Ringwald (void)memcpy(setup->sm_local_rand, sm_connection->sm_local_rand, 8); 215459066796SMatthias Ringwald setup->sm_local_ediv = sm_connection->sm_local_ediv; 215559066796SMatthias Ringwald // re-establish used key encryption size 215659066796SMatthias Ringwald // no db for encryption size hack: encryption size is stored in lowest nibble of setup->sm_local_rand 21574ea43905SMatthias Ringwald sm_connection->sm_actual_encryption_key_size = (setup->sm_local_rand[7u] & 0x0fu) + 1u; 215859066796SMatthias Ringwald // no db for authenticated flag hack: flag is stored in bit 4 of LSB 21594ea43905SMatthias Ringwald sm_connection->sm_connection_authenticated = (setup->sm_local_rand[7u] & 0x10u) >> 4u; 21603dc3a67dSMatthias Ringwald // Legacy paring -> not SC 2161d7dbf891SMatthias Ringwald sm_connection->sm_connection_sc = false; 216259066796SMatthias Ringwald log_info("sm: received ltk request with key size %u, authenticated %u", 216359066796SMatthias Ringwald sm_connection->sm_actual_encryption_key_size, sm_connection->sm_connection_authenticated); 216459066796SMatthias Ringwald } 216542134bc6SMatthias Ringwald #endif 216659066796SMatthias Ringwald 21673deb3ec6SMatthias Ringwald // distributed key generation 2168d7f1c72eSMatthias Ringwald static bool sm_run_dpkg(void){ 21693deb3ec6SMatthias Ringwald switch (dkg_state){ 21703deb3ec6SMatthias Ringwald case DKG_CALC_IRK: 21713deb3ec6SMatthias Ringwald // already busy? 21723deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_IDLE) { 2173d1a1f6a4SMatthias Ringwald log_info("DKG_CALC_IRK started"); 21743deb3ec6SMatthias Ringwald // IRK = d1(IR, 1, 0) 2175d1a1f6a4SMatthias Ringwald sm_d1_d_prime(1, 0, sm_aes128_plaintext); // plaintext = d1 prime 2176d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2177d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_ir, sm_aes128_plaintext, sm_persistent_irk, sm_handle_encryption_result_dkg_irk, NULL); 2178d7f1c72eSMatthias Ringwald return true; 21793deb3ec6SMatthias Ringwald } 21803deb3ec6SMatthias Ringwald break; 21813deb3ec6SMatthias Ringwald case DKG_CALC_DHK: 21823deb3ec6SMatthias Ringwald // already busy? 21833deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_IDLE) { 2184d1a1f6a4SMatthias Ringwald log_info("DKG_CALC_DHK started"); 21853deb3ec6SMatthias Ringwald // DHK = d1(IR, 3, 0) 2186d1a1f6a4SMatthias Ringwald sm_d1_d_prime(3, 0, sm_aes128_plaintext); // plaintext = d1 prime 2187d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2188d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_ir, sm_aes128_plaintext, sm_persistent_dhk, sm_handle_encryption_result_dkg_dhk, NULL); 2189d7f1c72eSMatthias Ringwald return true; 21903deb3ec6SMatthias Ringwald } 21913deb3ec6SMatthias Ringwald break; 21923deb3ec6SMatthias Ringwald default: 21933deb3ec6SMatthias Ringwald break; 21943deb3ec6SMatthias Ringwald } 2195d7f1c72eSMatthias Ringwald return false; 2196d7f1c72eSMatthias Ringwald } 21973deb3ec6SMatthias Ringwald 21983deb3ec6SMatthias Ringwald // random address updates 2199d7f1c72eSMatthias Ringwald static bool sm_run_rau(void){ 22003deb3ec6SMatthias Ringwald switch (rau_state){ 2201fbd4e238SMatthias Ringwald case RAU_GET_RANDOM: 2202fbd4e238SMatthias Ringwald rau_state = RAU_W4_RANDOM; 22035b4dd597SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_address, 6, &sm_handle_random_result_rau, NULL); 2204d7f1c72eSMatthias Ringwald return true; 22053deb3ec6SMatthias Ringwald case RAU_GET_ENC: 22063deb3ec6SMatthias Ringwald // already busy? 22073deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_IDLE) { 2208d1a1f6a4SMatthias Ringwald sm_ah_r_prime(sm_random_address, sm_aes128_plaintext); 2209d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2210d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_irk, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_rau, NULL); 2211d7f1c72eSMatthias Ringwald return true; 22123deb3ec6SMatthias Ringwald } 22133deb3ec6SMatthias Ringwald break; 22143deb3ec6SMatthias Ringwald default: 22153deb3ec6SMatthias Ringwald break; 22163deb3ec6SMatthias Ringwald } 2217d7f1c72eSMatthias Ringwald return false; 2218d7f1c72eSMatthias Ringwald } 22193deb3ec6SMatthias Ringwald 22203deb3ec6SMatthias Ringwald // CSRK Lookup 2221d7f1c72eSMatthias Ringwald static bool sm_run_csrk(void){ 2222d7f1c72eSMatthias Ringwald btstack_linked_list_iterator_t it; 2223d7f1c72eSMatthias Ringwald 22243deb3ec6SMatthias Ringwald // -- if csrk lookup ready, find connection that require csrk lookup 22253deb3ec6SMatthias Ringwald if (sm_address_resolution_idle()){ 22263deb3ec6SMatthias Ringwald hci_connections_get_iterator(&it); 2227665d90f2SMatthias Ringwald while(btstack_linked_list_iterator_has_next(&it)){ 2228665d90f2SMatthias Ringwald hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 22293deb3ec6SMatthias Ringwald sm_connection_t * sm_connection = &hci_connection->sm_connection; 22303deb3ec6SMatthias Ringwald if (sm_connection->sm_irk_lookup_state == IRK_LOOKUP_W4_READY){ 22313deb3ec6SMatthias Ringwald // and start lookup 22323deb3ec6SMatthias Ringwald sm_address_resolution_start_lookup(sm_connection->sm_peer_addr_type, sm_connection->sm_handle, sm_connection->sm_peer_address, ADDRESS_RESOLUTION_FOR_CONNECTION, sm_connection); 22333deb3ec6SMatthias Ringwald sm_connection->sm_irk_lookup_state = IRK_LOOKUP_STARTED; 22343deb3ec6SMatthias Ringwald break; 22353deb3ec6SMatthias Ringwald } 22363deb3ec6SMatthias Ringwald } 22373deb3ec6SMatthias Ringwald } 22383deb3ec6SMatthias Ringwald 22393deb3ec6SMatthias Ringwald // -- if csrk lookup ready, resolved addresses for received addresses 22403deb3ec6SMatthias Ringwald if (sm_address_resolution_idle()) { 2241665d90f2SMatthias Ringwald if (!btstack_linked_list_empty(&sm_address_resolution_general_queue)){ 22423deb3ec6SMatthias Ringwald sm_lookup_entry_t * entry = (sm_lookup_entry_t *) sm_address_resolution_general_queue; 2243665d90f2SMatthias Ringwald btstack_linked_list_remove(&sm_address_resolution_general_queue, (btstack_linked_item_t *) entry); 22443deb3ec6SMatthias Ringwald sm_address_resolution_start_lookup(entry->address_type, 0, entry->address, ADDRESS_RESOLUTION_GENERAL, NULL); 22453deb3ec6SMatthias Ringwald btstack_memory_sm_lookup_entry_free(entry); 22463deb3ec6SMatthias Ringwald } 22473deb3ec6SMatthias Ringwald } 22483deb3ec6SMatthias Ringwald 2249ca685291SMatthias Ringwald // -- Continue with device lookup by public or resolvable private address 22503deb3ec6SMatthias Ringwald if (!sm_address_resolution_idle()){ 2251092ec58eSMatthias Ringwald while (sm_address_resolution_test < le_device_db_max_count()){ 2252adf5eaa9SMatthias Ringwald int addr_type = BD_ADDR_TYPE_UNKNOWN; 22533deb3ec6SMatthias Ringwald bd_addr_t addr; 22543deb3ec6SMatthias Ringwald sm_key_t irk; 22553deb3ec6SMatthias Ringwald le_device_db_info(sm_address_resolution_test, &addr_type, addr, irk); 22563deb3ec6SMatthias Ringwald 2257adf5eaa9SMatthias Ringwald // skip unused entries 2258adf5eaa9SMatthias Ringwald if (addr_type == BD_ADDR_TYPE_UNKNOWN){ 2259adf5eaa9SMatthias Ringwald sm_address_resolution_test++; 2260adf5eaa9SMatthias Ringwald continue; 2261adf5eaa9SMatthias Ringwald } 2262adf5eaa9SMatthias Ringwald 2263ca685291SMatthias Ringwald log_info("LE Device Lookup: device %u of %u", sm_address_resolution_test, le_device_db_max_count()); 2264ca685291SMatthias Ringwald 2265515f33beSMatthias Ringwald // map resolved identiry addresses to regular addresses 2266515f33beSMatthias Ringwald int regular_addr_type = sm_address_resolution_addr_type & 1; 2267515f33beSMatthias Ringwald if ((regular_addr_type == addr_type) && (memcmp(addr, sm_address_resolution_address, 6) == 0)){ 2268ca685291SMatthias Ringwald log_info("LE Device Lookup: found by { addr_type, address} "); 2269a66b030fSMatthias Ringwald sm_address_resolution_handle_event(ADDRESS_RESOLUTION_SUCCEEDED); 22703deb3ec6SMatthias Ringwald break; 22713deb3ec6SMatthias Ringwald } 22723deb3ec6SMatthias Ringwald 2273a9987c8eSMatthias Ringwald // if connection type is public, it must be a different one 2274a9987c8eSMatthias Ringwald if (sm_address_resolution_addr_type == BD_ADDR_TYPE_LE_PUBLIC){ 22753deb3ec6SMatthias Ringwald sm_address_resolution_test++; 22763deb3ec6SMatthias Ringwald continue; 22773deb3ec6SMatthias Ringwald } 22783deb3ec6SMatthias Ringwald 22798cc81b50SMatthias Ringwald // skip AH if no IRK 22808cc81b50SMatthias Ringwald if (sm_is_null_key(irk)){ 22818cc81b50SMatthias Ringwald sm_address_resolution_test++; 22828cc81b50SMatthias Ringwald continue; 22838cc81b50SMatthias Ringwald } 22848cc81b50SMatthias Ringwald 22853deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 22863deb3ec6SMatthias Ringwald 22873deb3ec6SMatthias Ringwald log_info("LE Device Lookup: calculate AH"); 22888314c363SMatthias Ringwald log_info_key("IRK", irk); 22893deb3ec6SMatthias Ringwald 22906535961aSMatthias Ringwald (void)memcpy(sm_aes128_key, irk, 16); 2291d1a1f6a4SMatthias Ringwald sm_ah_r_prime(sm_address_resolution_address, sm_aes128_plaintext); 2292d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2293d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_aes128_key, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_address_resolution, NULL); 2294d7f1c72eSMatthias Ringwald return true; 22953deb3ec6SMatthias Ringwald } 22963deb3ec6SMatthias Ringwald 2297092ec58eSMatthias Ringwald if (sm_address_resolution_test >= le_device_db_max_count()){ 22983deb3ec6SMatthias Ringwald log_info("LE Device Lookup: not found"); 22993deb3ec6SMatthias Ringwald sm_address_resolution_handle_event(ADDRESS_RESOLUTION_FAILED); 23003deb3ec6SMatthias Ringwald } 23013deb3ec6SMatthias Ringwald } 2302d7f1c72eSMatthias Ringwald return false; 2303d7f1c72eSMatthias Ringwald } 23043deb3ec6SMatthias Ringwald 2305d7f1c72eSMatthias Ringwald // SC OOB 2306d7f1c72eSMatthias Ringwald static bool sm_run_oob(void){ 2307c59d0c92SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2308c59d0c92SMatthias Ringwald switch (sm_sc_oob_state){ 2309c59d0c92SMatthias Ringwald case SM_SC_OOB_W2_CALC_CONFIRM: 2310c59d0c92SMatthias Ringwald if (!sm_cmac_ready()) break; 2311c59d0c92SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_W4_CONFIRM; 2312c59d0c92SMatthias Ringwald f4_engine(NULL, ec_q, ec_q, sm_sc_oob_random, 0); 2313d7f1c72eSMatthias Ringwald return true; 2314c59d0c92SMatthias Ringwald default: 2315c59d0c92SMatthias Ringwald break; 2316c59d0c92SMatthias Ringwald } 2317c59d0c92SMatthias Ringwald #endif 2318d7f1c72eSMatthias Ringwald return false; 2319d7f1c72eSMatthias Ringwald } 2320275aafe8SMatthias Ringwald 2321687a03c8SMatthias Ringwald static void sm_send_connectionless(sm_connection_t * sm_connection, const uint8_t * buffer, uint16_t size){ 2322687a03c8SMatthias Ringwald l2cap_send_connectionless(sm_connection->sm_handle, sm_connection->sm_cid, (uint8_t*) buffer, size); 2323687a03c8SMatthias Ringwald } 2324687a03c8SMatthias Ringwald 232541d32297SMatthias Ringwald // handle basic actions that don't requires the full context 2326d7f1c72eSMatthias Ringwald static bool sm_run_basic(void){ 2327d7f1c72eSMatthias Ringwald btstack_linked_list_iterator_t it; 232841d32297SMatthias Ringwald hci_connections_get_iterator(&it); 2329e9af1bf6SMatthias Ringwald while(btstack_linked_list_iterator_has_next(&it)){ 233041d32297SMatthias Ringwald hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 233141d32297SMatthias Ringwald sm_connection_t * sm_connection = &hci_connection->sm_connection; 233241d32297SMatthias Ringwald switch(sm_connection->sm_engine_state){ 2333f4935286SMatthias Ringwald 2334f4935286SMatthias Ringwald // general 2335f4935286SMatthias Ringwald case SM_GENERAL_SEND_PAIRING_FAILED: { 2336f4935286SMatthias Ringwald uint8_t buffer[2]; 2337f4935286SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_FAILED; 2338f4935286SMatthias Ringwald buffer[1] = sm_connection->sm_pairing_failed_reason; 2339f4935286SMatthias Ringwald sm_connection->sm_engine_state = sm_connection->sm_role ? SM_RESPONDER_IDLE : SM_INITIATOR_CONNECTED; 2340687a03c8SMatthias Ringwald sm_send_connectionless(sm_connection, (uint8_t*) buffer, sizeof(buffer)); 2341f4935286SMatthias Ringwald sm_pairing_complete(sm_connection, ERROR_CODE_AUTHENTICATION_FAILURE, sm_connection->sm_pairing_failed_reason); 2342f4935286SMatthias Ringwald sm_done_for_handle(sm_connection->sm_handle); 2343f4935286SMatthias Ringwald break; 2344f4935286SMatthias Ringwald } 2345f4935286SMatthias Ringwald 234641d32297SMatthias Ringwald // responder side 234741d32297SMatthias Ringwald case SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY: 234841d32297SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_IDLE; 234941d32297SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_negative_reply, sm_connection->sm_handle); 2350d7f1c72eSMatthias Ringwald return true; 23514b8b5afeSMatthias Ringwald 23524b8b5afeSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 23534b8b5afeSMatthias Ringwald case SM_SC_RECEIVED_LTK_REQUEST: 23544b8b5afeSMatthias Ringwald switch (sm_connection->sm_irk_lookup_state){ 23554b8b5afeSMatthias Ringwald case IRK_LOOKUP_FAILED: 2356e9af1bf6SMatthias Ringwald log_info("LTK Request: IRK Lookup Failed)"); 23574b8b5afeSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_IDLE; 23584b8b5afeSMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_negative_reply, sm_connection->sm_handle); 2359d7f1c72eSMatthias Ringwald return true; 23604b8b5afeSMatthias Ringwald default: 23614b8b5afeSMatthias Ringwald break; 23624b8b5afeSMatthias Ringwald } 23634b8b5afeSMatthias Ringwald break; 23644b8b5afeSMatthias Ringwald #endif 236541d32297SMatthias Ringwald default: 236641d32297SMatthias Ringwald break; 236741d32297SMatthias Ringwald } 236841d32297SMatthias Ringwald } 2369d7f1c72eSMatthias Ringwald return false; 2370d7f1c72eSMatthias Ringwald } 23713deb3ec6SMatthias Ringwald 2372d7f1c72eSMatthias Ringwald static void sm_run_activate_connection(void){ 23733deb3ec6SMatthias Ringwald // Find connections that requires setup context and make active if no other is locked 2374d7f1c72eSMatthias Ringwald btstack_linked_list_iterator_t it; 23753deb3ec6SMatthias Ringwald hci_connections_get_iterator(&it); 23767149bde5SMatthias Ringwald while((sm_active_connection_handle == HCI_CON_HANDLE_INVALID) && btstack_linked_list_iterator_has_next(&it)){ 2377665d90f2SMatthias Ringwald hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 23783deb3ec6SMatthias Ringwald sm_connection_t * sm_connection = &hci_connection->sm_connection; 23793deb3ec6SMatthias Ringwald // - if no connection locked and we're ready/waiting for setup context, fetch it and start 23801979f09cSMatthias Ringwald bool done = true; 23813deb3ec6SMatthias Ringwald int err; 238242134bc6SMatthias Ringwald UNUSED(err); 238334b6528fSMatthias Ringwald 238434b6528fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 238534b6528fSMatthias Ringwald // assert ec key is ready 2386505f1c30SMatthias Ringwald if ( (sm_connection->sm_engine_state == SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED) 2387178e8c1bSMatthias Ringwald || (sm_connection->sm_engine_state == SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST) 2388178e8c1bSMatthias Ringwald || (sm_connection->sm_engine_state == SM_RESPONDER_SEND_SECURITY_REQUEST)){ 238934b6528fSMatthias Ringwald if (ec_key_generation_state == EC_KEY_GENERATION_IDLE){ 239034b6528fSMatthias Ringwald sm_ec_generate_new_key(); 239134b6528fSMatthias Ringwald } 239234b6528fSMatthias Ringwald if (ec_key_generation_state != EC_KEY_GENERATION_DONE){ 239334b6528fSMatthias Ringwald continue; 239434b6528fSMatthias Ringwald } 239534b6528fSMatthias Ringwald } 239634b6528fSMatthias Ringwald #endif 239734b6528fSMatthias Ringwald 23983deb3ec6SMatthias Ringwald switch (sm_connection->sm_engine_state) { 239942134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 24003deb3ec6SMatthias Ringwald case SM_RESPONDER_SEND_SECURITY_REQUEST: 24013deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED: 240242134bc6SMatthias Ringwald case SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST: 2403549ad5d2SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 240406cd539fSMatthias Ringwald case SM_SC_RECEIVED_LTK_REQUEST: 240587014f74SMatthias Ringwald #endif 240687014f74SMatthias Ringwald #endif 240734c39fbdSMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 24085567aa60SMatthias Ringwald case SM_INITIATOR_PH4_HAS_LTK: 240934c39fbdSMatthias Ringwald case SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST: 2410549ad5d2SMatthias Ringwald #endif 2411c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 2412c18be159SMatthias Ringwald case SM_BR_EDR_RESPONDER_PAIRING_REQUEST_RECEIVED: 2413c18be159SMatthias Ringwald case SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST: 2414c18be159SMatthias Ringwald #endif 241587014f74SMatthias Ringwald // just lock context 241687014f74SMatthias Ringwald break; 24173deb3ec6SMatthias Ringwald default: 24181979f09cSMatthias Ringwald done = false; 24193deb3ec6SMatthias Ringwald break; 24203deb3ec6SMatthias Ringwald } 24213deb3ec6SMatthias Ringwald if (done){ 24227149bde5SMatthias Ringwald sm_active_connection_handle = sm_connection->sm_handle; 24237149bde5SMatthias Ringwald log_info("sm: connection 0x%04x locked setup context as %s, state %u", sm_active_connection_handle, sm_connection->sm_role ? "responder" : "initiator", sm_connection->sm_engine_state); 24243deb3ec6SMatthias Ringwald } 24253deb3ec6SMatthias Ringwald } 2426d7f1c72eSMatthias Ringwald } 2427d7f1c72eSMatthias Ringwald 2428403280b9SMatthias Ringwald static void sm_run_send_keypress_notification(sm_connection_t * connection){ 2429403280b9SMatthias Ringwald int i; 2430403280b9SMatthias Ringwald uint8_t flags = setup->sm_keypress_notification & 0x1fu; 2431403280b9SMatthias Ringwald uint8_t num_actions = setup->sm_keypress_notification >> 5; 2432403280b9SMatthias Ringwald uint8_t action = 0; 2433403280b9SMatthias Ringwald for (i=SM_KEYPRESS_PASSKEY_ENTRY_STARTED;i<=SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED;i++){ 24341d80f1e6SMatthias Ringwald if ((flags & (1u<<i)) != 0u){ 2435403280b9SMatthias Ringwald bool clear_flag = true; 2436403280b9SMatthias Ringwald switch (i){ 2437403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_STARTED: 2438403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_CLEARED: 2439403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED: 2440403280b9SMatthias Ringwald default: 2441403280b9SMatthias Ringwald break; 2442403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ENTERED: 2443403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ERASED: 2444403280b9SMatthias Ringwald num_actions--; 2445403280b9SMatthias Ringwald clear_flag = num_actions == 0u; 2446403280b9SMatthias Ringwald break; 2447403280b9SMatthias Ringwald } 2448403280b9SMatthias Ringwald if (clear_flag){ 2449403280b9SMatthias Ringwald flags &= ~(1<<i); 2450403280b9SMatthias Ringwald } 2451403280b9SMatthias Ringwald action = i; 2452403280b9SMatthias Ringwald break; 2453403280b9SMatthias Ringwald } 2454403280b9SMatthias Ringwald } 2455403280b9SMatthias Ringwald setup->sm_keypress_notification = (num_actions << 5) | flags; 2456403280b9SMatthias Ringwald 2457403280b9SMatthias Ringwald // send keypress notification 2458403280b9SMatthias Ringwald uint8_t buffer[2]; 2459403280b9SMatthias Ringwald buffer[0] = SM_CODE_KEYPRESS_NOTIFICATION; 2460403280b9SMatthias Ringwald buffer[1] = action; 2461687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2462403280b9SMatthias Ringwald 2463403280b9SMatthias Ringwald // try 2464384eabd3SMatthias Ringwald l2cap_request_can_send_fix_channel_now_event(sm_active_connection_handle, connection->sm_cid); 2465403280b9SMatthias Ringwald } 2466403280b9SMatthias Ringwald 2467403280b9SMatthias Ringwald static void sm_run_distribute_keys(sm_connection_t * connection){ 24681d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION) != 0u){ 2469403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 2470403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 2471403280b9SMatthias Ringwald uint8_t buffer[17]; 2472403280b9SMatthias Ringwald buffer[0] = SM_CODE_ENCRYPTION_INFORMATION; 2473403280b9SMatthias Ringwald reverse_128(setup->sm_ltk, &buffer[1]); 2474687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2475403280b9SMatthias Ringwald sm_timeout_reset(connection); 2476403280b9SMatthias Ringwald return; 2477403280b9SMatthias Ringwald } 24781d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_MASTER_IDENTIFICATION) != 0u){ 2479403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 2480403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 2481403280b9SMatthias Ringwald uint8_t buffer[11]; 2482403280b9SMatthias Ringwald buffer[0] = SM_CODE_MASTER_IDENTIFICATION; 2483403280b9SMatthias Ringwald little_endian_store_16(buffer, 1, setup->sm_local_ediv); 2484403280b9SMatthias Ringwald reverse_64(setup->sm_local_rand, &buffer[3]); 2485687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2486403280b9SMatthias Ringwald sm_timeout_reset(connection); 2487403280b9SMatthias Ringwald return; 2488403280b9SMatthias Ringwald } 24891d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION) != 0u){ 2490403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 2491403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 2492403280b9SMatthias Ringwald uint8_t buffer[17]; 2493403280b9SMatthias Ringwald buffer[0] = SM_CODE_IDENTITY_INFORMATION; 2494403280b9SMatthias Ringwald reverse_128(sm_persistent_irk, &buffer[1]); 2495687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2496403280b9SMatthias Ringwald sm_timeout_reset(connection); 2497403280b9SMatthias Ringwald return; 2498403280b9SMatthias Ringwald } 24991d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION) != 0u){ 2500403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 2501403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 2502403280b9SMatthias Ringwald bd_addr_t local_address; 2503403280b9SMatthias Ringwald uint8_t buffer[8]; 2504403280b9SMatthias Ringwald buffer[0] = SM_CODE_IDENTITY_ADDRESS_INFORMATION; 2505403280b9SMatthias Ringwald switch (gap_random_address_get_mode()){ 2506403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_OFF: 2507403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_STATIC: 2508403280b9SMatthias Ringwald // public or static random 2509403280b9SMatthias Ringwald gap_le_get_own_address(&buffer[1], local_address); 2510403280b9SMatthias Ringwald break; 2511403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_NON_RESOLVABLE: 2512403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_RESOLVABLE: 2513403280b9SMatthias Ringwald // fallback to public 2514403280b9SMatthias Ringwald gap_local_bd_addr(local_address); 2515403280b9SMatthias Ringwald buffer[1] = 0; 2516403280b9SMatthias Ringwald break; 2517403280b9SMatthias Ringwald default: 2518403280b9SMatthias Ringwald btstack_assert(false); 2519403280b9SMatthias Ringwald break; 2520403280b9SMatthias Ringwald } 2521403280b9SMatthias Ringwald reverse_bd_addr(local_address, &buffer[2]); 2522687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2523403280b9SMatthias Ringwald sm_timeout_reset(connection); 2524403280b9SMatthias Ringwald return; 2525403280b9SMatthias Ringwald } 25261d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION) != 0u){ 2527403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 2528403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 2529403280b9SMatthias Ringwald 2530403280b9SMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 2531403280b9SMatthias Ringwald // hack to reproduce test runs 2532403280b9SMatthias Ringwald if (test_use_fixed_local_csrk){ 2533403280b9SMatthias Ringwald memset(setup->sm_local_csrk, 0xcc, 16); 2534403280b9SMatthias Ringwald } 2535403280b9SMatthias Ringwald 2536403280b9SMatthias Ringwald // store local CSRK 2537403280b9SMatthias Ringwald if (setup->sm_le_device_index >= 0){ 2538403280b9SMatthias Ringwald log_info("sm: store local CSRK"); 2539403280b9SMatthias Ringwald le_device_db_local_csrk_set(setup->sm_le_device_index, setup->sm_local_csrk); 2540403280b9SMatthias Ringwald le_device_db_local_counter_set(setup->sm_le_device_index, 0); 2541403280b9SMatthias Ringwald } 2542403280b9SMatthias Ringwald #endif 2543403280b9SMatthias Ringwald 2544403280b9SMatthias Ringwald uint8_t buffer[17]; 2545403280b9SMatthias Ringwald buffer[0] = SM_CODE_SIGNING_INFORMATION; 2546403280b9SMatthias Ringwald reverse_128(setup->sm_local_csrk, &buffer[1]); 2547687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2548403280b9SMatthias Ringwald sm_timeout_reset(connection); 2549403280b9SMatthias Ringwald return; 2550403280b9SMatthias Ringwald } 2551403280b9SMatthias Ringwald btstack_assert(false); 2552403280b9SMatthias Ringwald } 2553403280b9SMatthias Ringwald 2554bbd73538SMatthias Ringwald static bool sm_ctkd_from_le(sm_connection_t *sm_connection) { 2555bbd73538SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 2556bbd73538SMatthias Ringwald // requirements to derive link key from LE: 2557bbd73538SMatthias Ringwald // - use secure connections 2558bbd73538SMatthias Ringwald if (setup->sm_use_secure_connections == 0) return false; 2559bbd73538SMatthias Ringwald // - bonding needs to be enabled: 2560bbd73538SMatthias Ringwald bool bonding_enabled = (sm_pairing_packet_get_auth_req(setup->sm_m_preq) & sm_pairing_packet_get_auth_req(setup->sm_s_pres) & SM_AUTHREQ_BONDING ) != 0u; 2561bbd73538SMatthias Ringwald if (!bonding_enabled) return false; 2562bbd73538SMatthias Ringwald // - need identity address / public addr 2563bbd73538SMatthias Ringwald bool have_identity_address_info = ((setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION) != 0) || (setup->sm_peer_addr_type == 0); 2564bbd73538SMatthias Ringwald if (!have_identity_address_info) return false; 2565bbd73538SMatthias Ringwald // - there is no stored BR/EDR link key or the derived key has at least the same level of authentication (bail if stored key has higher authentication) 2566bbd73538SMatthias Ringwald // this requirement is motivated by BLURtooth paper. The paper recommends to not overwrite keys at all. 2567bbd73538SMatthias Ringwald // If SC is authenticated, we consider it safe to overwrite a stored key. 2568bbd73538SMatthias Ringwald // If stored link key is not authenticated, it could already be compromised by a MITM attack. Allowing overwrite by unauthenticated derived key does not make it worse. 2569bbd73538SMatthias Ringwald uint8_t link_key[16]; 2570bbd73538SMatthias Ringwald link_key_type_t link_key_type; 2571bbd73538SMatthias Ringwald bool have_link_key = gap_get_link_key_for_bd_addr(setup->sm_peer_address, link_key, &link_key_type); 25727040ba26SMatthias Ringwald bool link_key_authenticated = gap_authenticated_for_link_key_type(link_key_type); 2573bbd73538SMatthias Ringwald bool derived_key_authenticated = sm_connection->sm_connection_authenticated != 0; 2574bbd73538SMatthias Ringwald if (have_link_key && link_key_authenticated && !derived_key_authenticated) { 2575bbd73538SMatthias Ringwald return false; 2576bbd73538SMatthias Ringwald } 2577bbd73538SMatthias Ringwald // get started (all of the above are true) 2578bbd73538SMatthias Ringwald return true; 2579bbd73538SMatthias Ringwald #else 2580bbd73538SMatthias Ringwald UNUSED(sm_connection); 2581bbd73538SMatthias Ringwald return false; 2582bbd73538SMatthias Ringwald #endif 2583bbd73538SMatthias Ringwald } 2584bbd73538SMatthias Ringwald 25856a718a5eSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 25866a718a5eSMatthias Ringwald static bool sm_ctkd_from_classic(sm_connection_t * sm_connection){ 25876a718a5eSMatthias Ringwald hci_connection_t * hci_connection = hci_connection_for_handle(sm_connection->sm_handle); 25886a718a5eSMatthias Ringwald btstack_assert(hci_connection != NULL); 25896a718a5eSMatthias Ringwald // requirements to derive ltk from BR/EDR: 25906a718a5eSMatthias Ringwald // - BR/EDR uses secure connections 25916a718a5eSMatthias Ringwald if (gap_secure_connection_for_link_key_type(hci_connection->link_key_type) == false) return false; 25926a718a5eSMatthias Ringwald // - bonding needs to be enabled: 25936a718a5eSMatthias Ringwald bool bonding_enabled = (sm_pairing_packet_get_auth_req(setup->sm_m_preq) & sm_pairing_packet_get_auth_req(setup->sm_s_pres) & SM_AUTHREQ_BONDING ) != 0u; 25946a718a5eSMatthias Ringwald if (!bonding_enabled) return false; 25956a718a5eSMatthias Ringwald // - there is no stored LTK or the derived key has at least the same level of authentication (bail if LTK is authenticated but Link Key isn't) 25966a718a5eSMatthias Ringwald bool link_key_authenticated = gap_authenticated_for_link_key_type(hci_connection->link_key_type); 25976a718a5eSMatthias Ringwald if (link_key_authenticated) return true; 25986a718a5eSMatthias Ringwald int index = sm_le_device_db_index_lookup(BD_ADDR_TYPE_LE_PUBLIC, hci_connection->address); 25996a718a5eSMatthias Ringwald if (index >= 0){ 26006a718a5eSMatthias Ringwald int ltk_authenticated; 26016a718a5eSMatthias Ringwald sm_key_t ltk; 26026a718a5eSMatthias Ringwald le_device_db_encryption_get(sm_connection->sm_le_db_index, NULL, NULL, ltk, NULL, <k_authenticated, NULL, NULL); 26036a718a5eSMatthias Ringwald bool have_ltk = !sm_is_null_key(ltk); 26046a718a5eSMatthias Ringwald if (have_ltk && ltk_authenticated) return false; 26056a718a5eSMatthias Ringwald } 26066a718a5eSMatthias Ringwald return true; 26076a718a5eSMatthias Ringwald } 26086a718a5eSMatthias Ringwald #endif 26096a718a5eSMatthias Ringwald 26106f7422f1SMatthias Ringwald static void sm_key_distribution_complete_responder(sm_connection_t * connection){ 26116f7422f1SMatthias Ringwald if (sm_ctkd_from_le(connection)){ 26126f7422f1SMatthias Ringwald bool use_h7 = (sm_pairing_packet_get_auth_req(setup->sm_m_preq) & sm_pairing_packet_get_auth_req(setup->sm_s_pres) & SM_AUTHREQ_CT2) != 0; 26136f7422f1SMatthias Ringwald connection->sm_engine_state = use_h7 ? SM_SC_W2_CALCULATE_ILK_USING_H7 : SM_SC_W2_CALCULATE_ILK_USING_H6; 26146f7422f1SMatthias Ringwald } else { 26156f7422f1SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_IDLE; 26166f7422f1SMatthias Ringwald sm_pairing_complete(connection, ERROR_CODE_SUCCESS, 0); 26176f7422f1SMatthias Ringwald sm_done_for_handle(connection->sm_handle); 26186f7422f1SMatthias Ringwald } 26196f7422f1SMatthias Ringwald } 26206f7422f1SMatthias Ringwald 2621af7ef9d1SMatthias Ringwald static void sm_key_distribution_complete_initiator(sm_connection_t * connection){ 2622af7ef9d1SMatthias Ringwald if (sm_ctkd_from_le(connection)){ 2623af7ef9d1SMatthias Ringwald bool use_h7 = (sm_pairing_packet_get_auth_req(setup->sm_m_preq) & sm_pairing_packet_get_auth_req(setup->sm_s_pres) & SM_AUTHREQ_CT2) != 0; 2624af7ef9d1SMatthias Ringwald connection->sm_engine_state = use_h7 ? SM_SC_W2_CALCULATE_ILK_USING_H7 : SM_SC_W2_CALCULATE_ILK_USING_H6; 2625af7ef9d1SMatthias Ringwald } else { 2626af7ef9d1SMatthias Ringwald sm_master_pairing_success(connection); 2627af7ef9d1SMatthias Ringwald } 2628af7ef9d1SMatthias Ringwald } 2629af7ef9d1SMatthias Ringwald 2630b919f264SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2631b919f264SMatthias Ringwald static void sm_run_state_sc_send_confirmation(sm_connection_t *connection) { 2632b919f264SMatthias Ringwald uint8_t buffer[17]; 2633b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_CONFIRM; 2634b919f264SMatthias Ringwald reverse_128(setup->sm_local_confirm, &buffer[1]); 2635b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2636b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2637b919f264SMatthias Ringwald } else { 2638b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2639b919f264SMatthias Ringwald } 2640b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2641b919f264SMatthias Ringwald sm_timeout_reset(connection); 2642b919f264SMatthias Ringwald } 2643b919f264SMatthias Ringwald 2644b919f264SMatthias Ringwald static void sm_run_state_sc_send_pairing_random(sm_connection_t *connection) { 2645b919f264SMatthias Ringwald uint8_t buffer[17]; 2646b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_RANDOM; 2647b919f264SMatthias Ringwald reverse_128(setup->sm_local_nonce, &buffer[1]); 2648b919f264SMatthias Ringwald log_info("stk method %u, bit num: %u", setup->sm_stk_generation_method, setup->sm_passkey_bit); 2649b919f264SMatthias Ringwald if (sm_passkey_entry(setup->sm_stk_generation_method) && (setup->sm_passkey_bit < 20u)){ 2650b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM A"); 2651b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2652b919f264SMatthias Ringwald // responder 2653b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2654b919f264SMatthias Ringwald } else { 2655b919f264SMatthias Ringwald // initiator 2656b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2657b919f264SMatthias Ringwald } 2658b919f264SMatthias Ringwald } else { 2659b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM B"); 2660b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2661b919f264SMatthias Ringwald // responder 2662b919f264SMatthias Ringwald if (setup->sm_stk_generation_method == NUMERIC_COMPARISON){ 2663b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM B1"); 2664b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W2_CALCULATE_G2; 2665b919f264SMatthias Ringwald } else { 2666b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM B2"); 2667b919f264SMatthias Ringwald sm_sc_prepare_dhkey_check(connection); 2668b919f264SMatthias Ringwald } 2669b919f264SMatthias Ringwald } else { 2670b919f264SMatthias Ringwald // initiator 2671b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2672b919f264SMatthias Ringwald } 2673b919f264SMatthias Ringwald } 2674b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2675b919f264SMatthias Ringwald sm_timeout_reset(connection); 2676b919f264SMatthias Ringwald } 2677b919f264SMatthias Ringwald 2678b919f264SMatthias Ringwald static void sm_run_state_sc_send_dhkey_check_command(sm_connection_t *connection) { 2679b919f264SMatthias Ringwald uint8_t buffer[17]; 2680b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_DHKEY_CHECK; 2681b919f264SMatthias Ringwald reverse_128(setup->sm_local_dhkey_check, &buffer[1]); 2682b919f264SMatthias Ringwald 2683b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2684b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_LTK_REQUEST_SC; 2685b919f264SMatthias Ringwald } else { 2686b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_DHKEY_CHECK_COMMAND; 2687b919f264SMatthias Ringwald } 2688b919f264SMatthias Ringwald 2689b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2690b919f264SMatthias Ringwald sm_timeout_reset(connection); 2691b919f264SMatthias Ringwald } 2692b919f264SMatthias Ringwald 2693b919f264SMatthias Ringwald static void sm_run_state_sc_send_public_key_command(sm_connection_t *connection) { 2694b919f264SMatthias Ringwald bool trigger_user_response = false; 2695b919f264SMatthias Ringwald bool trigger_start_calculating_local_confirm = false; 2696b919f264SMatthias Ringwald uint8_t buffer[65]; 2697b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_PUBLIC_KEY; 2698b919f264SMatthias Ringwald // 2699b919f264SMatthias Ringwald reverse_256(&ec_q[0], &buffer[1]); 2700b919f264SMatthias Ringwald reverse_256(&ec_q[32], &buffer[33]); 2701b919f264SMatthias Ringwald 2702b919f264SMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 2703b919f264SMatthias Ringwald if (test_pairing_failure == SM_REASON_DHKEY_CHECK_FAILED){ 2704b919f264SMatthias Ringwald log_info("testing_support: invalidating public key"); 2705b919f264SMatthias Ringwald // flip single bit of public key coordinate 2706b919f264SMatthias Ringwald buffer[1] ^= 1; 2707b919f264SMatthias Ringwald } 2708b919f264SMatthias Ringwald #endif 2709b919f264SMatthias Ringwald 2710b919f264SMatthias Ringwald // stk generation method 2711b919f264SMatthias Ringwald // passkey entry: notify app to show passkey or to request passkey 2712b919f264SMatthias Ringwald switch (setup->sm_stk_generation_method){ 2713b919f264SMatthias Ringwald case JUST_WORKS: 2714b919f264SMatthias Ringwald case NUMERIC_COMPARISON: 2715b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2716b919f264SMatthias Ringwald // responder 2717b919f264SMatthias Ringwald trigger_start_calculating_local_confirm = true; 2718b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_LOCAL_NONCE; 2719b919f264SMatthias Ringwald } else { 2720b919f264SMatthias Ringwald // initiator 2721b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2722b919f264SMatthias Ringwald } 2723b919f264SMatthias Ringwald break; 2724b919f264SMatthias Ringwald case PK_INIT_INPUT: 2725b919f264SMatthias Ringwald case PK_RESP_INPUT: 2726b919f264SMatthias Ringwald case PK_BOTH_INPUT: 2727b919f264SMatthias Ringwald // use random TK for display 2728b919f264SMatthias Ringwald (void)memcpy(setup->sm_ra, setup->sm_tk, 16); 2729b919f264SMatthias Ringwald (void)memcpy(setup->sm_rb, setup->sm_tk, 16); 2730b919f264SMatthias Ringwald setup->sm_passkey_bit = 0; 2731b919f264SMatthias Ringwald 2732b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2733b919f264SMatthias Ringwald // responder 2734b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2735b919f264SMatthias Ringwald } else { 2736b919f264SMatthias Ringwald // initiator 2737b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2738b919f264SMatthias Ringwald } 2739b919f264SMatthias Ringwald trigger_user_response = true; 2740b919f264SMatthias Ringwald break; 2741b919f264SMatthias Ringwald case OOB: 2742b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2743b919f264SMatthias Ringwald // responder 2744b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2745b919f264SMatthias Ringwald } else { 2746b919f264SMatthias Ringwald // initiator 2747b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2748b919f264SMatthias Ringwald } 2749b919f264SMatthias Ringwald break; 2750b919f264SMatthias Ringwald default: 2751b919f264SMatthias Ringwald btstack_assert(false); 2752b919f264SMatthias Ringwald break; 2753b919f264SMatthias Ringwald } 2754b919f264SMatthias Ringwald 2755b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2756b919f264SMatthias Ringwald sm_timeout_reset(connection); 2757b919f264SMatthias Ringwald 2758b919f264SMatthias Ringwald // trigger user response and calc confirm after sending pdu 2759b919f264SMatthias Ringwald if (trigger_user_response){ 2760b919f264SMatthias Ringwald sm_trigger_user_response(connection); 2761b919f264SMatthias Ringwald } 2762b919f264SMatthias Ringwald if (trigger_start_calculating_local_confirm){ 2763b919f264SMatthias Ringwald sm_sc_start_calculating_local_confirm(connection); 2764b919f264SMatthias Ringwald } 2765b919f264SMatthias Ringwald } 2766b919f264SMatthias Ringwald #endif 2767b919f264SMatthias Ringwald 2768de42cac5SMatthias Ringwald static bool sm_run_non_connection_logic(void){ 2769de42cac5SMatthias Ringwald bool done;; 2770de42cac5SMatthias Ringwald 2771de42cac5SMatthias Ringwald done = sm_run_dpkg(); 2772de42cac5SMatthias Ringwald if (done) return true; 2773de42cac5SMatthias Ringwald 2774de42cac5SMatthias Ringwald done = sm_run_rau(); 2775de42cac5SMatthias Ringwald if (done) return true; 2776de42cac5SMatthias Ringwald 2777de42cac5SMatthias Ringwald done = sm_run_csrk(); 2778de42cac5SMatthias Ringwald if (done) return true; 2779de42cac5SMatthias Ringwald 2780de42cac5SMatthias Ringwald done = sm_run_oob(); 2781de42cac5SMatthias Ringwald return done; 2782de42cac5SMatthias Ringwald } 2783b919f264SMatthias Ringwald 2784d7f1c72eSMatthias Ringwald static void sm_run(void){ 2785d7f1c72eSMatthias Ringwald 2786d7f1c72eSMatthias Ringwald // assert that stack has already bootet 2787d7f1c72eSMatthias Ringwald if (hci_get_state() != HCI_STATE_WORKING) return; 2788d7f1c72eSMatthias Ringwald 2789d7f1c72eSMatthias Ringwald // assert that we can send at least commands 2790d7f1c72eSMatthias Ringwald if (!hci_can_send_command_packet_now()) return; 2791d7f1c72eSMatthias Ringwald 2792d7f1c72eSMatthias Ringwald // pause until IR/ER are ready 2793d7f1c72eSMatthias Ringwald if (sm_persistent_keys_random_active) return; 2794d7f1c72eSMatthias Ringwald 2795d7f1c72eSMatthias Ringwald // non-connection related behaviour 2796de42cac5SMatthias Ringwald bool done = sm_run_non_connection_logic(); 2797d7f1c72eSMatthias Ringwald if (done) return; 2798d7f1c72eSMatthias Ringwald 2799d7f1c72eSMatthias Ringwald // assert that we can send at least commands - cmd might have been sent by crypto engine 2800d7f1c72eSMatthias Ringwald if (!hci_can_send_command_packet_now()) return; 2801d7f1c72eSMatthias Ringwald 2802d7f1c72eSMatthias Ringwald // handle basic actions that don't requires the full context 2803d7f1c72eSMatthias Ringwald done = sm_run_basic(); 2804d7f1c72eSMatthias Ringwald if (done) return; 2805d7f1c72eSMatthias Ringwald 2806d7f1c72eSMatthias Ringwald // 2807d7f1c72eSMatthias Ringwald // active connection handling 2808d7f1c72eSMatthias Ringwald // -- use loop to handle next connection if lock on setup context is released 2809d7f1c72eSMatthias Ringwald 2810d7f1c72eSMatthias Ringwald while (true) { 2811d7f1c72eSMatthias Ringwald 2812d7f1c72eSMatthias Ringwald sm_run_activate_connection(); 2813d7f1c72eSMatthias Ringwald 2814d7f1c72eSMatthias Ringwald if (sm_active_connection_handle == HCI_CON_HANDLE_INVALID) return; 28153deb3ec6SMatthias Ringwald 28163deb3ec6SMatthias Ringwald // 28173deb3ec6SMatthias Ringwald // active connection handling 28183deb3ec6SMatthias Ringwald // 28193deb3ec6SMatthias Ringwald 28203cf37b8cSMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(sm_active_connection_handle); 28213cf37b8cSMatthias Ringwald if (!connection) { 28223cf37b8cSMatthias Ringwald log_info("no connection for handle 0x%04x", sm_active_connection_handle); 28233cf37b8cSMatthias Ringwald return; 28243cf37b8cSMatthias Ringwald } 28253cf37b8cSMatthias Ringwald 28263deb3ec6SMatthias Ringwald // assert that we could send a SM PDU - not needed for all of the following 2827384eabd3SMatthias Ringwald if (!l2cap_can_send_fixed_channel_packet_now(sm_active_connection_handle, connection->sm_cid)) { 28287149bde5SMatthias Ringwald log_info("cannot send now, requesting can send now event"); 2829384eabd3SMatthias Ringwald l2cap_request_can_send_fix_channel_now_event(sm_active_connection_handle, connection->sm_cid); 2830b170b20fSMatthias Ringwald return; 2831b170b20fSMatthias Ringwald } 28323deb3ec6SMatthias Ringwald 28333d7fe1e9SMatthias Ringwald // send keypress notifications 28341d80f1e6SMatthias Ringwald if (setup->sm_keypress_notification != 0u){ 2835403280b9SMatthias Ringwald sm_run_send_keypress_notification(connection); 2836d7471931SMatthias Ringwald return; 28373d7fe1e9SMatthias Ringwald } 28383d7fe1e9SMatthias Ringwald 2839f7ea4423SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2840234022e5SMatthias Ringwald // assert that sm cmac engine is ready 2841234022e5SMatthias Ringwald if (sm_cmac_ready() == false){ 2842234022e5SMatthias Ringwald break; 2843234022e5SMatthias Ringwald } 2844f7ea4423SMatthias Ringwald #endif 2845234022e5SMatthias Ringwald 28463deb3ec6SMatthias Ringwald int key_distribution_flags; 284742134bc6SMatthias Ringwald UNUSED(key_distribution_flags); 2848b6f39a74SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 2849b6afa23eSMatthias Ringwald int err; 28509b75de03SMatthias Ringwald bool have_ltk; 28519b75de03SMatthias Ringwald uint8_t ltk[16]; 2852b6f39a74SMatthias Ringwald #endif 28533deb3ec6SMatthias Ringwald 28543deb3ec6SMatthias Ringwald log_info("sm_run: state %u", connection->sm_engine_state); 28553deb3ec6SMatthias Ringwald switch (connection->sm_engine_state){ 28563deb3ec6SMatthias Ringwald 2857f32b7a88SMatthias Ringwald // secure connections, initiator + responding states 2858aec94140SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2859aec94140SMatthias Ringwald case SM_SC_W2_CMAC_FOR_CONFIRMATION: 2860aec94140SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CMAC_FOR_CONFIRMATION; 2861aec94140SMatthias Ringwald sm_sc_calculate_local_confirm(connection); 2862aec94140SMatthias Ringwald break; 2863688a08f9SMatthias Ringwald case SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION: 2864688a08f9SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CMAC_FOR_CHECK_CONFIRMATION; 2865688a08f9SMatthias Ringwald sm_sc_calculate_remote_confirm(connection); 2866688a08f9SMatthias Ringwald break; 2867dc300847SMatthias Ringwald case SM_SC_W2_CALCULATE_F6_FOR_DHKEY_CHECK: 2868dc300847SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F6_FOR_DHKEY_CHECK; 2869dc300847SMatthias Ringwald sm_sc_calculate_f6_for_dhkey_check(connection); 2870dc300847SMatthias Ringwald break; 2871019005a0SMatthias Ringwald case SM_SC_W2_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK: 2872019005a0SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK; 28730346c37cSMatthias Ringwald sm_sc_calculate_f6_to_verify_dhkey_check(connection); 28740346c37cSMatthias Ringwald break; 28750346c37cSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_SALT: 28760346c37cSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F5_SALT; 28770346c37cSMatthias Ringwald f5_calculate_salt(connection); 28780346c37cSMatthias Ringwald break; 28790346c37cSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_MACKEY: 28800346c37cSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F5_MACKEY; 28810346c37cSMatthias Ringwald f5_calculate_mackey(connection); 28820346c37cSMatthias Ringwald break; 28830346c37cSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_LTK: 28840346c37cSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F5_LTK; 28850346c37cSMatthias Ringwald f5_calculate_ltk(connection); 2886019005a0SMatthias Ringwald break; 2887bd57ffebSMatthias Ringwald case SM_SC_W2_CALCULATE_G2: 2888bd57ffebSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_G2; 2889b35a3de2SMatthias Ringwald g2_calculate(connection); 2890bd57ffebSMatthias Ringwald break; 2891e0a03c85SMatthias Ringwald #endif 2892e0a03c85SMatthias Ringwald 289342134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 28943deb3ec6SMatthias Ringwald // initiator side 2895f32b7a88SMatthias Ringwald 28965567aa60SMatthias Ringwald case SM_INITIATOR_PH4_HAS_LTK: { 2897f32b7a88SMatthias Ringwald sm_reset_setup(); 2898f32b7a88SMatthias Ringwald sm_load_security_info(connection); 2899f32b7a88SMatthias Ringwald 29003deb3ec6SMatthias Ringwald sm_key_t peer_ltk_flipped; 29019c80e4ccSMatthias Ringwald reverse_128(setup->sm_peer_ltk, peer_ltk_flipped); 29025567aa60SMatthias Ringwald connection->sm_engine_state = SM_PH4_W4_CONNECTION_ENCRYPTED; 29033deb3ec6SMatthias Ringwald log_info("sm: hci_le_start_encryption ediv 0x%04x", setup->sm_peer_ediv); 2904c9b8fdd9SMatthias Ringwald uint32_t rand_high = big_endian_read_32(setup->sm_peer_rand, 0); 2905c9b8fdd9SMatthias Ringwald uint32_t rand_low = big_endian_read_32(setup->sm_peer_rand, 4); 29063deb3ec6SMatthias Ringwald hci_send_cmd(&hci_le_start_encryption, connection->sm_handle,rand_low, rand_high, setup->sm_peer_ediv, peer_ltk_flipped); 290749c9e430SMatthias Ringwald 290849c9e430SMatthias Ringwald // notify after sending 290949c9e430SMatthias Ringwald sm_reencryption_started(connection); 29103deb3ec6SMatthias Ringwald return; 29113deb3ec6SMatthias Ringwald } 29123deb3ec6SMatthias Ringwald 2913b26f445fSMatthias Ringwald case SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST: 2914b26f445fSMatthias Ringwald sm_reset_setup(); 2915b26f445fSMatthias Ringwald sm_init_setup(connection); 2916b26f445fSMatthias Ringwald 29171ad129beSMatthias Ringwald sm_pairing_packet_set_code(setup->sm_m_preq, SM_CODE_PAIRING_REQUEST); 29183deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH1_W4_PAIRING_RESPONSE; 2919687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) &setup->sm_m_preq, sizeof(sm_pairing_packet_t)); 29203deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 292149c9e430SMatthias Ringwald 292249c9e430SMatthias Ringwald // notify after sending 292349c9e430SMatthias Ringwald sm_pairing_started(connection); 29243deb3ec6SMatthias Ringwald break; 292542134bc6SMatthias Ringwald #endif 29263deb3ec6SMatthias Ringwald 292727c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2928b919f264SMatthias Ringwald case SM_SC_SEND_PUBLIC_KEY_COMMAND: 2929b919f264SMatthias Ringwald sm_run_state_sc_send_public_key_command(connection); 293045a61d50SMatthias Ringwald break; 2931b919f264SMatthias Ringwald case SM_SC_SEND_CONFIRMATION: 2932b919f264SMatthias Ringwald sm_run_state_sc_send_confirmation(connection); 293345a61d50SMatthias Ringwald break; 2934b919f264SMatthias Ringwald case SM_SC_SEND_PAIRING_RANDOM: 2935b919f264SMatthias Ringwald sm_run_state_sc_send_pairing_random(connection); 293645a61d50SMatthias Ringwald break; 2937b919f264SMatthias Ringwald case SM_SC_SEND_DHKEY_CHECK_COMMAND: 2938b919f264SMatthias Ringwald sm_run_state_sc_send_dhkey_check_command(connection); 29397bbeb3adSMilanka Ringwald break; 2940e53be891SMatthias Ringwald #endif 294142134bc6SMatthias Ringwald 294242134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 2943dd12a62bSMatthias Ringwald 294487014f74SMatthias Ringwald case SM_RESPONDER_SEND_SECURITY_REQUEST: { 294587014f74SMatthias Ringwald const uint8_t buffer[2] = {SM_CODE_SECURITY_REQUEST, sm_auth_req}; 294687014f74SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH1_W4_PAIRING_REQUEST; 2947687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t *) buffer, sizeof(buffer)); 2948c8d0ff33SMatthias Ringwald sm_timeout_start(connection); 294987014f74SMatthias Ringwald break; 295087014f74SMatthias Ringwald } 295187014f74SMatthias Ringwald 295238196718SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 295338196718SMatthias Ringwald case SM_SC_RECEIVED_LTK_REQUEST: 295438196718SMatthias Ringwald switch (connection->sm_irk_lookup_state){ 295538196718SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 295638196718SMatthias Ringwald // assuming Secure Connection, we have a stored LTK and the EDIV/RAND are null 295738196718SMatthias Ringwald // start using context by loading security info 295838196718SMatthias Ringwald sm_reset_setup(); 295938196718SMatthias Ringwald sm_load_security_info(connection); 296038196718SMatthias Ringwald if ((setup->sm_peer_ediv == 0u) && sm_is_null_random(setup->sm_peer_rand) && !sm_is_null_key(setup->sm_peer_ltk)){ 296138196718SMatthias Ringwald (void)memcpy(setup->sm_ltk, setup->sm_peer_ltk, 16); 296238196718SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH4_SEND_LTK_REPLY; 296342646f38SMatthias Ringwald sm_reencryption_started(connection); 296438196718SMatthias Ringwald sm_trigger_run(); 296538196718SMatthias Ringwald break; 296638196718SMatthias Ringwald } 296738196718SMatthias Ringwald log_info("LTK Request: ediv & random are empty, but no stored LTK (IRK Lookup Succeeded)"); 296838196718SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_IDLE; 296938196718SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_negative_reply, connection->sm_handle); 297038196718SMatthias Ringwald return; 297138196718SMatthias Ringwald default: 297238196718SMatthias Ringwald // just wait until IRK lookup is completed 297338196718SMatthias Ringwald break; 297438196718SMatthias Ringwald } 297538196718SMatthias Ringwald break; 297638196718SMatthias Ringwald #endif /* ENABLE_LE_SECURE_CONNECTIONS */ 297738196718SMatthias Ringwald 2978b6afa23eSMatthias Ringwald case SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED: 2979b6afa23eSMatthias Ringwald sm_reset_setup(); 29809b75de03SMatthias Ringwald 29819b75de03SMatthias Ringwald // handle Pairing Request with LTK available 29829b75de03SMatthias Ringwald switch (connection->sm_irk_lookup_state) { 29839b75de03SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 29849b75de03SMatthias Ringwald le_device_db_encryption_get(connection->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); 29859b75de03SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 29869b75de03SMatthias Ringwald if (have_ltk){ 29879b75de03SMatthias Ringwald log_info("pairing request but LTK available"); 298819a40772SMatthias Ringwald // emit re-encryption start/fail sequence 29899b75de03SMatthias Ringwald sm_reencryption_started(connection); 29909b75de03SMatthias Ringwald sm_reencryption_complete(connection, ERROR_CODE_PIN_OR_KEY_MISSING); 29919b75de03SMatthias Ringwald } 29929b75de03SMatthias Ringwald break; 29939b75de03SMatthias Ringwald default: 29949b75de03SMatthias Ringwald break; 29959b75de03SMatthias Ringwald } 29969b75de03SMatthias Ringwald 2997b6afa23eSMatthias Ringwald sm_init_setup(connection); 299839543d07SMatthias Ringwald 2999b6afa23eSMatthias Ringwald // recover pairing request 3000b6afa23eSMatthias Ringwald (void)memcpy(&setup->sm_m_preq, &connection->sm_m_preq, sizeof(sm_pairing_packet_t)); 3001b6afa23eSMatthias Ringwald err = sm_stk_generation_init(connection); 3002b6afa23eSMatthias Ringwald 3003b6afa23eSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 3004b6afa23eSMatthias Ringwald if ((0 < test_pairing_failure) && (test_pairing_failure < SM_REASON_DHKEY_CHECK_FAILED)){ 3005b6afa23eSMatthias Ringwald log_info("testing_support: respond with pairing failure %u", test_pairing_failure); 3006b6afa23eSMatthias Ringwald err = test_pairing_failure; 3007b6afa23eSMatthias Ringwald } 3008b6afa23eSMatthias Ringwald #endif 30099305033eSMatthias Ringwald if (err != 0){ 301049c9e430SMatthias Ringwald // emit pairing started/failed sequence 301149c9e430SMatthias Ringwald sm_pairing_started(connection); 3012f4935286SMatthias Ringwald sm_pairing_error(connection, err); 3013b6afa23eSMatthias Ringwald sm_trigger_run(); 3014b6afa23eSMatthias Ringwald break; 3015b6afa23eSMatthias Ringwald } 3016b6afa23eSMatthias Ringwald 3017b6afa23eSMatthias Ringwald sm_timeout_start(connection); 3018b6afa23eSMatthias Ringwald 3019b6afa23eSMatthias Ringwald // generate random number first, if we need to show passkey, otherwise send response 3020b6afa23eSMatthias Ringwald if (setup->sm_stk_generation_method == PK_INIT_INPUT){ 3021b6afa23eSMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph2_tk, (void *)(uintptr_t) connection->sm_handle); 3022b6afa23eSMatthias Ringwald break; 3023b6afa23eSMatthias Ringwald } 3024b6afa23eSMatthias Ringwald 3025b6afa23eSMatthias Ringwald /* fall through */ 3026b6afa23eSMatthias Ringwald 30273deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE: 30281ad129beSMatthias Ringwald sm_pairing_packet_set_code(setup->sm_s_pres,SM_CODE_PAIRING_RESPONSE); 3029f55bd529SMatthias Ringwald 3030f55bd529SMatthias Ringwald // start with initiator key dist flags 30313deb3ec6SMatthias Ringwald key_distribution_flags = sm_key_distribution_flags_for_auth_req(); 30321ad129beSMatthias Ringwald 3033f55bd529SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 3034b2072c76SMatthias Ringwald // LTK (= encryption information & master identification) only exchanged for LE Legacy Connection 3035f55bd529SMatthias Ringwald if (setup->sm_use_secure_connections){ 3036f55bd529SMatthias Ringwald key_distribution_flags &= ~SM_KEYDIST_ENC_KEY; 3037f55bd529SMatthias Ringwald } 3038f55bd529SMatthias Ringwald #endif 3039f55bd529SMatthias Ringwald // setup in response 3040f55bd529SMatthias Ringwald sm_pairing_packet_set_initiator_key_distribution(setup->sm_s_pres, sm_pairing_packet_get_initiator_key_distribution(setup->sm_m_preq) & key_distribution_flags); 3041f55bd529SMatthias Ringwald sm_pairing_packet_set_responder_key_distribution(setup->sm_s_pres, sm_pairing_packet_get_responder_key_distribution(setup->sm_m_preq) & key_distribution_flags); 3042f55bd529SMatthias Ringwald 3043f55bd529SMatthias Ringwald // update key distribution after ENC was dropped 30449a90d41aSMatthias Ringwald sm_setup_key_distribution(sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres), sm_pairing_packet_get_initiator_key_distribution(setup->sm_s_pres)); 3045f55bd529SMatthias Ringwald 304627c32905SMatthias Ringwald if (setup->sm_use_secure_connections){ 3047c6b7cbd9SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 30480b8af2a5SMatthias Ringwald } else { 30490b8af2a5SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH1_W4_PAIRING_CONFIRM; 305027c32905SMatthias Ringwald } 30510b8af2a5SMatthias Ringwald 3052687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) &setup->sm_s_pres, sizeof(sm_pairing_packet_t)); 30533deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 305449c9e430SMatthias Ringwald 305549c9e430SMatthias Ringwald // notify after sending 305649c9e430SMatthias Ringwald sm_pairing_started(connection); 305749c9e430SMatthias Ringwald 3058446a8c36SMatthias Ringwald // SC Numeric Comparison will trigger user response after public keys & nonces have been exchanged 3059c1ab6cc1SMatthias Ringwald if (!setup->sm_use_secure_connections || (setup->sm_stk_generation_method == JUST_WORKS)){ 30603deb3ec6SMatthias Ringwald sm_trigger_user_response(connection); 3061446a8c36SMatthias Ringwald } 30623deb3ec6SMatthias Ringwald return; 306342134bc6SMatthias Ringwald #endif 30643deb3ec6SMatthias Ringwald 30653deb3ec6SMatthias Ringwald case SM_PH2_SEND_PAIRING_RANDOM: { 30663deb3ec6SMatthias Ringwald uint8_t buffer[17]; 30673deb3ec6SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_RANDOM; 30689c80e4ccSMatthias Ringwald reverse_128(setup->sm_local_random, &buffer[1]); 306942134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 30703deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH2_W4_LTK_REQUEST; 30713deb3ec6SMatthias Ringwald } else { 30723deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH2_W4_PAIRING_RANDOM; 30733deb3ec6SMatthias Ringwald } 3074687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 30753deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 30763deb3ec6SMatthias Ringwald break; 30773deb3ec6SMatthias Ringwald } 30783deb3ec6SMatthias Ringwald 3079d1a1f6a4SMatthias Ringwald case SM_PH2_C1_GET_ENC_A: 30803deb3ec6SMatthias Ringwald // already busy? 30813deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 3082d1a1f6a4SMatthias Ringwald // calculate confirm using aes128 engine - step 1 3083d1a1f6a4SMatthias Ringwald sm_c1_t1(setup->sm_local_random, (uint8_t*) &setup->sm_m_preq, (uint8_t*) &setup->sm_s_pres, setup->sm_m_addr_type, setup->sm_s_addr_type, sm_aes128_plaintext); 3084d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_W4_ENC_A; 3085d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3086f3582630SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, setup->sm_tk, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_enc_a, (void *)(uintptr_t) connection->sm_handle); 30873deb3ec6SMatthias Ringwald break; 30883deb3ec6SMatthias Ringwald 30893deb3ec6SMatthias Ringwald case SM_PH2_C1_GET_ENC_C: 30903deb3ec6SMatthias Ringwald // already busy? 30913deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 30923deb3ec6SMatthias Ringwald // calculate m_confirm using aes128 engine - step 1 3093d1a1f6a4SMatthias Ringwald sm_c1_t1(setup->sm_peer_random, (uint8_t*) &setup->sm_m_preq, (uint8_t*) &setup->sm_s_pres, setup->sm_m_addr_type, setup->sm_s_addr_type, sm_aes128_plaintext); 3094d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_W4_ENC_C; 3095d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3096f3582630SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, setup->sm_tk, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_enc_c, (void *)(uintptr_t) connection->sm_handle); 30973deb3ec6SMatthias Ringwald break; 3098d1a1f6a4SMatthias Ringwald 30993deb3ec6SMatthias Ringwald case SM_PH2_CALC_STK: 31003deb3ec6SMatthias Ringwald // already busy? 31013deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31023deb3ec6SMatthias Ringwald // calculate STK 310342134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 3104d1a1f6a4SMatthias Ringwald sm_s1_r_prime(setup->sm_local_random, setup->sm_peer_random, sm_aes128_plaintext); 31053deb3ec6SMatthias Ringwald } else { 3106d1a1f6a4SMatthias Ringwald sm_s1_r_prime(setup->sm_peer_random, setup->sm_local_random, sm_aes128_plaintext); 31073deb3ec6SMatthias Ringwald } 3108d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_W4_STK; 3109d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3110f3582630SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, setup->sm_tk, sm_aes128_plaintext, setup->sm_ltk, sm_handle_encryption_result_enc_stk, (void *)(uintptr_t) connection->sm_handle); 31113deb3ec6SMatthias Ringwald break; 3112d1a1f6a4SMatthias Ringwald 31133deb3ec6SMatthias Ringwald case SM_PH3_Y_GET_ENC: 31143deb3ec6SMatthias Ringwald // already busy? 31153deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31163deb3ec6SMatthias Ringwald // PH3B2 - calculate Y from - enc 31179ad0dd7cSMatthias Ringwald 31189ad0dd7cSMatthias Ringwald // dm helper (was sm_dm_r_prime) 31199ad0dd7cSMatthias Ringwald // r' = padding || r 31209ad0dd7cSMatthias Ringwald // r - 64 bit value 31219ad0dd7cSMatthias Ringwald memset(&sm_aes128_plaintext[0], 0, 8); 31226535961aSMatthias Ringwald (void)memcpy(&sm_aes128_plaintext[8], setup->sm_local_rand, 8); 31239ad0dd7cSMatthias Ringwald 31243deb3ec6SMatthias Ringwald // Y = dm(DHK, Rand) 3125d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH3_Y_W4_ENC; 3126d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3127f3582630SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_dhk, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_enc_ph3_y, (void *)(uintptr_t) connection->sm_handle); 3128d1a1f6a4SMatthias Ringwald break; 3129d1a1f6a4SMatthias Ringwald 31303deb3ec6SMatthias Ringwald case SM_PH2_C1_SEND_PAIRING_CONFIRM: { 31313deb3ec6SMatthias Ringwald uint8_t buffer[17]; 31323deb3ec6SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_CONFIRM; 31339c80e4ccSMatthias Ringwald reverse_128(setup->sm_local_confirm, &buffer[1]); 313442134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 31353deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH2_W4_PAIRING_RANDOM; 31363deb3ec6SMatthias Ringwald } else { 31373deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH2_W4_PAIRING_CONFIRM; 31383deb3ec6SMatthias Ringwald } 3139687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 31403deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 31413deb3ec6SMatthias Ringwald return; 31423deb3ec6SMatthias Ringwald } 314342134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 31443deb3ec6SMatthias Ringwald case SM_RESPONDER_PH2_SEND_LTK_REPLY: { 3145916ea5b2SMatthias Ringwald // cache key before using 3146916ea5b2SMatthias Ringwald sm_cache_ltk(connection, setup->sm_ltk); 31473deb3ec6SMatthias Ringwald sm_key_t stk_flipped; 31489c80e4ccSMatthias Ringwald reverse_128(setup->sm_ltk, stk_flipped); 31493deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH2_W4_CONNECTION_ENCRYPTED; 31503deb3ec6SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_request_reply, connection->sm_handle, stk_flipped); 31513deb3ec6SMatthias Ringwald return; 31523deb3ec6SMatthias Ringwald } 3153d7471931SMatthias Ringwald case SM_RESPONDER_PH4_SEND_LTK_REPLY: { 3154b96d60a6SMatthias Ringwald // allow to override LTK 3155b96d60a6SMatthias Ringwald if (sm_get_ltk_callback != NULL){ 3156b96d60a6SMatthias Ringwald (void)(*sm_get_ltk_callback)(connection->sm_handle, connection->sm_peer_addr_type, connection->sm_peer_address, setup->sm_ltk); 3157b96d60a6SMatthias Ringwald } 3158916ea5b2SMatthias Ringwald // cache key before using 3159916ea5b2SMatthias Ringwald sm_cache_ltk(connection, setup->sm_ltk); 31603deb3ec6SMatthias Ringwald sm_key_t ltk_flipped; 31619c80e4ccSMatthias Ringwald reverse_128(setup->sm_ltk, ltk_flipped); 31625567aa60SMatthias Ringwald connection->sm_engine_state = SM_PH4_W4_CONNECTION_ENCRYPTED; 31633deb3ec6SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_request_reply, connection->sm_handle, ltk_flipped); 31643deb3ec6SMatthias Ringwald return; 31653deb3ec6SMatthias Ringwald } 3166dd12a62bSMatthias Ringwald 3167dd12a62bSMatthias Ringwald case SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST: 31683deb3ec6SMatthias Ringwald // already busy? 31693deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31703deb3ec6SMatthias Ringwald log_info("LTK Request: recalculating with ediv 0x%04x", setup->sm_local_ediv); 3171c61cfe5aSMatthias Ringwald 3172dd12a62bSMatthias Ringwald sm_reset_setup(); 3173dd12a62bSMatthias Ringwald sm_start_calculating_ltk_from_ediv_and_rand(connection); 3174dd12a62bSMatthias Ringwald 317542646f38SMatthias Ringwald sm_reencryption_started(connection); 317642646f38SMatthias Ringwald 3177c61cfe5aSMatthias Ringwald // dm helper (was sm_dm_r_prime) 3178c61cfe5aSMatthias Ringwald // r' = padding || r 3179c61cfe5aSMatthias Ringwald // r - 64 bit value 3180c61cfe5aSMatthias Ringwald memset(&sm_aes128_plaintext[0], 0, 8); 31816535961aSMatthias Ringwald (void)memcpy(&sm_aes128_plaintext[8], setup->sm_local_rand, 8); 3182c61cfe5aSMatthias Ringwald 31833deb3ec6SMatthias Ringwald // Y = dm(DHK, Rand) 3184d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH4_Y_W4_ENC; 3185d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3186f3582630SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_dhk, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_enc_ph4_y, (void *)(uintptr_t) connection->sm_handle); 31873deb3ec6SMatthias Ringwald return; 318842134bc6SMatthias Ringwald #endif 318942134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 319042134bc6SMatthias Ringwald case SM_INITIATOR_PH3_SEND_START_ENCRYPTION: { 319142134bc6SMatthias Ringwald sm_key_t stk_flipped; 319242134bc6SMatthias Ringwald reverse_128(setup->sm_ltk, stk_flipped); 319342134bc6SMatthias Ringwald connection->sm_engine_state = SM_PH2_W4_CONNECTION_ENCRYPTED; 319442134bc6SMatthias Ringwald hci_send_cmd(&hci_le_start_encryption, connection->sm_handle, 0, 0, 0, stk_flipped); 319542134bc6SMatthias Ringwald return; 319642134bc6SMatthias Ringwald } 319742134bc6SMatthias Ringwald #endif 31983deb3ec6SMatthias Ringwald 31993deb3ec6SMatthias Ringwald case SM_PH3_DISTRIBUTE_KEYS: 3200e94757aeSMatthias Ringwald // send next key 3201403280b9SMatthias Ringwald if (setup->sm_key_distribution_send_set != 0){ 3202403280b9SMatthias Ringwald sm_run_distribute_keys(connection); 3203e94757aeSMatthias Ringwald } 3204e94757aeSMatthias Ringwald 3205e94757aeSMatthias Ringwald // more to send? 3206e94757aeSMatthias Ringwald if (setup->sm_key_distribution_send_set != 0){ 32073deb3ec6SMatthias Ringwald return; 32083deb3ec6SMatthias Ringwald } 32093deb3ec6SMatthias Ringwald 32103deb3ec6SMatthias Ringwald // keys are sent 321142134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 32123deb3ec6SMatthias Ringwald // slave -> receive master keys if any 321361d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 32143deb3ec6SMatthias Ringwald sm_key_distribution_handle_all_received(connection); 3215f5020412SMatthias Ringwald sm_key_distribution_complete_responder(connection); 3216f5020412SMatthias Ringwald // start CTKD right away 3217f5020412SMatthias Ringwald continue; 32183deb3ec6SMatthias Ringwald } else { 32193deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH3_RECEIVE_KEYS; 32203deb3ec6SMatthias Ringwald } 32213deb3ec6SMatthias Ringwald } else { 32221dca9d8aSMatthias Ringwald sm_master_pairing_success(connection); 32233deb3ec6SMatthias Ringwald } 32243deb3ec6SMatthias Ringwald break; 32253deb3ec6SMatthias Ringwald 3226c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 3227c18be159SMatthias Ringwald case SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST: 3228c18be159SMatthias Ringwald // fill in sm setup (lite version of sm_init_setup) 3229c18be159SMatthias Ringwald sm_reset_setup(); 3230c18be159SMatthias Ringwald setup->sm_peer_addr_type = connection->sm_peer_addr_type; 3231c18be159SMatthias Ringwald setup->sm_m_addr_type = connection->sm_peer_addr_type; 3232c18be159SMatthias Ringwald setup->sm_s_addr_type = connection->sm_own_addr_type; 3233c18be159SMatthias Ringwald (void) memcpy(setup->sm_peer_address, connection->sm_peer_address, 6); 3234c18be159SMatthias Ringwald (void) memcpy(setup->sm_m_address, connection->sm_peer_address, 6); 3235c18be159SMatthias Ringwald (void) memcpy(setup->sm_s_address, connection->sm_own_address, 6); 3236c18be159SMatthias Ringwald setup->sm_use_secure_connections = true; 3237c18be159SMatthias Ringwald sm_ctkd_fetch_br_edr_link_key(connection); 3238c18be159SMatthias Ringwald 3239c18be159SMatthias Ringwald // Enc Key and IRK if requested 3240c18be159SMatthias Ringwald key_distribution_flags = SM_KEYDIST_ID_KEY | SM_KEYDIST_ENC_KEY; 3241c18be159SMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 3242c18be159SMatthias Ringwald // Plus signing key if supported 3243c18be159SMatthias Ringwald key_distribution_flags |= SM_KEYDIST_ID_KEY; 3244c18be159SMatthias Ringwald #endif 3245c18be159SMatthias Ringwald sm_pairing_packet_set_code(setup->sm_m_preq, SM_CODE_PAIRING_REQUEST); 3246c18be159SMatthias Ringwald sm_pairing_packet_set_io_capability(setup->sm_m_preq, 0); 3247c18be159SMatthias Ringwald sm_pairing_packet_set_oob_data_flag(setup->sm_m_preq, 0); 3248c18be159SMatthias Ringwald sm_pairing_packet_set_auth_req(setup->sm_m_preq, SM_AUTHREQ_CT2); 3249c18be159SMatthias Ringwald sm_pairing_packet_set_max_encryption_key_size(setup->sm_m_preq, sm_max_encryption_key_size); 3250c18be159SMatthias Ringwald sm_pairing_packet_set_initiator_key_distribution(setup->sm_m_preq, key_distribution_flags); 3251c18be159SMatthias Ringwald sm_pairing_packet_set_responder_key_distribution(setup->sm_m_preq, key_distribution_flags); 3252c18be159SMatthias Ringwald 3253c18be159SMatthias Ringwald // set state and send pairing response 3254c18be159SMatthias Ringwald sm_timeout_start(connection); 3255c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_INITIATOR_W4_PAIRING_RESPONSE; 3256c18be159SMatthias Ringwald sm_send_connectionless(connection, (uint8_t *) &setup->sm_m_preq, sizeof(sm_pairing_packet_t)); 3257c18be159SMatthias Ringwald break; 3258c18be159SMatthias Ringwald 3259c18be159SMatthias Ringwald case SM_BR_EDR_RESPONDER_PAIRING_REQUEST_RECEIVED: 3260c18be159SMatthias Ringwald // fill in sm setup (lite version of sm_init_setup) 3261c18be159SMatthias Ringwald sm_reset_setup(); 3262c18be159SMatthias Ringwald setup->sm_peer_addr_type = connection->sm_peer_addr_type; 3263c18be159SMatthias Ringwald setup->sm_m_addr_type = connection->sm_peer_addr_type; 3264c18be159SMatthias Ringwald setup->sm_s_addr_type = connection->sm_own_addr_type; 3265c18be159SMatthias Ringwald (void) memcpy(setup->sm_peer_address, connection->sm_peer_address, 6); 3266c18be159SMatthias Ringwald (void) memcpy(setup->sm_m_address, connection->sm_peer_address, 6); 3267c18be159SMatthias Ringwald (void) memcpy(setup->sm_s_address, connection->sm_own_address, 6); 3268c18be159SMatthias Ringwald setup->sm_use_secure_connections = true; 3269c18be159SMatthias Ringwald sm_ctkd_fetch_br_edr_link_key(connection); 3270c18be159SMatthias Ringwald (void) memcpy(&setup->sm_m_preq, &connection->sm_m_preq, sizeof(sm_pairing_packet_t)); 3271c18be159SMatthias Ringwald 3272c18be159SMatthias Ringwald // Enc Key and IRK if requested 3273c18be159SMatthias Ringwald key_distribution_flags = SM_KEYDIST_ID_KEY | SM_KEYDIST_ENC_KEY; 3274c18be159SMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 3275c18be159SMatthias Ringwald // Plus signing key if supported 3276c18be159SMatthias Ringwald key_distribution_flags |= SM_KEYDIST_ID_KEY; 3277c18be159SMatthias Ringwald #endif 3278c18be159SMatthias Ringwald // drop flags not requested by initiator 3279c18be159SMatthias Ringwald key_distribution_flags &= sm_pairing_packet_get_initiator_key_distribution(connection->sm_m_preq); 3280c18be159SMatthias Ringwald 3281c18be159SMatthias Ringwald // If Secure Connections pairing has been initiated over BR/EDR, the following fields of the SM Pairing Request PDU are reserved for future use: 3282c18be159SMatthias Ringwald // - the IO Capability field, 3283c18be159SMatthias Ringwald // - the OOB data flag field, and 3284c18be159SMatthias Ringwald // - all bits in the Auth Req field except the CT2 bit. 3285c18be159SMatthias Ringwald sm_pairing_packet_set_code(setup->sm_s_pres, SM_CODE_PAIRING_RESPONSE); 3286c18be159SMatthias Ringwald sm_pairing_packet_set_io_capability(setup->sm_s_pres, 0); 3287c18be159SMatthias Ringwald sm_pairing_packet_set_oob_data_flag(setup->sm_s_pres, 0); 3288c18be159SMatthias Ringwald sm_pairing_packet_set_auth_req(setup->sm_s_pres, SM_AUTHREQ_CT2); 3289c18be159SMatthias Ringwald sm_pairing_packet_set_max_encryption_key_size(setup->sm_s_pres, connection->sm_actual_encryption_key_size); 3290c18be159SMatthias Ringwald sm_pairing_packet_set_initiator_key_distribution(setup->sm_s_pres, key_distribution_flags); 3291c18be159SMatthias Ringwald sm_pairing_packet_set_responder_key_distribution(setup->sm_s_pres, key_distribution_flags); 3292c18be159SMatthias Ringwald 3293c18be159SMatthias Ringwald // configure key distribution, LTK is derived locally 3294c18be159SMatthias Ringwald key_distribution_flags &= ~SM_KEYDIST_ENC_KEY; 3295c18be159SMatthias Ringwald sm_setup_key_distribution(key_distribution_flags, key_distribution_flags); 3296c18be159SMatthias Ringwald 3297c18be159SMatthias Ringwald // set state and send pairing response 3298c18be159SMatthias Ringwald sm_timeout_start(connection); 3299c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_DISTRIBUTE_KEYS; 3300c18be159SMatthias Ringwald sm_send_connectionless(connection, (uint8_t *) &setup->sm_s_pres, sizeof(sm_pairing_packet_t)); 3301c18be159SMatthias Ringwald break; 3302c18be159SMatthias Ringwald case SM_BR_EDR_DISTRIBUTE_KEYS: 3303c18be159SMatthias Ringwald if (setup->sm_key_distribution_send_set != 0) { 3304c18be159SMatthias Ringwald sm_run_distribute_keys(connection); 3305c18be159SMatthias Ringwald return; 3306c18be159SMatthias Ringwald } 3307c18be159SMatthias Ringwald // keys are sent 3308c18be159SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)) { 3309c18be159SMatthias Ringwald // responder -> receive master keys if there are any 331061d1a45eSMatthias Ringwald if (!sm_key_distribution_all_received()){ 3311c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_RECEIVE_KEYS; 3312c18be159SMatthias Ringwald break; 3313c18be159SMatthias Ringwald } 3314c18be159SMatthias Ringwald } 3315c18be159SMatthias Ringwald // otherwise start CTKD right away (responder and no keys to receive / initiator) 3316c18be159SMatthias Ringwald sm_ctkd_start_from_br_edr(connection); 3317c18be159SMatthias Ringwald continue; 3318c18be159SMatthias Ringwald case SM_SC_W2_CALCULATE_ILK_USING_H6: 3319c18be159SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_ILK; 3320c18be159SMatthias Ringwald h6_calculate_ilk_from_le_ltk(connection); 3321c18be159SMatthias Ringwald break; 3322c18be159SMatthias Ringwald case SM_SC_W2_CALCULATE_BR_EDR_LINK_KEY: 3323c18be159SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_BR_EDR_LINK_KEY; 3324c18be159SMatthias Ringwald h6_calculate_br_edr_link_key(connection); 3325c18be159SMatthias Ringwald break; 3326c18be159SMatthias Ringwald case SM_SC_W2_CALCULATE_ILK_USING_H7: 3327c18be159SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_ILK; 3328c18be159SMatthias Ringwald h7_calculate_ilk_from_le_ltk(connection); 3329c18be159SMatthias Ringwald break; 3330c18be159SMatthias Ringwald case SM_BR_EDR_W2_CALCULATE_ILK_USING_H6: 3331c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_W4_CALCULATE_ILK; 3332c18be159SMatthias Ringwald h6_calculate_ilk_from_br_edr(connection); 3333c18be159SMatthias Ringwald break; 3334c18be159SMatthias Ringwald case SM_BR_EDR_W2_CALCULATE_LE_LTK: 3335c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_W4_CALCULATE_LE_LTK; 3336c18be159SMatthias Ringwald h6_calculate_le_ltk(connection); 3337c18be159SMatthias Ringwald break; 3338c18be159SMatthias Ringwald case SM_BR_EDR_W2_CALCULATE_ILK_USING_H7: 3339c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_W4_CALCULATE_ILK; 3340c18be159SMatthias Ringwald h7_calculate_ilk_from_br_edr(connection); 3341c18be159SMatthias Ringwald break; 3342c18be159SMatthias Ringwald #endif 3343c18be159SMatthias Ringwald 33443deb3ec6SMatthias Ringwald default: 33453deb3ec6SMatthias Ringwald break; 33463deb3ec6SMatthias Ringwald } 33473deb3ec6SMatthias Ringwald 33483deb3ec6SMatthias Ringwald // check again if active connection was released 33497149bde5SMatthias Ringwald if (sm_active_connection_handle != HCI_CON_HANDLE_INVALID) break; 33503deb3ec6SMatthias Ringwald } 33513deb3ec6SMatthias Ringwald } 33523deb3ec6SMatthias Ringwald 3353d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3354d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_a(void *arg){ 3355f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 335604678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 335704678764SMatthias Ringwald 3358f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3359f3582630SMatthias Ringwald if (connection == NULL) return; 3360f3582630SMatthias Ringwald 3361d1a1f6a4SMatthias Ringwald sm_c1_t3(sm_aes128_ciphertext, setup->sm_m_address, setup->sm_s_address, setup->sm_c1_t3_value); 336204678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3363f3582630SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, setup->sm_tk, setup->sm_c1_t3_value, setup->sm_local_confirm, sm_handle_encryption_result_enc_b, (void *)(uintptr_t) connection->sm_handle); 3364d1a1f6a4SMatthias Ringwald } 33653deb3ec6SMatthias Ringwald 3366d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_b(void *arg){ 3367f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 336804678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 336904678764SMatthias Ringwald 3370f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3371f3582630SMatthias Ringwald if (connection == NULL) return; 3372f3582630SMatthias Ringwald 33738314c363SMatthias Ringwald log_info_key("c1!", setup->sm_local_confirm); 33743deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_SEND_PAIRING_CONFIRM; 337570b44dd4SMatthias Ringwald sm_trigger_run(); 3376d1a1f6a4SMatthias Ringwald } 3377d1a1f6a4SMatthias Ringwald 3378d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3379d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_c(void *arg){ 3380f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 338104678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 338204678764SMatthias Ringwald 3383f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3384f3582630SMatthias Ringwald if (connection == NULL) return; 3385f3582630SMatthias Ringwald 3386d1a1f6a4SMatthias Ringwald sm_c1_t3(sm_aes128_ciphertext, setup->sm_m_address, setup->sm_s_address, setup->sm_c1_t3_value); 338704678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3388f3582630SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, setup->sm_tk, setup->sm_c1_t3_value, sm_aes128_ciphertext, sm_handle_encryption_result_enc_d, (void *)(uintptr_t) connection->sm_handle); 3389d1a1f6a4SMatthias Ringwald } 3390d1a1f6a4SMatthias Ringwald 3391d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_d(void * arg){ 3392f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 339304678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 339404678764SMatthias Ringwald 3395f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3396f3582630SMatthias Ringwald if (connection == NULL) return; 3397f3582630SMatthias Ringwald 3398d1a1f6a4SMatthias Ringwald log_info_key("c1!", sm_aes128_ciphertext); 3399d1a1f6a4SMatthias Ringwald if (memcmp(setup->sm_peer_confirm, sm_aes128_ciphertext, 16) != 0){ 3400f4935286SMatthias Ringwald sm_pairing_error(connection, SM_REASON_CONFIRM_VALUE_FAILED); 340170b44dd4SMatthias Ringwald sm_trigger_run(); 34023deb3ec6SMatthias Ringwald return; 34033deb3ec6SMatthias Ringwald } 340442134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 34053deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH2_SEND_PAIRING_RANDOM; 340670b44dd4SMatthias Ringwald sm_trigger_run(); 34073deb3ec6SMatthias Ringwald } else { 3408d1a1f6a4SMatthias Ringwald sm_s1_r_prime(setup->sm_peer_random, setup->sm_local_random, sm_aes128_plaintext); 3409d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3410f3582630SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, setup->sm_tk, sm_aes128_plaintext, setup->sm_ltk, sm_handle_encryption_result_enc_stk, (void *)(uintptr_t) connection->sm_handle); 34113deb3ec6SMatthias Ringwald } 34123deb3ec6SMatthias Ringwald } 3413d1a1f6a4SMatthias Ringwald 3414d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_stk(void *arg){ 341504678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 3416f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 341704678764SMatthias Ringwald 3418f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3419f3582630SMatthias Ringwald if (connection == NULL) return; 3420f3582630SMatthias Ringwald 34213deb3ec6SMatthias Ringwald sm_truncate_key(setup->sm_ltk, connection->sm_actual_encryption_key_size); 34228314c363SMatthias Ringwald log_info_key("stk", setup->sm_ltk); 342342134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 34243deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH2_SEND_LTK_REPLY; 34253deb3ec6SMatthias Ringwald } else { 34263deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH3_SEND_START_ENCRYPTION; 34273deb3ec6SMatthias Ringwald } 342870b44dd4SMatthias Ringwald sm_trigger_run(); 3429d1a1f6a4SMatthias Ringwald } 3430d1a1f6a4SMatthias Ringwald 3431d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3432d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph3_y(void *arg){ 3433f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 343404678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 343504678764SMatthias Ringwald 3436f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3437f3582630SMatthias Ringwald if (connection == NULL) return; 3438f3582630SMatthias Ringwald 3439d1a1f6a4SMatthias Ringwald setup->sm_local_y = big_endian_read_16(sm_aes128_ciphertext, 14); 34403deb3ec6SMatthias Ringwald log_info_hex16("y", setup->sm_local_y); 34413deb3ec6SMatthias Ringwald // PH3B3 - calculate EDIV 34423deb3ec6SMatthias Ringwald setup->sm_local_ediv = setup->sm_local_y ^ setup->sm_local_div; 34433deb3ec6SMatthias Ringwald log_info_hex16("ediv", setup->sm_local_ediv); 34443deb3ec6SMatthias Ringwald // PH3B4 - calculate LTK - enc 34453deb3ec6SMatthias Ringwald // LTK = d1(ER, DIV, 0)) 3446d1a1f6a4SMatthias Ringwald sm_d1_d_prime(setup->sm_local_div, 0, sm_aes128_plaintext); 344704678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3448f3582630SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_er, sm_aes128_plaintext, setup->sm_ltk, sm_handle_encryption_result_enc_ph3_ltk, (void *)(uintptr_t) connection->sm_handle); 34493deb3ec6SMatthias Ringwald } 3450d1a1f6a4SMatthias Ringwald 34512a526f21SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 3452d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3453d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph4_y(void *arg){ 345404678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 3455f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 345604678764SMatthias Ringwald 3457f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3458f3582630SMatthias Ringwald if (connection == NULL) return; 3459f3582630SMatthias Ringwald 3460d1a1f6a4SMatthias Ringwald setup->sm_local_y = big_endian_read_16(sm_aes128_ciphertext, 14); 34613deb3ec6SMatthias Ringwald log_info_hex16("y", setup->sm_local_y); 34623deb3ec6SMatthias Ringwald 34633deb3ec6SMatthias Ringwald // PH3B3 - calculate DIV 34643deb3ec6SMatthias Ringwald setup->sm_local_div = setup->sm_local_y ^ setup->sm_local_ediv; 34653deb3ec6SMatthias Ringwald log_info_hex16("ediv", setup->sm_local_ediv); 34663deb3ec6SMatthias Ringwald // PH3B4 - calculate LTK - enc 34673deb3ec6SMatthias Ringwald // LTK = d1(ER, DIV, 0)) 3468d1a1f6a4SMatthias Ringwald sm_d1_d_prime(setup->sm_local_div, 0, sm_aes128_plaintext); 346904678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3470f3582630SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_er, sm_aes128_plaintext, setup->sm_ltk, sm_handle_encryption_result_enc_ph4_ltk, (void *)(uintptr_t) connection->sm_handle); 34713deb3ec6SMatthias Ringwald } 34722a526f21SMatthias Ringwald #endif 3473d1a1f6a4SMatthias Ringwald 3474d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3475d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph3_ltk(void *arg){ 3476f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 347704678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 347804678764SMatthias Ringwald 3479f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3480f3582630SMatthias Ringwald if (connection == NULL) return; 3481f3582630SMatthias Ringwald 34828314c363SMatthias Ringwald log_info_key("ltk", setup->sm_ltk); 34833deb3ec6SMatthias Ringwald // calc CSRK next 3484d1a1f6a4SMatthias Ringwald sm_d1_d_prime(setup->sm_local_div, 1, sm_aes128_plaintext); 348504678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3486f3582630SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_er, sm_aes128_plaintext, setup->sm_local_csrk, sm_handle_encryption_result_enc_csrk, (void *)(uintptr_t) connection->sm_handle); 3487d1a1f6a4SMatthias Ringwald } 3488d1a1f6a4SMatthias Ringwald 3489d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_csrk(void *arg){ 3490f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 349104678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 349204678764SMatthias Ringwald 3493f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3494f3582630SMatthias Ringwald if (connection == NULL) return; 3495f3582630SMatthias Ringwald 3496d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 34978314c363SMatthias Ringwald log_info_key("csrk", setup->sm_local_csrk); 34981d80f1e6SMatthias Ringwald if (setup->sm_key_distribution_send_set != 0u){ 34993deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 35003deb3ec6SMatthias Ringwald } else { 35013deb3ec6SMatthias Ringwald // no keys to send, just continue 350242134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 350361d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 3504c5a72e35SMatthias Ringwald sm_key_distribution_handle_all_received(connection); 3505c5a72e35SMatthias Ringwald sm_key_distribution_complete_responder(connection); 3506c5a72e35SMatthias Ringwald } else { 35073deb3ec6SMatthias Ringwald // slave -> receive master keys 35083deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH3_RECEIVE_KEYS; 3509c5a72e35SMatthias Ringwald } 35103deb3ec6SMatthias Ringwald } else { 3511af7ef9d1SMatthias Ringwald sm_key_distribution_complete_initiator(connection); 35123deb3ec6SMatthias Ringwald } 35132bacf595SMatthias Ringwald } 351470b44dd4SMatthias Ringwald sm_trigger_run(); 3515d1a1f6a4SMatthias Ringwald } 3516d1a1f6a4SMatthias Ringwald 351742134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 3518d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph4_ltk(void *arg){ 3519f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 352004678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 352104678764SMatthias Ringwald 3522f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3523f3582630SMatthias Ringwald if (connection == NULL) return; 3524f3582630SMatthias Ringwald 35253deb3ec6SMatthias Ringwald sm_truncate_key(setup->sm_ltk, connection->sm_actual_encryption_key_size); 35268314c363SMatthias Ringwald log_info_key("ltk", setup->sm_ltk); 3527d7471931SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH4_SEND_LTK_REPLY; 352870b44dd4SMatthias Ringwald sm_trigger_run(); 3529d1a1f6a4SMatthias Ringwald } 3530d1a1f6a4SMatthias Ringwald #endif 3531d1a1f6a4SMatthias Ringwald 3532d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_address_resolution(void *arg){ 3533d1a1f6a4SMatthias Ringwald UNUSED(arg); 3534d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 353504678764SMatthias Ringwald 3536d1a1f6a4SMatthias Ringwald // compare calulated address against connecting device 3537d1a1f6a4SMatthias Ringwald uint8_t * hash = &sm_aes128_ciphertext[13]; 3538d1a1f6a4SMatthias Ringwald if (memcmp(&sm_address_resolution_address[3], hash, 3) == 0){ 3539d1a1f6a4SMatthias Ringwald log_info("LE Device Lookup: matched resolvable private address"); 3540a66b030fSMatthias Ringwald sm_address_resolution_handle_event(ADDRESS_RESOLUTION_SUCCEEDED); 354170b44dd4SMatthias Ringwald sm_trigger_run(); 35423deb3ec6SMatthias Ringwald return; 35433deb3ec6SMatthias Ringwald } 3544d1a1f6a4SMatthias Ringwald // no match, try next 3545d1a1f6a4SMatthias Ringwald sm_address_resolution_test++; 354670b44dd4SMatthias Ringwald sm_trigger_run(); 35473deb3ec6SMatthias Ringwald } 35483deb3ec6SMatthias Ringwald 3549d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_dkg_irk(void *arg){ 3550d1a1f6a4SMatthias Ringwald UNUSED(arg); 3551d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 355204678764SMatthias Ringwald 3553d1a1f6a4SMatthias Ringwald log_info_key("irk", sm_persistent_irk); 3554d1a1f6a4SMatthias Ringwald dkg_state = DKG_CALC_DHK; 355570b44dd4SMatthias Ringwald sm_trigger_run(); 35567df18c15SMatthias Ringwald } 3557d1a1f6a4SMatthias Ringwald 3558d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_dkg_dhk(void *arg){ 3559d1a1f6a4SMatthias Ringwald UNUSED(arg); 3560d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 356104678764SMatthias Ringwald 3562d1a1f6a4SMatthias Ringwald log_info_key("dhk", sm_persistent_dhk); 3563d1a1f6a4SMatthias Ringwald dkg_state = DKG_READY; 356470b44dd4SMatthias Ringwald sm_trigger_run(); 35657df18c15SMatthias Ringwald } 3566d1a1f6a4SMatthias Ringwald 3567d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_rau(void *arg){ 3568d1a1f6a4SMatthias Ringwald UNUSED(arg); 3569d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 357004678764SMatthias Ringwald 35716535961aSMatthias Ringwald (void)memcpy(&sm_random_address[3], &sm_aes128_ciphertext[13], 3); 3572e91ddb40SMatthias Ringwald rau_state = RAU_IDLE; 3573e91ddb40SMatthias Ringwald hci_le_random_address_set(sm_random_address); 3574e91ddb40SMatthias Ringwald 357570b44dd4SMatthias Ringwald sm_trigger_run(); 357651fa0b28SMatthias Ringwald } 35777df18c15SMatthias Ringwald 3578d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_rau(void * arg){ 3579d1a1f6a4SMatthias Ringwald UNUSED(arg); 35803deb3ec6SMatthias Ringwald // non-resolvable vs. resolvable 35813deb3ec6SMatthias Ringwald switch (gap_random_adress_type){ 35823deb3ec6SMatthias Ringwald case GAP_RANDOM_ADDRESS_RESOLVABLE: 35833deb3ec6SMatthias Ringwald // resolvable: use random as prand and calc address hash 35843deb3ec6SMatthias Ringwald // "The two most significant bits of prand shall be equal to ‘0’ and ‘1" 35854ea43905SMatthias Ringwald sm_random_address[0u] &= 0x3fu; 35864ea43905SMatthias Ringwald sm_random_address[0u] |= 0x40u; 35873deb3ec6SMatthias Ringwald rau_state = RAU_GET_ENC; 35883deb3ec6SMatthias Ringwald break; 35893deb3ec6SMatthias Ringwald case GAP_RANDOM_ADDRESS_NON_RESOLVABLE: 35903deb3ec6SMatthias Ringwald default: 35913deb3ec6SMatthias Ringwald // "The two most significant bits of the address shall be equal to ‘0’"" 35924ea43905SMatthias Ringwald sm_random_address[0u] &= 0x3fu; 35932954e6c6SMatthias Ringwald rau_state = RAU_IDLE; 3594e91ddb40SMatthias Ringwald hci_le_random_address_set(sm_random_address); 35953deb3ec6SMatthias Ringwald break; 35963deb3ec6SMatthias Ringwald } 359770b44dd4SMatthias Ringwald sm_trigger_run(); 35983deb3ec6SMatthias Ringwald } 35993deb3ec6SMatthias Ringwald 3600c59d0c92SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 36016ca80073SMatthias Ringwald static void sm_handle_random_result_sc_next_send_pairing_random(void * arg){ 3602f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3603f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3604f3582630SMatthias Ringwald if (connection == NULL) return; 3605c59d0c92SMatthias Ringwald 360665a9a04eSMatthias Ringwald connection->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM; 360770b44dd4SMatthias Ringwald sm_trigger_run(); 360865a9a04eSMatthias Ringwald } 3609d1a1f6a4SMatthias Ringwald 36106ca80073SMatthias Ringwald static void sm_handle_random_result_sc_next_w2_cmac_for_confirmation(void * arg){ 36116ca80073SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 36126ca80073SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 36136ca80073SMatthias Ringwald if (connection == NULL) return; 36146ca80073SMatthias Ringwald 3615b35a3de2SMatthias Ringwald connection->sm_engine_state = SM_SC_W2_CMAC_FOR_CONFIRMATION; 361670b44dd4SMatthias Ringwald sm_trigger_run(); 3617d1a1f6a4SMatthias Ringwald } 3618f1c1783eSMatthias Ringwald #endif 3619f1c1783eSMatthias Ringwald 3620d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph2_random(void * arg){ 3621f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3622f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3623f3582630SMatthias Ringwald if (connection == NULL) return; 3624f3582630SMatthias Ringwald 3625d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_GET_ENC_A; 362670b44dd4SMatthias Ringwald sm_trigger_run(); 3627d1a1f6a4SMatthias Ringwald } 3628d1a1f6a4SMatthias Ringwald 3629d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph2_tk(void * arg){ 3630f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3631f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3632f3582630SMatthias Ringwald if (connection == NULL) return; 3633f3582630SMatthias Ringwald 3634caf15bf3SMatthias Ringwald sm_reset_tk(); 3635caf15bf3SMatthias Ringwald uint32_t tk; 36365ce1359eSMatthias Ringwald if (sm_fixed_passkey_in_display_role == 0xffffffffU){ 36373deb3ec6SMatthias Ringwald // map random to 0-999999 without speding much cycles on a modulus operation 3638d1a1f6a4SMatthias Ringwald tk = little_endian_read_32(sm_random_data,0); 36393deb3ec6SMatthias Ringwald tk = tk & 0xfffff; // 1048575 36404ea43905SMatthias Ringwald if (tk >= 999999u){ 36414ea43905SMatthias Ringwald tk = tk - 999999u; 36423deb3ec6SMatthias Ringwald } 3643caf15bf3SMatthias Ringwald } else { 3644caf15bf3SMatthias Ringwald // override with pre-defined passkey 36454b8c611fSMatthias Ringwald tk = sm_fixed_passkey_in_display_role; 3646caf15bf3SMatthias Ringwald } 3647f8fbdce0SMatthias Ringwald big_endian_store_32(setup->sm_tk, 12, tk); 364842134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 36493deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE; 36503deb3ec6SMatthias Ringwald } else { 3651b41539d5SMatthias Ringwald if (setup->sm_use_secure_connections){ 3652b41539d5SMatthias Ringwald connection->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 3653b41539d5SMatthias Ringwald } else { 36543deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 36553deb3ec6SMatthias Ringwald sm_trigger_user_response(connection); 36563deb3ec6SMatthias Ringwald // response_idle == nothing <--> sm_trigger_user_response() did not require response 36573deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ 3658f3582630SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_random, 16, &sm_handle_random_result_ph2_random, (void *)(uintptr_t) connection->sm_handle); 36593deb3ec6SMatthias Ringwald } 36603deb3ec6SMatthias Ringwald } 3661b41539d5SMatthias Ringwald } 366270b44dd4SMatthias Ringwald sm_trigger_run(); 36633deb3ec6SMatthias Ringwald } 3664d1a1f6a4SMatthias Ringwald 3665d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph3_div(void * arg){ 3666f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3667f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3668f3582630SMatthias Ringwald if (connection == NULL) return; 3669f3582630SMatthias Ringwald 3670d1a1f6a4SMatthias Ringwald // use 16 bit from random value as div 3671d1a1f6a4SMatthias Ringwald setup->sm_local_div = big_endian_read_16(sm_random_data, 0); 3672d1a1f6a4SMatthias Ringwald log_info_hex16("div", setup->sm_local_div); 3673d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH3_Y_GET_ENC; 367470b44dd4SMatthias Ringwald sm_trigger_run(); 3675d1a1f6a4SMatthias Ringwald } 3676d1a1f6a4SMatthias Ringwald 3677d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph3_random(void * arg){ 3678f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3679f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3680f3582630SMatthias Ringwald if (connection == NULL) return; 3681f3582630SMatthias Ringwald 3682d1a1f6a4SMatthias Ringwald reverse_64(sm_random_data, setup->sm_local_rand); 36833deb3ec6SMatthias Ringwald // no db for encryption size hack: encryption size is stored in lowest nibble of setup->sm_local_rand 36844ea43905SMatthias Ringwald setup->sm_local_rand[7u] = (setup->sm_local_rand[7u] & 0xf0u) + (connection->sm_actual_encryption_key_size - 1u); 36853deb3ec6SMatthias Ringwald // no db for authenticated flag hack: store flag in bit 4 of LSB 36864ea43905SMatthias Ringwald setup->sm_local_rand[7u] = (setup->sm_local_rand[7u] & 0xefu) + (connection->sm_connection_authenticated << 4u); 36878b3ffec5SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 2, &sm_handle_random_result_ph3_div, (void *)(uintptr_t) connection->sm_handle); 36883deb3ec6SMatthias Ringwald } 3689899e6e02SMatthias Ringwald static void sm_validate_er_ir(void){ 3690899e6e02SMatthias Ringwald // warn about default ER/IR 36911979f09cSMatthias Ringwald bool warning = false; 3692899e6e02SMatthias Ringwald if (sm_ir_is_default()){ 36931979f09cSMatthias Ringwald warning = true; 3694899e6e02SMatthias Ringwald log_error("Persistent IR not set with sm_set_ir. Use of private addresses will cause pairing issues"); 3695899e6e02SMatthias Ringwald } 3696899e6e02SMatthias Ringwald if (sm_er_is_default()){ 36971979f09cSMatthias Ringwald warning = true; 3698899e6e02SMatthias Ringwald log_error("Persistent ER not set with sm_set_er. Legacy Pairing LTK is not secure"); 3699899e6e02SMatthias Ringwald } 370021045273SMatthias Ringwald if (warning) { 3701899e6e02SMatthias Ringwald log_error("Please configure btstack_tlv to let BTstack setup ER and IR keys"); 3702899e6e02SMatthias Ringwald } 370321045273SMatthias Ringwald } 3704899e6e02SMatthias Ringwald 3705899e6e02SMatthias Ringwald static void sm_handle_random_result_ir(void *arg){ 37061979f09cSMatthias Ringwald sm_persistent_keys_random_active = false; 37079305033eSMatthias Ringwald if (arg != NULL){ 3708899e6e02SMatthias Ringwald // key generated, store in tlv 37094ea43905SMatthias Ringwald int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16u); 3710899e6e02SMatthias Ringwald log_info("Generated IR key. Store in TLV status: %d", status); 3711e0d13a19SMilanka Ringwald UNUSED(status); 3712899e6e02SMatthias Ringwald } 3713899e6e02SMatthias Ringwald log_info_key("IR", sm_persistent_ir); 37148d9b6072SMatthias Ringwald dkg_state = DKG_CALC_IRK; 3715841468bbSMatthias Ringwald 3716841468bbSMatthias Ringwald if (test_use_fixed_local_irk){ 3717841468bbSMatthias Ringwald log_info_key("IRK", sm_persistent_irk); 3718841468bbSMatthias Ringwald dkg_state = DKG_CALC_DHK; 3719841468bbSMatthias Ringwald } 3720841468bbSMatthias Ringwald 372170b44dd4SMatthias Ringwald sm_trigger_run(); 3722899e6e02SMatthias Ringwald } 3723899e6e02SMatthias Ringwald 3724899e6e02SMatthias Ringwald static void sm_handle_random_result_er(void *arg){ 37251979f09cSMatthias Ringwald sm_persistent_keys_random_active = false; 37269305033eSMatthias Ringwald if (arg != 0){ 3727899e6e02SMatthias Ringwald // key generated, store in tlv 37284ea43905SMatthias Ringwald int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16u); 3729899e6e02SMatthias Ringwald log_info("Generated ER key. Store in TLV status: %d", status); 3730e0d13a19SMilanka Ringwald UNUSED(status); 3731899e6e02SMatthias Ringwald } 3732899e6e02SMatthias Ringwald log_info_key("ER", sm_persistent_er); 3733899e6e02SMatthias Ringwald 3734899e6e02SMatthias Ringwald // try load ir 37354ea43905SMatthias Ringwald int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16u); 3736899e6e02SMatthias Ringwald if (key_size == 16){ 3737899e6e02SMatthias Ringwald // ok, let's continue 3738899e6e02SMatthias Ringwald log_info("IR from TLV"); 3739899e6e02SMatthias Ringwald sm_handle_random_result_ir( NULL ); 3740899e6e02SMatthias Ringwald } else { 3741899e6e02SMatthias Ringwald // invalid, generate new random one 37421979f09cSMatthias Ringwald sm_persistent_keys_random_active = true; 3743899e6e02SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_ir, 16, &sm_handle_random_result_ir, &sm_persistent_ir); 3744899e6e02SMatthias Ringwald } 3745899e6e02SMatthias Ringwald } 37463deb3ec6SMatthias Ringwald 3747f664b5e8SMatthias Ringwald static void sm_connection_init(sm_connection_t * sm_conn, hci_con_handle_t con_handle, uint8_t role, uint8_t addr_type, bd_addr_t address){ 3748f664b5e8SMatthias Ringwald 3749f664b5e8SMatthias Ringwald // connection info 3750f664b5e8SMatthias Ringwald sm_conn->sm_handle = con_handle; 3751f664b5e8SMatthias Ringwald sm_conn->sm_role = role; 3752f664b5e8SMatthias Ringwald sm_conn->sm_peer_addr_type = addr_type; 3753f664b5e8SMatthias Ringwald memcpy(sm_conn->sm_peer_address, address, 6); 3754f664b5e8SMatthias Ringwald 3755f664b5e8SMatthias Ringwald // security properties 3756f664b5e8SMatthias Ringwald sm_conn->sm_connection_encrypted = 0; 3757f664b5e8SMatthias Ringwald sm_conn->sm_connection_authenticated = 0; 3758f664b5e8SMatthias Ringwald sm_conn->sm_connection_authorization_state = AUTHORIZATION_UNKNOWN; 3759f664b5e8SMatthias Ringwald sm_conn->sm_le_db_index = -1; 3760f664b5e8SMatthias Ringwald sm_conn->sm_reencryption_active = false; 3761f664b5e8SMatthias Ringwald 3762f664b5e8SMatthias Ringwald // prepare CSRK lookup (does not involve setup) 3763f664b5e8SMatthias Ringwald sm_conn->sm_irk_lookup_state = IRK_LOOKUP_W4_READY; 3764f664b5e8SMatthias Ringwald 3765f664b5e8SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_IDLE; 3766f664b5e8SMatthias Ringwald } 3767f664b5e8SMatthias Ringwald 3768599e89daSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 3769599e89daSMatthias Ringwald static void sm_event_handle_classic_encryption_event(sm_connection_t * sm_conn, hci_con_handle_t con_handle){ 3770599e89daSMatthias Ringwald // CTKD requires BR/EDR Secure Connection 3771599e89daSMatthias Ringwald if (sm_conn->sm_connection_encrypted != 2) return; 3772599e89daSMatthias Ringwald // prepare for pairing request 3773599e89daSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 3774599e89daSMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_RESPONDER_W4_PAIRING_REQUEST; 3775599e89daSMatthias Ringwald } else if (sm_conn->sm_pairing_requested){ 3776599e89daSMatthias Ringwald // check if remote supports fixed channels 3777599e89daSMatthias Ringwald bool defer = true; 3778599e89daSMatthias Ringwald const hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); 3779599e89daSMatthias Ringwald if (hci_connection->l2cap_state.information_state == L2CAP_INFORMATION_STATE_DONE){ 3780599e89daSMatthias Ringwald // check if remote supports SMP over BR/EDR 3781599e89daSMatthias Ringwald if ((hci_connection->l2cap_state.fixed_channels_supported & (1 << L2CAP_CID_BR_EDR_SECURITY_MANAGER)) != 0){ 3782599e89daSMatthias Ringwald log_info("CTKD: SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST"); 3783599e89daSMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST; 3784599e89daSMatthias Ringwald } else { 3785599e89daSMatthias Ringwald defer = false; 3786599e89daSMatthias Ringwald } 3787599e89daSMatthias Ringwald } else { 3788599e89daSMatthias Ringwald // wait for fixed channel info 3789599e89daSMatthias Ringwald log_info("CTKD: SM_BR_EDR_INITIATOR_W4_FIXED_CHANNEL_MASK"); 3790599e89daSMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_INITIATOR_W4_FIXED_CHANNEL_MASK; 3791599e89daSMatthias Ringwald } 3792599e89daSMatthias Ringwald if (defer){ 3793599e89daSMatthias Ringwald hci_dedicated_bonding_defer_disconnect(con_handle, true); 3794599e89daSMatthias Ringwald } 3795599e89daSMatthias Ringwald } 3796599e89daSMatthias Ringwald } 3797599e89daSMatthias Ringwald #endif 3798599e89daSMatthias Ringwald 3799d9a7306aSMatthias Ringwald static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 38003deb3ec6SMatthias Ringwald 3801cbdfe9f7SMatthias Ringwald UNUSED(channel); // ok: there is no channel 3802cbdfe9f7SMatthias Ringwald UNUSED(size); // ok: fixed format HCI events 38039ec2630cSMatthias Ringwald 38043deb3ec6SMatthias Ringwald sm_connection_t * sm_conn; 3805711e6c80SMatthias Ringwald hci_con_handle_t con_handle; 3806fbe050beSMatthias Ringwald uint8_t status; 3807f664b5e8SMatthias Ringwald bd_addr_t addr; 3808f664b5e8SMatthias Ringwald 38093deb3ec6SMatthias Ringwald switch (packet_type) { 38103deb3ec6SMatthias Ringwald 38113deb3ec6SMatthias Ringwald case HCI_EVENT_PACKET: 38120e2df43fSMatthias Ringwald switch (hci_event_packet_get_type(packet)) { 38133deb3ec6SMatthias Ringwald 38143deb3ec6SMatthias Ringwald case BTSTACK_EVENT_STATE: 3815745015f6SMatthias Ringwald switch (btstack_event_state_get_state(packet)){ 3816745015f6SMatthias Ringwald case HCI_STATE_WORKING: 38173deb3ec6SMatthias Ringwald log_info("HCI Working!"); 3818899e6e02SMatthias Ringwald // setup IR/ER with TLV 3819899e6e02SMatthias Ringwald btstack_tlv_get_instance(&sm_tlv_impl, &sm_tlv_context); 38209305033eSMatthias Ringwald if (sm_tlv_impl != NULL){ 38214ea43905SMatthias Ringwald int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16u); 3822899e6e02SMatthias Ringwald if (key_size == 16){ 3823899e6e02SMatthias Ringwald // ok, let's continue 3824899e6e02SMatthias Ringwald log_info("ER from TLV"); 3825899e6e02SMatthias Ringwald sm_handle_random_result_er( NULL ); 3826899e6e02SMatthias Ringwald } else { 3827899e6e02SMatthias Ringwald // invalid, generate random one 38281979f09cSMatthias Ringwald sm_persistent_keys_random_active = true; 3829899e6e02SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_er, 16, &sm_handle_random_result_er, &sm_persistent_er); 3830899e6e02SMatthias Ringwald } 3831899e6e02SMatthias Ringwald } else { 3832899e6e02SMatthias Ringwald sm_validate_er_ir(); 38338d9b6072SMatthias Ringwald dkg_state = DKG_CALC_IRK; 3834841468bbSMatthias Ringwald 3835841468bbSMatthias Ringwald if (test_use_fixed_local_irk){ 3836841468bbSMatthias Ringwald log_info_key("IRK", sm_persistent_irk); 3837841468bbSMatthias Ringwald dkg_state = DKG_CALC_DHK; 3838841468bbSMatthias Ringwald } 3839899e6e02SMatthias Ringwald } 38401bf086daSMatthias Ringwald 384115211b85SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 384215211b85SMatthias Ringwald // trigger ECC key generation 384315211b85SMatthias Ringwald if (ec_key_generation_state == EC_KEY_GENERATION_IDLE){ 384415211b85SMatthias Ringwald sm_ec_generate_new_key(); 384515211b85SMatthias Ringwald } 384615211b85SMatthias Ringwald #endif 384715211b85SMatthias Ringwald 38481bf086daSMatthias Ringwald // restart random address updates after power cycle 38494a688bd1SMatthias Ringwald if (gap_random_adress_type == GAP_RANDOM_ADDRESS_TYPE_STATIC){ 38504a688bd1SMatthias Ringwald gap_random_address_set(sm_random_address); 38514a688bd1SMatthias Ringwald } else { 38521bf086daSMatthias Ringwald gap_random_address_set_mode(gap_random_adress_type); 38534a688bd1SMatthias Ringwald } 3854745015f6SMatthias Ringwald break; 3855745015f6SMatthias Ringwald 3856745015f6SMatthias Ringwald case HCI_STATE_OFF: 38577f775357SMatthias Ringwald case HCI_STATE_HALTING: 3858cbdd51cfSMatthias Ringwald log_info("SM: reset state"); 3859745015f6SMatthias Ringwald // stop random address update 3860745015f6SMatthias Ringwald gap_random_address_update_stop(); 3861cbdd51cfSMatthias Ringwald // reset state 3862cbdd51cfSMatthias Ringwald sm_state_reset(); 3863745015f6SMatthias Ringwald break; 3864745015f6SMatthias Ringwald 3865745015f6SMatthias Ringwald default: 3866745015f6SMatthias Ringwald break; 38673deb3ec6SMatthias Ringwald } 38683deb3ec6SMatthias Ringwald break; 3869c18be159SMatthias Ringwald 38702d095694SMatthias Ringwald #ifdef ENABLE_CLASSIC 38712d095694SMatthias Ringwald case HCI_EVENT_CONNECTION_COMPLETE: 38722d095694SMatthias Ringwald // ignore if connection failed 38732d095694SMatthias Ringwald if (hci_event_connection_complete_get_status(packet)) return; 38743deb3ec6SMatthias Ringwald 38752d095694SMatthias Ringwald con_handle = hci_event_connection_complete_get_connection_handle(packet); 38762d095694SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 38772d095694SMatthias Ringwald if (!sm_conn) break; 38782d095694SMatthias Ringwald 38792d095694SMatthias Ringwald hci_event_connection_complete_get_bd_addr(packet, addr); 38802d095694SMatthias Ringwald sm_connection_init(sm_conn, 38812d095694SMatthias Ringwald con_handle, 38822d095694SMatthias Ringwald (uint8_t) gap_get_role(con_handle), 3883f72f7944SMatthias Ringwald BD_ADDR_TYPE_LE_PUBLIC, 38842d095694SMatthias Ringwald addr); 38852d095694SMatthias Ringwald // classic connection corresponds to public le address 38862d095694SMatthias Ringwald sm_conn->sm_own_addr_type = BD_ADDR_TYPE_LE_PUBLIC; 38872d095694SMatthias Ringwald gap_local_bd_addr(sm_conn->sm_own_address); 38882d095694SMatthias Ringwald sm_conn->sm_cid = L2CAP_CID_BR_EDR_SECURITY_MANAGER; 3889c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_W4_ENCRYPTION_COMPLETE; 38902d095694SMatthias Ringwald break; 38912d095694SMatthias Ringwald #endif 3892c18be159SMatthias Ringwald 3893c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 3894c18be159SMatthias Ringwald case HCI_EVENT_SIMPLE_PAIRING_COMPLETE: 3895c18be159SMatthias Ringwald if (hci_event_simple_pairing_complete_get_status(packet) != ERROR_CODE_SUCCESS) break; 3896c18be159SMatthias Ringwald hci_event_simple_pairing_complete_get_bd_addr(packet, addr); 3897c18be159SMatthias Ringwald sm_conn = sm_get_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL); 3898c18be159SMatthias Ringwald if (sm_conn == NULL) break; 38995f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 3900c18be159SMatthias Ringwald break; 3901c18be159SMatthias Ringwald #endif 3902c18be159SMatthias Ringwald 39039d1eff91SMatthias Ringwald case HCI_EVENT_META_GAP: 39049d1eff91SMatthias Ringwald switch (hci_event_gap_meta_get_subevent_code(packet)) { 39059d1eff91SMatthias Ringwald case GAP_SUBEVENT_LE_CONNECTION_COMPLETE: 3906f664b5e8SMatthias Ringwald // ignore if connection failed 39079d1eff91SMatthias Ringwald if (gap_subevent_le_connection_complete_get_status(packet) != ERROR_CODE_SUCCESS) break; 39083deb3ec6SMatthias Ringwald 39099d1eff91SMatthias Ringwald con_handle = gap_subevent_le_connection_complete_get_connection_handle(packet); 3910711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 39113deb3ec6SMatthias Ringwald if (!sm_conn) break; 39123deb3ec6SMatthias Ringwald 39139d1eff91SMatthias Ringwald gap_subevent_le_connection_complete_get_peer_address(packet, addr); 3914f664b5e8SMatthias Ringwald sm_connection_init(sm_conn, 3915f664b5e8SMatthias Ringwald con_handle, 39169d1eff91SMatthias Ringwald gap_subevent_le_connection_complete_get_role(packet), 39179d1eff91SMatthias Ringwald gap_subevent_le_connection_complete_get_peer_address_type(packet), 3918f664b5e8SMatthias Ringwald addr); 3919687a03c8SMatthias Ringwald sm_conn->sm_cid = L2CAP_CID_SECURITY_MANAGER_PROTOCOL; 3920f664b5e8SMatthias Ringwald 3921f664b5e8SMatthias Ringwald // track our addr used for this connection and set state 3922b6f39a74SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 39239d1eff91SMatthias Ringwald if (gap_subevent_le_connection_complete_get_role(packet) != 0){ 3924ba9fc867SMatthias Ringwald // responder - use own address from advertisements 3925ba9fc867SMatthias Ringwald gap_le_get_own_advertisements_address(&sm_conn->sm_own_addr_type, sm_conn->sm_own_address); 3926f664b5e8SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 3927b892db1cSMatthias Ringwald } 3928b892db1cSMatthias Ringwald #endif 3929b892db1cSMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 39309d1eff91SMatthias Ringwald if (gap_subevent_le_connection_complete_get_role(packet) == 0){ 3931ba9fc867SMatthias Ringwald // initiator - use own address from create connection 3932ba9fc867SMatthias Ringwald gap_le_get_own_connection_address(&sm_conn->sm_own_addr_type, sm_conn->sm_own_address); 39333deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 39343deb3ec6SMatthias Ringwald } 3935b892db1cSMatthias Ringwald #endif 39363deb3ec6SMatthias Ringwald break; 39379d1eff91SMatthias Ringwald default: 39389d1eff91SMatthias Ringwald break; 39399d1eff91SMatthias Ringwald } 39409d1eff91SMatthias Ringwald break; 39419d1eff91SMatthias Ringwald case HCI_EVENT_LE_META: 39429d1eff91SMatthias Ringwald switch (hci_event_le_meta_get_subevent_code(packet)) { 39433deb3ec6SMatthias Ringwald case HCI_SUBEVENT_LE_LONG_TERM_KEY_REQUEST: 39449d1eff91SMatthias Ringwald con_handle = hci_subevent_le_long_term_key_request_get_connection_handle(packet); 3945711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 39463deb3ec6SMatthias Ringwald if (!sm_conn) break; 39473deb3ec6SMatthias Ringwald 39483deb3ec6SMatthias Ringwald log_info("LTK Request: state %u", sm_conn->sm_engine_state); 39493deb3ec6SMatthias Ringwald if (sm_conn->sm_engine_state == SM_RESPONDER_PH2_W4_LTK_REQUEST){ 39503deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_CALC_STK; 39513deb3ec6SMatthias Ringwald break; 39523deb3ec6SMatthias Ringwald } 3953c6b7cbd9SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_LTK_REQUEST_SC){ 3954778b6aadSMatthias Ringwald // PH2 SEND LTK as we need to exchange keys in PH3 3955778b6aadSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH2_SEND_LTK_REPLY; 3956e53be891SMatthias Ringwald break; 3957e53be891SMatthias Ringwald } 39583deb3ec6SMatthias Ringwald 39593deb3ec6SMatthias Ringwald // store rand and ediv 39609c80e4ccSMatthias Ringwald reverse_64(&packet[5], sm_conn->sm_local_rand); 39619d1eff91SMatthias Ringwald sm_conn->sm_local_ediv = hci_subevent_le_long_term_key_request_get_encryption_diversifier(packet); 3962549ad5d2SMatthias Ringwald 3963549ad5d2SMatthias Ringwald // For Legacy Pairing (<=> EDIV != 0 || RAND != NULL), we need to recalculated our LTK as a 3964549ad5d2SMatthias Ringwald // potentially stored LTK is from the master 39654ea43905SMatthias Ringwald if ((sm_conn->sm_local_ediv != 0u) || !sm_is_null_random(sm_conn->sm_local_rand)){ 39666c39055aSMatthias Ringwald if (sm_reconstruct_ltk_without_le_device_db_entry){ 396706cd539fSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST; 3968549ad5d2SMatthias Ringwald break; 3969549ad5d2SMatthias Ringwald } 39706c39055aSMatthias Ringwald // additionally check if remote is in LE Device DB if requested 39716c39055aSMatthias Ringwald switch(sm_conn->sm_irk_lookup_state){ 39726c39055aSMatthias Ringwald case IRK_LOOKUP_FAILED: 39736c39055aSMatthias Ringwald log_info("LTK Request: device not in device db"); 39746c39055aSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY; 39756c39055aSMatthias Ringwald break; 39766c39055aSMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 39776c39055aSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST; 39786c39055aSMatthias Ringwald break; 39796c39055aSMatthias Ringwald default: 39806c39055aSMatthias Ringwald // wait for irk look doen 39816c39055aSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK; 39826c39055aSMatthias Ringwald break; 39836c39055aSMatthias Ringwald } 39846c39055aSMatthias Ringwald break; 39856c39055aSMatthias Ringwald } 3986549ad5d2SMatthias Ringwald 3987549ad5d2SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 398806cd539fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_RECEIVED_LTK_REQUEST; 3989549ad5d2SMatthias Ringwald #else 3990549ad5d2SMatthias Ringwald log_info("LTK Request: ediv & random are empty, but LE Secure Connections not supported"); 3991549ad5d2SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY; 3992549ad5d2SMatthias Ringwald #endif 39933deb3ec6SMatthias Ringwald break; 3994804d3e67SMatthias Ringwald 39953deb3ec6SMatthias Ringwald default: 39963deb3ec6SMatthias Ringwald break; 39973deb3ec6SMatthias Ringwald } 39983deb3ec6SMatthias Ringwald break; 39993deb3ec6SMatthias Ringwald 40003deb3ec6SMatthias Ringwald case HCI_EVENT_ENCRYPTION_CHANGE: 40018601e696SMatthias Ringwald case HCI_EVENT_ENCRYPTION_CHANGE_V2: 40023b7fd749SMatthias Ringwald con_handle = hci_event_encryption_change_get_connection_handle(packet); 4003711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 40043deb3ec6SMatthias Ringwald if (!sm_conn) break; 40053deb3ec6SMatthias Ringwald 40063b7fd749SMatthias Ringwald sm_conn->sm_connection_encrypted = hci_event_encryption_change_get_encryption_enabled(packet); 40073deb3ec6SMatthias Ringwald log_info("Encryption state change: %u, key size %u", sm_conn->sm_connection_encrypted, 40083deb3ec6SMatthias Ringwald sm_conn->sm_actual_encryption_key_size); 40093deb3ec6SMatthias Ringwald log_info("event handler, state %u", sm_conn->sm_engine_state); 401003a9359aSMatthias Ringwald 4011fbe050beSMatthias Ringwald switch (sm_conn->sm_engine_state){ 4012fbe050beSMatthias Ringwald 40135567aa60SMatthias Ringwald case SM_PH4_W4_CONNECTION_ENCRYPTED: 401403a9359aSMatthias Ringwald // encryption change event concludes re-encryption for bonded devices (even if it fails) 40151d80f1e6SMatthias Ringwald if (sm_conn->sm_connection_encrypted != 0u) { 4016fbe050beSMatthias Ringwald status = ERROR_CODE_SUCCESS; 40171d80f1e6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 40188d4eef95SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 40198d4eef95SMatthias Ringwald } else { 402003a9359aSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 40218d4eef95SMatthias Ringwald } 4022fbe050beSMatthias Ringwald } else { 4023e28291c1SMatthias Ringwald status = hci_event_encryption_change_get_status(packet); 4024cb6d7eb0SMatthias Ringwald // set state to 'RE-ENCRYPTION FAILED' to allow pairing but prevent other interactions 40253b7fd749SMatthias Ringwald // also, gap_reconnect_security_setup_active will return true 4026cb6d7eb0SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_REENCRYPTION_FAILED; 40273b7fd749SMatthias Ringwald } 4028fbe050beSMatthias Ringwald 4029fbe050beSMatthias Ringwald // emit re-encryption complete 403073102768SMatthias Ringwald sm_reencryption_complete(sm_conn, status); 4031fbe050beSMatthias Ringwald 4032c245ca32SMatthias Ringwald // notify client, if pairing was requested before 4033c245ca32SMatthias Ringwald if (sm_conn->sm_pairing_requested){ 40345f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = false; 40350ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, status, 0); 403603a9359aSMatthias Ringwald } 403703a9359aSMatthias Ringwald 40383deb3ec6SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 40393deb3ec6SMatthias Ringwald break; 4040fbe050beSMatthias Ringwald 40413deb3ec6SMatthias Ringwald case SM_PH2_W4_CONNECTION_ENCRYPTED: 4042fbe050beSMatthias Ringwald if (!sm_conn->sm_connection_encrypted) break; 404357ff4745SMatthias Ringwald // handler for HCI_EVENT_ENCRYPTION_KEY_REFRESH_COMPLETE 404457ff4745SMatthias Ringwald // contains the same code for this state 4045dd583d9fSMatthias Ringwald sm_conn->sm_connection_sc = setup->sm_use_secure_connections; 404642134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 40473deb3ec6SMatthias Ringwald // slave 404857ff4745SMatthias Ringwald if (sm_conn->sm_connection_sc){ 4049bbf8db22SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 4050bbf8db22SMatthias Ringwald } else { 4051f3582630SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph3_random, (void *)(uintptr_t) sm_conn->sm_handle); 4052bbf8db22SMatthias Ringwald } 40533deb3ec6SMatthias Ringwald } else { 40543deb3ec6SMatthias Ringwald // master 405561d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 40563deb3ec6SMatthias Ringwald // skip receiving keys as there are none 40573deb3ec6SMatthias Ringwald sm_key_distribution_handle_all_received(sm_conn); 4058f3582630SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph3_random, (void *)(uintptr_t) sm_conn->sm_handle); 40593deb3ec6SMatthias Ringwald } else { 40603deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS; 40613deb3ec6SMatthias Ringwald } 40623deb3ec6SMatthias Ringwald } 40633deb3ec6SMatthias Ringwald break; 4064c18be159SMatthias Ringwald 4065c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 4066c18be159SMatthias Ringwald case SM_BR_EDR_W4_ENCRYPTION_COMPLETE: 4067599e89daSMatthias Ringwald sm_event_handle_classic_encryption_event(sm_conn, con_handle); 4068c18be159SMatthias Ringwald break; 4069c18be159SMatthias Ringwald #endif 40703deb3ec6SMatthias Ringwald default: 40713deb3ec6SMatthias Ringwald break; 40723deb3ec6SMatthias Ringwald } 40733deb3ec6SMatthias Ringwald break; 40743deb3ec6SMatthias Ringwald 40753deb3ec6SMatthias Ringwald case HCI_EVENT_ENCRYPTION_KEY_REFRESH_COMPLETE: 4076711e6c80SMatthias Ringwald con_handle = little_endian_read_16(packet, 3); 4077711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 40783deb3ec6SMatthias Ringwald if (!sm_conn) break; 40793deb3ec6SMatthias Ringwald 40803deb3ec6SMatthias Ringwald log_info("Encryption key refresh complete, key size %u", sm_conn->sm_actual_encryption_key_size); 40813deb3ec6SMatthias Ringwald log_info("event handler, state %u", sm_conn->sm_engine_state); 40823deb3ec6SMatthias Ringwald // continue if part of initial pairing 40833deb3ec6SMatthias Ringwald switch (sm_conn->sm_engine_state){ 40845567aa60SMatthias Ringwald case SM_PH4_W4_CONNECTION_ENCRYPTED: 40851d80f1e6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 40865567aa60SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 40875567aa60SMatthias Ringwald } else { 40883deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 40895567aa60SMatthias Ringwald } 40903deb3ec6SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 40913deb3ec6SMatthias Ringwald break; 40923deb3ec6SMatthias Ringwald case SM_PH2_W4_CONNECTION_ENCRYPTED: 409357ff4745SMatthias Ringwald // handler for HCI_EVENT_ENCRYPTION_CHANGE 409457ff4745SMatthias Ringwald // contains the same code for this state 409557ff4745SMatthias Ringwald sm_conn->sm_connection_sc = setup->sm_use_secure_connections; 409642134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 40973deb3ec6SMatthias Ringwald // slave 409857ff4745SMatthias Ringwald if (sm_conn->sm_connection_sc){ 409957ff4745SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 410057ff4745SMatthias Ringwald } else { 4101f3582630SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph3_random, (void *)(uintptr_t) sm_conn->sm_handle); 410257ff4745SMatthias Ringwald } 41033deb3ec6SMatthias Ringwald } else { 41043deb3ec6SMatthias Ringwald // master 410557ff4745SMatthias Ringwald if (sm_key_distribution_all_received()){ 410657ff4745SMatthias Ringwald // skip receiving keys as there are none 410757ff4745SMatthias Ringwald sm_key_distribution_handle_all_received(sm_conn); 410857ff4745SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph3_random, (void *)(uintptr_t) sm_conn->sm_handle); 410957ff4745SMatthias Ringwald } else { 41103deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS; 41113deb3ec6SMatthias Ringwald } 411257ff4745SMatthias Ringwald } 41133deb3ec6SMatthias Ringwald break; 411494219034SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 411594219034SMatthias Ringwald case SM_BR_EDR_W4_ENCRYPTION_COMPLETE: 411694219034SMatthias Ringwald sm_event_handle_classic_encryption_event(sm_conn, con_handle); 411794219034SMatthias Ringwald break; 411894219034SMatthias Ringwald #endif 41193deb3ec6SMatthias Ringwald default: 41203deb3ec6SMatthias Ringwald break; 41213deb3ec6SMatthias Ringwald } 41223deb3ec6SMatthias Ringwald break; 41233deb3ec6SMatthias Ringwald 41243deb3ec6SMatthias Ringwald 41253deb3ec6SMatthias Ringwald case HCI_EVENT_DISCONNECTION_COMPLETE: 4126711e6c80SMatthias Ringwald con_handle = little_endian_read_16(packet, 3); 4127711e6c80SMatthias Ringwald sm_done_for_handle(con_handle); 4128711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 41293deb3ec6SMatthias Ringwald if (!sm_conn) break; 41303deb3ec6SMatthias Ringwald 413103f736b1SMatthias Ringwald // pairing failed, if it was ongoing 41327f3f442dSMatthias Ringwald switch (sm_conn->sm_engine_state){ 41337f3f442dSMatthias Ringwald case SM_GENERAL_IDLE: 41347f3f442dSMatthias Ringwald case SM_INITIATOR_CONNECTED: 41357f3f442dSMatthias Ringwald case SM_RESPONDER_IDLE: 41367f3f442dSMatthias Ringwald break; 41377f3f442dSMatthias Ringwald default: 413868a18fb9SMatthias Ringwald sm_reencryption_complete(sm_conn, ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION); 41390ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION, 0); 41407f3f442dSMatthias Ringwald break; 414103f736b1SMatthias Ringwald } 4142accbde80SMatthias Ringwald 41433deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_IDLE; 41443deb3ec6SMatthias Ringwald sm_conn->sm_handle = 0; 41453deb3ec6SMatthias Ringwald break; 41463deb3ec6SMatthias Ringwald 41473deb3ec6SMatthias Ringwald case HCI_EVENT_COMMAND_COMPLETE: 4148f7811256SMatthias Ringwald if (hci_event_command_complete_get_command_opcode(packet) == HCI_OPCODE_HCI_READ_BD_ADDR) { 41499091c5f5SMatthias Ringwald // set local addr for le device db 415033373e40SMatthias Ringwald reverse_bd_addr(&packet[OFFSET_OF_DATA_IN_COMMAND_COMPLETE + 1], addr); 41510c130b19SMatthias Ringwald le_device_db_set_local_bd_addr(addr); 415233373e40SMatthias Ringwald } 415365b44ffdSMatthias Ringwald break; 4154a036ae12SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 4155a036ae12SMatthias Ringwald case L2CAP_EVENT_INFORMATION_RESPONSE: 4156a036ae12SMatthias Ringwald con_handle = l2cap_event_information_response_get_con_handle(packet); 4157a036ae12SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 4158a036ae12SMatthias Ringwald if (!sm_conn) break; 4159a036ae12SMatthias Ringwald if (sm_conn->sm_engine_state == SM_BR_EDR_INITIATOR_W4_FIXED_CHANNEL_MASK){ 4160a036ae12SMatthias Ringwald // check if remote supports SMP over BR/EDR 4161a036ae12SMatthias Ringwald const hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); 4162a036ae12SMatthias Ringwald if ((hci_connection->l2cap_state.fixed_channels_supported & (1 << L2CAP_CID_BR_EDR_SECURITY_MANAGER)) != 0){ 4163a036ae12SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST; 4164a036ae12SMatthias Ringwald } else { 4165a036ae12SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 4166f82b8f4bSMatthias Ringwald hci_dedicated_bonding_defer_disconnect(con_handle, false); 4167a036ae12SMatthias Ringwald } 4168a036ae12SMatthias Ringwald } 4169a036ae12SMatthias Ringwald break; 4170a036ae12SMatthias Ringwald #endif 417165b44ffdSMatthias Ringwald default: 417265b44ffdSMatthias Ringwald break; 41733deb3ec6SMatthias Ringwald } 417465b44ffdSMatthias Ringwald break; 417565b44ffdSMatthias Ringwald default: 417665b44ffdSMatthias Ringwald break; 41773deb3ec6SMatthias Ringwald } 41783deb3ec6SMatthias Ringwald 41793deb3ec6SMatthias Ringwald sm_run(); 41803deb3ec6SMatthias Ringwald } 41813deb3ec6SMatthias Ringwald 41823deb3ec6SMatthias Ringwald static inline int sm_calc_actual_encryption_key_size(int other){ 41833deb3ec6SMatthias Ringwald if (other < sm_min_encryption_key_size) return 0; 41843deb3ec6SMatthias Ringwald if (other < sm_max_encryption_key_size) return other; 41853deb3ec6SMatthias Ringwald return sm_max_encryption_key_size; 41863deb3ec6SMatthias Ringwald } 41873deb3ec6SMatthias Ringwald 4188945888f5SMatthias Ringwald 418931c09488SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 41901d80f1e6SMatthias Ringwald static bool sm_just_works_or_numeric_comparison(stk_generation_method_t method){ 4191945888f5SMatthias Ringwald switch (method){ 4192945888f5SMatthias Ringwald case JUST_WORKS: 419347fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 41941d80f1e6SMatthias Ringwald return true; 4195945888f5SMatthias Ringwald default: 41961d80f1e6SMatthias Ringwald return false; 4197945888f5SMatthias Ringwald } 4198945888f5SMatthias Ringwald } 419907036a04SMatthias Ringwald // responder 4200945888f5SMatthias Ringwald 42011d80f1e6SMatthias Ringwald static bool sm_passkey_used(stk_generation_method_t method){ 4202688a08f9SMatthias Ringwald switch (method){ 4203688a08f9SMatthias Ringwald case PK_RESP_INPUT: 42041d80f1e6SMatthias Ringwald return true; 4205688a08f9SMatthias Ringwald default: 4206688a08f9SMatthias Ringwald return 0; 4207688a08f9SMatthias Ringwald } 4208688a08f9SMatthias Ringwald } 420940c5d850SMatthias Ringwald 42106777d8fdSMatthias Ringwald static bool sm_passkey_entry(stk_generation_method_t method){ 421140c5d850SMatthias Ringwald switch (method){ 421240c5d850SMatthias Ringwald case PK_RESP_INPUT: 421340c5d850SMatthias Ringwald case PK_INIT_INPUT: 421447fb4255SMatthias Ringwald case PK_BOTH_INPUT: 42156777d8fdSMatthias Ringwald return true; 421640c5d850SMatthias Ringwald default: 42176777d8fdSMatthias Ringwald return false; 421840c5d850SMatthias Ringwald } 421940c5d850SMatthias Ringwald } 422040c5d850SMatthias Ringwald 422131c09488SMatthias Ringwald #endif 4222688a08f9SMatthias Ringwald 42233deb3ec6SMatthias Ringwald /** 42243deb3ec6SMatthias Ringwald * @return ok 42253deb3ec6SMatthias Ringwald */ 42263deb3ec6SMatthias Ringwald static int sm_validate_stk_generation_method(void){ 42273deb3ec6SMatthias Ringwald // check if STK generation method is acceptable by client 42283deb3ec6SMatthias Ringwald switch (setup->sm_stk_generation_method){ 42293deb3ec6SMatthias Ringwald case JUST_WORKS: 42304ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_JUST_WORKS) != 0u; 42313deb3ec6SMatthias Ringwald case PK_RESP_INPUT: 42323deb3ec6SMatthias Ringwald case PK_INIT_INPUT: 423347fb4255SMatthias Ringwald case PK_BOTH_INPUT: 42344ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_PASSKEY) != 0u; 42353deb3ec6SMatthias Ringwald case OOB: 42364ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_OOB) != 0u; 423747fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 42384ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_NUMERIC_COMPARISON) != 0u; 42393deb3ec6SMatthias Ringwald default: 42403deb3ec6SMatthias Ringwald return 0; 42413deb3ec6SMatthias Ringwald } 42423deb3ec6SMatthias Ringwald } 42433deb3ec6SMatthias Ringwald 424436f0defaSMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 424536f0defaSMatthias Ringwald static void sm_initiator_connected_handle_security_request(sm_connection_t * sm_conn, const uint8_t *packet){ 424636f0defaSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 424736f0defaSMatthias Ringwald if (sm_sc_only_mode){ 424836f0defaSMatthias Ringwald uint8_t auth_req = packet[1]; 424936f0defaSMatthias Ringwald if ((auth_req & SM_AUTHREQ_SECURE_CONNECTION) == 0){ 425036f0defaSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_AUTHENTHICATION_REQUIREMENTS); 425136f0defaSMatthias Ringwald return; 425236f0defaSMatthias Ringwald } 425336f0defaSMatthias Ringwald } 425436f0defaSMatthias Ringwald #else 425536f0defaSMatthias Ringwald UNUSED(packet); 425636f0defaSMatthias Ringwald #endif 425736f0defaSMatthias Ringwald 425836f0defaSMatthias Ringwald int have_ltk; 425936f0defaSMatthias Ringwald uint8_t ltk[16]; 426036f0defaSMatthias Ringwald 426136f0defaSMatthias Ringwald // IRK complete? 426236f0defaSMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 426336f0defaSMatthias Ringwald case IRK_LOOKUP_FAILED: 426436f0defaSMatthias Ringwald // start pairing 426536f0defaSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 426636f0defaSMatthias Ringwald break; 426736f0defaSMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 426836f0defaSMatthias Ringwald le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); 426936f0defaSMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 427036f0defaSMatthias Ringwald log_info("central: security request - have_ltk %u, encryption %u", have_ltk, sm_conn->sm_connection_encrypted); 427136f0defaSMatthias Ringwald if (have_ltk && (sm_conn->sm_connection_encrypted == 0)){ 427236f0defaSMatthias Ringwald // start re-encrypt if we have LTK and the connection is not already encrypted 427336f0defaSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH4_HAS_LTK; 427436f0defaSMatthias Ringwald } else { 427536f0defaSMatthias Ringwald // start pairing 427636f0defaSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 427736f0defaSMatthias Ringwald } 427836f0defaSMatthias Ringwald break; 427936f0defaSMatthias Ringwald default: 428036f0defaSMatthias Ringwald // otherwise, store security request 42810dcaa15fSMatthias Ringwald sm_conn->sm_security_request_received = true; 428236f0defaSMatthias Ringwald break; 428336f0defaSMatthias Ringwald } 428436f0defaSMatthias Ringwald } 428536f0defaSMatthias Ringwald #endif 428636f0defaSMatthias Ringwald 4287f9bda154SMatthias Ringwald static uint8_t sm_pdu_validate_and_get_opcode(uint8_t packet_type, const uint8_t *packet, uint16_t size){ 42888334d3d8SMatthias Ringwald 42894c1d1092SMatthias Ringwald // size of complete sm_pdu used to validate input 42904c1d1092SMatthias Ringwald static const uint8_t sm_pdu_size[] = { 42914c1d1092SMatthias Ringwald 0, // 0x00 invalid opcode 42924c1d1092SMatthias Ringwald 7, // 0x01 pairing request 42934c1d1092SMatthias Ringwald 7, // 0x02 pairing response 42944c1d1092SMatthias Ringwald 17, // 0x03 pairing confirm 42954c1d1092SMatthias Ringwald 17, // 0x04 pairing random 42964c1d1092SMatthias Ringwald 2, // 0x05 pairing failed 42974c1d1092SMatthias Ringwald 17, // 0x06 encryption information 42987a2e6387SMatthias Ringwald 11, // 0x07 master identification 42994c1d1092SMatthias Ringwald 17, // 0x08 identification information 43004c1d1092SMatthias Ringwald 8, // 0x09 identify address information 43014c1d1092SMatthias Ringwald 17, // 0x0a signing information 43024c1d1092SMatthias Ringwald 2, // 0x0b security request 43034c1d1092SMatthias Ringwald 65, // 0x0c pairing public key 43044c1d1092SMatthias Ringwald 17, // 0x0d pairing dhk check 43054c1d1092SMatthias Ringwald 2, // 0x0e keypress notification 43064c1d1092SMatthias Ringwald }; 43073deb3ec6SMatthias Ringwald 4308f9bda154SMatthias Ringwald if (packet_type != SM_DATA_PACKET) return 0; 4309f9bda154SMatthias Ringwald if (size == 0u) return 0; 43104c1d1092SMatthias Ringwald 43114c1d1092SMatthias Ringwald uint8_t sm_pdu_code = packet[0]; 43124c1d1092SMatthias Ringwald 43134c1d1092SMatthias Ringwald // validate pdu size 4314f9bda154SMatthias Ringwald if (sm_pdu_code >= sizeof(sm_pdu_size)) return 0; 4315f9bda154SMatthias Ringwald if (sm_pdu_size[sm_pdu_code] != size) return 0; 4316f9bda154SMatthias Ringwald 4317f9bda154SMatthias Ringwald return sm_pdu_code; 4318f9bda154SMatthias Ringwald } 4319f9bda154SMatthias Ringwald 4320f9bda154SMatthias Ringwald static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uint8_t *packet, uint16_t size){ 4321f9bda154SMatthias Ringwald 4322f9bda154SMatthias Ringwald if ((packet_type == HCI_EVENT_PACKET) && (packet[0] == L2CAP_EVENT_CAN_SEND_NOW)){ 4323f9bda154SMatthias Ringwald sm_run(); 4324f9bda154SMatthias Ringwald } 4325f9bda154SMatthias Ringwald 4326f9bda154SMatthias Ringwald uint8_t sm_pdu_code = sm_pdu_validate_and_get_opcode(packet_type, packet, size); 4327f9bda154SMatthias Ringwald if (sm_pdu_code == 0) return; 43283deb3ec6SMatthias Ringwald 4329711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 43303deb3ec6SMatthias Ringwald if (!sm_conn) return; 43313deb3ec6SMatthias Ringwald 43324c1d1092SMatthias Ringwald if (sm_pdu_code == SM_CODE_PAIRING_FAILED){ 433368a18fb9SMatthias Ringwald sm_reencryption_complete(sm_conn, ERROR_CODE_AUTHENTICATION_FAILURE); 43340ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_AUTHENTICATION_FAILURE, packet[1]); 4335accbde80SMatthias Ringwald sm_done_for_handle(con_handle); 43363deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = sm_conn->sm_role ? SM_RESPONDER_IDLE : SM_INITIATOR_CONNECTED; 43373deb3ec6SMatthias Ringwald return; 43383deb3ec6SMatthias Ringwald } 43393deb3ec6SMatthias Ringwald 43404c1d1092SMatthias Ringwald log_debug("sm_pdu_handler: state %u, pdu 0x%02x", sm_conn->sm_engine_state, sm_pdu_code); 43413deb3ec6SMatthias Ringwald 43423deb3ec6SMatthias Ringwald int err; 4343afbd946dSMatthias Ringwald uint8_t max_encryption_key_size; 434442134bc6SMatthias Ringwald UNUSED(err); 43453deb3ec6SMatthias Ringwald 43464c1d1092SMatthias Ringwald if (sm_pdu_code == SM_CODE_KEYPRESS_NOTIFICATION){ 43473d7fe1e9SMatthias Ringwald uint8_t buffer[5]; 43483d7fe1e9SMatthias Ringwald buffer[0] = SM_EVENT_KEYPRESS_NOTIFICATION; 43493d7fe1e9SMatthias Ringwald buffer[1] = 3; 43503d7fe1e9SMatthias Ringwald little_endian_store_16(buffer, 2, con_handle); 43513d7fe1e9SMatthias Ringwald buffer[4] = packet[1]; 43523d7fe1e9SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, buffer, sizeof(buffer)); 43533d7fe1e9SMatthias Ringwald return; 43543d7fe1e9SMatthias Ringwald } 43553d7fe1e9SMatthias Ringwald 43563deb3ec6SMatthias Ringwald switch (sm_conn->sm_engine_state){ 43573deb3ec6SMatthias Ringwald 4358c8d0ff33SMatthias Ringwald // a sm timeout requires a new physical connection 43593deb3ec6SMatthias Ringwald case SM_GENERAL_TIMEOUT: 43603deb3ec6SMatthias Ringwald return; 43613deb3ec6SMatthias Ringwald 436242134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 436342134bc6SMatthias Ringwald 43643deb3ec6SMatthias Ringwald // Initiator 43653deb3ec6SMatthias Ringwald case SM_INITIATOR_CONNECTED: 43664c1d1092SMatthias Ringwald if ((sm_pdu_code != SM_CODE_SECURITY_REQUEST) || (sm_conn->sm_role)){ 43673deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 43683deb3ec6SMatthias Ringwald break; 43693deb3ec6SMatthias Ringwald } 437036f0defaSMatthias Ringwald sm_initiator_connected_handle_security_request(sm_conn, packet); 4371dc8ca372SMatthias Ringwald break; 43723deb3ec6SMatthias Ringwald 43733deb3ec6SMatthias Ringwald case SM_INITIATOR_PH1_W4_PAIRING_RESPONSE: 4374aacfafc3SMatthias Ringwald // Core 5, Vol 3, Part H, 2.4.6: 4375aacfafc3SMatthias Ringwald // "The master shall ignore the slave’s Security Request if the master has sent a Pairing Request 4376aacfafc3SMatthias Ringwald // without receiving a Pairing Response from the slave or if the master has initiated encryption mode setup." 4377aacfafc3SMatthias Ringwald if (sm_pdu_code == SM_CODE_SECURITY_REQUEST){ 4378aacfafc3SMatthias Ringwald log_info("Ignoring Security Request"); 4379aacfafc3SMatthias Ringwald break; 4380aacfafc3SMatthias Ringwald } 4381aacfafc3SMatthias Ringwald 4382aacfafc3SMatthias Ringwald // all other pdus are incorrect 43834c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RESPONSE){ 43843deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 43853deb3ec6SMatthias Ringwald break; 43863deb3ec6SMatthias Ringwald } 43870af429c6SMatthias Ringwald 43883deb3ec6SMatthias Ringwald // store pairing request 43896535961aSMatthias Ringwald (void)memcpy(&setup->sm_s_pres, packet, 43906535961aSMatthias Ringwald sizeof(sm_pairing_packet_t)); 4391afbd946dSMatthias Ringwald 4392afbd946dSMatthias Ringwald // validate encryption key size 4393afbd946dSMatthias Ringwald max_encryption_key_size = sm_pairing_packet_get_max_encryption_key_size(setup->sm_s_pres); 4394afbd946dSMatthias Ringwald if ((max_encryption_key_size < 7) || (max_encryption_key_size > 16)){ 4395afbd946dSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_INVALID_PARAMETERS); 4396afbd946dSMatthias Ringwald break; 4397afbd946dSMatthias Ringwald } 4398afbd946dSMatthias Ringwald 43993deb3ec6SMatthias Ringwald err = sm_stk_generation_init(sm_conn); 44000af429c6SMatthias Ringwald 44010af429c6SMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 44020af429c6SMatthias Ringwald if (0 < test_pairing_failure && test_pairing_failure < SM_REASON_DHKEY_CHECK_FAILED){ 44030af429c6SMatthias Ringwald log_info("testing_support: abort with pairing failure %u", test_pairing_failure); 44040af429c6SMatthias Ringwald err = test_pairing_failure; 44050af429c6SMatthias Ringwald } 44060af429c6SMatthias Ringwald #endif 44070af429c6SMatthias Ringwald 44089305033eSMatthias Ringwald if (err != 0){ 4409f4935286SMatthias Ringwald sm_pairing_error(sm_conn, err); 44103deb3ec6SMatthias Ringwald break; 44113deb3ec6SMatthias Ringwald } 4412b41539d5SMatthias Ringwald 4413b41539d5SMatthias Ringwald // generate random number first, if we need to show passkey 4414b41539d5SMatthias Ringwald if (setup->sm_stk_generation_method == PK_RESP_INPUT){ 4415f3582630SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph2_tk, (void *)(uintptr_t) sm_conn->sm_handle); 4416b41539d5SMatthias Ringwald break; 4417b41539d5SMatthias Ringwald } 4418b41539d5SMatthias Ringwald 4419136d331aSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4420136d331aSMatthias Ringwald if (setup->sm_use_secure_connections){ 44218cba5ca3SMatthias Ringwald // SC Numeric Comparison will trigger user response after public keys & nonces have been exchanged 44228cba5ca3SMatthias Ringwald if (setup->sm_stk_generation_method == JUST_WORKS){ 4423136d331aSMatthias Ringwald sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 4424136d331aSMatthias Ringwald sm_trigger_user_response(sm_conn); 4425136d331aSMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ 4426c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 4427136d331aSMatthias Ringwald } 44288cba5ca3SMatthias Ringwald } else { 4429c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 44308cba5ca3SMatthias Ringwald } 4431136d331aSMatthias Ringwald break; 4432136d331aSMatthias Ringwald } 4433136d331aSMatthias Ringwald #endif 44343deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 44353deb3ec6SMatthias Ringwald sm_trigger_user_response(sm_conn); 44363deb3ec6SMatthias Ringwald // response_idle == nothing <--> sm_trigger_user_response() did not require response 44373deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ 4438f3582630SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_random, 16, &sm_handle_random_result_ph2_random, (void *)(uintptr_t) sm_conn->sm_handle); 44393deb3ec6SMatthias Ringwald } 44403deb3ec6SMatthias Ringwald break; 44413deb3ec6SMatthias Ringwald 44423deb3ec6SMatthias Ringwald case SM_INITIATOR_PH2_W4_PAIRING_CONFIRM: 44434c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_CONFIRM){ 44443deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 44453deb3ec6SMatthias Ringwald break; 44463deb3ec6SMatthias Ringwald } 44473deb3ec6SMatthias Ringwald 44483deb3ec6SMatthias Ringwald // store s_confirm 44499c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_confirm); 4450192365feSMatthias Ringwald 4451aa9b34e5SMatthias Ringwald // abort if s_confirm matches m_confirm 4452aa9b34e5SMatthias Ringwald if (memcmp(setup->sm_local_confirm, setup->sm_peer_confirm, 16) == 0){ 4453aa9b34e5SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4454aa9b34e5SMatthias Ringwald break; 4455aa9b34e5SMatthias Ringwald } 4456aa9b34e5SMatthias Ringwald 4457192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 4458192365feSMatthias Ringwald if (test_pairing_failure == SM_REASON_CONFIRM_VALUE_FAILED){ 4459192365feSMatthias Ringwald log_info("testing_support: reset confirm value"); 4460192365feSMatthias Ringwald memset(setup->sm_peer_confirm, 0, 16); 4461192365feSMatthias Ringwald } 4462192365feSMatthias Ringwald #endif 44633deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_SEND_PAIRING_RANDOM; 44643deb3ec6SMatthias Ringwald break; 44653deb3ec6SMatthias Ringwald 44663deb3ec6SMatthias Ringwald case SM_INITIATOR_PH2_W4_PAIRING_RANDOM: 44674c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RANDOM){ 44683deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 44693deb3ec6SMatthias Ringwald break;; 44703deb3ec6SMatthias Ringwald } 44713deb3ec6SMatthias Ringwald 44723deb3ec6SMatthias Ringwald // received random value 44739c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_random); 44743deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_C1_GET_ENC_C; 44753deb3ec6SMatthias Ringwald break; 4476dc542de1SMatthias Ringwald 4477dc542de1SMatthias Ringwald case SM_PH4_W4_CONNECTION_ENCRYPTED: 4478dc542de1SMatthias Ringwald // ignore Security Request, see SM_INITIATOR_PH1_W4_PAIRING_RESPONSE above 4479dc542de1SMatthias Ringwald if (sm_pdu_code != SM_CODE_SECURITY_REQUEST){ 4480dc542de1SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4481dc542de1SMatthias Ringwald } 4482dc542de1SMatthias Ringwald break; 448342134bc6SMatthias Ringwald #endif 44843deb3ec6SMatthias Ringwald 448542134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 44863deb3ec6SMatthias Ringwald // Responder 44873deb3ec6SMatthias Ringwald case SM_RESPONDER_IDLE: 44883deb3ec6SMatthias Ringwald case SM_RESPONDER_SEND_SECURITY_REQUEST: 44893deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_W4_PAIRING_REQUEST: 44904c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_REQUEST){ 44913deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 44923deb3ec6SMatthias Ringwald break;; 44933deb3ec6SMatthias Ringwald } 44943deb3ec6SMatthias Ringwald 44953deb3ec6SMatthias Ringwald // store pairing request 4496212d735eSMatthias Ringwald (void)memcpy(&sm_conn->sm_m_preq, packet, sizeof(sm_pairing_packet_t)); 4497212d735eSMatthias Ringwald 4498afbd946dSMatthias Ringwald // validation encryption key size 4499afbd946dSMatthias Ringwald max_encryption_key_size = sm_pairing_packet_get_max_encryption_key_size(sm_conn->sm_m_preq); 4500afbd946dSMatthias Ringwald if ((max_encryption_key_size < 7) || (max_encryption_key_size > 16)){ 4501afbd946dSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_INVALID_PARAMETERS); 4502afbd946dSMatthias Ringwald break; 4503afbd946dSMatthias Ringwald } 4504afbd946dSMatthias Ringwald 4505212d735eSMatthias Ringwald // check if IRK completed 4506212d735eSMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 4507212d735eSMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 4508212d735eSMatthias Ringwald case IRK_LOOKUP_FAILED: 45093deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED; 45103deb3ec6SMatthias Ringwald break; 4511212d735eSMatthias Ringwald default: 4512212d735eSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED_W4_IRK; 4513212d735eSMatthias Ringwald break; 4514212d735eSMatthias Ringwald } 4515212d735eSMatthias Ringwald break; 451642134bc6SMatthias Ringwald #endif 45173deb3ec6SMatthias Ringwald 451827c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4519c6b7cbd9SMatthias Ringwald case SM_SC_W4_PUBLIC_KEY_COMMAND: 45204c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_PUBLIC_KEY){ 452127c32905SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 452227c32905SMatthias Ringwald break; 452327c32905SMatthias Ringwald } 4524bccf5e67SMatthias Ringwald 4525e53be891SMatthias Ringwald // store public key for DH Key calculation 4526fc5bff5fSMatthias Ringwald reverse_256(&packet[01], &setup->sm_peer_q[0]); 4527fc5bff5fSMatthias Ringwald reverse_256(&packet[33], &setup->sm_peer_q[32]); 4528bccf5e67SMatthias Ringwald 452902658749SMatthias Ringwald // CVE-2020-26558: abort pairing if remote uses the same public key 453002658749SMatthias Ringwald if (memcmp(&setup->sm_peer_q, ec_q, 64) == 0){ 453102658749SMatthias Ringwald log_info("Remote PK matches ours"); 453202658749SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 453302658749SMatthias Ringwald break; 453402658749SMatthias Ringwald } 453502658749SMatthias Ringwald 4536d1a1f6a4SMatthias Ringwald // validate public key 4537d1a1f6a4SMatthias Ringwald err = btstack_crypto_ecc_p256_validate_public_key(setup->sm_peer_q); 45389305033eSMatthias Ringwald if (err != 0){ 453902658749SMatthias Ringwald log_info("sm: peer public key invalid %x", err); 4540349d0adbSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 4541bccf5e67SMatthias Ringwald break; 4542bccf5e67SMatthias Ringwald } 4543891bb64aSMatthias Ringwald 4544d1a1f6a4SMatthias Ringwald // start calculating dhkey 4545f3582630SMatthias Ringwald btstack_crypto_ecc_p256_calculate_dhkey(&sm_crypto_ecc_p256_request, setup->sm_peer_q, setup->sm_dhkey, sm_sc_dhkey_calculated, (void*)(uintptr_t) sm_conn->sm_handle); 45463cf37b8cSMatthias Ringwald 454765a9a04eSMatthias Ringwald 454865a9a04eSMatthias Ringwald log_info("public key received, generation method %u", setup->sm_stk_generation_method); 454942134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 4550136d331aSMatthias Ringwald // responder 4551c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 4552136d331aSMatthias Ringwald } else { 4553136d331aSMatthias Ringwald // initiator 4554a1e31e9cSMatthias Ringwald // stk generation method 4555a1e31e9cSMatthias Ringwald // passkey entry: notify app to show passkey or to request passkey 4556a1e31e9cSMatthias Ringwald switch (setup->sm_stk_generation_method){ 4557a1e31e9cSMatthias Ringwald case JUST_WORKS: 455847fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 4559c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_CONFIRMATION; 4560a1e31e9cSMatthias Ringwald break; 4561a1e31e9cSMatthias Ringwald case PK_RESP_INPUT: 456207036a04SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 456307036a04SMatthias Ringwald break; 456407036a04SMatthias Ringwald case PK_INIT_INPUT: 456547fb4255SMatthias Ringwald case PK_BOTH_INPUT: 456607036a04SMatthias Ringwald if (setup->sm_user_response != SM_USER_RESPONSE_PASSKEY){ 456707036a04SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_USER_RESPONSE; 456807036a04SMatthias Ringwald break; 456907036a04SMatthias Ringwald } 4570b35a3de2SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 4571a1e31e9cSMatthias Ringwald break; 4572a1e31e9cSMatthias Ringwald case OOB: 4573d1a1f6a4SMatthias Ringwald // generate Nx 45744acf7b7bSMatthias Ringwald log_info("Generate Na"); 45756ca80073SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_nonce, 16, &sm_handle_random_result_sc_next_send_pairing_random, (void*)(uintptr_t) sm_conn->sm_handle); 4576a1e31e9cSMatthias Ringwald break; 45777bbeb3adSMilanka Ringwald default: 45787bbeb3adSMilanka Ringwald btstack_assert(false); 45797bbeb3adSMilanka Ringwald break; 4580a1e31e9cSMatthias Ringwald } 4581136d331aSMatthias Ringwald } 458227c32905SMatthias Ringwald break; 4583e53be891SMatthias Ringwald 4584c6b7cbd9SMatthias Ringwald case SM_SC_W4_CONFIRMATION: 45854c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_CONFIRM){ 458645a61d50SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 458745a61d50SMatthias Ringwald break; 458845a61d50SMatthias Ringwald } 458945a61d50SMatthias Ringwald // received confirm value 459045a61d50SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_confirm); 459145a61d50SMatthias Ringwald 4592192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 4593192365feSMatthias Ringwald if (test_pairing_failure == SM_REASON_CONFIRM_VALUE_FAILED){ 4594192365feSMatthias Ringwald log_info("testing_support: reset confirm value"); 4595192365feSMatthias Ringwald memset(setup->sm_peer_confirm, 0, 16); 4596192365feSMatthias Ringwald } 4597192365feSMatthias Ringwald #endif 459842134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 459945a61d50SMatthias Ringwald // responder 460007036a04SMatthias Ringwald if (sm_passkey_used(setup->sm_stk_generation_method)){ 460107036a04SMatthias Ringwald if (setup->sm_user_response != SM_USER_RESPONSE_PASSKEY){ 460207036a04SMatthias Ringwald // still waiting for passkey 460307036a04SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_USER_RESPONSE; 460407036a04SMatthias Ringwald break; 460507036a04SMatthias Ringwald } 460607036a04SMatthias Ringwald } 4607b35a3de2SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 460845a61d50SMatthias Ringwald } else { 460945a61d50SMatthias Ringwald // initiator 4610945888f5SMatthias Ringwald if (sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method)){ 46116ca80073SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_nonce, 16, &sm_handle_random_result_sc_next_send_pairing_random, (void*)(uintptr_t) sm_conn->sm_handle); 4612f1c1783eSMatthias Ringwald } else { 4613c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM; 461445a61d50SMatthias Ringwald } 4615f1c1783eSMatthias Ringwald } 461645a61d50SMatthias Ringwald break; 461745a61d50SMatthias Ringwald 4618c6b7cbd9SMatthias Ringwald case SM_SC_W4_PAIRING_RANDOM: 46194c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RANDOM){ 4620e53be891SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4621136d331aSMatthias Ringwald break; 4622e53be891SMatthias Ringwald } 4623e53be891SMatthias Ringwald 4624e53be891SMatthias Ringwald // received random value 4625e53be891SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_nonce); 4626e53be891SMatthias Ringwald 46275a293e6eSMatthias Ringwald // validate confirm value if Cb = f4(Pkb, Pka, Nb, z) 4628ae451ec5SMatthias Ringwald // only check for JUST WORK/NC in initiator role OR passkey entry 4629d686b2d0SMatthias Ringwald log_info("SM_SC_W4_PAIRING_RANDOM, responder: %u, just works: %u, passkey used %u, passkey entry %u", 4630d686b2d0SMatthias Ringwald IS_RESPONDER(sm_conn->sm_role), sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method), 4631d686b2d0SMatthias Ringwald sm_passkey_used(setup->sm_stk_generation_method), sm_passkey_entry(setup->sm_stk_generation_method)); 463265a9a04eSMatthias Ringwald if ( (!IS_RESPONDER(sm_conn->sm_role) && sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method)) 4633d686b2d0SMatthias Ringwald || (sm_passkey_entry(setup->sm_stk_generation_method)) ) { 4634688a08f9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION; 4635ae451ec5SMatthias Ringwald break; 46365a293e6eSMatthias Ringwald } 46376f52a196SMatthias Ringwald 46384acf7b7bSMatthias Ringwald // OOB 46394acf7b7bSMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 46404acf7b7bSMatthias Ringwald 46414acf7b7bSMatthias Ringwald // setup local random, set to zero if remote did not receive our data 46424acf7b7bSMatthias Ringwald log_info("Received nonce, setup local random ra/rb for dhkey check"); 46434acf7b7bSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 46444ea43905SMatthias Ringwald if (sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq) == 0u){ 46454acf7b7bSMatthias Ringwald log_info("Reset rb as A does not have OOB data"); 46464acf7b7bSMatthias Ringwald memset(setup->sm_rb, 0, 16); 46474acf7b7bSMatthias Ringwald } else { 46486535961aSMatthias Ringwald (void)memcpy(setup->sm_rb, sm_sc_oob_random, 16); 46494acf7b7bSMatthias Ringwald log_info("Use stored rb"); 46504acf7b7bSMatthias Ringwald log_info_hexdump(setup->sm_rb, 16); 46514acf7b7bSMatthias Ringwald } 46524acf7b7bSMatthias Ringwald } else { 46534ea43905SMatthias Ringwald if (sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres) == 0u){ 46544acf7b7bSMatthias Ringwald log_info("Reset ra as B does not have OOB data"); 46554acf7b7bSMatthias Ringwald memset(setup->sm_ra, 0, 16); 46564acf7b7bSMatthias Ringwald } else { 46576535961aSMatthias Ringwald (void)memcpy(setup->sm_ra, sm_sc_oob_random, 16); 46584acf7b7bSMatthias Ringwald log_info("Use stored ra"); 46594acf7b7bSMatthias Ringwald log_info_hexdump(setup->sm_ra, 16); 46604acf7b7bSMatthias Ringwald } 46614acf7b7bSMatthias Ringwald } 46624acf7b7bSMatthias Ringwald 4663a680ba6bSMatthias Ringwald // validate confirm value if Cb = f4(PKb, Pkb, rb, 0) for OOB if data received 46644acf7b7bSMatthias Ringwald if (setup->sm_have_oob_data){ 4665a680ba6bSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION; 4666a680ba6bSMatthias Ringwald break; 4667a680ba6bSMatthias Ringwald } 46684acf7b7bSMatthias Ringwald } 4669a680ba6bSMatthias Ringwald 4670a680ba6bSMatthias Ringwald // TODO: we only get here for Responder role with JW/NC 4671688a08f9SMatthias Ringwald sm_sc_state_after_receiving_random(sm_conn); 4672e53be891SMatthias Ringwald break; 4673e53be891SMatthias Ringwald 4674901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_G2: 4675901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_G2: 46763cf37b8cSMatthias Ringwald case SM_SC_W4_CALCULATE_DHKEY: 4677901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_SALT: 4678901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_SALT: 4679901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_MACKEY: 4680901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_MACKEY: 4681901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_LTK: 4682901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_LTK: 4683901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F6_FOR_DHKEY_CHECK: 4684c6b7cbd9SMatthias Ringwald case SM_SC_W4_DHKEY_CHECK_COMMAND: 4685901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F6_FOR_DHKEY_CHECK: 4686d08147dfSMatthias Ringwald case SM_SC_W4_USER_RESPONSE: 46874c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_DHKEY_CHECK){ 4688e53be891SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4689e53be891SMatthias Ringwald break; 4690e53be891SMatthias Ringwald } 4691e53be891SMatthias Ringwald // store DHKey Check 4692901c000fSMatthias Ringwald setup->sm_state_vars |= SM_STATE_VAR_DHKEY_COMMAND_RECEIVED; 4693e53be891SMatthias Ringwald reverse_128(&packet[01], setup->sm_peer_dhkey_check); 4694446a8c36SMatthias Ringwald 4695901c000fSMatthias Ringwald // have we been only waiting for dhkey check command? 4696901c000fSMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_DHKEY_CHECK_COMMAND){ 4697019005a0SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK; 4698bd57ffebSMatthias Ringwald } 4699bd57ffebSMatthias Ringwald break; 470027c32905SMatthias Ringwald #endif 470127c32905SMatthias Ringwald 470242134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 47033deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_W4_PAIRING_CONFIRM: 47044c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_CONFIRM){ 47053deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 470627c32905SMatthias Ringwald break; 47073deb3ec6SMatthias Ringwald } 47083deb3ec6SMatthias Ringwald 47093deb3ec6SMatthias Ringwald // received confirm value 47109c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_confirm); 47113deb3ec6SMatthias Ringwald 4712192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 4713192365feSMatthias Ringwald if (test_pairing_failure == SM_REASON_CONFIRM_VALUE_FAILED){ 4714192365feSMatthias Ringwald log_info("testing_support: reset confirm value"); 4715192365feSMatthias Ringwald memset(setup->sm_peer_confirm, 0, 16); 4716192365feSMatthias Ringwald } 4717192365feSMatthias Ringwald #endif 47183deb3ec6SMatthias Ringwald // notify client to hide shown passkey 47193deb3ec6SMatthias Ringwald if (setup->sm_stk_generation_method == PK_INIT_INPUT){ 47205611a760SMatthias Ringwald sm_notify_client_base(SM_EVENT_PASSKEY_DISPLAY_CANCEL, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address); 47213deb3ec6SMatthias Ringwald } 47223deb3ec6SMatthias Ringwald 47233deb3ec6SMatthias Ringwald // handle user cancel pairing? 47243deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_DECLINE){ 4725f4935286SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_PASSKEY_ENTRY_FAILED); 47263deb3ec6SMatthias Ringwald break; 47273deb3ec6SMatthias Ringwald } 47283deb3ec6SMatthias Ringwald 47293deb3ec6SMatthias Ringwald // wait for user action? 47303deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_PENDING){ 47313deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 47323deb3ec6SMatthias Ringwald break; 47333deb3ec6SMatthias Ringwald } 47343deb3ec6SMatthias Ringwald 47353deb3ec6SMatthias Ringwald // calculate and send local_confirm 4736f3582630SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_random, 16, &sm_handle_random_result_ph2_random, (void *)(uintptr_t) sm_conn->sm_handle); 47373deb3ec6SMatthias Ringwald break; 47383deb3ec6SMatthias Ringwald 47393deb3ec6SMatthias Ringwald case SM_RESPONDER_PH2_W4_PAIRING_RANDOM: 47404c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RANDOM){ 47413deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 47423deb3ec6SMatthias Ringwald break;; 47433deb3ec6SMatthias Ringwald } 47443deb3ec6SMatthias Ringwald 47453deb3ec6SMatthias Ringwald // received random value 47469c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_random); 47473deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_C1_GET_ENC_C; 47483deb3ec6SMatthias Ringwald break; 474942134bc6SMatthias Ringwald #endif 47503deb3ec6SMatthias Ringwald 4751672dc582SMatthias Ringwald case SM_PH2_W4_CONNECTION_ENCRYPTED: 47523deb3ec6SMatthias Ringwald case SM_PH3_RECEIVE_KEYS: 47534c1d1092SMatthias Ringwald switch(sm_pdu_code){ 47543deb3ec6SMatthias Ringwald case SM_CODE_ENCRYPTION_INFORMATION: 47553deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 47569c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_ltk); 47573deb3ec6SMatthias Ringwald break; 47583deb3ec6SMatthias Ringwald 47593deb3ec6SMatthias Ringwald case SM_CODE_MASTER_IDENTIFICATION: 47603deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 4761f8fbdce0SMatthias Ringwald setup->sm_peer_ediv = little_endian_read_16(packet, 1); 47629c80e4ccSMatthias Ringwald reverse_64(&packet[3], setup->sm_peer_rand); 47633deb3ec6SMatthias Ringwald break; 47643deb3ec6SMatthias Ringwald 47653deb3ec6SMatthias Ringwald case SM_CODE_IDENTITY_INFORMATION: 47663deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 47679c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_irk); 47683deb3ec6SMatthias Ringwald break; 47693deb3ec6SMatthias Ringwald 47703deb3ec6SMatthias Ringwald case SM_CODE_IDENTITY_ADDRESS_INFORMATION: 47713deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 47723deb3ec6SMatthias Ringwald setup->sm_peer_addr_type = packet[1]; 4773724d70a2SMatthias Ringwald reverse_bd_addr(&packet[2], setup->sm_peer_address); 47743deb3ec6SMatthias Ringwald break; 47753deb3ec6SMatthias Ringwald 47763deb3ec6SMatthias Ringwald case SM_CODE_SIGNING_INFORMATION: 47773deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 47789c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_csrk); 47793deb3ec6SMatthias Ringwald break; 47803deb3ec6SMatthias Ringwald default: 47813deb3ec6SMatthias Ringwald // Unexpected PDU 47823deb3ec6SMatthias Ringwald log_info("Unexpected PDU %u in SM_PH3_RECEIVE_KEYS", packet[0]); 47833deb3ec6SMatthias Ringwald break; 47843deb3ec6SMatthias Ringwald } 47853deb3ec6SMatthias Ringwald // done with key distribution? 478661d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 47873deb3ec6SMatthias Ringwald 47883deb3ec6SMatthias Ringwald sm_key_distribution_handle_all_received(sm_conn); 47893deb3ec6SMatthias Ringwald 479042134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 47916f7422f1SMatthias Ringwald sm_key_distribution_complete_responder(sm_conn); 47923deb3ec6SMatthias Ringwald } else { 4793625f00b2SMatthias Ringwald if (setup->sm_use_secure_connections){ 4794625f00b2SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 4795bbf8db22SMatthias Ringwald } else { 4796f3582630SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph3_random, (void *)(uintptr_t) sm_conn->sm_handle); 4797625f00b2SMatthias Ringwald } 47983deb3ec6SMatthias Ringwald } 47993deb3ec6SMatthias Ringwald } 48003deb3ec6SMatthias Ringwald break; 4801c18be159SMatthias Ringwald 4802c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 4803b322498eSMatthias Ringwald 4804b322498eSMatthias Ringwald case SM_BR_EDR_W4_ENCRYPTION_COMPLETE: 4805b322498eSMatthias Ringwald // GAP/DM/LEP/BI-02-C - reject CTKD if P-192 encryption is used 4806b322498eSMatthias Ringwald if (sm_pdu_code == SM_CODE_PAIRING_REQUEST){ 4807b322498eSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_CROSS_TRANSPORT_KEY_DERIVATION_NOT_ALLOWED); 4808b322498eSMatthias Ringwald } 4809b322498eSMatthias Ringwald break; 4810b322498eSMatthias Ringwald 4811c18be159SMatthias Ringwald case SM_BR_EDR_INITIATOR_W4_PAIRING_RESPONSE: 4812553c9408SMatthias Ringwald 4813553c9408SMatthias Ringwald // dedicated bonding complete 4814f82b8f4bSMatthias Ringwald hci_dedicated_bonding_defer_disconnect(sm_conn->sm_handle, false); 4815553c9408SMatthias Ringwald 4816c18be159SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RESPONSE){ 4817c18be159SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4818c18be159SMatthias Ringwald break; 4819c18be159SMatthias Ringwald } 4820c18be159SMatthias Ringwald // store pairing response 4821c18be159SMatthias Ringwald (void)memcpy(&setup->sm_s_pres, packet, sizeof(sm_pairing_packet_t)); 4822c18be159SMatthias Ringwald 4823c18be159SMatthias Ringwald // validate encryption key size 4824afbd946dSMatthias Ringwald max_encryption_key_size = sm_pairing_packet_get_max_encryption_key_size(setup->sm_s_pres); 4825afbd946dSMatthias Ringwald if ((max_encryption_key_size < 7) || (max_encryption_key_size > 16)){ 4826afbd946dSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_INVALID_PARAMETERS); 4827afbd946dSMatthias Ringwald break; 4828afbd946dSMatthias Ringwald } 4829afbd946dSMatthias Ringwald sm_conn->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(max_encryption_key_size); 4830c18be159SMatthias Ringwald // SC Only mandates 128 bit key size 4831c18be159SMatthias Ringwald if (sm_sc_only_mode && (sm_conn->sm_actual_encryption_key_size < 16)) { 4832c18be159SMatthias Ringwald sm_conn->sm_actual_encryption_key_size = 0; 4833c18be159SMatthias Ringwald } 4834c18be159SMatthias Ringwald if (sm_conn->sm_actual_encryption_key_size == 0){ 4835c18be159SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_ENCRYPTION_KEY_SIZE); 4836c18be159SMatthias Ringwald break; 4837c18be159SMatthias Ringwald } 4838c18be159SMatthias Ringwald 4839c18be159SMatthias Ringwald // prepare key exchange, LTK is derived locally 4840c18be159SMatthias Ringwald sm_setup_key_distribution(sm_pairing_packet_get_initiator_key_distribution(setup->sm_s_pres) & ~SM_KEYDIST_ENC_KEY, 4841c18be159SMatthias Ringwald sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres) & ~SM_KEYDIST_ENC_KEY); 4842c18be159SMatthias Ringwald 4843c18be159SMatthias Ringwald // skip receive if there are none 484461d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 4845c18be159SMatthias Ringwald // distribute keys in run handles 'no keys to send' 4846c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_DISTRIBUTE_KEYS; 4847c18be159SMatthias Ringwald } else { 4848c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_RECEIVE_KEYS; 4849c18be159SMatthias Ringwald } 4850c18be159SMatthias Ringwald break; 4851c18be159SMatthias Ringwald 4852c18be159SMatthias Ringwald case SM_BR_EDR_RESPONDER_W4_PAIRING_REQUEST: 4853c18be159SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_REQUEST){ 4854c18be159SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4855c18be159SMatthias Ringwald break; 4856c18be159SMatthias Ringwald } 4857afbd946dSMatthias Ringwald 4858c18be159SMatthias Ringwald // store pairing request 4859c18be159SMatthias Ringwald (void)memcpy(&sm_conn->sm_m_preq, packet, sizeof(sm_pairing_packet_t)); 4860afbd946dSMatthias Ringwald 4861c18be159SMatthias Ringwald // validate encryption key size 4862afbd946dSMatthias Ringwald max_encryption_key_size = sm_pairing_packet_get_max_encryption_key_size(setup->sm_m_preq); 4863afbd946dSMatthias Ringwald if ((max_encryption_key_size < 7) || (max_encryption_key_size > 16)){ 4864afbd946dSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_INVALID_PARAMETERS); 4865afbd946dSMatthias Ringwald break; 4866afbd946dSMatthias Ringwald } 4867afbd946dSMatthias Ringwald sm_conn->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(max_encryption_key_size); 4868c18be159SMatthias Ringwald // SC Only mandates 128 bit key size 4869c18be159SMatthias Ringwald if (sm_sc_only_mode && (sm_conn->sm_actual_encryption_key_size < 16)) { 4870c18be159SMatthias Ringwald sm_conn->sm_actual_encryption_key_size = 0; 4871c18be159SMatthias Ringwald } 4872c18be159SMatthias Ringwald if (sm_conn->sm_actual_encryption_key_size == 0){ 4873c18be159SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_ENCRYPTION_KEY_SIZE); 4874c18be159SMatthias Ringwald break; 4875c18be159SMatthias Ringwald } 4876c18be159SMatthias Ringwald // trigger response 48776a718a5eSMatthias Ringwald if (sm_ctkd_from_classic(sm_conn)){ 4878c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_RESPONDER_PAIRING_REQUEST_RECEIVED; 48796a718a5eSMatthias Ringwald } else { 48806a718a5eSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_CROSS_TRANSPORT_KEY_DERIVATION_NOT_ALLOWED); 48816a718a5eSMatthias Ringwald } 4882c18be159SMatthias Ringwald break; 4883c18be159SMatthias Ringwald 4884c18be159SMatthias Ringwald case SM_BR_EDR_RECEIVE_KEYS: 4885c18be159SMatthias Ringwald switch(sm_pdu_code){ 4886c18be159SMatthias Ringwald case SM_CODE_IDENTITY_INFORMATION: 4887c18be159SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 4888c18be159SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_irk); 4889c18be159SMatthias Ringwald break; 4890c18be159SMatthias Ringwald case SM_CODE_IDENTITY_ADDRESS_INFORMATION: 4891c18be159SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 4892c18be159SMatthias Ringwald setup->sm_peer_addr_type = packet[1]; 4893c18be159SMatthias Ringwald reverse_bd_addr(&packet[2], setup->sm_peer_address); 4894c18be159SMatthias Ringwald break; 4895c18be159SMatthias Ringwald case SM_CODE_SIGNING_INFORMATION: 4896c18be159SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 4897c18be159SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_csrk); 4898c18be159SMatthias Ringwald break; 4899c18be159SMatthias Ringwald default: 4900c18be159SMatthias Ringwald // Unexpected PDU 4901c18be159SMatthias Ringwald log_info("Unexpected PDU %u in SM_PH3_RECEIVE_KEYS", packet[0]); 4902c18be159SMatthias Ringwald break; 4903c18be159SMatthias Ringwald } 4904c18be159SMatthias Ringwald 4905c18be159SMatthias Ringwald // all keys received 490661d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 4907c18be159SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 4908c18be159SMatthias Ringwald // responder -> keys exchanged, derive LE LTK 4909c18be159SMatthias Ringwald sm_ctkd_start_from_br_edr(sm_conn); 4910c18be159SMatthias Ringwald } else { 4911c18be159SMatthias Ringwald // initiator -> send our keys if any 4912c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_DISTRIBUTE_KEYS; 4913c18be159SMatthias Ringwald } 4914c18be159SMatthias Ringwald } 4915c18be159SMatthias Ringwald break; 4916c18be159SMatthias Ringwald #endif 4917c18be159SMatthias Ringwald 49183deb3ec6SMatthias Ringwald default: 49193deb3ec6SMatthias Ringwald // Unexpected PDU 49203deb3ec6SMatthias Ringwald log_info("Unexpected PDU %u in state %u", packet[0], sm_conn->sm_engine_state); 49212d095694SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 49223deb3ec6SMatthias Ringwald break; 49233deb3ec6SMatthias Ringwald } 49243deb3ec6SMatthias Ringwald 492570b44dd4SMatthias Ringwald // try to send next pdu 492670b44dd4SMatthias Ringwald sm_trigger_run(); 49273deb3ec6SMatthias Ringwald } 49283deb3ec6SMatthias Ringwald 49293deb3ec6SMatthias Ringwald // Security Manager Client API 4930a680ba6bSMatthias Ringwald void sm_register_oob_data_callback( int (*get_oob_data_callback)(uint8_t address_type, bd_addr_t addr, uint8_t * oob_data)){ 49313deb3ec6SMatthias Ringwald sm_get_oob_data = get_oob_data_callback; 49323deb3ec6SMatthias Ringwald } 49333deb3ec6SMatthias Ringwald 49344acf7b7bSMatthias Ringwald void sm_register_sc_oob_data_callback( int (*get_sc_oob_data_callback)(uint8_t address_type, bd_addr_t addr, uint8_t * oob_sc_peer_confirm, uint8_t * oob_sc_peer_random)){ 4935a680ba6bSMatthias Ringwald sm_get_sc_oob_data = get_sc_oob_data_callback; 4936a680ba6bSMatthias Ringwald } 4937a680ba6bSMatthias Ringwald 4938b96d60a6SMatthias Ringwald void sm_register_ltk_callback( bool (*get_ltk_callback)(hci_con_handle_t con_handle, uint8_t address_type, bd_addr_t addr, uint8_t * ltk)){ 4939b96d60a6SMatthias Ringwald sm_get_ltk_callback = get_ltk_callback; 4940b96d60a6SMatthias Ringwald } 4941b96d60a6SMatthias Ringwald 494289a78d34SMatthias Ringwald void sm_add_event_handler(btstack_packet_callback_registration_t * callback_handler){ 494389a78d34SMatthias Ringwald btstack_linked_list_add_tail(&sm_event_handlers, (btstack_linked_item_t*) callback_handler); 494489a78d34SMatthias Ringwald } 494589a78d34SMatthias Ringwald 494667f708e0SMatthias Ringwald void sm_remove_event_handler(btstack_packet_callback_registration_t * callback_handler){ 494767f708e0SMatthias Ringwald btstack_linked_list_remove(&sm_event_handlers, (btstack_linked_item_t*) callback_handler); 494867f708e0SMatthias Ringwald } 494967f708e0SMatthias Ringwald 49503deb3ec6SMatthias Ringwald void sm_set_accepted_stk_generation_methods(uint8_t accepted_stk_generation_methods){ 49513deb3ec6SMatthias Ringwald sm_accepted_stk_generation_methods = accepted_stk_generation_methods; 49523deb3ec6SMatthias Ringwald } 49533deb3ec6SMatthias Ringwald 49543deb3ec6SMatthias Ringwald void sm_set_encryption_key_size_range(uint8_t min_size, uint8_t max_size){ 49553deb3ec6SMatthias Ringwald sm_min_encryption_key_size = min_size; 49563deb3ec6SMatthias Ringwald sm_max_encryption_key_size = max_size; 49573deb3ec6SMatthias Ringwald } 49583deb3ec6SMatthias Ringwald 49593deb3ec6SMatthias Ringwald void sm_set_authentication_requirements(uint8_t auth_req){ 496098d95509SMatthias Ringwald #ifndef ENABLE_LE_SECURE_CONNECTIONS 496198d95509SMatthias Ringwald if (auth_req & SM_AUTHREQ_SECURE_CONNECTION){ 496298d95509SMatthias Ringwald log_error("ENABLE_LE_SECURE_CONNECTIONS not defined, but requested by app. Dropping SC flag"); 496398d95509SMatthias Ringwald auth_req &= ~SM_AUTHREQ_SECURE_CONNECTION; 496498d95509SMatthias Ringwald } 496598d95509SMatthias Ringwald #endif 49663deb3ec6SMatthias Ringwald sm_auth_req = auth_req; 49673deb3ec6SMatthias Ringwald } 49683deb3ec6SMatthias Ringwald 49693deb3ec6SMatthias Ringwald void sm_set_io_capabilities(io_capability_t io_capability){ 49703deb3ec6SMatthias Ringwald sm_io_capabilities = io_capability; 49713deb3ec6SMatthias Ringwald } 49723deb3ec6SMatthias Ringwald 497342134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 4974728f6757SMatthias Ringwald void sm_set_request_security(bool enable){ 49753deb3ec6SMatthias Ringwald sm_slave_request_security = enable; 49763deb3ec6SMatthias Ringwald } 497742134bc6SMatthias Ringwald #endif 49783deb3ec6SMatthias Ringwald 49793deb3ec6SMatthias Ringwald void sm_set_er(sm_key_t er){ 49806535961aSMatthias Ringwald (void)memcpy(sm_persistent_er, er, 16); 49813deb3ec6SMatthias Ringwald } 49823deb3ec6SMatthias Ringwald 49833deb3ec6SMatthias Ringwald void sm_set_ir(sm_key_t ir){ 49846535961aSMatthias Ringwald (void)memcpy(sm_persistent_ir, ir, 16); 49853deb3ec6SMatthias Ringwald } 49863deb3ec6SMatthias Ringwald 49873deb3ec6SMatthias Ringwald // Testing support only 49883deb3ec6SMatthias Ringwald void sm_test_set_irk(sm_key_t irk){ 49896535961aSMatthias Ringwald (void)memcpy(sm_persistent_irk, irk, 16); 4990103fa6b0SMatthias Ringwald dkg_state = DKG_CALC_DHK; 4991841468bbSMatthias Ringwald test_use_fixed_local_irk = true; 49923deb3ec6SMatthias Ringwald } 49933deb3ec6SMatthias Ringwald 49943deb3ec6SMatthias Ringwald void sm_test_use_fixed_local_csrk(void){ 4995841468bbSMatthias Ringwald test_use_fixed_local_csrk = true; 49963deb3ec6SMatthias Ringwald } 49973deb3ec6SMatthias Ringwald 4998d1a1f6a4SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4999d1a1f6a4SMatthias Ringwald static void sm_ec_generated(void * arg){ 5000d1a1f6a4SMatthias Ringwald UNUSED(arg); 5001d1a1f6a4SMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_DONE; 500234b6528fSMatthias Ringwald // trigger pairing if pending for ec key 500370b44dd4SMatthias Ringwald sm_trigger_run(); 5004d1a1f6a4SMatthias Ringwald } 5005674e5b4aSMatthias Ringwald static void sm_ec_generate_new_key(void) { 500634b6528fSMatthias Ringwald log_info("sm: generate new ec key"); 5007db88441fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS_DEBUG_KEY 5008db88441fSMatthias Ringwald // LE Secure Connections Debug Key 5009db88441fSMatthias Ringwald const uint8_t debug_key_public[64] = { 5010db88441fSMatthias Ringwald 0x20, 0xb0, 0x03, 0xd2, 0xf2, 0x97, 0xbe, 0x2c, 0x5e, 0x2c, 0x83, 0xa7, 0xe9, 0xf9, 0xa5, 0xb9, 5011db88441fSMatthias Ringwald 0xef, 0xf4, 0x91, 0x11, 0xac, 0xf4, 0xfd, 0xdb, 0xcc, 0x03, 0x01, 0x48, 0x0e, 0x35, 0x9d, 0xe6, 5012db88441fSMatthias Ringwald 0xdc, 0x80, 0x9c, 0x49, 0x65, 0x2a, 0xeb, 0x6d, 0x63, 0x32, 0x9a, 0xbf, 0x5a, 0x52, 0x15, 0x5c, 5013db88441fSMatthias Ringwald 0x76, 0x63, 0x45, 0xc2, 0x8f, 0xed, 0x30, 0x24, 0x74, 0x1c, 0x8e, 0xd0, 0x15, 0x89, 0xd2, 0x8b 5014db88441fSMatthias Ringwald }; 5015db88441fSMatthias Ringwald const uint8_t debug_key_private[32] = { 5016db88441fSMatthias Ringwald 0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, 0x74, 0xc9, 0xb3, 0xe3, 0xd2, 0x10, 0x3f, 0x50, 5017db88441fSMatthias Ringwald 0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd 5018db88441fSMatthias Ringwald }; 5019db88441fSMatthias Ringwald if (sm_sc_debug_keys_enabled) { 5020db88441fSMatthias Ringwald memcpy(ec_q, debug_key_public, 64); 5021db88441fSMatthias Ringwald btstack_crypto_ecc_p256_set_key(debug_key_public, debug_key_private); 5022db88441fSMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_DONE; 5023db88441fSMatthias Ringwald } else 5024db88441fSMatthias Ringwald #endif 5025db88441fSMatthias Ringwald { 5026674e5b4aSMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_ACTIVE; 5027674e5b4aSMatthias Ringwald btstack_crypto_ecc_p256_generate_key(&sm_crypto_ecc_p256_request, ec_q, &sm_ec_generated, NULL); 5028674e5b4aSMatthias Ringwald } 5029db88441fSMatthias Ringwald } 5030d1a1f6a4SMatthias Ringwald #endif 5031d1a1f6a4SMatthias Ringwald 5032192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 5033192365feSMatthias Ringwald void sm_test_set_pairing_failure(int reason){ 5034192365feSMatthias Ringwald test_pairing_failure = reason; 5035192365feSMatthias Ringwald } 5036192365feSMatthias Ringwald #endif 5037192365feSMatthias Ringwald 50387887cd92SMatthias Ringwald static void sm_state_reset(void) { 50397f775357SMatthias Ringwald #ifdef USE_CMAC_ENGINE 50407f775357SMatthias Ringwald sm_cmac_active = 0; 50417f775357SMatthias Ringwald #endif 50427f775357SMatthias Ringwald dkg_state = DKG_W4_WORKING; 50437f775357SMatthias Ringwald rau_state = RAU_IDLE; 50447f775357SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 50457f775357SMatthias Ringwald sm_address_resolution_test = -1; // no private address to resolve yet 50467f775357SMatthias Ringwald sm_address_resolution_mode = ADDRESS_RESOLUTION_IDLE; 50477f775357SMatthias Ringwald sm_address_resolution_general_queue = NULL; 50487f775357SMatthias Ringwald sm_active_connection_handle = HCI_CON_HANDLE_INVALID; 5049cbdd51cfSMatthias Ringwald sm_persistent_keys_random_active = false; 50507f775357SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 505115211b85SMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_IDLE; 50527f775357SMatthias Ringwald #endif 50537f775357SMatthias Ringwald } 50547f775357SMatthias Ringwald 50553deb3ec6SMatthias Ringwald void sm_init(void){ 50562d2d4d3cSMatthias Ringwald 50572d2d4d3cSMatthias Ringwald if (sm_initialized) return; 50582d2d4d3cSMatthias Ringwald 5059899e6e02SMatthias Ringwald // set default ER and IR values (should be unique - set by app or sm later using TLV) 5060899e6e02SMatthias Ringwald sm_er_ir_set_default(); 5061899e6e02SMatthias Ringwald 50623deb3ec6SMatthias Ringwald // defaults 50633deb3ec6SMatthias Ringwald sm_accepted_stk_generation_methods = SM_STK_GENERATION_METHOD_JUST_WORKS 50643deb3ec6SMatthias Ringwald | SM_STK_GENERATION_METHOD_OOB 5065b4343428SMatthias Ringwald | SM_STK_GENERATION_METHOD_PASSKEY 5066b4343428SMatthias Ringwald | SM_STK_GENERATION_METHOD_NUMERIC_COMPARISON; 5067b4343428SMatthias Ringwald 50683deb3ec6SMatthias Ringwald sm_max_encryption_key_size = 16; 50693deb3ec6SMatthias Ringwald sm_min_encryption_key_size = 7; 50703deb3ec6SMatthias Ringwald 50715ce1359eSMatthias Ringwald sm_fixed_passkey_in_display_role = 0xffffffffU; 50721979f09cSMatthias Ringwald sm_reconstruct_ltk_without_le_device_db_entry = true; 5073caf15bf3SMatthias Ringwald 50743deb3ec6SMatthias Ringwald gap_random_adress_update_period = 15 * 60 * 1000L; 50753deb3ec6SMatthias Ringwald 5076841468bbSMatthias Ringwald test_use_fixed_local_csrk = false; 50773deb3ec6SMatthias Ringwald 50787f775357SMatthias Ringwald // other 507984c0c5c7SMatthias Ringwald btstack_run_loop_set_timer_handler(&sm_run_timer, &sm_run_timer_handler); 508084c0c5c7SMatthias Ringwald 5081a036ae12SMatthias Ringwald // register for HCI Events 5082e03e489aSMatthias Ringwald hci_event_callback_registration.callback = &sm_event_packet_handler; 5083e03e489aSMatthias Ringwald hci_add_event_handler(&hci_event_callback_registration); 5084e03e489aSMatthias Ringwald 5085bad51150SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 5086a036ae12SMatthias Ringwald // register for L2CAP events 5087a036ae12SMatthias Ringwald l2cap_event_callback_registration.callback = &sm_event_packet_handler; 5088a036ae12SMatthias Ringwald l2cap_add_event_handler(&l2cap_event_callback_registration); 5089bad51150SMatthias Ringwald #endif 5090a036ae12SMatthias Ringwald 5091d1a1f6a4SMatthias Ringwald // 5092d1a1f6a4SMatthias Ringwald btstack_crypto_init(); 5093d1a1f6a4SMatthias Ringwald 509451bd74d1SMatthias Ringwald // init le_device_db 509551bd74d1SMatthias Ringwald le_device_db_init(); 509651bd74d1SMatthias Ringwald 5097b170b20fSMatthias Ringwald // and L2CAP PDUs + L2CAP_EVENT_CAN_SEND_NOW 5098e03e489aSMatthias Ringwald l2cap_register_fixed_channel(sm_pdu_handler, L2CAP_CID_SECURITY_MANAGER_PROTOCOL); 5099384eabd3SMatthias Ringwald #ifdef ENABLE_CLASSIC 5100384eabd3SMatthias Ringwald l2cap_register_fixed_channel(sm_pdu_handler, L2CAP_CID_BR_EDR_SECURITY_MANAGER); 5101384eabd3SMatthias Ringwald #endif 510227c32905SMatthias Ringwald 51037f775357SMatthias Ringwald // state 51047f775357SMatthias Ringwald sm_state_reset(); 51052d2d4d3cSMatthias Ringwald 51062d2d4d3cSMatthias Ringwald sm_initialized = true; 51073deb3ec6SMatthias Ringwald } 51083deb3ec6SMatthias Ringwald 510915537ea4SMatthias Ringwald void sm_deinit(void){ 511015537ea4SMatthias Ringwald sm_initialized = false; 511115537ea4SMatthias Ringwald btstack_run_loop_remove_timer(&sm_run_timer); 511292f8d6b6SMatthias Ringwald #if defined(ENABLE_LE_SECURE_CONNECTIONS) && defined (ENABLE_LE_SECURE_CONNECTION_DEBUG_KEY) 5113db88441fSMatthias Ringwald sm_sc_debug_keys_enabled = false; 5114db88441fSMatthias Ringwald #endif 511515537ea4SMatthias Ringwald } 511615537ea4SMatthias Ringwald 51174b8c611fSMatthias Ringwald void sm_use_fixed_passkey_in_display_role(uint32_t passkey){ 51184b8c611fSMatthias Ringwald sm_fixed_passkey_in_display_role = passkey; 5119caf15bf3SMatthias Ringwald } 5120caf15bf3SMatthias Ringwald 51216c39055aSMatthias Ringwald void sm_allow_ltk_reconstruction_without_le_device_db_entry(int allow){ 51221979f09cSMatthias Ringwald sm_reconstruct_ltk_without_le_device_db_entry = allow != 0; 51236c39055aSMatthias Ringwald } 51246c39055aSMatthias Ringwald 5125711e6c80SMatthias Ringwald static sm_connection_t * sm_get_connection_for_handle(hci_con_handle_t con_handle){ 5126711e6c80SMatthias Ringwald hci_connection_t * hci_con = hci_connection_for_handle(con_handle); 51273deb3ec6SMatthias Ringwald if (!hci_con) return NULL; 51283deb3ec6SMatthias Ringwald return &hci_con->sm_connection; 51293deb3ec6SMatthias Ringwald } 51303deb3ec6SMatthias Ringwald 5131916ea5b2SMatthias Ringwald static void sm_cache_ltk(sm_connection_t * connection, const sm_key_t ltk){ 5132916ea5b2SMatthias Ringwald hci_connection_t * hci_con = hci_connection_for_handle(connection->sm_handle); 5133916ea5b2SMatthias Ringwald btstack_assert(hci_con != NULL); 5134916ea5b2SMatthias Ringwald memcpy(hci_con->link_key, ltk, 16); 5135916ea5b2SMatthias Ringwald hci_con->link_key_type = 1; 5136916ea5b2SMatthias Ringwald } 5137916ea5b2SMatthias Ringwald 513877e2e5edSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 513977e2e5edSMatthias Ringwald static sm_connection_t * sm_get_connection_for_bd_addr_and_type(bd_addr_t address, bd_addr_type_t addr_type){ 514077e2e5edSMatthias Ringwald hci_connection_t * hci_con = hci_connection_for_bd_addr_and_type(address, addr_type); 514177e2e5edSMatthias Ringwald if (!hci_con) return NULL; 514277e2e5edSMatthias Ringwald return &hci_con->sm_connection; 514377e2e5edSMatthias Ringwald } 514477e2e5edSMatthias Ringwald #endif 514577e2e5edSMatthias Ringwald 51466bc3aba4SMatthias Ringwald // @deprecated: map onto sm_request_pairing 5147711e6c80SMatthias Ringwald void sm_send_security_request(hci_con_handle_t con_handle){ 5148711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 51493deb3ec6SMatthias Ringwald if (!sm_conn) return; 51506bc3aba4SMatthias Ringwald if (!IS_RESPONDER(sm_conn->sm_role)) return; 51516bc3aba4SMatthias Ringwald sm_request_pairing(con_handle); 51523deb3ec6SMatthias Ringwald } 51533deb3ec6SMatthias Ringwald 51543deb3ec6SMatthias Ringwald // request pairing 5155711e6c80SMatthias Ringwald void sm_request_pairing(hci_con_handle_t con_handle){ 5156711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 51573deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 51583deb3ec6SMatthias Ringwald 51597af5dcd5SMatthias Ringwald bool have_ltk; 51607af5dcd5SMatthias Ringwald uint8_t ltk[16]; 51612d68601cSMatthias Ringwald bool auth_required; 51622d68601cSMatthias Ringwald int authenticated; 51632d68601cSMatthias Ringwald bool trigger_reencryption; 51643deb3ec6SMatthias Ringwald log_info("sm_request_pairing in role %u, state %u", sm_conn->sm_role, sm_conn->sm_engine_state); 516542134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 516624c20dc4SMatthias Ringwald switch (sm_conn->sm_engine_state){ 516724c20dc4SMatthias Ringwald case SM_GENERAL_IDLE: 516824c20dc4SMatthias Ringwald case SM_RESPONDER_IDLE: 51697af5dcd5SMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 51707af5dcd5SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 51717af5dcd5SMatthias Ringwald le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); 51727af5dcd5SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 51737af5dcd5SMatthias Ringwald log_info("have ltk %u", have_ltk); 51747af5dcd5SMatthias Ringwald if (have_ltk){ 51755f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 517624c20dc4SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 51777af5dcd5SMatthias Ringwald sm_reencryption_started(sm_conn); 51787af5dcd5SMatthias Ringwald break; 51797af5dcd5SMatthias Ringwald } 51807af5dcd5SMatthias Ringwald /* fall through */ 51817af5dcd5SMatthias Ringwald 51827af5dcd5SMatthias Ringwald case IRK_LOOKUP_FAILED: 51835f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 51847af5dcd5SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 51857af5dcd5SMatthias Ringwald sm_pairing_started(sm_conn); 51867af5dcd5SMatthias Ringwald break; 51877af5dcd5SMatthias Ringwald default: 51887af5dcd5SMatthias Ringwald log_info("irk lookup pending"); 51895f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 51907af5dcd5SMatthias Ringwald break; 51917af5dcd5SMatthias Ringwald } 519224c20dc4SMatthias Ringwald break; 519324c20dc4SMatthias Ringwald default: 519424c20dc4SMatthias Ringwald break; 519524c20dc4SMatthias Ringwald } 51963deb3ec6SMatthias Ringwald } else { 51973deb3ec6SMatthias Ringwald // used as a trigger to start central/master/initiator security procedures 5198175b7faaSMatthias Ringwald switch (sm_conn->sm_engine_state){ 5199175b7faaSMatthias Ringwald case SM_INITIATOR_CONNECTED: 52003deb3ec6SMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 52013deb3ec6SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 52022d68601cSMatthias Ringwald le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, &authenticated, NULL, NULL); 5203f53ec649SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 52042d68601cSMatthias Ringwald auth_required = sm_auth_req & SM_AUTHREQ_MITM_PROTECTION; 52052d68601cSMatthias Ringwald // re-encrypt is sufficient if we have ltk and that is either already authenticated or we don't require authentication 52062d68601cSMatthias Ringwald trigger_reencryption = have_ltk && ((authenticated != 0) || (auth_required == false)); 52072d68601cSMatthias Ringwald log_info("have ltk %u, authenticated %u, auth required %u => reencrypt %u", have_ltk, authenticated, auth_required, trigger_reencryption); 52082d68601cSMatthias Ringwald if (trigger_reencryption){ 52095f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 52105567aa60SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH4_HAS_LTK; 5211c245ca32SMatthias Ringwald break; 5212f53ec649SMatthias Ringwald } 5213cf373d3aSMatthias Ringwald /* fall through */ 5214c245ca32SMatthias Ringwald 521534c39fbdSMatthias Ringwald case IRK_LOOKUP_FAILED: 52163deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 52173deb3ec6SMatthias Ringwald break; 52183deb3ec6SMatthias Ringwald default: 5219d1a1f6a4SMatthias Ringwald log_info("irk lookup pending"); 52205f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 52213deb3ec6SMatthias Ringwald break; 52223deb3ec6SMatthias Ringwald } 5223175b7faaSMatthias Ringwald break; 5224cb6d7eb0SMatthias Ringwald case SM_GENERAL_REENCRYPTION_FAILED: 5225cb6d7eb0SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 5226cb6d7eb0SMatthias Ringwald break; 5227175b7faaSMatthias Ringwald case SM_GENERAL_IDLE: 52285f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 5229175b7faaSMatthias Ringwald break; 5230175b7faaSMatthias Ringwald default: 5231175b7faaSMatthias Ringwald break; 52323deb3ec6SMatthias Ringwald } 52333deb3ec6SMatthias Ringwald } 523470b44dd4SMatthias Ringwald sm_trigger_run(); 52353deb3ec6SMatthias Ringwald } 52363deb3ec6SMatthias Ringwald 52373deb3ec6SMatthias Ringwald // called by client app on authorization request 5238711e6c80SMatthias Ringwald void sm_authorization_decline(hci_con_handle_t con_handle){ 5239711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 52403deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 52413deb3ec6SMatthias Ringwald sm_conn->sm_connection_authorization_state = AUTHORIZATION_DECLINED; 5242589f5a99SMatthias Ringwald sm_notify_client_status(SM_EVENT_AUTHORIZATION_RESULT, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address, 0); 52433deb3ec6SMatthias Ringwald } 52443deb3ec6SMatthias Ringwald 5245711e6c80SMatthias Ringwald void sm_authorization_grant(hci_con_handle_t con_handle){ 5246711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 52473deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 52483deb3ec6SMatthias Ringwald sm_conn->sm_connection_authorization_state = AUTHORIZATION_GRANTED; 5249589f5a99SMatthias Ringwald sm_notify_client_status(SM_EVENT_AUTHORIZATION_RESULT, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address, 1); 52503deb3ec6SMatthias Ringwald } 52513deb3ec6SMatthias Ringwald 52523deb3ec6SMatthias Ringwald // GAP Bonding API 52533deb3ec6SMatthias Ringwald 5254711e6c80SMatthias Ringwald void sm_bonding_decline(hci_con_handle_t con_handle){ 5255711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 52563deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 52573deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_DECLINE; 52580af429c6SMatthias Ringwald log_info("decline, state %u", sm_conn->sm_engine_state); 52590af429c6SMatthias Ringwald switch(sm_conn->sm_engine_state){ 52600af429c6SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 52610af429c6SMatthias Ringwald case SM_SC_W4_USER_RESPONSE: 52620af429c6SMatthias Ringwald case SM_SC_W4_CONFIRMATION: 52630af429c6SMatthias Ringwald case SM_SC_W4_PUBLIC_KEY_COMMAND: 52640af429c6SMatthias Ringwald #endif 52650af429c6SMatthias Ringwald case SM_PH1_W4_USER_RESPONSE: 5266de2fd182SMatthias Ringwald switch (setup->sm_stk_generation_method){ 5267de2fd182SMatthias Ringwald case PK_RESP_INPUT: 5268de2fd182SMatthias Ringwald case PK_INIT_INPUT: 526947fb4255SMatthias Ringwald case PK_BOTH_INPUT: 52700af429c6SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_PASSKEY_ENTRY_FAILED); 5271de2fd182SMatthias Ringwald break; 527247fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 5273de2fd182SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_NUMERIC_COMPARISON_FAILED); 5274de2fd182SMatthias Ringwald break; 5275de2fd182SMatthias Ringwald case JUST_WORKS: 5276de2fd182SMatthias Ringwald case OOB: 5277de2fd182SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_UNSPECIFIED_REASON); 5278de2fd182SMatthias Ringwald break; 52797bbeb3adSMilanka Ringwald default: 52807bbeb3adSMilanka Ringwald btstack_assert(false); 52817bbeb3adSMilanka Ringwald break; 5282de2fd182SMatthias Ringwald } 52830af429c6SMatthias Ringwald break; 52840af429c6SMatthias Ringwald default: 52850af429c6SMatthias Ringwald break; 52863deb3ec6SMatthias Ringwald } 528770b44dd4SMatthias Ringwald sm_trigger_run(); 52883deb3ec6SMatthias Ringwald } 52893deb3ec6SMatthias Ringwald 5290711e6c80SMatthias Ringwald void sm_just_works_confirm(hci_con_handle_t con_handle){ 5291711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 52923deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 52933deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_CONFIRM; 52943deb3ec6SMatthias Ringwald if (sm_conn->sm_engine_state == SM_PH1_W4_USER_RESPONSE){ 5295136d331aSMatthias Ringwald if (setup->sm_use_secure_connections){ 5296c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 5297bbf8db22SMatthias Ringwald } else { 5298f3582630SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_random, 16, &sm_handle_random_result_ph2_random, (void *)(uintptr_t) sm_conn->sm_handle); 5299136d331aSMatthias Ringwald } 53003deb3ec6SMatthias Ringwald } 53010346c37cSMatthias Ringwald 53020346c37cSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 5303c6b7cbd9SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_USER_RESPONSE){ 5304dc300847SMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 5305446a8c36SMatthias Ringwald } 53060346c37cSMatthias Ringwald #endif 53070346c37cSMatthias Ringwald 530870b44dd4SMatthias Ringwald sm_trigger_run(); 53093deb3ec6SMatthias Ringwald } 53103deb3ec6SMatthias Ringwald 5311c8c46d51SMatthias Ringwald void sm_numeric_comparison_confirm(hci_con_handle_t con_handle){ 5312c8c46d51SMatthias Ringwald // for now, it's the same 5313c8c46d51SMatthias Ringwald sm_just_works_confirm(con_handle); 5314c8c46d51SMatthias Ringwald } 5315c8c46d51SMatthias Ringwald 5316711e6c80SMatthias Ringwald void sm_passkey_input(hci_con_handle_t con_handle, uint32_t passkey){ 5317711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 53183deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 53193deb3ec6SMatthias Ringwald sm_reset_tk(); 5320f8fbdce0SMatthias Ringwald big_endian_store_32(setup->sm_tk, 12, passkey); 53213deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_PASSKEY; 53223deb3ec6SMatthias Ringwald if (sm_conn->sm_engine_state == SM_PH1_W4_USER_RESPONSE){ 5323f3582630SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_random, 16, &sm_handle_random_result_ph2_random, (void *)(uintptr_t) sm_conn->sm_handle); 53243deb3ec6SMatthias Ringwald } 53251c516d8fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 53266535961aSMatthias Ringwald (void)memcpy(setup->sm_ra, setup->sm_tk, 16); 53276535961aSMatthias Ringwald (void)memcpy(setup->sm_rb, setup->sm_tk, 16); 532807036a04SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_USER_RESPONSE){ 532907036a04SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 533007036a04SMatthias Ringwald } 53311c516d8fSMatthias Ringwald #endif 533270b44dd4SMatthias Ringwald sm_trigger_run(); 53333deb3ec6SMatthias Ringwald } 53343deb3ec6SMatthias Ringwald 53353d7fe1e9SMatthias Ringwald void sm_keypress_notification(hci_con_handle_t con_handle, uint8_t action){ 53363d7fe1e9SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 53373d7fe1e9SMatthias Ringwald if (!sm_conn) return; // wrong connection 53383d7fe1e9SMatthias Ringwald if (action > SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED) return; 5339dd4a08fbSMatthias Ringwald uint8_t num_actions = setup->sm_keypress_notification >> 5; 53404ea43905SMatthias Ringwald uint8_t flags = setup->sm_keypress_notification & 0x1fu; 5341dd4a08fbSMatthias Ringwald switch (action){ 5342dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_STARTED: 5343dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED: 53444ea43905SMatthias Ringwald flags |= (1u << action); 5345dd4a08fbSMatthias Ringwald break; 5346dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_CLEARED: 5347dd4a08fbSMatthias Ringwald // clear counter, keypress & erased flags + set passkey cleared 53484ea43905SMatthias Ringwald flags = (flags & 0x19u) | (1u << SM_KEYPRESS_PASSKEY_CLEARED); 5349dd4a08fbSMatthias Ringwald break; 5350dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ENTERED: 53511d80f1e6SMatthias Ringwald if ((flags & (1u << SM_KEYPRESS_PASSKEY_DIGIT_ERASED)) != 0u){ 5352dd4a08fbSMatthias Ringwald // erase actions queued 5353dd4a08fbSMatthias Ringwald num_actions--; 53544ea43905SMatthias Ringwald if (num_actions == 0u){ 5355dd4a08fbSMatthias Ringwald // clear counter, keypress & erased flags 53564ea43905SMatthias Ringwald flags &= 0x19u; 5357dd4a08fbSMatthias Ringwald } 5358dd4a08fbSMatthias Ringwald break; 5359dd4a08fbSMatthias Ringwald } 5360dd4a08fbSMatthias Ringwald num_actions++; 53614ea43905SMatthias Ringwald flags |= (1u << SM_KEYPRESS_PASSKEY_DIGIT_ENTERED); 5362dd4a08fbSMatthias Ringwald break; 5363dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ERASED: 53641d80f1e6SMatthias Ringwald if ((flags & (1u << SM_KEYPRESS_PASSKEY_DIGIT_ENTERED)) != 0u){ 5365dd4a08fbSMatthias Ringwald // enter actions queued 5366dd4a08fbSMatthias Ringwald num_actions--; 53674ea43905SMatthias Ringwald if (num_actions == 0u){ 5368dd4a08fbSMatthias Ringwald // clear counter, keypress & erased flags 53694ea43905SMatthias Ringwald flags &= 0x19u; 5370dd4a08fbSMatthias Ringwald } 5371dd4a08fbSMatthias Ringwald break; 5372dd4a08fbSMatthias Ringwald } 5373dd4a08fbSMatthias Ringwald num_actions++; 53744ea43905SMatthias Ringwald flags |= (1u << SM_KEYPRESS_PASSKEY_DIGIT_ERASED); 5375dd4a08fbSMatthias Ringwald break; 5376dd4a08fbSMatthias Ringwald default: 5377dd4a08fbSMatthias Ringwald break; 5378dd4a08fbSMatthias Ringwald } 5379dd4a08fbSMatthias Ringwald setup->sm_keypress_notification = (num_actions << 5) | flags; 538070b44dd4SMatthias Ringwald sm_trigger_run(); 53813d7fe1e9SMatthias Ringwald } 53823d7fe1e9SMatthias Ringwald 5383c59d0c92SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 5384d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_oob(void * arg){ 5385d1a1f6a4SMatthias Ringwald UNUSED(arg); 5386d1a1f6a4SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_W2_CALC_CONFIRM; 538770b44dd4SMatthias Ringwald sm_trigger_run(); 5388d1a1f6a4SMatthias Ringwald } 5389c59d0c92SMatthias Ringwald uint8_t sm_generate_sc_oob_data(void (*callback)(const uint8_t * confirm_value, const uint8_t * random_value)){ 53908334d3d8SMatthias Ringwald 53918334d3d8SMatthias Ringwald static btstack_crypto_random_t sm_crypto_random_oob_request; 53928334d3d8SMatthias Ringwald 5393c59d0c92SMatthias Ringwald if (sm_sc_oob_state != SM_SC_OOB_IDLE) return ERROR_CODE_COMMAND_DISALLOWED; 5394c59d0c92SMatthias Ringwald sm_sc_oob_callback = callback; 5395d1a1f6a4SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_W4_RANDOM; 5396d1a1f6a4SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_oob_request, sm_sc_oob_random, 16, &sm_handle_random_result_oob, NULL); 5397c59d0c92SMatthias Ringwald return 0; 5398c59d0c92SMatthias Ringwald } 5399c59d0c92SMatthias Ringwald #endif 5400c59d0c92SMatthias Ringwald 54013deb3ec6SMatthias Ringwald /** 5402ba394633SMatthias Ringwald * @brief Get Identity Resolving state 5403ba394633SMatthias Ringwald * @param con_handle 5404ba394633SMatthias Ringwald * @return irk_lookup_state_t 5405ba394633SMatthias Ringwald */ 5406ba394633SMatthias Ringwald irk_lookup_state_t sm_identity_resolving_state(hci_con_handle_t con_handle){ 5407ba394633SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 5408ba394633SMatthias Ringwald if (!sm_conn) return IRK_LOOKUP_IDLE; 5409ba394633SMatthias Ringwald return sm_conn->sm_irk_lookup_state; 5410ba394633SMatthias Ringwald } 5411ba394633SMatthias Ringwald 5412ba394633SMatthias Ringwald /** 54133deb3ec6SMatthias Ringwald * @brief Identify device in LE Device DB 54143deb3ec6SMatthias Ringwald * @param handle 54156b65794dSMilanka Ringwald * @return index from le_device_db or -1 if not found/identified 54163deb3ec6SMatthias Ringwald */ 5417711e6c80SMatthias Ringwald int sm_le_device_index(hci_con_handle_t con_handle ){ 5418711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 54193deb3ec6SMatthias Ringwald if (!sm_conn) return -1; 54203deb3ec6SMatthias Ringwald return sm_conn->sm_le_db_index; 54213deb3ec6SMatthias Ringwald } 54223deb3ec6SMatthias Ringwald 5423916ea5b2SMatthias Ringwald uint8_t sm_get_ltk(hci_con_handle_t con_handle, sm_key_t ltk){ 5424916ea5b2SMatthias Ringwald hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); 5425916ea5b2SMatthias Ringwald if (hci_connection == NULL){ 5426916ea5b2SMatthias Ringwald return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 5427916ea5b2SMatthias Ringwald } 5428916ea5b2SMatthias Ringwald if (hci_connection->link_key_type == 0){ 5429916ea5b2SMatthias Ringwald return ERROR_CODE_PIN_OR_KEY_MISSING; 5430916ea5b2SMatthias Ringwald } 5431916ea5b2SMatthias Ringwald memcpy(ltk, hci_connection->link_key, 16); 5432916ea5b2SMatthias Ringwald return ERROR_CODE_SUCCESS; 5433916ea5b2SMatthias Ringwald } 5434916ea5b2SMatthias Ringwald 54358f57b085SMatthias Ringwald static int gap_random_address_type_requires_updates(void){ 543647ba4de1SMatthias Ringwald switch (gap_random_adress_type){ 543747ba4de1SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_OFF: 543847ba4de1SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_STATIC: 543947ba4de1SMatthias Ringwald return 0; 544047ba4de1SMatthias Ringwald default: 54418f57b085SMatthias Ringwald return 1; 54428f57b085SMatthias Ringwald } 544347ba4de1SMatthias Ringwald } 5444d70217a2SMatthias Ringwald 544533373e40SMatthias Ringwald static uint8_t own_address_type(void){ 5446b95a5a35SMatthias Ringwald switch (gap_random_adress_type){ 5447b95a5a35SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_OFF: 5448b95a5a35SMatthias Ringwald return BD_ADDR_TYPE_LE_PUBLIC; 5449b95a5a35SMatthias Ringwald default: 5450b95a5a35SMatthias Ringwald return BD_ADDR_TYPE_LE_RANDOM; 5451b95a5a35SMatthias Ringwald } 545233373e40SMatthias Ringwald } 54538f57b085SMatthias Ringwald 54543deb3ec6SMatthias Ringwald // GAP LE API 54553deb3ec6SMatthias Ringwald void gap_random_address_set_mode(gap_random_address_type_t random_address_type){ 54563deb3ec6SMatthias Ringwald gap_random_address_update_stop(); 54573deb3ec6SMatthias Ringwald gap_random_adress_type = random_address_type; 5458b95a5a35SMatthias Ringwald hci_le_set_own_address_type(own_address_type()); 54598f57b085SMatthias Ringwald if (!gap_random_address_type_requires_updates()) return; 54603deb3ec6SMatthias Ringwald gap_random_address_update_start(); 54613deb3ec6SMatthias Ringwald gap_random_address_trigger(); 54623deb3ec6SMatthias Ringwald } 54633deb3ec6SMatthias Ringwald 54643deb3ec6SMatthias Ringwald gap_random_address_type_t gap_random_address_get_mode(void){ 54653deb3ec6SMatthias Ringwald return gap_random_adress_type; 54663deb3ec6SMatthias Ringwald } 54673deb3ec6SMatthias Ringwald 54683deb3ec6SMatthias Ringwald void gap_random_address_set_update_period(int period_ms){ 54693deb3ec6SMatthias Ringwald gap_random_adress_update_period = period_ms; 54708f57b085SMatthias Ringwald if (!gap_random_address_type_requires_updates()) return; 54713deb3ec6SMatthias Ringwald gap_random_address_update_stop(); 54723deb3ec6SMatthias Ringwald gap_random_address_update_start(); 54733deb3ec6SMatthias Ringwald } 54743deb3ec6SMatthias Ringwald 5475667ba9d1SMatthias Ringwald void gap_random_address_set(const bd_addr_t addr){ 54768f57b085SMatthias Ringwald gap_random_address_set_mode(GAP_RANDOM_ADDRESS_TYPE_STATIC); 54776535961aSMatthias Ringwald (void)memcpy(sm_random_address, addr, 6); 547863d302e8SMatthias Ringwald // assert msb bits are set to '11' 547963d302e8SMatthias Ringwald sm_random_address[0] |= 0xc0; 548063d302e8SMatthias Ringwald hci_le_random_address_set(sm_random_address); 54817e252622SMatthias Ringwald } 54827e252622SMatthias Ringwald 5483d70217a2SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 54843deb3ec6SMatthias Ringwald /* 54853deb3ec6SMatthias Ringwald * @brief Set Advertisement Paramters 54863deb3ec6SMatthias Ringwald * @param adv_int_min 54873deb3ec6SMatthias Ringwald * @param adv_int_max 54883deb3ec6SMatthias Ringwald * @param adv_type 54893deb3ec6SMatthias Ringwald * @param direct_address_type 54903deb3ec6SMatthias Ringwald * @param direct_address 54913deb3ec6SMatthias Ringwald * @param channel_map 54923deb3ec6SMatthias Ringwald * @param filter_policy 54933deb3ec6SMatthias Ringwald * 54943deb3ec6SMatthias Ringwald * @note own_address_type is used from gap_random_address_set_mode 54953deb3ec6SMatthias Ringwald */ 54963deb3ec6SMatthias Ringwald void gap_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, 54973deb3ec6SMatthias Ringwald uint8_t direct_address_typ, bd_addr_t direct_address, uint8_t channel_map, uint8_t filter_policy){ 5498b95a5a35SMatthias Ringwald hci_le_advertisements_set_params(adv_int_min, adv_int_max, adv_type, 54993deb3ec6SMatthias Ringwald direct_address_typ, direct_address, channel_map, filter_policy); 55003deb3ec6SMatthias Ringwald } 5501d70217a2SMatthias Ringwald #endif 5502dcd6c9b5SMatthias Ringwald 5503c7ceba59SMatthias Ringwald bool gap_reconnect_security_setup_active(hci_con_handle_t con_handle){ 5504dcd6c9b5SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 5505dcd6c9b5SMatthias Ringwald // wrong connection 5506c7ceba59SMatthias Ringwald if (!sm_conn) return false; 5507dcd6c9b5SMatthias Ringwald // already encrypted 5508c7ceba59SMatthias Ringwald if (sm_conn->sm_connection_encrypted) return false; 5509dcd6c9b5SMatthias Ringwald // irk status? 5510dcd6c9b5SMatthias Ringwald switch(sm_conn->sm_irk_lookup_state){ 5511dcd6c9b5SMatthias Ringwald case IRK_LOOKUP_FAILED: 5512dcd6c9b5SMatthias Ringwald // done, cannot setup encryption 5513c7ceba59SMatthias Ringwald return false; 5514dcd6c9b5SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 5515dcd6c9b5SMatthias Ringwald break; 5516dcd6c9b5SMatthias Ringwald default: 5517dcd6c9b5SMatthias Ringwald // IR Lookup pending 5518c7ceba59SMatthias Ringwald return true; 5519dcd6c9b5SMatthias Ringwald } 5520f0674e22SMatthias Ringwald // IRK Lookup Succeeded, re-encryption should be initiated. When done, state gets reset or indicates failure 5521c7ceba59SMatthias Ringwald if (sm_conn->sm_engine_state == SM_GENERAL_REENCRYPTION_FAILED) return false; 5522c7ceba59SMatthias Ringwald if (sm_conn->sm_role != 0){ 5523b15d5ceaSMatthias Ringwald return sm_conn->sm_engine_state != SM_RESPONDER_IDLE; 5524b15d5ceaSMatthias Ringwald } else { 5525dcd6c9b5SMatthias Ringwald return sm_conn->sm_engine_state != SM_INITIATOR_CONNECTED; 5526dcd6c9b5SMatthias Ringwald } 5527b15d5ceaSMatthias Ringwald } 55283cdbe9dbSMatthias Ringwald 55293cdbe9dbSMatthias Ringwald void sm_set_secure_connections_only_mode(bool enable){ 55303cdbe9dbSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 55313cdbe9dbSMatthias Ringwald sm_sc_only_mode = enable; 55323cdbe9dbSMatthias Ringwald #else 55333cdbe9dbSMatthias Ringwald // SC Only mode not possible without support for SC 55343cdbe9dbSMatthias Ringwald btstack_assert(enable == false); 55353cdbe9dbSMatthias Ringwald #endif 55363cdbe9dbSMatthias Ringwald } 5537052bbdc5SMatthias Ringwald 553892f8d6b6SMatthias Ringwald #if defined(ENABLE_LE_SECURE_CONNECTIONS) && defined (ENABLE_LE_SECURE_CONNECTION_DEBUG_KEY) 5539db88441fSMatthias Ringwald void sm_test_enable_secure_connections_debug_keys(void) { 5540db88441fSMatthias Ringwald log_info("Enable LE Secure Connection Debug Keys for testing"); 5541db88441fSMatthias Ringwald sm_sc_debug_keys_enabled = true; 5542db88441fSMatthias Ringwald // set debug key 5543db88441fSMatthias Ringwald sm_ec_generate_new_key(); 5544db88441fSMatthias Ringwald } 5545db88441fSMatthias Ringwald #endif 5546db88441fSMatthias Ringwald 5547052bbdc5SMatthias Ringwald const uint8_t * gap_get_persistent_irk(void){ 5548052bbdc5SMatthias Ringwald return sm_persistent_irk; 5549052bbdc5SMatthias Ringwald } 55504f384501SMatthias Ringwald 55514f384501SMatthias Ringwald void gap_delete_bonding(bd_addr_type_t address_type, bd_addr_t address){ 555222cb578bSMatthias Ringwald int index = sm_le_device_db_index_lookup(address_type, address); 555322cb578bSMatthias Ringwald if (index >= 0){ 555422cb578bSMatthias Ringwald sm_remove_le_device_db_entry(index); 55554f384501SMatthias Ringwald } 55564f384501SMatthias Ringwald } 5557