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 5629da9850bSMatthias Ringwald hci_dump_btstack_event(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 12044361507fSMatthias Ringwald log_info("our address %s type %u", bd_addr_to_str(sm_conn->sm_own_address), sm_conn->sm_own_addr_type); 12054361507fSMatthias Ringwald log_info("peer address %s type %u", bd_addr_to_str(sm_conn->sm_peer_address), sm_conn->sm_peer_addr_type); 12064361507fSMatthias Ringwald 120757132f12SMatthias Ringwald uint8_t auth_req = sm_auth_req & ~SM_AUTHREQ_CT2; 1208d0ea782aSMatthias Ringwald uint8_t max_encryption_key_size = sm_max_encryption_key_size; 12092c041b42SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 12102c041b42SMatthias Ringwald // enable SC for SC only mode 12112c041b42SMatthias Ringwald if (sm_sc_only_mode){ 12122c041b42SMatthias Ringwald auth_req |= SM_AUTHREQ_SECURE_CONNECTION; 1213d0ea782aSMatthias Ringwald max_encryption_key_size = 16; 12142c041b42SMatthias Ringwald } 12152c041b42SMatthias Ringwald #endif 121657132f12SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 121757132f12SMatthias Ringwald // set CT2 if SC + Bonding + CTKD 121857132f12SMatthias Ringwald const uint8_t auth_req_for_ct2 = SM_AUTHREQ_SECURE_CONNECTION | SM_AUTHREQ_BONDING; 121957132f12SMatthias Ringwald if ((auth_req & auth_req_for_ct2) == auth_req_for_ct2){ 122057132f12SMatthias Ringwald auth_req |= SM_AUTHREQ_CT2; 122157132f12SMatthias Ringwald } 122257132f12SMatthias Ringwald #endif 12231ad129beSMatthias Ringwald sm_pairing_packet_set_io_capability(*local_packet, sm_io_capabilities); 1224a680ba6bSMatthias Ringwald sm_pairing_packet_set_oob_data_flag(*local_packet, setup->sm_have_oob_data); 1225df86eb96SMatthias Ringwald sm_pairing_packet_set_auth_req(*local_packet, auth_req); 1226d0ea782aSMatthias Ringwald sm_pairing_packet_set_max_encryption_key_size(*local_packet, max_encryption_key_size); 12273deb3ec6SMatthias Ringwald } 12283deb3ec6SMatthias Ringwald 12293deb3ec6SMatthias Ringwald static int sm_stk_generation_init(sm_connection_t * sm_conn){ 12303deb3ec6SMatthias Ringwald 12313deb3ec6SMatthias Ringwald sm_pairing_packet_t * remote_packet; 12329a90d41aSMatthias Ringwald uint8_t keys_to_send; 12339a90d41aSMatthias Ringwald uint8_t keys_to_receive; 123442134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 123552f9cf63SMatthias Ringwald // slave / responder 12363deb3ec6SMatthias Ringwald remote_packet = &setup->sm_m_preq; 12379a90d41aSMatthias Ringwald keys_to_send = sm_pairing_packet_get_responder_key_distribution(setup->sm_m_preq); 12389a90d41aSMatthias Ringwald keys_to_receive = sm_pairing_packet_get_initiator_key_distribution(setup->sm_m_preq); 12393deb3ec6SMatthias Ringwald } else { 12403deb3ec6SMatthias Ringwald // master / initiator 12413deb3ec6SMatthias Ringwald remote_packet = &setup->sm_s_pres; 12429a90d41aSMatthias Ringwald keys_to_send = sm_pairing_packet_get_initiator_key_distribution(setup->sm_s_pres); 12439a90d41aSMatthias Ringwald keys_to_receive = sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres); 12443deb3ec6SMatthias Ringwald } 12453deb3ec6SMatthias Ringwald 12463deb3ec6SMatthias Ringwald // check key size 12472c041b42SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 12482c041b42SMatthias Ringwald // SC Only mandates 128 bit key size 12492c041b42SMatthias Ringwald if (sm_sc_only_mode && (sm_pairing_packet_get_max_encryption_key_size(*remote_packet) < 16)) { 12502c041b42SMatthias Ringwald return SM_REASON_ENCRYPTION_KEY_SIZE; 12512c041b42SMatthias Ringwald } 12522c041b42SMatthias Ringwald #endif 12531ad129beSMatthias Ringwald sm_conn->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(sm_pairing_packet_get_max_encryption_key_size(*remote_packet)); 12544ea43905SMatthias Ringwald if (sm_conn->sm_actual_encryption_key_size == 0u) return SM_REASON_ENCRYPTION_KEY_SIZE; 12553deb3ec6SMatthias Ringwald 1256eddc894fSMatthias Ringwald // decide on STK generation method / SC 12573deb3ec6SMatthias Ringwald sm_setup_tk(); 12583deb3ec6SMatthias Ringwald log_info("SMP: generation method %u", setup->sm_stk_generation_method); 12593deb3ec6SMatthias Ringwald 12603deb3ec6SMatthias Ringwald // check if STK generation method is acceptable by client 12613deb3ec6SMatthias Ringwald if (!sm_validate_stk_generation_method()) return SM_REASON_AUTHENTHICATION_REQUIREMENTS; 12623deb3ec6SMatthias Ringwald 1263eddc894fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 12642c041b42SMatthias Ringwald // Check LE SC Only mode 12653cdbe9dbSMatthias Ringwald if (sm_sc_only_mode && (setup->sm_use_secure_connections == false)){ 12663cdbe9dbSMatthias Ringwald log_info("SC Only mode active but SC not possible"); 12673cdbe9dbSMatthias Ringwald return SM_REASON_AUTHENTHICATION_REQUIREMENTS; 12683cdbe9dbSMatthias Ringwald } 12693cdbe9dbSMatthias Ringwald 12709a90d41aSMatthias Ringwald // LTK (= encryption information & master identification) only used exchanged for LE Legacy Connection 1271eddc894fSMatthias Ringwald if (setup->sm_use_secure_connections){ 12729a90d41aSMatthias Ringwald keys_to_send &= ~SM_KEYDIST_ENC_KEY; 12739a90d41aSMatthias Ringwald keys_to_receive &= ~SM_KEYDIST_ENC_KEY; 1274eddc894fSMatthias Ringwald } 1275eddc894fSMatthias Ringwald #endif 1276eddc894fSMatthias Ringwald 127752f9cf63SMatthias Ringwald // identical to responder 12789a90d41aSMatthias Ringwald sm_setup_key_distribution(keys_to_send, keys_to_receive); 127952f9cf63SMatthias Ringwald 12803deb3ec6SMatthias Ringwald // JUST WORKS doens't provide authentication 1281c1ab6cc1SMatthias Ringwald sm_conn->sm_connection_authenticated = (setup->sm_stk_generation_method == JUST_WORKS) ? 0 : 1; 12823deb3ec6SMatthias Ringwald 12833deb3ec6SMatthias Ringwald return 0; 12843deb3ec6SMatthias Ringwald } 12853deb3ec6SMatthias Ringwald 12863deb3ec6SMatthias Ringwald static void sm_address_resolution_handle_event(address_resolution_event_t event){ 12873deb3ec6SMatthias Ringwald 12883deb3ec6SMatthias Ringwald // cache and reset context 12893deb3ec6SMatthias Ringwald int matched_device_id = sm_address_resolution_test; 12903deb3ec6SMatthias Ringwald address_resolution_mode_t mode = sm_address_resolution_mode; 12913deb3ec6SMatthias Ringwald void * context = sm_address_resolution_context; 12923deb3ec6SMatthias Ringwald 12933deb3ec6SMatthias Ringwald // reset context 12943deb3ec6SMatthias Ringwald sm_address_resolution_mode = ADDRESS_RESOLUTION_IDLE; 12953deb3ec6SMatthias Ringwald sm_address_resolution_context = NULL; 12963deb3ec6SMatthias Ringwald sm_address_resolution_test = -1; 12973deb3ec6SMatthias Ringwald 129845d80b08SMatthias Ringwald hci_con_handle_t con_handle = HCI_CON_HANDLE_INVALID; 12993deb3ec6SMatthias Ringwald sm_connection_t * sm_connection; 1300d2e90122SMatthias Ringwald sm_key_t ltk; 13011979f09cSMatthias Ringwald bool have_ltk; 130245d80b08SMatthias Ringwald int authenticated; 13036c44b759SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 13041979f09cSMatthias Ringwald bool trigger_pairing; 130542134bc6SMatthias Ringwald #endif 130645d80b08SMatthias Ringwald 13073deb3ec6SMatthias Ringwald switch (mode){ 13083deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_GENERAL: 13093deb3ec6SMatthias Ringwald break; 13103deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_FOR_CONNECTION: 13113deb3ec6SMatthias Ringwald sm_connection = (sm_connection_t *) context; 1312711e6c80SMatthias Ringwald con_handle = sm_connection->sm_handle; 13136c44b759SMatthias Ringwald 13146c44b759SMatthias Ringwald // have ltk -> start encryption / send security request 13156c44b759SMatthias Ringwald // Core 5, Vol 3, Part C, 10.3.2 Initiating a Service Request 13166c44b759SMatthias Ringwald // "When a bond has been created between two devices, any reconnection should result in the local device 13176c44b759SMatthias Ringwald // enabling or requesting encryption with the remote device before initiating any service request." 13186c44b759SMatthias Ringwald 13193deb3ec6SMatthias Ringwald switch (event){ 1320a66b030fSMatthias Ringwald case ADDRESS_RESOLUTION_SUCCEEDED: 13213deb3ec6SMatthias Ringwald sm_connection->sm_irk_lookup_state = IRK_LOOKUP_SUCCEEDED; 13223deb3ec6SMatthias Ringwald sm_connection->sm_le_db_index = matched_device_id; 1323a66b030fSMatthias Ringwald log_info("ADDRESS_RESOLUTION_SUCCEEDED, index %d", sm_connection->sm_le_db_index); 13246c44b759SMatthias Ringwald 13252d68601cSMatthias Ringwald le_device_db_encryption_get(sm_connection->sm_le_db_index, NULL, NULL, ltk, NULL, &authenticated, NULL, NULL); 13266c44b759SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 13276c44b759SMatthias Ringwald 1328f688bdb8SMatthias Ringwald if (IS_RESPONDER(sm_connection->sm_role)) { 13296c44b759SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 1330212d735eSMatthias Ringwald // IRK required before, continue 13316c39055aSMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK){ 13326c39055aSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST; 13336c39055aSMatthias Ringwald break; 13346c39055aSMatthias Ringwald } 1335434260a1SMatthias Ringwald // Pairing request before, continue 1336212d735eSMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED_W4_IRK){ 1337212d735eSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED; 1338212d735eSMatthias Ringwald break; 1339212d735eSMatthias Ringwald } 1340728f6757SMatthias Ringwald bool trigger_security_request = sm_connection->sm_pairing_requested || sm_slave_request_security; 13415f3874afSMatthias Ringwald sm_connection->sm_pairing_requested = false; 13426c44b759SMatthias Ringwald #ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 13437af5dcd5SMatthias Ringwald // trigger security request for Proactive Authentication if LTK available 13447af5dcd5SMatthias Ringwald trigger_security_request = trigger_security_request || have_ltk; 13456c44b759SMatthias Ringwald #endif 13467af5dcd5SMatthias Ringwald 13477af5dcd5SMatthias Ringwald log_info("peripheral: pairing request local %u, have_ltk %u => trigger_security_request %u", 13485f3874afSMatthias Ringwald (int) sm_connection->sm_pairing_requested, (int) have_ltk, trigger_security_request); 13497af5dcd5SMatthias Ringwald 13507af5dcd5SMatthias Ringwald if (trigger_security_request){ 13517af5dcd5SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 13527af5dcd5SMatthias Ringwald if (have_ltk){ 13537af5dcd5SMatthias Ringwald sm_reencryption_started(sm_connection); 13547af5dcd5SMatthias Ringwald } else { 13557af5dcd5SMatthias Ringwald sm_pairing_started(sm_connection); 13567af5dcd5SMatthias Ringwald } 13577af5dcd5SMatthias Ringwald sm_trigger_run(); 13586c44b759SMatthias Ringwald } 13596c44b759SMatthias Ringwald #endif 13606c44b759SMatthias Ringwald } else { 13616c44b759SMatthias Ringwald 136242134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 13636c44b759SMatthias Ringwald // check if pairing already requested and reset requests 13646c44b759SMatthias Ringwald trigger_pairing = sm_connection->sm_pairing_requested || sm_connection->sm_security_request_received; 13652d68601cSMatthias Ringwald bool auth_required = sm_auth_req & SM_AUTHREQ_MITM_PROTECTION; 13662d68601cSMatthias Ringwald 13676c44b759SMatthias Ringwald log_info("central: pairing request local %u, remote %u => trigger_pairing %u. have_ltk %u", 13685f3874afSMatthias Ringwald (int) sm_connection->sm_pairing_requested, (int) sm_connection->sm_security_request_received, (int) trigger_pairing, (int) have_ltk); 13690dcaa15fSMatthias Ringwald sm_connection->sm_security_request_received = false; 13705f3874afSMatthias Ringwald sm_connection->sm_pairing_requested = false; 137132bc5d65SMatthias Ringwald bool trigger_reencryption = false; 1372c245ca32SMatthias Ringwald 1373d4af1595SMatthias Ringwald if (have_ltk){ 13742d68601cSMatthias Ringwald if (trigger_pairing){ 13752d68601cSMatthias Ringwald // if pairing is requested, re-encryption is sufficient, if ltk is already authenticated or we don't require authentication 13762d68601cSMatthias Ringwald trigger_reencryption = (authenticated != 0) || (auth_required == false); 13772d68601cSMatthias Ringwald } else { 13786a43f611SMatthias Ringwald #ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 1379b187cc61SMatthias Ringwald trigger_reencryption = true; 138032bc5d65SMatthias Ringwald #else 138132bc5d65SMatthias Ringwald log_info("central: defer enabling encryption for bonded device"); 138232bc5d65SMatthias Ringwald #endif 138332bc5d65SMatthias Ringwald } 13842d68601cSMatthias Ringwald } 138532bc5d65SMatthias Ringwald 138632bc5d65SMatthias Ringwald if (trigger_reencryption){ 13876c44b759SMatthias Ringwald log_info("central: enable encryption for bonded device"); 13885567aa60SMatthias Ringwald sm_connection->sm_engine_state = SM_INITIATOR_PH4_HAS_LTK; 1389d4af1595SMatthias Ringwald break; 1390d4af1595SMatthias Ringwald } 13916c44b759SMatthias Ringwald 13926c44b759SMatthias Ringwald // pairing_request -> send pairing request 13936c44b759SMatthias Ringwald if (trigger_pairing){ 13943deb3ec6SMatthias Ringwald sm_connection->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 1395d4af1595SMatthias Ringwald break; 13963deb3ec6SMatthias Ringwald } 139742134bc6SMatthias Ringwald #endif 1398298ab52bSMatthias Ringwald } 13993deb3ec6SMatthias Ringwald break; 14003deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_FAILED: 14013deb3ec6SMatthias Ringwald sm_connection->sm_irk_lookup_state = IRK_LOOKUP_FAILED; 1402f688bdb8SMatthias Ringwald if (IS_RESPONDER(sm_connection->sm_role)) { 14037af5dcd5SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 14046c39055aSMatthias Ringwald // LTK request received before, IRK required -> negative LTK reply 14056c39055aSMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK){ 14066c39055aSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY; 14076c39055aSMatthias Ringwald } 1408434260a1SMatthias Ringwald // Pairing request before, continue 1409434260a1SMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED_W4_IRK){ 1410434260a1SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED; 1411434260a1SMatthias Ringwald break; 1412434260a1SMatthias Ringwald } 14137af5dcd5SMatthias Ringwald // send security request if requested 1414728f6757SMatthias Ringwald bool trigger_security_request = sm_connection->sm_pairing_requested || sm_slave_request_security; 14155f3874afSMatthias Ringwald sm_connection->sm_pairing_requested = false; 14167af5dcd5SMatthias Ringwald if (trigger_security_request){ 14177af5dcd5SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 14187af5dcd5SMatthias Ringwald sm_pairing_started(sm_connection); 14197af5dcd5SMatthias Ringwald } 14206c39055aSMatthias Ringwald break; 14217af5dcd5SMatthias Ringwald #endif 14226c39055aSMatthias Ringwald } 142342134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 14245f3874afSMatthias Ringwald if ((sm_connection->sm_pairing_requested == false) && (sm_connection->sm_security_request_received == false)) break; 14250dcaa15fSMatthias Ringwald sm_connection->sm_security_request_received = false; 14265f3874afSMatthias Ringwald sm_connection->sm_pairing_requested = false; 14273deb3ec6SMatthias Ringwald sm_connection->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 142842134bc6SMatthias Ringwald #endif 14293deb3ec6SMatthias Ringwald break; 14307bbeb3adSMilanka Ringwald 14317bbeb3adSMilanka Ringwald default: 14327bbeb3adSMilanka Ringwald btstack_assert(false); 14337bbeb3adSMilanka Ringwald break; 14343deb3ec6SMatthias Ringwald } 14353deb3ec6SMatthias Ringwald break; 14363deb3ec6SMatthias Ringwald default: 14373deb3ec6SMatthias Ringwald break; 14383deb3ec6SMatthias Ringwald } 14393deb3ec6SMatthias Ringwald 14403deb3ec6SMatthias Ringwald switch (event){ 1441a66b030fSMatthias Ringwald case ADDRESS_RESOLUTION_SUCCEEDED: 1442711e6c80SMatthias Ringwald sm_notify_client_index(SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED, con_handle, sm_address_resolution_addr_type, sm_address_resolution_address, matched_device_id); 14433deb3ec6SMatthias Ringwald break; 14443deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_FAILED: 1445711e6c80SMatthias Ringwald sm_notify_client_base(SM_EVENT_IDENTITY_RESOLVING_FAILED, con_handle, sm_address_resolution_addr_type, sm_address_resolution_address); 14463deb3ec6SMatthias Ringwald break; 14477bbeb3adSMilanka Ringwald default: 14487bbeb3adSMilanka Ringwald btstack_assert(false); 14497bbeb3adSMilanka Ringwald break; 14503deb3ec6SMatthias Ringwald } 14513deb3ec6SMatthias Ringwald } 14523deb3ec6SMatthias Ringwald 145355f09f49SMatthias Ringwald static void sm_store_bonding_information(sm_connection_t * sm_conn){ 14543deb3ec6SMatthias Ringwald int le_db_index = -1; 14553deb3ec6SMatthias Ringwald 14563deb3ec6SMatthias Ringwald // lookup device based on IRK 1457f688bdb8SMatthias Ringwald if ((setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION) != 0u){ 14583deb3ec6SMatthias Ringwald int i; 1459092ec58eSMatthias Ringwald for (i=0; i < le_device_db_max_count(); i++){ 14603deb3ec6SMatthias Ringwald sm_key_t irk; 14613deb3ec6SMatthias Ringwald bd_addr_t address; 1462c7e2c1a5SMatthias Ringwald int address_type = BD_ADDR_TYPE_UNKNOWN; 14633deb3ec6SMatthias Ringwald le_device_db_info(i, &address_type, address, irk); 1464adf5eaa9SMatthias Ringwald // skip unused entries 1465c7e2c1a5SMatthias Ringwald if (address_type == BD_ADDR_TYPE_UNKNOWN) continue; 146611d10bdaSMatthias Ringwald // compare Identity Address 146711d10bdaSMatthias Ringwald if (memcmp(address, setup->sm_peer_address, 6) != 0) continue; 146811d10bdaSMatthias Ringwald // compare Identity Resolving Key 1469c7e2c1a5SMatthias Ringwald if (memcmp(irk, setup->sm_peer_irk, 16) != 0) continue; 1470c7e2c1a5SMatthias Ringwald 14713deb3ec6SMatthias Ringwald log_info("sm: device found for IRK, updating"); 14723deb3ec6SMatthias Ringwald le_db_index = i; 14733deb3ec6SMatthias Ringwald break; 14743deb3ec6SMatthias Ringwald } 1475c7e2c1a5SMatthias Ringwald } else { 1476c7e2c1a5SMatthias Ringwald // assert IRK is set to zero 1477c7e2c1a5SMatthias Ringwald memset(setup->sm_peer_irk, 0, 16); 14783deb3ec6SMatthias Ringwald } 14793deb3ec6SMatthias Ringwald 14803deb3ec6SMatthias Ringwald // if not found, lookup via public address if possible 14813deb3ec6SMatthias Ringwald log_info("sm peer addr type %u, peer addres %s", setup->sm_peer_addr_type, bd_addr_to_str(setup->sm_peer_address)); 1482c1ab6cc1SMatthias Ringwald if ((le_db_index < 0) && (setup->sm_peer_addr_type == BD_ADDR_TYPE_LE_PUBLIC)){ 14833deb3ec6SMatthias Ringwald int i; 1484092ec58eSMatthias Ringwald for (i=0; i < le_device_db_max_count(); i++){ 14853deb3ec6SMatthias Ringwald bd_addr_t address; 1486adf5eaa9SMatthias Ringwald int address_type = BD_ADDR_TYPE_UNKNOWN; 14873deb3ec6SMatthias Ringwald le_device_db_info(i, &address_type, address, NULL); 1488adf5eaa9SMatthias Ringwald // skip unused entries 1489adf5eaa9SMatthias Ringwald if (address_type == BD_ADDR_TYPE_UNKNOWN) continue; 14903deb3ec6SMatthias Ringwald log_info("device %u, sm peer addr type %u, peer addres %s", i, address_type, bd_addr_to_str(address)); 14915df9dc78SMatthias Ringwald if ((address_type == BD_ADDR_TYPE_LE_PUBLIC) && (memcmp(address, setup->sm_peer_address, 6) == 0)){ 14923deb3ec6SMatthias Ringwald log_info("sm: device found for public address, updating"); 14933deb3ec6SMatthias Ringwald le_db_index = i; 14943deb3ec6SMatthias Ringwald break; 14953deb3ec6SMatthias Ringwald } 14963deb3ec6SMatthias Ringwald } 14973deb3ec6SMatthias Ringwald } 14983deb3ec6SMatthias Ringwald 14993deb3ec6SMatthias Ringwald // if not found, add to db 150002b02cffSMatthias Ringwald bool new_to_le_device_db = false; 15013deb3ec6SMatthias Ringwald if (le_db_index < 0) { 15023deb3ec6SMatthias Ringwald le_db_index = le_device_db_add(setup->sm_peer_addr_type, setup->sm_peer_address, setup->sm_peer_irk); 150302b02cffSMatthias Ringwald new_to_le_device_db = true; 15043deb3ec6SMatthias Ringwald } 15053deb3ec6SMatthias Ringwald 15063deb3ec6SMatthias Ringwald if (le_db_index >= 0){ 15073deb3ec6SMatthias Ringwald 150802b02cffSMatthias Ringwald #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION 150902b02cffSMatthias Ringwald if (!new_to_le_device_db){ 151002b02cffSMatthias Ringwald hci_remove_le_device_db_entry_from_resolving_list(le_db_index); 151102b02cffSMatthias Ringwald } 151202b02cffSMatthias Ringwald hci_load_le_device_db_entry_into_resolving_list(le_db_index); 151302b02cffSMatthias Ringwald #else 151402b02cffSMatthias Ringwald UNUSED(new_to_le_device_db); 151502b02cffSMatthias Ringwald #endif 151602b02cffSMatthias Ringwald 151748163929SMatthias 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); 1518e1086030SMatthias Ringwald sm_conn->sm_irk_lookup_state = IRK_LOOKUP_SUCCEEDED; 15197710ebd2SMatthias Ringwald sm_conn->sm_le_db_index = le_db_index; 152048163929SMatthias Ringwald 1521eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 15223deb3ec6SMatthias Ringwald // store local CSRK 1523715a43d1SMatthias Ringwald setup->sm_le_device_index = le_db_index; 1524715a43d1SMatthias Ringwald if ((setup->sm_key_distribution_sent_set) & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION){ 15253deb3ec6SMatthias Ringwald log_info("sm: store local CSRK"); 15263deb3ec6SMatthias Ringwald le_device_db_local_csrk_set(le_db_index, setup->sm_local_csrk); 15273deb3ec6SMatthias Ringwald le_device_db_local_counter_set(le_db_index, 0); 15283deb3ec6SMatthias Ringwald } 15293deb3ec6SMatthias Ringwald 15303deb3ec6SMatthias Ringwald // store remote CSRK 15313deb3ec6SMatthias Ringwald if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION){ 15323deb3ec6SMatthias Ringwald log_info("sm: store remote CSRK"); 15333deb3ec6SMatthias Ringwald le_device_db_remote_csrk_set(le_db_index, setup->sm_peer_csrk); 15343deb3ec6SMatthias Ringwald le_device_db_remote_counter_set(le_db_index, 0); 15353deb3ec6SMatthias Ringwald } 1536eda85fbfSMatthias Ringwald #endif 153778f44163SMatthias Ringwald // store encryption information for secure connections: LTK generated by ECDH 153878f44163SMatthias Ringwald if (setup->sm_use_secure_connections){ 1539e6343eb6SMatthias Ringwald log_info("sm: store SC LTK (key size %u, authenticated %u)", sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated); 154078f44163SMatthias Ringwald uint8_t zero_rand[8]; 154178f44163SMatthias Ringwald memset(zero_rand, 0, 8); 154278f44163SMatthias Ringwald le_device_db_encryption_set(le_db_index, 0, zero_rand, setup->sm_ltk, sm_conn->sm_actual_encryption_key_size, 15433dc3a67dSMatthias Ringwald sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED, 1); 154478f44163SMatthias Ringwald } 154578f44163SMatthias Ringwald 1546e6343eb6SMatthias Ringwald // store encryption information for legacy pairing: peer LTK, EDIV, RAND 154778f44163SMatthias Ringwald else if ( (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION) 154878f44163SMatthias Ringwald && (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_MASTER_IDENTIFICATION )){ 1549e6343eb6SMatthias Ringwald log_info("sm: set encryption information (key size %u, authenticated %u)", sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated); 15503deb3ec6SMatthias Ringwald le_device_db_encryption_set(le_db_index, setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk, 15513dc3a67dSMatthias Ringwald sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED, 0); 155278f44163SMatthias Ringwald 15533deb3ec6SMatthias Ringwald } 15543deb3ec6SMatthias Ringwald } 155555f09f49SMatthias Ringwald } 155655f09f49SMatthias Ringwald 15578980298aSMatthias Ringwald static void sm_pairing_error(sm_connection_t * sm_conn, uint8_t reason){ 15588980298aSMatthias Ringwald sm_conn->sm_pairing_failed_reason = reason; 15598980298aSMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_SEND_PAIRING_FAILED; 15608980298aSMatthias Ringwald } 15618980298aSMatthias Ringwald 156222cb578bSMatthias Ringwald static int sm_le_device_db_index_lookup(bd_addr_type_t address_type, bd_addr_t address){ 15631a55487aSMatthias Ringwald int i; 15641a55487aSMatthias Ringwald for (i=0; i < le_device_db_max_count(); i++){ 156522cb578bSMatthias Ringwald bd_addr_t db_address; 156622cb578bSMatthias Ringwald int db_address_type = BD_ADDR_TYPE_UNKNOWN; 156722cb578bSMatthias Ringwald le_device_db_info(i, &db_address_type, db_address, NULL); 15681a55487aSMatthias Ringwald // skip unused entries 15691a55487aSMatthias Ringwald if (address_type == BD_ADDR_TYPE_UNKNOWN) continue; 15703548b7cbSDirk Helbig if ((address_type == (unsigned int)db_address_type) && (memcmp(address, db_address, 6) == 0)){ 15711a55487aSMatthias Ringwald return i; 15721a55487aSMatthias Ringwald } 15731a55487aSMatthias Ringwald } 15741a55487aSMatthias Ringwald return -1; 15751a55487aSMatthias Ringwald } 15761a55487aSMatthias Ringwald 15772e08b70bSMatthias Ringwald static void sm_remove_le_device_db_entry(uint16_t i) { 15782e08b70bSMatthias Ringwald le_device_db_remove(i); 1579672dc582SMatthias Ringwald #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION 1580672dc582SMatthias Ringwald // to remove an entry from the resolving list requires its identity address, which was already deleted 1581672dc582SMatthias Ringwald // fully reload resolving list instead 1582672dc582SMatthias Ringwald gap_load_resolving_list_from_le_device_db(); 1583672dc582SMatthias Ringwald #endif 15842e08b70bSMatthias Ringwald } 15852e08b70bSMatthias Ringwald 15868980298aSMatthias Ringwald static uint8_t sm_key_distribution_validate_received(sm_connection_t * sm_conn){ 15871a55487aSMatthias Ringwald // if identity is provided, abort if we have bonding with same address but different irk 1588f688bdb8SMatthias Ringwald if ((setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION) != 0u){ 158922cb578bSMatthias Ringwald int index = sm_le_device_db_index_lookup(BD_ADDR_TYPE_LE_PUBLIC, setup->sm_peer_address); 15901a55487aSMatthias Ringwald if (index >= 0){ 15911a55487aSMatthias Ringwald sm_key_t irk; 15921a55487aSMatthias Ringwald le_device_db_info(index, NULL, NULL, irk); 15931a55487aSMatthias Ringwald if (memcmp(irk, setup->sm_peer_irk, 16) != 0){ 15941a55487aSMatthias Ringwald // IRK doesn't match, delete bonding information 15951a55487aSMatthias 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); 15969202d845SMatthias Ringwald sm_remove_le_device_db_entry(index); 15971a55487aSMatthias Ringwald } 15981a55487aSMatthias Ringwald } 15991a55487aSMatthias Ringwald } 16008980298aSMatthias Ringwald return 0; 16018980298aSMatthias Ringwald } 16028980298aSMatthias Ringwald 160355f09f49SMatthias Ringwald static void sm_key_distribution_handle_all_received(sm_connection_t * sm_conn){ 160455f09f49SMatthias Ringwald 16058980298aSMatthias Ringwald // abort pairing if received keys are not valid 16068980298aSMatthias Ringwald uint8_t reason = sm_key_distribution_validate_received(sm_conn); 16078980298aSMatthias Ringwald if (reason != 0){ 16088980298aSMatthias Ringwald sm_pairing_error(sm_conn, reason); 16098980298aSMatthias Ringwald return; 16108980298aSMatthias Ringwald } 16118980298aSMatthias Ringwald 161255f09f49SMatthias Ringwald // only store pairing information if both sides are bondable, i.e., the bonadble flag is set 161355f09f49SMatthias Ringwald bool bonding_enabled = (sm_pairing_packet_get_auth_req(setup->sm_m_preq) 161455f09f49SMatthias Ringwald & sm_pairing_packet_get_auth_req(setup->sm_s_pres) 161555f09f49SMatthias Ringwald & SM_AUTHREQ_BONDING ) != 0u; 161655f09f49SMatthias Ringwald 161755f09f49SMatthias Ringwald if (bonding_enabled){ 161855f09f49SMatthias Ringwald sm_store_bonding_information(sm_conn); 161927ef8bc8SMatthias Ringwald } else { 162027ef8bc8SMatthias Ringwald log_info("Ignoring received keys, bonding not enabled"); 162127ef8bc8SMatthias Ringwald } 16223deb3ec6SMatthias Ringwald } 16233deb3ec6SMatthias Ringwald 1624688a08f9SMatthias Ringwald static inline void sm_pdu_received_in_wrong_state(sm_connection_t * sm_conn){ 1625688a08f9SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_UNSPECIFIED_REASON); 1626688a08f9SMatthias Ringwald } 1627688a08f9SMatthias Ringwald 16289af0f475SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 1629688a08f9SMatthias Ringwald 1630dc300847SMatthias Ringwald static void sm_sc_prepare_dhkey_check(sm_connection_t * sm_conn); 16311d80f1e6SMatthias Ringwald static bool sm_passkey_used(stk_generation_method_t method); 16321d80f1e6SMatthias Ringwald static bool sm_just_works_or_numeric_comparison(stk_generation_method_t method); 1633dc300847SMatthias Ringwald 1634b35a3de2SMatthias Ringwald static void sm_sc_start_calculating_local_confirm(sm_connection_t * sm_conn){ 1635b90c4e75SMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 16361f9d84e9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CONFIRMATION; 1637b90c4e75SMatthias Ringwald } else { 1638b90c4e75SMatthias 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); 1639b35a3de2SMatthias Ringwald } 1640b35a3de2SMatthias Ringwald } 1641b35a3de2SMatthias Ringwald 1642688a08f9SMatthias Ringwald static void sm_sc_state_after_receiving_random(sm_connection_t * sm_conn){ 164342134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1644688a08f9SMatthias Ringwald // Responder 16454acf7b7bSMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 16464acf7b7bSMatthias Ringwald // generate Nb 16474acf7b7bSMatthias Ringwald log_info("Generate Nb"); 16486ca80073SMatthias 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); 16494acf7b7bSMatthias Ringwald } else { 1650688a08f9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM; 16514acf7b7bSMatthias Ringwald } 1652688a08f9SMatthias Ringwald } else { 1653688a08f9SMatthias Ringwald // Initiator role 1654688a08f9SMatthias Ringwald switch (setup->sm_stk_generation_method){ 1655688a08f9SMatthias Ringwald case JUST_WORKS: 1656dc300847SMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 1657688a08f9SMatthias Ringwald break; 1658688a08f9SMatthias Ringwald 165947fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 1660bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_G2; 1661688a08f9SMatthias Ringwald break; 1662688a08f9SMatthias Ringwald case PK_INIT_INPUT: 1663688a08f9SMatthias Ringwald case PK_RESP_INPUT: 166447fb4255SMatthias Ringwald case PK_BOTH_INPUT: 16654ea43905SMatthias Ringwald if (setup->sm_passkey_bit < 20u) { 1666b35a3de2SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 1667688a08f9SMatthias Ringwald } else { 1668dc300847SMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 1669688a08f9SMatthias Ringwald } 1670688a08f9SMatthias Ringwald break; 1671688a08f9SMatthias Ringwald case OOB: 167265a9a04eSMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 1673688a08f9SMatthias Ringwald break; 16747bbeb3adSMilanka Ringwald default: 16757bbeb3adSMilanka Ringwald btstack_assert(false); 16767bbeb3adSMilanka Ringwald break; 1677688a08f9SMatthias Ringwald } 1678688a08f9SMatthias Ringwald } 1679688a08f9SMatthias Ringwald } 1680688a08f9SMatthias Ringwald 1681aec94140SMatthias Ringwald static void sm_sc_cmac_done(uint8_t * hash){ 1682688a08f9SMatthias Ringwald log_info("sm_sc_cmac_done: "); 1683688a08f9SMatthias Ringwald log_info_hexdump(hash, 16); 1684688a08f9SMatthias Ringwald 1685c59d0c92SMatthias Ringwald if (sm_sc_oob_state == SM_SC_OOB_W4_CONFIRM){ 1686c59d0c92SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_IDLE; 1687a680ba6bSMatthias Ringwald (*sm_sc_oob_callback)(hash, sm_sc_oob_random); 1688c59d0c92SMatthias Ringwald return; 1689c59d0c92SMatthias Ringwald } 1690c59d0c92SMatthias Ringwald 1691bd57ffebSMatthias Ringwald sm_connection_t * sm_conn = sm_cmac_connection; 1692bd57ffebSMatthias Ringwald sm_cmac_connection = NULL; 16936857ad8fSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 16942bacf595SMatthias Ringwald link_key_type_t link_key_type; 1695b4f65634SMatthias Ringwald #endif 1696bd57ffebSMatthias Ringwald 1697bd57ffebSMatthias Ringwald switch (sm_conn->sm_engine_state){ 1698aec94140SMatthias Ringwald case SM_SC_W4_CMAC_FOR_CONFIRMATION: 16996535961aSMatthias Ringwald (void)memcpy(setup->sm_local_confirm, hash, 16); 1700bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_CONFIRMATION; 1701aec94140SMatthias Ringwald break; 1702688a08f9SMatthias Ringwald case SM_SC_W4_CMAC_FOR_CHECK_CONFIRMATION: 1703688a08f9SMatthias Ringwald // check 1704688a08f9SMatthias Ringwald if (0 != memcmp(hash, setup->sm_peer_confirm, 16)){ 1705bd57ffebSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_CONFIRM_VALUE_FAILED); 1706688a08f9SMatthias Ringwald break; 1707688a08f9SMatthias Ringwald } 1708bd57ffebSMatthias Ringwald sm_sc_state_after_receiving_random(sm_conn); 1709688a08f9SMatthias Ringwald break; 1710901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_G2: { 1711901c000fSMatthias Ringwald uint32_t vab = big_endian_read_32(hash, 12) % 1000000; 1712901c000fSMatthias Ringwald big_endian_store_32(setup->sm_tk, 12, vab); 1713901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_USER_RESPONSE; 1714901c000fSMatthias Ringwald sm_trigger_user_response(sm_conn); 1715019005a0SMatthias Ringwald break; 1716019005a0SMatthias Ringwald } 17170346c37cSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_SALT: 17186535961aSMatthias Ringwald (void)memcpy(setup->sm_t, hash, 16); 1719bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_MACKEY; 17200346c37cSMatthias Ringwald break; 17210346c37cSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_MACKEY: 17226535961aSMatthias Ringwald (void)memcpy(setup->sm_mackey, hash, 16); 1723bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_LTK; 17240346c37cSMatthias Ringwald break; 17250346c37cSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_LTK: 1726b18300a6SMatthias Ringwald // truncate sm_ltk, but keep full LTK for cross-transport key derivation in sm_local_ltk 1727b18300a6SMatthias Ringwald // Errata Service Release to the Bluetooth Specification: ESR09 1728b18300a6SMatthias Ringwald // E6405 – Cross transport key derivation from a key of size less than 128 bits 1729b18300a6SMatthias Ringwald // Note: When the BR/EDR link key is being derived from the LTK, the derivation is done before the LTK gets masked." 17306535961aSMatthias Ringwald (void)memcpy(setup->sm_ltk, hash, 16); 17316535961aSMatthias Ringwald (void)memcpy(setup->sm_local_ltk, hash, 16); 1732893e9333SMatthias Ringwald sm_truncate_key(setup->sm_ltk, sm_conn->sm_actual_encryption_key_size); 1733bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F6_FOR_DHKEY_CHECK; 1734019005a0SMatthias Ringwald break; 1735901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F6_FOR_DHKEY_CHECK: 17366535961aSMatthias Ringwald (void)memcpy(setup->sm_local_dhkey_check, hash, 16); 173742134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1738901c000fSMatthias Ringwald // responder 1739f688bdb8SMatthias Ringwald if ((setup->sm_state_vars & SM_STATE_VAR_DHKEY_COMMAND_RECEIVED) != 0u){ 1740901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK; 1741901c000fSMatthias Ringwald } else { 1742901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_DHKEY_CHECK_COMMAND; 1743901c000fSMatthias Ringwald } 1744901c000fSMatthias Ringwald } else { 1745901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_DHKEY_CHECK_COMMAND; 1746901c000fSMatthias Ringwald } 1747901c000fSMatthias Ringwald break; 1748901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK: 1749901c000fSMatthias Ringwald if (0 != memcmp(hash, setup->sm_peer_dhkey_check, 16) ){ 1750901c000fSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 1751aec94140SMatthias Ringwald break; 1752aec94140SMatthias Ringwald } 175342134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1754901c000fSMatthias Ringwald // responder 1755901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_DHKEY_CHECK_COMMAND; 1756901c000fSMatthias Ringwald } else { 1757901c000fSMatthias Ringwald // initiator 1758901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH3_SEND_START_ENCRYPTION; 1759bd57ffebSMatthias Ringwald } 1760901c000fSMatthias Ringwald break; 17616857ad8fSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 176257132f12SMatthias Ringwald case SM_SC_W4_CALCULATE_ILK: 17636535961aSMatthias Ringwald (void)memcpy(setup->sm_t, hash, 16); 176457132f12SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_BR_EDR_LINK_KEY; 17652bacf595SMatthias Ringwald break; 176657132f12SMatthias Ringwald case SM_SC_W4_CALCULATE_BR_EDR_LINK_KEY: 17672bacf595SMatthias Ringwald reverse_128(hash, setup->sm_t); 17682bacf595SMatthias Ringwald link_key_type = sm_conn->sm_connection_authenticated ? 17692bacf595SMatthias Ringwald AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256 : UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256; 17708974e43fSMatthias Ringwald log_info("Derived classic link key from LE using h6, type %u", (int) link_key_type); 177155160b1cSMatthias Ringwald gap_store_link_key_for_bd_addr(setup->sm_peer_address, setup->sm_t, link_key_type); 17728974e43fSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 17732bacf595SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 17742bacf595SMatthias Ringwald } else { 17752bacf595SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 17762bacf595SMatthias Ringwald } 17770ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_SUCCESS, 0); 17782bacf595SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 17792bacf595SMatthias Ringwald break; 1780e0a03c85SMatthias Ringwald case SM_BR_EDR_W4_CALCULATE_ILK: 1781e0a03c85SMatthias Ringwald (void)memcpy(setup->sm_t, hash, 16); 1782e0a03c85SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_W2_CALCULATE_LE_LTK; 1783e0a03c85SMatthias Ringwald break; 1784e0a03c85SMatthias Ringwald case SM_BR_EDR_W4_CALCULATE_LE_LTK: 1785e0a03c85SMatthias Ringwald log_info("Derived LE LTK from BR/EDR Link Key"); 1786e0a03c85SMatthias Ringwald log_info_key("Link Key", hash); 1787e0a03c85SMatthias Ringwald (void)memcpy(setup->sm_ltk, hash, 16); 1788e0a03c85SMatthias Ringwald sm_truncate_key(setup->sm_ltk, sm_conn->sm_actual_encryption_key_size); 1789e0a03c85SMatthias Ringwald sm_conn->sm_connection_authenticated = setup->sm_link_key_type == AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256; 1790e0a03c85SMatthias Ringwald sm_store_bonding_information(sm_conn); 1791c18be159SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 1792e0a03c85SMatthias Ringwald break; 1793bdb14b0eSMatthias Ringwald #endif 1794bd57ffebSMatthias Ringwald default: 1795bd57ffebSMatthias Ringwald log_error("sm_sc_cmac_done in state %u", sm_conn->sm_engine_state); 1796bd57ffebSMatthias Ringwald break; 1797bd57ffebSMatthias Ringwald } 179870b44dd4SMatthias Ringwald sm_trigger_run(); 1799aec94140SMatthias Ringwald } 1800aec94140SMatthias Ringwald 1801688a08f9SMatthias 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){ 1802dc300847SMatthias Ringwald const uint16_t message_len = 65; 1803aec94140SMatthias Ringwald sm_cmac_connection = sm_conn; 18046535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, u, 32); 18056535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 32, v, 32); 1806aec94140SMatthias Ringwald sm_cmac_sc_buffer[64] = z; 1807aec94140SMatthias Ringwald log_info("f4 key"); 1808aec94140SMatthias Ringwald log_info_hexdump(x, 16); 1809aec94140SMatthias Ringwald log_info("f4 message"); 1810dc300847SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1811d1a1f6a4SMatthias Ringwald sm_cmac_message_start(x, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 1812aec94140SMatthias Ringwald } 1813aec94140SMatthias Ringwald 18140346c37cSMatthias Ringwald static const uint8_t f5_key_id[] = { 0x62, 0x74, 0x6c, 0x65 }; 18150346c37cSMatthias Ringwald static const uint8_t f5_length[] = { 0x01, 0x00}; 18160346c37cSMatthias Ringwald 18170346c37cSMatthias Ringwald static void f5_calculate_salt(sm_connection_t * sm_conn){ 18188334d3d8SMatthias Ringwald 18198334d3d8SMatthias Ringwald static const sm_key_t f5_salt = { 0x6C ,0x88, 0x83, 0x91, 0xAA, 0xF5, 0xA5, 0x38, 0x60, 0x37, 0x0B, 0xDB, 0x5A, 0x60, 0x83, 0xBE}; 18208334d3d8SMatthias Ringwald 182140c5d850SMatthias Ringwald log_info("f5_calculate_salt"); 18220346c37cSMatthias Ringwald // calculate salt for f5 18230346c37cSMatthias Ringwald const uint16_t message_len = 32; 18240346c37cSMatthias Ringwald sm_cmac_connection = sm_conn; 18256535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, setup->sm_dhkey, message_len); 1826d1a1f6a4SMatthias Ringwald sm_cmac_message_start(f5_salt, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 18270346c37cSMatthias Ringwald } 18280346c37cSMatthias Ringwald 18290346c37cSMatthias 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){ 18300346c37cSMatthias Ringwald const uint16_t message_len = 53; 18310346c37cSMatthias Ringwald sm_cmac_connection = sm_conn; 18320346c37cSMatthias Ringwald 18330346c37cSMatthias Ringwald // f5(W, N1, N2, A1, A2) = AES-CMACT (Counter = 0 || keyID || N1 || N2|| A1|| A2 || Length = 256) -- this is the MacKey 18340346c37cSMatthias Ringwald sm_cmac_sc_buffer[0] = 0; 18356535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 01, f5_key_id, 4); 18366535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 05, n1, 16); 18376535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 21, n2, 16); 18386535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 37, a1, 7); 18396535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 44, a2, 7); 18406535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 51, f5_length, 2); 18410346c37cSMatthias Ringwald log_info("f5 key"); 18420346c37cSMatthias Ringwald log_info_hexdump(t, 16); 18430346c37cSMatthias Ringwald log_info("f5 message for MacKey"); 18440346c37cSMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1845d1a1f6a4SMatthias Ringwald sm_cmac_message_start(t, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 18460346c37cSMatthias Ringwald } 18470346c37cSMatthias Ringwald 18480346c37cSMatthias Ringwald static void f5_calculate_mackey(sm_connection_t * sm_conn){ 18490346c37cSMatthias Ringwald sm_key56_t bd_addr_master, bd_addr_slave; 18500346c37cSMatthias Ringwald bd_addr_master[0] = setup->sm_m_addr_type; 18510346c37cSMatthias Ringwald bd_addr_slave[0] = setup->sm_s_addr_type; 18526535961aSMatthias Ringwald (void)memcpy(&bd_addr_master[1], setup->sm_m_address, 6); 18536535961aSMatthias Ringwald (void)memcpy(&bd_addr_slave[1], setup->sm_s_address, 6); 185442134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 18550346c37cSMatthias Ringwald // responder 18560346c37cSMatthias Ringwald f5_mackkey(sm_conn, setup->sm_t, setup->sm_peer_nonce, setup->sm_local_nonce, bd_addr_master, bd_addr_slave); 18570346c37cSMatthias Ringwald } else { 18580346c37cSMatthias Ringwald // initiator 18590346c37cSMatthias Ringwald f5_mackkey(sm_conn, setup->sm_t, setup->sm_local_nonce, setup->sm_peer_nonce, bd_addr_master, bd_addr_slave); 18600346c37cSMatthias Ringwald } 18610346c37cSMatthias Ringwald } 18620346c37cSMatthias Ringwald 18630346c37cSMatthias Ringwald // note: must be called right after f5_mackey, as sm_cmac_buffer[1..52] will be reused 18640346c37cSMatthias Ringwald static inline void f5_ltk(sm_connection_t * sm_conn, sm_key_t t){ 18650346c37cSMatthias Ringwald const uint16_t message_len = 53; 18660346c37cSMatthias Ringwald sm_cmac_connection = sm_conn; 18670346c37cSMatthias Ringwald sm_cmac_sc_buffer[0] = 1; 18680346c37cSMatthias Ringwald // 1..52 setup before 18690346c37cSMatthias Ringwald log_info("f5 key"); 18700346c37cSMatthias Ringwald log_info_hexdump(t, 16); 18710346c37cSMatthias Ringwald log_info("f5 message for LTK"); 18720346c37cSMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1873d1a1f6a4SMatthias Ringwald sm_cmac_message_start(t, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 18740346c37cSMatthias Ringwald } 1875f92edc8eSMatthias Ringwald 18760346c37cSMatthias Ringwald static void f5_calculate_ltk(sm_connection_t * sm_conn){ 18770346c37cSMatthias Ringwald f5_ltk(sm_conn, setup->sm_t); 18780346c37cSMatthias Ringwald } 18790346c37cSMatthias Ringwald 188031f061fbSMatthias 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){ 18816535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, n1, 16); 18826535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 16, n2, 16); 18836535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 32, r, 16); 18846535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 48, io_cap, 3); 18856535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 51, a1, 7); 18866535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 58, a2, 7); 188731f061fbSMatthias Ringwald } 188831f061fbSMatthias Ringwald 188931f061fbSMatthias Ringwald static void f6_engine(sm_connection_t * sm_conn, const sm_key_t w){ 189031f061fbSMatthias Ringwald const uint16_t message_len = 65; 189131f061fbSMatthias Ringwald sm_cmac_connection = sm_conn; 1892dc300847SMatthias Ringwald log_info("f6 key"); 1893dc300847SMatthias Ringwald log_info_hexdump(w, 16); 1894dc300847SMatthias Ringwald log_info("f6 message"); 1895dc300847SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1896d1a1f6a4SMatthias Ringwald sm_cmac_message_start(w, 65, sm_cmac_sc_buffer, &sm_sc_cmac_done); 1897dc300847SMatthias Ringwald } 1898dc300847SMatthias Ringwald 1899f92edc8eSMatthias Ringwald // g2(U, V, X, Y) = AES-CMACX(U || V || Y) mod 2^32 1900f92edc8eSMatthias Ringwald // - U is 256 bits 1901f92edc8eSMatthias Ringwald // - V is 256 bits 1902f92edc8eSMatthias Ringwald // - X is 128 bits 1903f92edc8eSMatthias Ringwald // - Y is 128 bits 1904bd57ffebSMatthias 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){ 1905bd57ffebSMatthias Ringwald const uint16_t message_len = 80; 1906bd57ffebSMatthias Ringwald sm_cmac_connection = sm_conn; 19076535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, u, 32); 19086535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 32, v, 32); 19096535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 64, y, 16); 1910f92edc8eSMatthias Ringwald log_info("g2 key"); 1911f92edc8eSMatthias Ringwald log_info_hexdump(x, 16); 1912f92edc8eSMatthias Ringwald log_info("g2 message"); 19132bacf595SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1914d1a1f6a4SMatthias Ringwald sm_cmac_message_start(x, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 1915f92edc8eSMatthias Ringwald } 1916f92edc8eSMatthias Ringwald 1917b35a3de2SMatthias Ringwald static void g2_calculate(sm_connection_t * sm_conn) { 1918f92edc8eSMatthias Ringwald // calc Va if numeric comparison 191942134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1920f92edc8eSMatthias Ringwald // responder 1921fc5bff5fSMatthias Ringwald g2_engine(sm_conn, setup->sm_peer_q, ec_q, setup->sm_peer_nonce, setup->sm_local_nonce);; 1922f92edc8eSMatthias Ringwald } else { 1923f92edc8eSMatthias Ringwald // initiator 1924fc5bff5fSMatthias Ringwald g2_engine(sm_conn, ec_q, setup->sm_peer_q, setup->sm_local_nonce, setup->sm_peer_nonce); 1925f92edc8eSMatthias Ringwald } 1926f92edc8eSMatthias Ringwald } 1927f92edc8eSMatthias Ringwald 1928945888f5SMatthias Ringwald static void sm_sc_calculate_local_confirm(sm_connection_t * sm_conn){ 19299af0f475SMatthias Ringwald uint8_t z = 0; 193040c5d850SMatthias Ringwald if (sm_passkey_entry(setup->sm_stk_generation_method)){ 19319af0f475SMatthias Ringwald // some form of passkey 19329af0f475SMatthias Ringwald uint32_t pk = big_endian_read_32(setup->sm_tk, 12); 19334ea43905SMatthias Ringwald z = 0x80u | ((pk >> setup->sm_passkey_bit) & 1u); 19349af0f475SMatthias Ringwald setup->sm_passkey_bit++; 19359af0f475SMatthias Ringwald } 1936fc5bff5fSMatthias Ringwald f4_engine(sm_conn, ec_q, setup->sm_peer_q, setup->sm_local_nonce, z); 19379af0f475SMatthias Ringwald } 1938688a08f9SMatthias Ringwald 1939688a08f9SMatthias Ringwald static void sm_sc_calculate_remote_confirm(sm_connection_t * sm_conn){ 1940a680ba6bSMatthias Ringwald // OOB 1941a680ba6bSMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 19424acf7b7bSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 19434acf7b7bSMatthias Ringwald f4_engine(sm_conn, setup->sm_peer_q, setup->sm_peer_q, setup->sm_ra, 0); 19444acf7b7bSMatthias Ringwald } else { 19454acf7b7bSMatthias Ringwald f4_engine(sm_conn, setup->sm_peer_q, setup->sm_peer_q, setup->sm_rb, 0); 19464acf7b7bSMatthias Ringwald } 1947a680ba6bSMatthias Ringwald return; 1948a680ba6bSMatthias Ringwald } 1949a680ba6bSMatthias Ringwald 1950688a08f9SMatthias Ringwald uint8_t z = 0; 195140c5d850SMatthias Ringwald if (sm_passkey_entry(setup->sm_stk_generation_method)){ 1952688a08f9SMatthias Ringwald // some form of passkey 1953688a08f9SMatthias Ringwald uint32_t pk = big_endian_read_32(setup->sm_tk, 12); 1954688a08f9SMatthias Ringwald // sm_passkey_bit was increased before sending confirm value 19554ea43905SMatthias Ringwald z = 0x80u | ((pk >> (setup->sm_passkey_bit-1u)) & 1u); 1956688a08f9SMatthias Ringwald } 1957fc5bff5fSMatthias Ringwald f4_engine(sm_conn, setup->sm_peer_q, ec_q, setup->sm_peer_nonce, z); 1958688a08f9SMatthias Ringwald } 1959688a08f9SMatthias Ringwald 19600346c37cSMatthias Ringwald static void sm_sc_prepare_dhkey_check(sm_connection_t * sm_conn){ 1961f688bdb8SMatthias Ringwald log_info("sm_sc_prepare_dhkey_check, DHKEY calculated %u", (setup->sm_state_vars & SM_STATE_VAR_DHKEY_CALCULATED) != 0 ? 1 : 0); 19623cf37b8cSMatthias Ringwald 1963f688bdb8SMatthias Ringwald if ((setup->sm_state_vars & SM_STATE_VAR_DHKEY_CALCULATED) != 0u){ 19643cf37b8cSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_SALT; 19653cf37b8cSMatthias Ringwald } else { 19663cf37b8cSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_CALCULATE_DHKEY; 19673cf37b8cSMatthias Ringwald } 1968d1a1f6a4SMatthias Ringwald } 19693cf37b8cSMatthias Ringwald 1970d1a1f6a4SMatthias Ringwald static void sm_sc_dhkey_calculated(void * arg){ 1971f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 1972f3582630SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 1973f3582630SMatthias Ringwald if (sm_conn == NULL) return; 1974f3582630SMatthias Ringwald 19751c34405fSMatthias Ringwald // check for invalid public key detected by Controller 19761c34405fSMatthias Ringwald if (sm_is_ff(setup->sm_dhkey, 32)){ 19771c34405fSMatthias Ringwald log_info("sm: peer public key invalid"); 19781c34405fSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 19791c34405fSMatthias Ringwald return; 19801c34405fSMatthias Ringwald } 19811c34405fSMatthias Ringwald 1982d1a1f6a4SMatthias Ringwald log_info("dhkey"); 1983d1a1f6a4SMatthias Ringwald log_info_hexdump(&setup->sm_dhkey[0], 32); 1984d1a1f6a4SMatthias Ringwald setup->sm_state_vars |= SM_STATE_VAR_DHKEY_CALCULATED; 1985d1a1f6a4SMatthias Ringwald // trigger next step 1986d1a1f6a4SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_CALCULATE_DHKEY){ 1987d1a1f6a4SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_SALT; 1988d1a1f6a4SMatthias Ringwald } 198970b44dd4SMatthias Ringwald sm_trigger_run(); 1990dc300847SMatthias Ringwald } 1991dc300847SMatthias Ringwald 1992dc300847SMatthias Ringwald static void sm_sc_calculate_f6_for_dhkey_check(sm_connection_t * sm_conn){ 1993dc300847SMatthias Ringwald // calculate DHKCheck 1994dc300847SMatthias Ringwald sm_key56_t bd_addr_master, bd_addr_slave; 1995dc300847SMatthias Ringwald bd_addr_master[0] = setup->sm_m_addr_type; 1996dc300847SMatthias Ringwald bd_addr_slave[0] = setup->sm_s_addr_type; 19976535961aSMatthias Ringwald (void)memcpy(&bd_addr_master[1], setup->sm_m_address, 6); 19986535961aSMatthias Ringwald (void)memcpy(&bd_addr_slave[1], setup->sm_s_address, 6); 1999dc300847SMatthias Ringwald uint8_t iocap_a[3]; 2000dc300847SMatthias Ringwald iocap_a[0] = sm_pairing_packet_get_auth_req(setup->sm_m_preq); 2001dc300847SMatthias Ringwald iocap_a[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq); 2002dc300847SMatthias Ringwald iocap_a[2] = sm_pairing_packet_get_io_capability(setup->sm_m_preq); 2003dc300847SMatthias Ringwald uint8_t iocap_b[3]; 2004dc300847SMatthias Ringwald iocap_b[0] = sm_pairing_packet_get_auth_req(setup->sm_s_pres); 2005dc300847SMatthias Ringwald iocap_b[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres); 2006dc300847SMatthias Ringwald iocap_b[2] = sm_pairing_packet_get_io_capability(setup->sm_s_pres); 200742134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 2008dc300847SMatthias Ringwald // responder 200931f061fbSMatthias Ringwald f6_setup(setup->sm_local_nonce, setup->sm_peer_nonce, setup->sm_ra, iocap_b, bd_addr_slave, bd_addr_master); 201031f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2011dc300847SMatthias Ringwald } else { 2012dc300847SMatthias Ringwald // initiator 201331f061fbSMatthias Ringwald f6_setup( setup->sm_local_nonce, setup->sm_peer_nonce, setup->sm_rb, iocap_a, bd_addr_master, bd_addr_slave); 201431f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2015dc300847SMatthias Ringwald } 2016dc300847SMatthias Ringwald } 2017dc300847SMatthias Ringwald 2018019005a0SMatthias Ringwald static void sm_sc_calculate_f6_to_verify_dhkey_check(sm_connection_t * sm_conn){ 2019019005a0SMatthias Ringwald // validate E = f6() 2020019005a0SMatthias Ringwald sm_key56_t bd_addr_master, bd_addr_slave; 2021019005a0SMatthias Ringwald bd_addr_master[0] = setup->sm_m_addr_type; 2022019005a0SMatthias Ringwald bd_addr_slave[0] = setup->sm_s_addr_type; 20236535961aSMatthias Ringwald (void)memcpy(&bd_addr_master[1], setup->sm_m_address, 6); 20246535961aSMatthias Ringwald (void)memcpy(&bd_addr_slave[1], setup->sm_s_address, 6); 2025019005a0SMatthias Ringwald 2026019005a0SMatthias Ringwald uint8_t iocap_a[3]; 2027019005a0SMatthias Ringwald iocap_a[0] = sm_pairing_packet_get_auth_req(setup->sm_m_preq); 2028019005a0SMatthias Ringwald iocap_a[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq); 2029019005a0SMatthias Ringwald iocap_a[2] = sm_pairing_packet_get_io_capability(setup->sm_m_preq); 2030019005a0SMatthias Ringwald uint8_t iocap_b[3]; 2031019005a0SMatthias Ringwald iocap_b[0] = sm_pairing_packet_get_auth_req(setup->sm_s_pres); 2032019005a0SMatthias Ringwald iocap_b[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres); 2033019005a0SMatthias Ringwald iocap_b[2] = sm_pairing_packet_get_io_capability(setup->sm_s_pres); 203442134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 2035019005a0SMatthias Ringwald // responder 203631f061fbSMatthias Ringwald f6_setup(setup->sm_peer_nonce, setup->sm_local_nonce, setup->sm_rb, iocap_a, bd_addr_master, bd_addr_slave); 203731f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2038019005a0SMatthias Ringwald } else { 2039019005a0SMatthias Ringwald // initiator 204031f061fbSMatthias Ringwald f6_setup(setup->sm_peer_nonce, setup->sm_local_nonce, setup->sm_ra, iocap_b, bd_addr_slave, bd_addr_master); 204131f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2042019005a0SMatthias Ringwald } 2043019005a0SMatthias Ringwald } 20442bacf595SMatthias Ringwald 204555c62cf5SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 20462bacf595SMatthias Ringwald 20472bacf595SMatthias Ringwald // 20482bacf595SMatthias Ringwald // Link Key Conversion Function h6 20492bacf595SMatthias Ringwald // 205057132f12SMatthias Ringwald // h6(W, keyID) = AES-CMAC_W(keyID) 20512bacf595SMatthias Ringwald // - W is 128 bits 20522bacf595SMatthias Ringwald // - keyID is 32 bits 20532bacf595SMatthias Ringwald static void h6_engine(sm_connection_t * sm_conn, const sm_key_t w, const uint32_t key_id){ 20542bacf595SMatthias Ringwald const uint16_t message_len = 4; 20552bacf595SMatthias Ringwald sm_cmac_connection = sm_conn; 20562bacf595SMatthias Ringwald big_endian_store_32(sm_cmac_sc_buffer, 0, key_id); 20572bacf595SMatthias Ringwald log_info("h6 key"); 20582bacf595SMatthias Ringwald log_info_hexdump(w, 16); 20592bacf595SMatthias Ringwald log_info("h6 message"); 20602bacf595SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 2061d1a1f6a4SMatthias Ringwald sm_cmac_message_start(w, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 20622bacf595SMatthias Ringwald } 206357132f12SMatthias Ringwald // 206457132f12SMatthias Ringwald // Link Key Conversion Function h7 206557132f12SMatthias Ringwald // 206657132f12SMatthias Ringwald // h7(SALT, W) = AES-CMAC_SALT(W) 206757132f12SMatthias Ringwald // - SALT is 128 bits 206857132f12SMatthias Ringwald // - W is 128 bits 206957132f12SMatthias Ringwald static void h7_engine(sm_connection_t * sm_conn, const sm_key_t salt, const sm_key_t w) { 207057132f12SMatthias Ringwald const uint16_t message_len = 16; 207157132f12SMatthias Ringwald sm_cmac_connection = sm_conn; 207257132f12SMatthias Ringwald log_info("h7 key"); 207357132f12SMatthias Ringwald log_info_hexdump(salt, 16); 207457132f12SMatthias Ringwald log_info("h7 message"); 207557132f12SMatthias Ringwald log_info_hexdump(w, 16); 207657132f12SMatthias Ringwald sm_cmac_message_start(salt, message_len, w, &sm_sc_cmac_done); 207757132f12SMatthias Ringwald } 20782bacf595SMatthias Ringwald 2079b18300a6SMatthias Ringwald // For SC, setup->sm_local_ltk holds full LTK (sm_ltk is already truncated) 2080b18300a6SMatthias Ringwald // Errata Service Release to the Bluetooth Specification: ESR09 2081b18300a6SMatthias Ringwald // E6405 – Cross transport key derivation from a key of size less than 128 bits 2082b18300a6SMatthias Ringwald // "Note: When the BR/EDR link key is being derived from the LTK, the derivation is done before the LTK gets masked." 208357132f12SMatthias Ringwald 2084c82679c3SMatthias Ringwald static void h6_calculate_ilk_from_le_ltk(sm_connection_t * sm_conn){ 2085b18300a6SMatthias Ringwald h6_engine(sm_conn, setup->sm_local_ltk, 0x746D7031); // "tmp1" 20862bacf595SMatthias Ringwald } 20872bacf595SMatthias Ringwald 2088e0a03c85SMatthias Ringwald static void h6_calculate_ilk_from_br_edr(sm_connection_t * sm_conn){ 2089e0a03c85SMatthias Ringwald h6_engine(sm_conn, setup->sm_link_key, 0x746D7032); // "tmp2" 2090e0a03c85SMatthias Ringwald } 2091e0a03c85SMatthias Ringwald 20922bacf595SMatthias Ringwald static void h6_calculate_br_edr_link_key(sm_connection_t * sm_conn){ 20932bacf595SMatthias Ringwald h6_engine(sm_conn, setup->sm_t, 0x6c656272); // "lebr" 20942bacf595SMatthias Ringwald } 20952bacf595SMatthias Ringwald 2096e0a03c85SMatthias Ringwald static void h6_calculate_le_ltk(sm_connection_t * sm_conn){ 2097e0a03c85SMatthias Ringwald h6_engine(sm_conn, setup->sm_t, 0x62726C65); // "brle" 2098e0a03c85SMatthias Ringwald } 2099e0a03c85SMatthias Ringwald 2100c82679c3SMatthias Ringwald static void h7_calculate_ilk_from_le_ltk(sm_connection_t * sm_conn){ 210157132f12SMatthias Ringwald const uint8_t salt[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x6D, 0x70, 0x31}; // "tmp1" 210257132f12SMatthias Ringwald h7_engine(sm_conn, salt, setup->sm_local_ltk); 210357132f12SMatthias Ringwald } 2104e0a03c85SMatthias Ringwald 2105e0a03c85SMatthias Ringwald static void h7_calculate_ilk_from_br_edr(sm_connection_t * sm_conn){ 2106e0a03c85SMatthias Ringwald const uint8_t salt[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x6D, 0x70, 0x32}; // "tmp2" 2107e0a03c85SMatthias Ringwald h7_engine(sm_conn, salt, setup->sm_link_key); 2108e0a03c85SMatthias Ringwald } 2109e0a03c85SMatthias Ringwald 2110c18be159SMatthias Ringwald static void sm_ctkd_fetch_br_edr_link_key(sm_connection_t * sm_conn){ 2111e0a03c85SMatthias Ringwald hci_connection_t * hci_connection = hci_connection_for_handle(sm_conn->sm_handle); 2112e0a03c85SMatthias Ringwald btstack_assert(hci_connection != NULL); 2113e0a03c85SMatthias Ringwald reverse_128(hci_connection->link_key, setup->sm_link_key); 2114e0a03c85SMatthias Ringwald setup->sm_link_key_type = hci_connection->link_key_type; 2115e0a03c85SMatthias Ringwald } 2116e0a03c85SMatthias Ringwald 211713aed524SMatthias Ringwald static void sm_ctkd_start_from_br_edr(sm_connection_t * sm_conn){ 211813aed524SMatthias Ringwald // only derive LTK if EncKey is set by both 211913aed524SMatthias Ringwald bool derive_ltk = (sm_pairing_packet_get_initiator_key_distribution(setup->sm_s_pres) & 212013aed524SMatthias Ringwald sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres) & SM_KEYDIST_ENC_KEY) != 0; 212113aed524SMatthias Ringwald if (derive_ltk){ 2122c18be159SMatthias 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; 212313aed524SMatthias Ringwald sm_conn->sm_engine_state = use_h7 ? SM_BR_EDR_W2_CALCULATE_ILK_USING_H7 : SM_BR_EDR_W2_CALCULATE_ILK_USING_H6; 212413aed524SMatthias Ringwald } else { 212513aed524SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 212613aed524SMatthias Ringwald } 2127c18be159SMatthias Ringwald } 2128c18be159SMatthias Ringwald 21299af0f475SMatthias Ringwald #endif 21309af0f475SMatthias Ringwald 213155c62cf5SMatthias Ringwald #endif 213255c62cf5SMatthias Ringwald 2133613da3deSMatthias Ringwald // key management legacy connections: 2134613da3deSMatthias Ringwald // - potentially two different LTKs based on direction. each device stores LTK provided by peer 2135613da3deSMatthias Ringwald // - master stores LTK, EDIV, RAND. responder optionally stored master LTK (only if it needs to reconnect) 2136613da3deSMatthias Ringwald // - initiators reconnects: initiator uses stored LTK, EDIV, RAND generated by responder 2137613da3deSMatthias Ringwald // - responder reconnects: responder uses LTK receveived from master 2138613da3deSMatthias Ringwald 2139613da3deSMatthias Ringwald // key management secure connections: 2140613da3deSMatthias Ringwald // - both devices store same LTK from ECDH key exchange. 2141613da3deSMatthias Ringwald 214242134bc6SMatthias Ringwald #if defined(ENABLE_LE_SECURE_CONNECTIONS) || defined(ENABLE_LE_CENTRAL) 21435829ebe2SMatthias Ringwald static void sm_load_security_info(sm_connection_t * sm_connection){ 21445829ebe2SMatthias Ringwald int encryption_key_size; 21455829ebe2SMatthias Ringwald int authenticated; 21465829ebe2SMatthias Ringwald int authorized; 21473dc3a67dSMatthias Ringwald int secure_connection; 21485829ebe2SMatthias Ringwald 21495829ebe2SMatthias Ringwald // fetch data from device db - incl. authenticated/authorized/key size. Note all sm_connection_X require encryption enabled 21505829ebe2SMatthias Ringwald le_device_db_encryption_get(sm_connection->sm_le_db_index, &setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk, 21513dc3a67dSMatthias Ringwald &encryption_key_size, &authenticated, &authorized, &secure_connection); 21523dc3a67dSMatthias 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); 21535829ebe2SMatthias Ringwald sm_connection->sm_actual_encryption_key_size = encryption_key_size; 21545829ebe2SMatthias Ringwald sm_connection->sm_connection_authenticated = authenticated; 21555829ebe2SMatthias Ringwald sm_connection->sm_connection_authorization_state = authorized ? AUTHORIZATION_GRANTED : AUTHORIZATION_UNKNOWN; 2156d7dbf891SMatthias Ringwald sm_connection->sm_connection_sc = secure_connection != 0; 21575829ebe2SMatthias Ringwald } 215842134bc6SMatthias Ringwald #endif 2159bd57ffebSMatthias Ringwald 216042134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 216159066796SMatthias Ringwald static void sm_start_calculating_ltk_from_ediv_and_rand(sm_connection_t * sm_connection){ 21626535961aSMatthias Ringwald (void)memcpy(setup->sm_local_rand, sm_connection->sm_local_rand, 8); 216359066796SMatthias Ringwald setup->sm_local_ediv = sm_connection->sm_local_ediv; 216459066796SMatthias Ringwald // re-establish used key encryption size 216559066796SMatthias Ringwald // no db for encryption size hack: encryption size is stored in lowest nibble of setup->sm_local_rand 21664ea43905SMatthias Ringwald sm_connection->sm_actual_encryption_key_size = (setup->sm_local_rand[7u] & 0x0fu) + 1u; 216759066796SMatthias Ringwald // no db for authenticated flag hack: flag is stored in bit 4 of LSB 21684ea43905SMatthias Ringwald sm_connection->sm_connection_authenticated = (setup->sm_local_rand[7u] & 0x10u) >> 4u; 21693dc3a67dSMatthias Ringwald // Legacy paring -> not SC 2170d7dbf891SMatthias Ringwald sm_connection->sm_connection_sc = false; 217159066796SMatthias Ringwald log_info("sm: received ltk request with key size %u, authenticated %u", 217259066796SMatthias Ringwald sm_connection->sm_actual_encryption_key_size, sm_connection->sm_connection_authenticated); 217359066796SMatthias Ringwald } 217442134bc6SMatthias Ringwald #endif 217559066796SMatthias Ringwald 21763deb3ec6SMatthias Ringwald // distributed key generation 2177d7f1c72eSMatthias Ringwald static bool sm_run_dpkg(void){ 21783deb3ec6SMatthias Ringwald switch (dkg_state){ 21793deb3ec6SMatthias Ringwald case DKG_CALC_IRK: 21803deb3ec6SMatthias Ringwald // already busy? 21813deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_IDLE) { 2182d1a1f6a4SMatthias Ringwald log_info("DKG_CALC_IRK started"); 21833deb3ec6SMatthias Ringwald // IRK = d1(IR, 1, 0) 2184d1a1f6a4SMatthias Ringwald sm_d1_d_prime(1, 0, sm_aes128_plaintext); // plaintext = d1 prime 2185d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2186d1a1f6a4SMatthias 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); 2187d7f1c72eSMatthias Ringwald return true; 21883deb3ec6SMatthias Ringwald } 21893deb3ec6SMatthias Ringwald break; 21903deb3ec6SMatthias Ringwald case DKG_CALC_DHK: 21913deb3ec6SMatthias Ringwald // already busy? 21923deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_IDLE) { 2193d1a1f6a4SMatthias Ringwald log_info("DKG_CALC_DHK started"); 21943deb3ec6SMatthias Ringwald // DHK = d1(IR, 3, 0) 2195d1a1f6a4SMatthias Ringwald sm_d1_d_prime(3, 0, sm_aes128_plaintext); // plaintext = d1 prime 2196d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2197d1a1f6a4SMatthias 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); 2198d7f1c72eSMatthias Ringwald return true; 21993deb3ec6SMatthias Ringwald } 22003deb3ec6SMatthias Ringwald break; 22013deb3ec6SMatthias Ringwald default: 22023deb3ec6SMatthias Ringwald break; 22033deb3ec6SMatthias Ringwald } 2204d7f1c72eSMatthias Ringwald return false; 2205d7f1c72eSMatthias Ringwald } 22063deb3ec6SMatthias Ringwald 22073deb3ec6SMatthias Ringwald // random address updates 2208d7f1c72eSMatthias Ringwald static bool sm_run_rau(void){ 22093deb3ec6SMatthias Ringwald switch (rau_state){ 2210fbd4e238SMatthias Ringwald case RAU_GET_RANDOM: 2211fbd4e238SMatthias Ringwald rau_state = RAU_W4_RANDOM; 22125b4dd597SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_address, 6, &sm_handle_random_result_rau, NULL); 2213d7f1c72eSMatthias Ringwald return true; 22143deb3ec6SMatthias Ringwald case RAU_GET_ENC: 22153deb3ec6SMatthias Ringwald // already busy? 22163deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_IDLE) { 2217d1a1f6a4SMatthias Ringwald sm_ah_r_prime(sm_random_address, sm_aes128_plaintext); 2218d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2219d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_irk, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_rau, NULL); 2220d7f1c72eSMatthias Ringwald return true; 22213deb3ec6SMatthias Ringwald } 22223deb3ec6SMatthias Ringwald break; 22233deb3ec6SMatthias Ringwald default: 22243deb3ec6SMatthias Ringwald break; 22253deb3ec6SMatthias Ringwald } 2226d7f1c72eSMatthias Ringwald return false; 2227d7f1c72eSMatthias Ringwald } 22283deb3ec6SMatthias Ringwald 222951258968SMatthias Ringwald // device lookup with IRK 223051258968SMatthias Ringwald static bool sm_run_irk_lookup(void){ 2231d7f1c72eSMatthias Ringwald btstack_linked_list_iterator_t it; 2232d7f1c72eSMatthias Ringwald 223351258968SMatthias Ringwald // -- if IRK lookup ready, find connection that require csrk lookup 22343deb3ec6SMatthias Ringwald if (sm_address_resolution_idle()){ 22353deb3ec6SMatthias Ringwald hci_connections_get_iterator(&it); 2236665d90f2SMatthias Ringwald while(btstack_linked_list_iterator_has_next(&it)){ 2237665d90f2SMatthias Ringwald hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 22383deb3ec6SMatthias Ringwald sm_connection_t * sm_connection = &hci_connection->sm_connection; 22393deb3ec6SMatthias Ringwald if (sm_connection->sm_irk_lookup_state == IRK_LOOKUP_W4_READY){ 22403deb3ec6SMatthias Ringwald // and start lookup 22413deb3ec6SMatthias 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); 22423deb3ec6SMatthias Ringwald sm_connection->sm_irk_lookup_state = IRK_LOOKUP_STARTED; 22433deb3ec6SMatthias Ringwald break; 22443deb3ec6SMatthias Ringwald } 22453deb3ec6SMatthias Ringwald } 22463deb3ec6SMatthias Ringwald } 22473deb3ec6SMatthias Ringwald 22483deb3ec6SMatthias Ringwald // -- if csrk lookup ready, resolved addresses for received addresses 22493deb3ec6SMatthias Ringwald if (sm_address_resolution_idle()) { 2250665d90f2SMatthias Ringwald if (!btstack_linked_list_empty(&sm_address_resolution_general_queue)){ 22513deb3ec6SMatthias Ringwald sm_lookup_entry_t * entry = (sm_lookup_entry_t *) sm_address_resolution_general_queue; 2252665d90f2SMatthias Ringwald btstack_linked_list_remove(&sm_address_resolution_general_queue, (btstack_linked_item_t *) entry); 22533deb3ec6SMatthias Ringwald sm_address_resolution_start_lookup(entry->address_type, 0, entry->address, ADDRESS_RESOLUTION_GENERAL, NULL); 22543deb3ec6SMatthias Ringwald btstack_memory_sm_lookup_entry_free(entry); 22553deb3ec6SMatthias Ringwald } 22563deb3ec6SMatthias Ringwald } 22573deb3ec6SMatthias Ringwald 2258ca685291SMatthias Ringwald // -- Continue with device lookup by public or resolvable private address 22593deb3ec6SMatthias Ringwald if (!sm_address_resolution_idle()){ 226072d2978cSMatthias Ringwald bool started_aes128 = false; 2261092ec58eSMatthias Ringwald while (sm_address_resolution_test < le_device_db_max_count()){ 2262adf5eaa9SMatthias Ringwald int addr_type = BD_ADDR_TYPE_UNKNOWN; 22633deb3ec6SMatthias Ringwald bd_addr_t addr; 22643deb3ec6SMatthias Ringwald sm_key_t irk; 22653deb3ec6SMatthias Ringwald le_device_db_info(sm_address_resolution_test, &addr_type, addr, irk); 22663deb3ec6SMatthias Ringwald 2267adf5eaa9SMatthias Ringwald // skip unused entries 2268adf5eaa9SMatthias Ringwald if (addr_type == BD_ADDR_TYPE_UNKNOWN){ 2269adf5eaa9SMatthias Ringwald sm_address_resolution_test++; 2270adf5eaa9SMatthias Ringwald continue; 2271adf5eaa9SMatthias Ringwald } 2272adf5eaa9SMatthias Ringwald 2273c2b94d32SMatthias Ringwald log_info("LE Device Lookup: device %u of %u - type %u, %s", sm_address_resolution_test, 2274c2b94d32SMatthias Ringwald le_device_db_max_count(), addr_type, bd_addr_to_str(addr)); 2275ca685291SMatthias Ringwald 2276c2b94d32SMatthias Ringwald // map resolved identity addresses to regular addresses 2277515f33beSMatthias Ringwald int regular_addr_type = sm_address_resolution_addr_type & 1; 2278515f33beSMatthias Ringwald if ((regular_addr_type == addr_type) && (memcmp(addr, sm_address_resolution_address, 6) == 0)){ 2279ca685291SMatthias Ringwald log_info("LE Device Lookup: found by { addr_type, address} "); 2280a66b030fSMatthias Ringwald sm_address_resolution_handle_event(ADDRESS_RESOLUTION_SUCCEEDED); 22813deb3ec6SMatthias Ringwald break; 22823deb3ec6SMatthias Ringwald } 22833deb3ec6SMatthias Ringwald 2284c2b94d32SMatthias Ringwald // if connection type is not random (i.e. public or resolved identity), it must be a different entry 2285c2b94d32SMatthias Ringwald if (sm_address_resolution_addr_type != BD_ADDR_TYPE_LE_RANDOM){ 22863deb3ec6SMatthias Ringwald sm_address_resolution_test++; 22873deb3ec6SMatthias Ringwald continue; 22883deb3ec6SMatthias Ringwald } 22893deb3ec6SMatthias Ringwald 22908cc81b50SMatthias Ringwald // skip AH if no IRK 22918cc81b50SMatthias Ringwald if (sm_is_null_key(irk)){ 22928cc81b50SMatthias Ringwald sm_address_resolution_test++; 22938cc81b50SMatthias Ringwald continue; 22948cc81b50SMatthias Ringwald } 22958cc81b50SMatthias Ringwald 22963deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 22973deb3ec6SMatthias Ringwald 22983deb3ec6SMatthias Ringwald log_info("LE Device Lookup: calculate AH"); 22998314c363SMatthias Ringwald log_info_key("IRK", irk); 23003deb3ec6SMatthias Ringwald 23016535961aSMatthias Ringwald (void)memcpy(sm_aes128_key, irk, 16); 2302d1a1f6a4SMatthias Ringwald sm_ah_r_prime(sm_address_resolution_address, sm_aes128_plaintext); 2303d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2304d1a1f6a4SMatthias 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); 230572d2978cSMatthias Ringwald started_aes128 = true; 230672d2978cSMatthias Ringwald break; 230772d2978cSMatthias Ringwald } 230872d2978cSMatthias Ringwald 230972d2978cSMatthias Ringwald if (started_aes128){ 2310d7f1c72eSMatthias Ringwald return true; 23113deb3ec6SMatthias Ringwald } 23123deb3ec6SMatthias Ringwald 2313092ec58eSMatthias Ringwald if (sm_address_resolution_test >= le_device_db_max_count()){ 23143deb3ec6SMatthias Ringwald log_info("LE Device Lookup: not found"); 23153deb3ec6SMatthias Ringwald sm_address_resolution_handle_event(ADDRESS_RESOLUTION_FAILED); 23163deb3ec6SMatthias Ringwald } 23173deb3ec6SMatthias Ringwald } 2318d7f1c72eSMatthias Ringwald return false; 2319d7f1c72eSMatthias Ringwald } 23203deb3ec6SMatthias Ringwald 2321d7f1c72eSMatthias Ringwald // SC OOB 2322d7f1c72eSMatthias Ringwald static bool sm_run_oob(void){ 2323c59d0c92SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2324c59d0c92SMatthias Ringwald switch (sm_sc_oob_state){ 2325c59d0c92SMatthias Ringwald case SM_SC_OOB_W2_CALC_CONFIRM: 2326c59d0c92SMatthias Ringwald if (!sm_cmac_ready()) break; 2327c59d0c92SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_W4_CONFIRM; 2328c59d0c92SMatthias Ringwald f4_engine(NULL, ec_q, ec_q, sm_sc_oob_random, 0); 2329d7f1c72eSMatthias Ringwald return true; 2330c59d0c92SMatthias Ringwald default: 2331c59d0c92SMatthias Ringwald break; 2332c59d0c92SMatthias Ringwald } 2333c59d0c92SMatthias Ringwald #endif 2334d7f1c72eSMatthias Ringwald return false; 2335d7f1c72eSMatthias Ringwald } 2336275aafe8SMatthias Ringwald 2337687a03c8SMatthias Ringwald static void sm_send_connectionless(sm_connection_t * sm_connection, const uint8_t * buffer, uint16_t size){ 2338687a03c8SMatthias Ringwald l2cap_send_connectionless(sm_connection->sm_handle, sm_connection->sm_cid, (uint8_t*) buffer, size); 2339687a03c8SMatthias Ringwald } 2340687a03c8SMatthias Ringwald 234141d32297SMatthias Ringwald // handle basic actions that don't requires the full context 2342d7f1c72eSMatthias Ringwald static bool sm_run_basic(void){ 2343d7f1c72eSMatthias Ringwald btstack_linked_list_iterator_t it; 234441d32297SMatthias Ringwald hci_connections_get_iterator(&it); 2345e9af1bf6SMatthias Ringwald while(btstack_linked_list_iterator_has_next(&it)){ 234641d32297SMatthias Ringwald hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 234741d32297SMatthias Ringwald sm_connection_t * sm_connection = &hci_connection->sm_connection; 234841d32297SMatthias Ringwald switch(sm_connection->sm_engine_state){ 2349f4935286SMatthias Ringwald 2350f4935286SMatthias Ringwald // general 2351f4935286SMatthias Ringwald case SM_GENERAL_SEND_PAIRING_FAILED: { 2352f4935286SMatthias Ringwald uint8_t buffer[2]; 2353f4935286SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_FAILED; 2354f4935286SMatthias Ringwald buffer[1] = sm_connection->sm_pairing_failed_reason; 2355f4935286SMatthias Ringwald sm_connection->sm_engine_state = sm_connection->sm_role ? SM_RESPONDER_IDLE : SM_INITIATOR_CONNECTED; 2356687a03c8SMatthias Ringwald sm_send_connectionless(sm_connection, (uint8_t*) buffer, sizeof(buffer)); 2357f4935286SMatthias Ringwald sm_pairing_complete(sm_connection, ERROR_CODE_AUTHENTICATION_FAILURE, sm_connection->sm_pairing_failed_reason); 2358f4935286SMatthias Ringwald sm_done_for_handle(sm_connection->sm_handle); 2359f4935286SMatthias Ringwald break; 2360f4935286SMatthias Ringwald } 2361f4935286SMatthias Ringwald 236241d32297SMatthias Ringwald // responder side 236341d32297SMatthias Ringwald case SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY: 236441d32297SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_IDLE; 236541d32297SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_negative_reply, sm_connection->sm_handle); 2366d7f1c72eSMatthias Ringwald return true; 23674b8b5afeSMatthias Ringwald 23684b8b5afeSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 23694b8b5afeSMatthias Ringwald case SM_SC_RECEIVED_LTK_REQUEST: 23704b8b5afeSMatthias Ringwald switch (sm_connection->sm_irk_lookup_state){ 23714b8b5afeSMatthias Ringwald case IRK_LOOKUP_FAILED: 2372e9af1bf6SMatthias Ringwald log_info("LTK Request: IRK Lookup Failed)"); 23734b8b5afeSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_IDLE; 23744b8b5afeSMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_negative_reply, sm_connection->sm_handle); 2375d7f1c72eSMatthias Ringwald return true; 23764b8b5afeSMatthias Ringwald default: 23774b8b5afeSMatthias Ringwald break; 23784b8b5afeSMatthias Ringwald } 23794b8b5afeSMatthias Ringwald break; 23804b8b5afeSMatthias Ringwald #endif 238141d32297SMatthias Ringwald default: 238241d32297SMatthias Ringwald break; 238341d32297SMatthias Ringwald } 238441d32297SMatthias Ringwald } 2385d7f1c72eSMatthias Ringwald return false; 2386d7f1c72eSMatthias Ringwald } 23873deb3ec6SMatthias Ringwald 2388d7f1c72eSMatthias Ringwald static void sm_run_activate_connection(void){ 23893deb3ec6SMatthias Ringwald // Find connections that requires setup context and make active if no other is locked 2390d7f1c72eSMatthias Ringwald btstack_linked_list_iterator_t it; 23913deb3ec6SMatthias Ringwald hci_connections_get_iterator(&it); 23927149bde5SMatthias Ringwald while((sm_active_connection_handle == HCI_CON_HANDLE_INVALID) && btstack_linked_list_iterator_has_next(&it)){ 2393665d90f2SMatthias Ringwald hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 23943deb3ec6SMatthias Ringwald sm_connection_t * sm_connection = &hci_connection->sm_connection; 23953deb3ec6SMatthias Ringwald // - if no connection locked and we're ready/waiting for setup context, fetch it and start 23961979f09cSMatthias Ringwald bool done = true; 23973deb3ec6SMatthias Ringwald int err; 239842134bc6SMatthias Ringwald UNUSED(err); 239934b6528fSMatthias Ringwald 240034b6528fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 240134b6528fSMatthias Ringwald // assert ec key is ready 2402505f1c30SMatthias Ringwald if ( (sm_connection->sm_engine_state == SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED) 2403178e8c1bSMatthias Ringwald || (sm_connection->sm_engine_state == SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST) 2404178e8c1bSMatthias Ringwald || (sm_connection->sm_engine_state == SM_RESPONDER_SEND_SECURITY_REQUEST)){ 240534b6528fSMatthias Ringwald if (ec_key_generation_state == EC_KEY_GENERATION_IDLE){ 240634b6528fSMatthias Ringwald sm_ec_generate_new_key(); 240734b6528fSMatthias Ringwald } 240834b6528fSMatthias Ringwald if (ec_key_generation_state != EC_KEY_GENERATION_DONE){ 240934b6528fSMatthias Ringwald continue; 241034b6528fSMatthias Ringwald } 241134b6528fSMatthias Ringwald } 241234b6528fSMatthias Ringwald #endif 241334b6528fSMatthias Ringwald 24143deb3ec6SMatthias Ringwald switch (sm_connection->sm_engine_state) { 241542134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 24163deb3ec6SMatthias Ringwald case SM_RESPONDER_SEND_SECURITY_REQUEST: 24173deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED: 241842134bc6SMatthias Ringwald case SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST: 2419549ad5d2SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 242006cd539fSMatthias Ringwald case SM_SC_RECEIVED_LTK_REQUEST: 242187014f74SMatthias Ringwald #endif 242287014f74SMatthias Ringwald #endif 242334c39fbdSMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 24245567aa60SMatthias Ringwald case SM_INITIATOR_PH4_HAS_LTK: 242534c39fbdSMatthias Ringwald case SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST: 2426549ad5d2SMatthias Ringwald #endif 2427c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 2428c18be159SMatthias Ringwald case SM_BR_EDR_RESPONDER_PAIRING_REQUEST_RECEIVED: 2429c18be159SMatthias Ringwald case SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST: 2430c18be159SMatthias Ringwald #endif 243187014f74SMatthias Ringwald // just lock context 243287014f74SMatthias Ringwald break; 24333deb3ec6SMatthias Ringwald default: 24341979f09cSMatthias Ringwald done = false; 24353deb3ec6SMatthias Ringwald break; 24363deb3ec6SMatthias Ringwald } 24373deb3ec6SMatthias Ringwald if (done){ 24387149bde5SMatthias Ringwald sm_active_connection_handle = sm_connection->sm_handle; 24397149bde5SMatthias 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); 24403deb3ec6SMatthias Ringwald } 24413deb3ec6SMatthias Ringwald } 2442d7f1c72eSMatthias Ringwald } 2443d7f1c72eSMatthias Ringwald 2444403280b9SMatthias Ringwald static void sm_run_send_keypress_notification(sm_connection_t * connection){ 2445403280b9SMatthias Ringwald int i; 2446403280b9SMatthias Ringwald uint8_t flags = setup->sm_keypress_notification & 0x1fu; 2447403280b9SMatthias Ringwald uint8_t num_actions = setup->sm_keypress_notification >> 5; 2448403280b9SMatthias Ringwald uint8_t action = 0; 2449403280b9SMatthias Ringwald for (i=SM_KEYPRESS_PASSKEY_ENTRY_STARTED;i<=SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED;i++){ 24501d80f1e6SMatthias Ringwald if ((flags & (1u<<i)) != 0u){ 2451403280b9SMatthias Ringwald bool clear_flag = true; 2452403280b9SMatthias Ringwald switch (i){ 2453403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_STARTED: 2454403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_CLEARED: 2455403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED: 2456403280b9SMatthias Ringwald default: 2457403280b9SMatthias Ringwald break; 2458403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ENTERED: 2459403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ERASED: 2460403280b9SMatthias Ringwald num_actions--; 2461403280b9SMatthias Ringwald clear_flag = num_actions == 0u; 2462403280b9SMatthias Ringwald break; 2463403280b9SMatthias Ringwald } 2464403280b9SMatthias Ringwald if (clear_flag){ 2465403280b9SMatthias Ringwald flags &= ~(1<<i); 2466403280b9SMatthias Ringwald } 2467403280b9SMatthias Ringwald action = i; 2468403280b9SMatthias Ringwald break; 2469403280b9SMatthias Ringwald } 2470403280b9SMatthias Ringwald } 2471403280b9SMatthias Ringwald setup->sm_keypress_notification = (num_actions << 5) | flags; 2472403280b9SMatthias Ringwald 2473403280b9SMatthias Ringwald // send keypress notification 2474403280b9SMatthias Ringwald uint8_t buffer[2]; 2475403280b9SMatthias Ringwald buffer[0] = SM_CODE_KEYPRESS_NOTIFICATION; 2476403280b9SMatthias Ringwald buffer[1] = action; 2477687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2478403280b9SMatthias Ringwald 2479403280b9SMatthias Ringwald // try 2480384eabd3SMatthias Ringwald l2cap_request_can_send_fix_channel_now_event(sm_active_connection_handle, connection->sm_cid); 2481403280b9SMatthias Ringwald } 2482403280b9SMatthias Ringwald 2483403280b9SMatthias Ringwald static void sm_run_distribute_keys(sm_connection_t * connection){ 24841d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION) != 0u){ 2485403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 2486403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 2487403280b9SMatthias Ringwald uint8_t buffer[17]; 2488403280b9SMatthias Ringwald buffer[0] = SM_CODE_ENCRYPTION_INFORMATION; 2489403280b9SMatthias Ringwald reverse_128(setup->sm_ltk, &buffer[1]); 2490687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2491403280b9SMatthias Ringwald sm_timeout_reset(connection); 2492403280b9SMatthias Ringwald return; 2493403280b9SMatthias Ringwald } 24941d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_MASTER_IDENTIFICATION) != 0u){ 2495403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 2496403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 2497403280b9SMatthias Ringwald uint8_t buffer[11]; 2498403280b9SMatthias Ringwald buffer[0] = SM_CODE_MASTER_IDENTIFICATION; 2499403280b9SMatthias Ringwald little_endian_store_16(buffer, 1, setup->sm_local_ediv); 2500403280b9SMatthias Ringwald reverse_64(setup->sm_local_rand, &buffer[3]); 2501687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2502403280b9SMatthias Ringwald sm_timeout_reset(connection); 2503403280b9SMatthias Ringwald return; 2504403280b9SMatthias Ringwald } 25051d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION) != 0u){ 2506403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 2507403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 2508403280b9SMatthias Ringwald uint8_t buffer[17]; 2509403280b9SMatthias Ringwald buffer[0] = SM_CODE_IDENTITY_INFORMATION; 2510403280b9SMatthias Ringwald reverse_128(sm_persistent_irk, &buffer[1]); 2511687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2512403280b9SMatthias Ringwald sm_timeout_reset(connection); 2513403280b9SMatthias Ringwald return; 2514403280b9SMatthias Ringwald } 25151d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION) != 0u){ 2516403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 2517403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 2518403280b9SMatthias Ringwald bd_addr_t local_address; 2519403280b9SMatthias Ringwald uint8_t buffer[8]; 2520403280b9SMatthias Ringwald buffer[0] = SM_CODE_IDENTITY_ADDRESS_INFORMATION; 2521403280b9SMatthias Ringwald switch (gap_random_address_get_mode()){ 2522403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_OFF: 2523403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_STATIC: 2524403280b9SMatthias Ringwald // public or static random 2525403280b9SMatthias Ringwald gap_le_get_own_address(&buffer[1], local_address); 2526403280b9SMatthias Ringwald break; 2527403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_NON_RESOLVABLE: 2528403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_RESOLVABLE: 2529403280b9SMatthias Ringwald // fallback to public 2530403280b9SMatthias Ringwald gap_local_bd_addr(local_address); 2531403280b9SMatthias Ringwald buffer[1] = 0; 2532403280b9SMatthias Ringwald break; 2533403280b9SMatthias Ringwald default: 2534403280b9SMatthias Ringwald btstack_assert(false); 2535403280b9SMatthias Ringwald break; 2536403280b9SMatthias Ringwald } 2537403280b9SMatthias Ringwald reverse_bd_addr(local_address, &buffer[2]); 2538687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2539403280b9SMatthias Ringwald sm_timeout_reset(connection); 2540403280b9SMatthias Ringwald return; 2541403280b9SMatthias Ringwald } 25421d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION) != 0u){ 2543403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 2544403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 2545403280b9SMatthias Ringwald 2546403280b9SMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 2547403280b9SMatthias Ringwald // hack to reproduce test runs 2548403280b9SMatthias Ringwald if (test_use_fixed_local_csrk){ 2549403280b9SMatthias Ringwald memset(setup->sm_local_csrk, 0xcc, 16); 2550403280b9SMatthias Ringwald } 2551403280b9SMatthias Ringwald 2552403280b9SMatthias Ringwald // store local CSRK 2553403280b9SMatthias Ringwald if (setup->sm_le_device_index >= 0){ 2554403280b9SMatthias Ringwald log_info("sm: store local CSRK"); 2555403280b9SMatthias Ringwald le_device_db_local_csrk_set(setup->sm_le_device_index, setup->sm_local_csrk); 2556403280b9SMatthias Ringwald le_device_db_local_counter_set(setup->sm_le_device_index, 0); 2557403280b9SMatthias Ringwald } 2558403280b9SMatthias Ringwald #endif 2559403280b9SMatthias Ringwald 2560403280b9SMatthias Ringwald uint8_t buffer[17]; 2561403280b9SMatthias Ringwald buffer[0] = SM_CODE_SIGNING_INFORMATION; 2562403280b9SMatthias Ringwald reverse_128(setup->sm_local_csrk, &buffer[1]); 2563687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2564403280b9SMatthias Ringwald sm_timeout_reset(connection); 2565403280b9SMatthias Ringwald return; 2566403280b9SMatthias Ringwald } 2567403280b9SMatthias Ringwald btstack_assert(false); 2568403280b9SMatthias Ringwald } 2569403280b9SMatthias Ringwald 2570bbd73538SMatthias Ringwald static bool sm_ctkd_from_le(sm_connection_t *sm_connection) { 2571bbd73538SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 2572bbd73538SMatthias Ringwald // requirements to derive link key from LE: 2573bbd73538SMatthias Ringwald // - use secure connections 2574bbd73538SMatthias Ringwald if (setup->sm_use_secure_connections == 0) return false; 2575bbd73538SMatthias Ringwald // - bonding needs to be enabled: 2576bbd73538SMatthias 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; 2577bbd73538SMatthias Ringwald if (!bonding_enabled) return false; 2578bbd73538SMatthias Ringwald // - need identity address / public addr 2579bbd73538SMatthias 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); 2580bbd73538SMatthias Ringwald if (!have_identity_address_info) return false; 2581bbd73538SMatthias 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) 2582bbd73538SMatthias Ringwald // this requirement is motivated by BLURtooth paper. The paper recommends to not overwrite keys at all. 2583bbd73538SMatthias Ringwald // If SC is authenticated, we consider it safe to overwrite a stored key. 2584bbd73538SMatthias 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. 2585bbd73538SMatthias Ringwald uint8_t link_key[16]; 2586bbd73538SMatthias Ringwald link_key_type_t link_key_type; 2587bbd73538SMatthias Ringwald bool have_link_key = gap_get_link_key_for_bd_addr(setup->sm_peer_address, link_key, &link_key_type); 25887040ba26SMatthias Ringwald bool link_key_authenticated = gap_authenticated_for_link_key_type(link_key_type); 2589bbd73538SMatthias Ringwald bool derived_key_authenticated = sm_connection->sm_connection_authenticated != 0; 2590bbd73538SMatthias Ringwald if (have_link_key && link_key_authenticated && !derived_key_authenticated) { 2591bbd73538SMatthias Ringwald return false; 2592bbd73538SMatthias Ringwald } 2593bbd73538SMatthias Ringwald // get started (all of the above are true) 2594bbd73538SMatthias Ringwald return true; 2595bbd73538SMatthias Ringwald #else 2596bbd73538SMatthias Ringwald UNUSED(sm_connection); 2597bbd73538SMatthias Ringwald return false; 2598bbd73538SMatthias Ringwald #endif 2599bbd73538SMatthias Ringwald } 2600bbd73538SMatthias Ringwald 26016a718a5eSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 26026a718a5eSMatthias Ringwald static bool sm_ctkd_from_classic(sm_connection_t * sm_connection){ 26036a718a5eSMatthias Ringwald hci_connection_t * hci_connection = hci_connection_for_handle(sm_connection->sm_handle); 26046a718a5eSMatthias Ringwald btstack_assert(hci_connection != NULL); 26056a718a5eSMatthias Ringwald // requirements to derive ltk from BR/EDR: 26066a718a5eSMatthias Ringwald // - BR/EDR uses secure connections 26076a718a5eSMatthias Ringwald if (gap_secure_connection_for_link_key_type(hci_connection->link_key_type) == false) return false; 26086a718a5eSMatthias 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) 26096a718a5eSMatthias Ringwald bool link_key_authenticated = gap_authenticated_for_link_key_type(hci_connection->link_key_type); 26106a718a5eSMatthias Ringwald if (link_key_authenticated) return true; 26116a718a5eSMatthias Ringwald int index = sm_le_device_db_index_lookup(BD_ADDR_TYPE_LE_PUBLIC, hci_connection->address); 26126a718a5eSMatthias Ringwald if (index >= 0){ 26136a718a5eSMatthias Ringwald int ltk_authenticated; 26146a718a5eSMatthias Ringwald sm_key_t ltk; 26156a718a5eSMatthias Ringwald le_device_db_encryption_get(sm_connection->sm_le_db_index, NULL, NULL, ltk, NULL, <k_authenticated, NULL, NULL); 26166a718a5eSMatthias Ringwald bool have_ltk = !sm_is_null_key(ltk); 26176a718a5eSMatthias Ringwald if (have_ltk && ltk_authenticated) return false; 26186a718a5eSMatthias Ringwald } 26196a718a5eSMatthias Ringwald return true; 26206a718a5eSMatthias Ringwald } 26216a718a5eSMatthias Ringwald #endif 26226a718a5eSMatthias Ringwald 26236f7422f1SMatthias Ringwald static void sm_key_distribution_complete_responder(sm_connection_t * connection){ 26246f7422f1SMatthias Ringwald if (sm_ctkd_from_le(connection)){ 26256f7422f1SMatthias 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; 26266f7422f1SMatthias Ringwald connection->sm_engine_state = use_h7 ? SM_SC_W2_CALCULATE_ILK_USING_H7 : SM_SC_W2_CALCULATE_ILK_USING_H6; 26276f7422f1SMatthias Ringwald } else { 26286f7422f1SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_IDLE; 26296f7422f1SMatthias Ringwald sm_pairing_complete(connection, ERROR_CODE_SUCCESS, 0); 26306f7422f1SMatthias Ringwald sm_done_for_handle(connection->sm_handle); 26316f7422f1SMatthias Ringwald } 26326f7422f1SMatthias Ringwald } 26336f7422f1SMatthias Ringwald 2634af7ef9d1SMatthias Ringwald static void sm_key_distribution_complete_initiator(sm_connection_t * connection){ 2635af7ef9d1SMatthias Ringwald if (sm_ctkd_from_le(connection)){ 2636af7ef9d1SMatthias 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; 2637af7ef9d1SMatthias Ringwald connection->sm_engine_state = use_h7 ? SM_SC_W2_CALCULATE_ILK_USING_H7 : SM_SC_W2_CALCULATE_ILK_USING_H6; 2638af7ef9d1SMatthias Ringwald } else { 2639af7ef9d1SMatthias Ringwald sm_master_pairing_success(connection); 2640af7ef9d1SMatthias Ringwald } 2641af7ef9d1SMatthias Ringwald } 2642af7ef9d1SMatthias Ringwald 2643b919f264SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2644b919f264SMatthias Ringwald static void sm_run_state_sc_send_confirmation(sm_connection_t *connection) { 2645b919f264SMatthias Ringwald uint8_t buffer[17]; 2646b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_CONFIRM; 2647b919f264SMatthias Ringwald reverse_128(setup->sm_local_confirm, &buffer[1]); 2648b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2649b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2650b919f264SMatthias Ringwald } else { 2651b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2652b919f264SMatthias Ringwald } 2653b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2654b919f264SMatthias Ringwald sm_timeout_reset(connection); 2655b919f264SMatthias Ringwald } 2656b919f264SMatthias Ringwald 2657b919f264SMatthias Ringwald static void sm_run_state_sc_send_pairing_random(sm_connection_t *connection) { 2658b919f264SMatthias Ringwald uint8_t buffer[17]; 2659b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_RANDOM; 2660b919f264SMatthias Ringwald reverse_128(setup->sm_local_nonce, &buffer[1]); 2661b919f264SMatthias Ringwald log_info("stk method %u, bit num: %u", setup->sm_stk_generation_method, setup->sm_passkey_bit); 2662b919f264SMatthias Ringwald if (sm_passkey_entry(setup->sm_stk_generation_method) && (setup->sm_passkey_bit < 20u)){ 2663b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM A"); 2664b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2665b919f264SMatthias Ringwald // responder 2666b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2667b919f264SMatthias Ringwald } else { 2668b919f264SMatthias Ringwald // initiator 2669b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2670b919f264SMatthias Ringwald } 2671b919f264SMatthias Ringwald } else { 2672b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM B"); 2673b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2674b919f264SMatthias Ringwald // responder 2675b919f264SMatthias Ringwald if (setup->sm_stk_generation_method == NUMERIC_COMPARISON){ 2676b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM B1"); 2677b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W2_CALCULATE_G2; 2678b919f264SMatthias Ringwald } else { 2679b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM B2"); 2680b919f264SMatthias Ringwald sm_sc_prepare_dhkey_check(connection); 2681b919f264SMatthias Ringwald } 2682b919f264SMatthias Ringwald } else { 2683b919f264SMatthias Ringwald // initiator 2684b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2685b919f264SMatthias Ringwald } 2686b919f264SMatthias Ringwald } 2687b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2688b919f264SMatthias Ringwald sm_timeout_reset(connection); 2689b919f264SMatthias Ringwald } 2690b919f264SMatthias Ringwald 2691b919f264SMatthias Ringwald static void sm_run_state_sc_send_dhkey_check_command(sm_connection_t *connection) { 2692b919f264SMatthias Ringwald uint8_t buffer[17]; 2693b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_DHKEY_CHECK; 2694b919f264SMatthias Ringwald reverse_128(setup->sm_local_dhkey_check, &buffer[1]); 2695b919f264SMatthias Ringwald 2696b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2697b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_LTK_REQUEST_SC; 2698b919f264SMatthias Ringwald } else { 2699b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_DHKEY_CHECK_COMMAND; 2700b919f264SMatthias Ringwald } 2701b919f264SMatthias Ringwald 2702b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2703b919f264SMatthias Ringwald sm_timeout_reset(connection); 2704b919f264SMatthias Ringwald } 2705b919f264SMatthias Ringwald 2706b919f264SMatthias Ringwald static void sm_run_state_sc_send_public_key_command(sm_connection_t *connection) { 2707b919f264SMatthias Ringwald bool trigger_user_response = false; 2708b919f264SMatthias Ringwald bool trigger_start_calculating_local_confirm = false; 2709b919f264SMatthias Ringwald uint8_t buffer[65]; 2710b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_PUBLIC_KEY; 2711b919f264SMatthias Ringwald // 2712b919f264SMatthias Ringwald reverse_256(&ec_q[0], &buffer[1]); 2713b919f264SMatthias Ringwald reverse_256(&ec_q[32], &buffer[33]); 2714b919f264SMatthias Ringwald 2715b919f264SMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 2716b919f264SMatthias Ringwald if (test_pairing_failure == SM_REASON_DHKEY_CHECK_FAILED){ 2717b919f264SMatthias Ringwald log_info("testing_support: invalidating public key"); 2718b919f264SMatthias Ringwald // flip single bit of public key coordinate 2719b919f264SMatthias Ringwald buffer[1] ^= 1; 2720b919f264SMatthias Ringwald } 2721b919f264SMatthias Ringwald #endif 2722b919f264SMatthias Ringwald 2723b919f264SMatthias Ringwald // stk generation method 2724b919f264SMatthias Ringwald // passkey entry: notify app to show passkey or to request passkey 2725b919f264SMatthias Ringwald switch (setup->sm_stk_generation_method){ 2726b919f264SMatthias Ringwald case JUST_WORKS: 2727b919f264SMatthias Ringwald case NUMERIC_COMPARISON: 2728b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2729b919f264SMatthias Ringwald // responder 2730b919f264SMatthias Ringwald trigger_start_calculating_local_confirm = true; 2731b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_LOCAL_NONCE; 2732b919f264SMatthias Ringwald } else { 2733b919f264SMatthias Ringwald // initiator 2734b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2735b919f264SMatthias Ringwald } 2736b919f264SMatthias Ringwald break; 2737b919f264SMatthias Ringwald case PK_INIT_INPUT: 2738b919f264SMatthias Ringwald case PK_RESP_INPUT: 2739b919f264SMatthias Ringwald case PK_BOTH_INPUT: 2740b919f264SMatthias Ringwald // use random TK for display 2741b919f264SMatthias Ringwald (void)memcpy(setup->sm_ra, setup->sm_tk, 16); 2742b919f264SMatthias Ringwald (void)memcpy(setup->sm_rb, setup->sm_tk, 16); 2743b919f264SMatthias Ringwald setup->sm_passkey_bit = 0; 2744b919f264SMatthias Ringwald 2745b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2746b919f264SMatthias Ringwald // responder 2747b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2748b919f264SMatthias Ringwald } else { 2749b919f264SMatthias Ringwald // initiator 2750b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2751b919f264SMatthias Ringwald } 2752b919f264SMatthias Ringwald trigger_user_response = true; 2753b919f264SMatthias Ringwald break; 2754b919f264SMatthias Ringwald case OOB: 2755b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2756b919f264SMatthias Ringwald // responder 2757b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2758b919f264SMatthias Ringwald } else { 2759b919f264SMatthias Ringwald // initiator 2760b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2761b919f264SMatthias Ringwald } 2762b919f264SMatthias Ringwald break; 2763b919f264SMatthias Ringwald default: 2764b919f264SMatthias Ringwald btstack_assert(false); 2765b919f264SMatthias Ringwald break; 2766b919f264SMatthias Ringwald } 2767b919f264SMatthias Ringwald 2768b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2769b919f264SMatthias Ringwald sm_timeout_reset(connection); 2770b919f264SMatthias Ringwald 2771b919f264SMatthias Ringwald // trigger user response and calc confirm after sending pdu 2772b919f264SMatthias Ringwald if (trigger_user_response){ 2773b919f264SMatthias Ringwald sm_trigger_user_response(connection); 2774b919f264SMatthias Ringwald } 2775b919f264SMatthias Ringwald if (trigger_start_calculating_local_confirm){ 2776b919f264SMatthias Ringwald sm_sc_start_calculating_local_confirm(connection); 2777b919f264SMatthias Ringwald } 2778b919f264SMatthias Ringwald } 2779b919f264SMatthias Ringwald #endif 2780b919f264SMatthias Ringwald 2781de42cac5SMatthias Ringwald static bool sm_run_non_connection_logic(void){ 2782de42cac5SMatthias Ringwald bool done;; 2783de42cac5SMatthias Ringwald 2784de42cac5SMatthias Ringwald done = sm_run_dpkg(); 2785de42cac5SMatthias Ringwald if (done) return true; 2786de42cac5SMatthias Ringwald 2787de42cac5SMatthias Ringwald done = sm_run_rau(); 2788de42cac5SMatthias Ringwald if (done) return true; 2789de42cac5SMatthias Ringwald 279051258968SMatthias Ringwald done = sm_run_irk_lookup(); 2791de42cac5SMatthias Ringwald if (done) return true; 2792de42cac5SMatthias Ringwald 2793de42cac5SMatthias Ringwald done = sm_run_oob(); 2794de42cac5SMatthias Ringwald return done; 2795de42cac5SMatthias Ringwald } 2796b919f264SMatthias Ringwald 2797d7f1c72eSMatthias Ringwald static void sm_run(void){ 2798d7f1c72eSMatthias Ringwald 2799d7f1c72eSMatthias Ringwald // assert that stack has already bootet 2800d7f1c72eSMatthias Ringwald if (hci_get_state() != HCI_STATE_WORKING) return; 2801d7f1c72eSMatthias Ringwald 2802d7f1c72eSMatthias Ringwald // assert that we can send at least commands 2803d7f1c72eSMatthias Ringwald if (!hci_can_send_command_packet_now()) return; 2804d7f1c72eSMatthias Ringwald 2805d7f1c72eSMatthias Ringwald // pause until IR/ER are ready 2806d7f1c72eSMatthias Ringwald if (sm_persistent_keys_random_active) return; 2807d7f1c72eSMatthias Ringwald 2808d7f1c72eSMatthias Ringwald // non-connection related behaviour 2809de42cac5SMatthias Ringwald bool done = sm_run_non_connection_logic(); 2810d7f1c72eSMatthias Ringwald if (done) return; 2811d7f1c72eSMatthias Ringwald 2812d7f1c72eSMatthias Ringwald // assert that we can send at least commands - cmd might have been sent by crypto engine 2813d7f1c72eSMatthias Ringwald if (!hci_can_send_command_packet_now()) return; 2814d7f1c72eSMatthias Ringwald 2815d7f1c72eSMatthias Ringwald // handle basic actions that don't requires the full context 2816d7f1c72eSMatthias Ringwald done = sm_run_basic(); 2817d7f1c72eSMatthias Ringwald if (done) return; 2818d7f1c72eSMatthias Ringwald 2819d7f1c72eSMatthias Ringwald // 2820d7f1c72eSMatthias Ringwald // active connection handling 2821d7f1c72eSMatthias Ringwald // -- use loop to handle next connection if lock on setup context is released 2822d7f1c72eSMatthias Ringwald 2823d7f1c72eSMatthias Ringwald while (true) { 2824d7f1c72eSMatthias Ringwald 2825d7f1c72eSMatthias Ringwald sm_run_activate_connection(); 2826d7f1c72eSMatthias Ringwald 2827d7f1c72eSMatthias Ringwald if (sm_active_connection_handle == HCI_CON_HANDLE_INVALID) return; 28283deb3ec6SMatthias Ringwald 28293deb3ec6SMatthias Ringwald // 28303deb3ec6SMatthias Ringwald // active connection handling 28313deb3ec6SMatthias Ringwald // 28323deb3ec6SMatthias Ringwald 28333cf37b8cSMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(sm_active_connection_handle); 28343cf37b8cSMatthias Ringwald if (!connection) { 28353cf37b8cSMatthias Ringwald log_info("no connection for handle 0x%04x", sm_active_connection_handle); 28363cf37b8cSMatthias Ringwald return; 28373cf37b8cSMatthias Ringwald } 28383cf37b8cSMatthias Ringwald 28393deb3ec6SMatthias Ringwald // assert that we could send a SM PDU - not needed for all of the following 2840384eabd3SMatthias Ringwald if (!l2cap_can_send_fixed_channel_packet_now(sm_active_connection_handle, connection->sm_cid)) { 28417149bde5SMatthias Ringwald log_info("cannot send now, requesting can send now event"); 2842384eabd3SMatthias Ringwald l2cap_request_can_send_fix_channel_now_event(sm_active_connection_handle, connection->sm_cid); 2843b170b20fSMatthias Ringwald return; 2844b170b20fSMatthias Ringwald } 28453deb3ec6SMatthias Ringwald 28463d7fe1e9SMatthias Ringwald // send keypress notifications 28471d80f1e6SMatthias Ringwald if (setup->sm_keypress_notification != 0u){ 2848403280b9SMatthias Ringwald sm_run_send_keypress_notification(connection); 2849d7471931SMatthias Ringwald return; 28503d7fe1e9SMatthias Ringwald } 28513d7fe1e9SMatthias Ringwald 2852f7ea4423SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2853234022e5SMatthias Ringwald // assert that sm cmac engine is ready 2854234022e5SMatthias Ringwald if (sm_cmac_ready() == false){ 2855234022e5SMatthias Ringwald break; 2856234022e5SMatthias Ringwald } 2857f7ea4423SMatthias Ringwald #endif 2858234022e5SMatthias Ringwald 28593deb3ec6SMatthias Ringwald int key_distribution_flags; 286042134bc6SMatthias Ringwald UNUSED(key_distribution_flags); 2861b6f39a74SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 2862b6afa23eSMatthias Ringwald int err; 28639b75de03SMatthias Ringwald bool have_ltk; 28649b75de03SMatthias Ringwald uint8_t ltk[16]; 2865b6f39a74SMatthias Ringwald #endif 28663deb3ec6SMatthias Ringwald 28673deb3ec6SMatthias Ringwald log_info("sm_run: state %u", connection->sm_engine_state); 28683deb3ec6SMatthias Ringwald switch (connection->sm_engine_state){ 28693deb3ec6SMatthias Ringwald 2870f32b7a88SMatthias Ringwald // secure connections, initiator + responding states 2871aec94140SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2872aec94140SMatthias Ringwald case SM_SC_W2_CMAC_FOR_CONFIRMATION: 2873aec94140SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CMAC_FOR_CONFIRMATION; 2874aec94140SMatthias Ringwald sm_sc_calculate_local_confirm(connection); 2875aec94140SMatthias Ringwald break; 2876688a08f9SMatthias Ringwald case SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION: 2877688a08f9SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CMAC_FOR_CHECK_CONFIRMATION; 2878688a08f9SMatthias Ringwald sm_sc_calculate_remote_confirm(connection); 2879688a08f9SMatthias Ringwald break; 2880dc300847SMatthias Ringwald case SM_SC_W2_CALCULATE_F6_FOR_DHKEY_CHECK: 2881dc300847SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F6_FOR_DHKEY_CHECK; 2882dc300847SMatthias Ringwald sm_sc_calculate_f6_for_dhkey_check(connection); 2883dc300847SMatthias Ringwald break; 2884019005a0SMatthias Ringwald case SM_SC_W2_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK: 2885019005a0SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK; 28860346c37cSMatthias Ringwald sm_sc_calculate_f6_to_verify_dhkey_check(connection); 28870346c37cSMatthias Ringwald break; 28880346c37cSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_SALT: 28890346c37cSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F5_SALT; 28900346c37cSMatthias Ringwald f5_calculate_salt(connection); 28910346c37cSMatthias Ringwald break; 28920346c37cSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_MACKEY: 28930346c37cSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F5_MACKEY; 28940346c37cSMatthias Ringwald f5_calculate_mackey(connection); 28950346c37cSMatthias Ringwald break; 28960346c37cSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_LTK: 28970346c37cSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F5_LTK; 28980346c37cSMatthias Ringwald f5_calculate_ltk(connection); 2899019005a0SMatthias Ringwald break; 2900bd57ffebSMatthias Ringwald case SM_SC_W2_CALCULATE_G2: 2901bd57ffebSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_G2; 2902b35a3de2SMatthias Ringwald g2_calculate(connection); 2903bd57ffebSMatthias Ringwald break; 2904e0a03c85SMatthias Ringwald #endif 2905e0a03c85SMatthias Ringwald 290642134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 29073deb3ec6SMatthias Ringwald // initiator side 2908f32b7a88SMatthias Ringwald 29095567aa60SMatthias Ringwald case SM_INITIATOR_PH4_HAS_LTK: { 2910f32b7a88SMatthias Ringwald sm_reset_setup(); 2911f32b7a88SMatthias Ringwald sm_load_security_info(connection); 2912f32b7a88SMatthias Ringwald 2913bcab6650SMatthias Ringwald // cache key before using 2914f76e733aSMatthias Ringwald sm_cache_ltk(connection, setup->sm_peer_ltk); 2915bcab6650SMatthias Ringwald 29163deb3ec6SMatthias Ringwald sm_key_t peer_ltk_flipped; 29179c80e4ccSMatthias Ringwald reverse_128(setup->sm_peer_ltk, peer_ltk_flipped); 29185567aa60SMatthias Ringwald connection->sm_engine_state = SM_PH4_W4_CONNECTION_ENCRYPTED; 29193deb3ec6SMatthias Ringwald log_info("sm: hci_le_start_encryption ediv 0x%04x", setup->sm_peer_ediv); 2920c9b8fdd9SMatthias Ringwald uint32_t rand_high = big_endian_read_32(setup->sm_peer_rand, 0); 2921c9b8fdd9SMatthias Ringwald uint32_t rand_low = big_endian_read_32(setup->sm_peer_rand, 4); 29223deb3ec6SMatthias Ringwald hci_send_cmd(&hci_le_start_encryption, connection->sm_handle,rand_low, rand_high, setup->sm_peer_ediv, peer_ltk_flipped); 292349c9e430SMatthias Ringwald 292449c9e430SMatthias Ringwald // notify after sending 292549c9e430SMatthias Ringwald sm_reencryption_started(connection); 29263deb3ec6SMatthias Ringwald return; 29273deb3ec6SMatthias Ringwald } 29283deb3ec6SMatthias Ringwald 2929b26f445fSMatthias Ringwald case SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST: 2930b26f445fSMatthias Ringwald sm_reset_setup(); 2931b26f445fSMatthias Ringwald sm_init_setup(connection); 2932b26f445fSMatthias Ringwald 29331ad129beSMatthias Ringwald sm_pairing_packet_set_code(setup->sm_m_preq, SM_CODE_PAIRING_REQUEST); 29343deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH1_W4_PAIRING_RESPONSE; 2935687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) &setup->sm_m_preq, sizeof(sm_pairing_packet_t)); 29363deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 293749c9e430SMatthias Ringwald 293849c9e430SMatthias Ringwald // notify after sending 293949c9e430SMatthias Ringwald sm_pairing_started(connection); 29403deb3ec6SMatthias Ringwald break; 294142134bc6SMatthias Ringwald #endif 29423deb3ec6SMatthias Ringwald 294327c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2944b919f264SMatthias Ringwald case SM_SC_SEND_PUBLIC_KEY_COMMAND: 2945b919f264SMatthias Ringwald sm_run_state_sc_send_public_key_command(connection); 294645a61d50SMatthias Ringwald break; 2947b919f264SMatthias Ringwald case SM_SC_SEND_CONFIRMATION: 2948b919f264SMatthias Ringwald sm_run_state_sc_send_confirmation(connection); 294945a61d50SMatthias Ringwald break; 2950b919f264SMatthias Ringwald case SM_SC_SEND_PAIRING_RANDOM: 2951b919f264SMatthias Ringwald sm_run_state_sc_send_pairing_random(connection); 295245a61d50SMatthias Ringwald break; 2953b919f264SMatthias Ringwald case SM_SC_SEND_DHKEY_CHECK_COMMAND: 2954b919f264SMatthias Ringwald sm_run_state_sc_send_dhkey_check_command(connection); 29557bbeb3adSMilanka Ringwald break; 2956e53be891SMatthias Ringwald #endif 295742134bc6SMatthias Ringwald 295842134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 2959dd12a62bSMatthias Ringwald 296087014f74SMatthias Ringwald case SM_RESPONDER_SEND_SECURITY_REQUEST: { 296187014f74SMatthias Ringwald const uint8_t buffer[2] = {SM_CODE_SECURITY_REQUEST, sm_auth_req}; 296287014f74SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH1_W4_PAIRING_REQUEST; 2963687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t *) buffer, sizeof(buffer)); 2964c8d0ff33SMatthias Ringwald sm_timeout_start(connection); 296587014f74SMatthias Ringwald break; 296687014f74SMatthias Ringwald } 296787014f74SMatthias Ringwald 296838196718SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 296938196718SMatthias Ringwald case SM_SC_RECEIVED_LTK_REQUEST: 297038196718SMatthias Ringwald switch (connection->sm_irk_lookup_state){ 297138196718SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 297238196718SMatthias Ringwald // assuming Secure Connection, we have a stored LTK and the EDIV/RAND are null 297338196718SMatthias Ringwald // start using context by loading security info 297438196718SMatthias Ringwald sm_reset_setup(); 297538196718SMatthias Ringwald sm_load_security_info(connection); 297638196718SMatthias Ringwald if ((setup->sm_peer_ediv == 0u) && sm_is_null_random(setup->sm_peer_rand) && !sm_is_null_key(setup->sm_peer_ltk)){ 297738196718SMatthias Ringwald (void)memcpy(setup->sm_ltk, setup->sm_peer_ltk, 16); 297838196718SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH4_SEND_LTK_REPLY; 297942646f38SMatthias Ringwald sm_reencryption_started(connection); 298038196718SMatthias Ringwald sm_trigger_run(); 298138196718SMatthias Ringwald break; 298238196718SMatthias Ringwald } 298338196718SMatthias Ringwald log_info("LTK Request: ediv & random are empty, but no stored LTK (IRK Lookup Succeeded)"); 298438196718SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_IDLE; 298538196718SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_negative_reply, connection->sm_handle); 298638196718SMatthias Ringwald return; 298738196718SMatthias Ringwald default: 298838196718SMatthias Ringwald // just wait until IRK lookup is completed 298938196718SMatthias Ringwald break; 299038196718SMatthias Ringwald } 299138196718SMatthias Ringwald break; 299238196718SMatthias Ringwald #endif /* ENABLE_LE_SECURE_CONNECTIONS */ 299338196718SMatthias Ringwald 2994b6afa23eSMatthias Ringwald case SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED: 2995b6afa23eSMatthias Ringwald sm_reset_setup(); 29969b75de03SMatthias Ringwald 29979b75de03SMatthias Ringwald // handle Pairing Request with LTK available 29989b75de03SMatthias Ringwald switch (connection->sm_irk_lookup_state) { 29999b75de03SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 30009b75de03SMatthias Ringwald le_device_db_encryption_get(connection->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); 30019b75de03SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 30029b75de03SMatthias Ringwald if (have_ltk){ 30039b75de03SMatthias Ringwald log_info("pairing request but LTK available"); 300419a40772SMatthias Ringwald // emit re-encryption start/fail sequence 30059b75de03SMatthias Ringwald sm_reencryption_started(connection); 30069b75de03SMatthias Ringwald sm_reencryption_complete(connection, ERROR_CODE_PIN_OR_KEY_MISSING); 30079b75de03SMatthias Ringwald } 30089b75de03SMatthias Ringwald break; 30099b75de03SMatthias Ringwald default: 30109b75de03SMatthias Ringwald break; 30119b75de03SMatthias Ringwald } 30129b75de03SMatthias Ringwald 3013b6afa23eSMatthias Ringwald sm_init_setup(connection); 301439543d07SMatthias Ringwald 3015b6afa23eSMatthias Ringwald // recover pairing request 3016b6afa23eSMatthias Ringwald (void)memcpy(&setup->sm_m_preq, &connection->sm_m_preq, sizeof(sm_pairing_packet_t)); 3017b6afa23eSMatthias Ringwald err = sm_stk_generation_init(connection); 3018b6afa23eSMatthias Ringwald 3019b6afa23eSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 3020b6afa23eSMatthias Ringwald if ((0 < test_pairing_failure) && (test_pairing_failure < SM_REASON_DHKEY_CHECK_FAILED)){ 3021b6afa23eSMatthias Ringwald log_info("testing_support: respond with pairing failure %u", test_pairing_failure); 3022b6afa23eSMatthias Ringwald err = test_pairing_failure; 3023b6afa23eSMatthias Ringwald } 3024b6afa23eSMatthias Ringwald #endif 30259305033eSMatthias Ringwald if (err != 0){ 302649c9e430SMatthias Ringwald // emit pairing started/failed sequence 302749c9e430SMatthias Ringwald sm_pairing_started(connection); 3028f4935286SMatthias Ringwald sm_pairing_error(connection, err); 3029b6afa23eSMatthias Ringwald sm_trigger_run(); 3030b6afa23eSMatthias Ringwald break; 3031b6afa23eSMatthias Ringwald } 3032b6afa23eSMatthias Ringwald 3033b6afa23eSMatthias Ringwald sm_timeout_start(connection); 3034b6afa23eSMatthias Ringwald 3035b6afa23eSMatthias Ringwald // generate random number first, if we need to show passkey, otherwise send response 3036b6afa23eSMatthias Ringwald if (setup->sm_stk_generation_method == PK_INIT_INPUT){ 3037b6afa23eSMatthias 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); 3038b6afa23eSMatthias Ringwald break; 3039b6afa23eSMatthias Ringwald } 3040b6afa23eSMatthias Ringwald 3041b6afa23eSMatthias Ringwald /* fall through */ 3042b6afa23eSMatthias Ringwald 30433deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE: 30441ad129beSMatthias Ringwald sm_pairing_packet_set_code(setup->sm_s_pres,SM_CODE_PAIRING_RESPONSE); 3045f55bd529SMatthias Ringwald 3046f55bd529SMatthias Ringwald // start with initiator key dist flags 30473deb3ec6SMatthias Ringwald key_distribution_flags = sm_key_distribution_flags_for_auth_req(); 30481ad129beSMatthias Ringwald 3049f55bd529SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 3050b2072c76SMatthias Ringwald // LTK (= encryption information & master identification) only exchanged for LE Legacy Connection 3051f55bd529SMatthias Ringwald if (setup->sm_use_secure_connections){ 3052f55bd529SMatthias Ringwald key_distribution_flags &= ~SM_KEYDIST_ENC_KEY; 3053f55bd529SMatthias Ringwald } 3054f55bd529SMatthias Ringwald #endif 3055f55bd529SMatthias Ringwald // setup in response 3056f55bd529SMatthias 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); 3057f55bd529SMatthias 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); 3058f55bd529SMatthias Ringwald 3059f55bd529SMatthias Ringwald // update key distribution after ENC was dropped 30609a90d41aSMatthias 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)); 3061f55bd529SMatthias Ringwald 306227c32905SMatthias Ringwald if (setup->sm_use_secure_connections){ 3063c6b7cbd9SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 30640b8af2a5SMatthias Ringwald } else { 30650b8af2a5SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH1_W4_PAIRING_CONFIRM; 306627c32905SMatthias Ringwald } 30670b8af2a5SMatthias Ringwald 3068687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) &setup->sm_s_pres, sizeof(sm_pairing_packet_t)); 30693deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 307049c9e430SMatthias Ringwald 307149c9e430SMatthias Ringwald // notify after sending 307249c9e430SMatthias Ringwald sm_pairing_started(connection); 307349c9e430SMatthias Ringwald 3074446a8c36SMatthias Ringwald // SC Numeric Comparison will trigger user response after public keys & nonces have been exchanged 3075c1ab6cc1SMatthias Ringwald if (!setup->sm_use_secure_connections || (setup->sm_stk_generation_method == JUST_WORKS)){ 30763deb3ec6SMatthias Ringwald sm_trigger_user_response(connection); 3077446a8c36SMatthias Ringwald } 30783deb3ec6SMatthias Ringwald return; 307942134bc6SMatthias Ringwald #endif 30803deb3ec6SMatthias Ringwald 30813deb3ec6SMatthias Ringwald case SM_PH2_SEND_PAIRING_RANDOM: { 30823deb3ec6SMatthias Ringwald uint8_t buffer[17]; 30833deb3ec6SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_RANDOM; 30849c80e4ccSMatthias Ringwald reverse_128(setup->sm_local_random, &buffer[1]); 308542134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 30863deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH2_W4_LTK_REQUEST; 30873deb3ec6SMatthias Ringwald } else { 30883deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH2_W4_PAIRING_RANDOM; 30893deb3ec6SMatthias Ringwald } 3090687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 30913deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 30923deb3ec6SMatthias Ringwald break; 30933deb3ec6SMatthias Ringwald } 30943deb3ec6SMatthias Ringwald 3095d1a1f6a4SMatthias Ringwald case SM_PH2_C1_GET_ENC_A: 30963deb3ec6SMatthias Ringwald // already busy? 30973deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 3098d1a1f6a4SMatthias Ringwald // calculate confirm using aes128 engine - step 1 3099d1a1f6a4SMatthias 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); 3100d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_W4_ENC_A; 3101d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3102f3582630SMatthias 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); 31033deb3ec6SMatthias Ringwald break; 31043deb3ec6SMatthias Ringwald 31053deb3ec6SMatthias Ringwald case SM_PH2_C1_GET_ENC_C: 31063deb3ec6SMatthias Ringwald // already busy? 31073deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31083deb3ec6SMatthias Ringwald // calculate m_confirm using aes128 engine - step 1 3109d1a1f6a4SMatthias 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); 3110d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_W4_ENC_C; 3111d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3112f3582630SMatthias 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); 31133deb3ec6SMatthias Ringwald break; 3114d1a1f6a4SMatthias Ringwald 31153deb3ec6SMatthias Ringwald case SM_PH2_CALC_STK: 31163deb3ec6SMatthias Ringwald // already busy? 31173deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31183deb3ec6SMatthias Ringwald // calculate STK 311942134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 3120d1a1f6a4SMatthias Ringwald sm_s1_r_prime(setup->sm_local_random, setup->sm_peer_random, sm_aes128_plaintext); 31213deb3ec6SMatthias Ringwald } else { 3122d1a1f6a4SMatthias Ringwald sm_s1_r_prime(setup->sm_peer_random, setup->sm_local_random, sm_aes128_plaintext); 31233deb3ec6SMatthias Ringwald } 3124d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_W4_STK; 3125d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3126f3582630SMatthias 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); 31273deb3ec6SMatthias Ringwald break; 3128d1a1f6a4SMatthias Ringwald 31293deb3ec6SMatthias Ringwald case SM_PH3_Y_GET_ENC: 31303deb3ec6SMatthias Ringwald // already busy? 31313deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31323deb3ec6SMatthias Ringwald // PH3B2 - calculate Y from - enc 31339ad0dd7cSMatthias Ringwald 31349ad0dd7cSMatthias Ringwald // dm helper (was sm_dm_r_prime) 31359ad0dd7cSMatthias Ringwald // r' = padding || r 31369ad0dd7cSMatthias Ringwald // r - 64 bit value 31379ad0dd7cSMatthias Ringwald memset(&sm_aes128_plaintext[0], 0, 8); 31386535961aSMatthias Ringwald (void)memcpy(&sm_aes128_plaintext[8], setup->sm_local_rand, 8); 31399ad0dd7cSMatthias Ringwald 31403deb3ec6SMatthias Ringwald // Y = dm(DHK, Rand) 3141d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH3_Y_W4_ENC; 3142d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3143f3582630SMatthias 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); 3144d1a1f6a4SMatthias Ringwald break; 3145d1a1f6a4SMatthias Ringwald 31463deb3ec6SMatthias Ringwald case SM_PH2_C1_SEND_PAIRING_CONFIRM: { 31473deb3ec6SMatthias Ringwald uint8_t buffer[17]; 31483deb3ec6SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_CONFIRM; 31499c80e4ccSMatthias Ringwald reverse_128(setup->sm_local_confirm, &buffer[1]); 315042134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 31513deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH2_W4_PAIRING_RANDOM; 31523deb3ec6SMatthias Ringwald } else { 31533deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH2_W4_PAIRING_CONFIRM; 31543deb3ec6SMatthias Ringwald } 3155687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 31563deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 31573deb3ec6SMatthias Ringwald return; 31583deb3ec6SMatthias Ringwald } 315942134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 31603deb3ec6SMatthias Ringwald case SM_RESPONDER_PH2_SEND_LTK_REPLY: { 3161916ea5b2SMatthias Ringwald // cache key before using 3162916ea5b2SMatthias Ringwald sm_cache_ltk(connection, setup->sm_ltk); 31633deb3ec6SMatthias Ringwald sm_key_t stk_flipped; 31649c80e4ccSMatthias Ringwald reverse_128(setup->sm_ltk, stk_flipped); 31653deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH2_W4_CONNECTION_ENCRYPTED; 31663deb3ec6SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_request_reply, connection->sm_handle, stk_flipped); 31673deb3ec6SMatthias Ringwald return; 31683deb3ec6SMatthias Ringwald } 3169d7471931SMatthias Ringwald case SM_RESPONDER_PH4_SEND_LTK_REPLY: { 3170b96d60a6SMatthias Ringwald // allow to override LTK 3171b96d60a6SMatthias Ringwald if (sm_get_ltk_callback != NULL){ 3172b96d60a6SMatthias Ringwald (void)(*sm_get_ltk_callback)(connection->sm_handle, connection->sm_peer_addr_type, connection->sm_peer_address, setup->sm_ltk); 3173b96d60a6SMatthias Ringwald } 3174916ea5b2SMatthias Ringwald // cache key before using 3175916ea5b2SMatthias Ringwald sm_cache_ltk(connection, setup->sm_ltk); 31763deb3ec6SMatthias Ringwald sm_key_t ltk_flipped; 31779c80e4ccSMatthias Ringwald reverse_128(setup->sm_ltk, ltk_flipped); 31785567aa60SMatthias Ringwald connection->sm_engine_state = SM_PH4_W4_CONNECTION_ENCRYPTED; 31793deb3ec6SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_request_reply, connection->sm_handle, ltk_flipped); 31803deb3ec6SMatthias Ringwald return; 31813deb3ec6SMatthias Ringwald } 3182dd12a62bSMatthias Ringwald 3183dd12a62bSMatthias Ringwald case SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST: 31843deb3ec6SMatthias Ringwald // already busy? 31853deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31863deb3ec6SMatthias Ringwald log_info("LTK Request: recalculating with ediv 0x%04x", setup->sm_local_ediv); 3187c61cfe5aSMatthias Ringwald 3188dd12a62bSMatthias Ringwald sm_reset_setup(); 3189dd12a62bSMatthias Ringwald sm_start_calculating_ltk_from_ediv_and_rand(connection); 3190dd12a62bSMatthias Ringwald 319142646f38SMatthias Ringwald sm_reencryption_started(connection); 319242646f38SMatthias Ringwald 3193c61cfe5aSMatthias Ringwald // dm helper (was sm_dm_r_prime) 3194c61cfe5aSMatthias Ringwald // r' = padding || r 3195c61cfe5aSMatthias Ringwald // r - 64 bit value 3196c61cfe5aSMatthias Ringwald memset(&sm_aes128_plaintext[0], 0, 8); 31976535961aSMatthias Ringwald (void)memcpy(&sm_aes128_plaintext[8], setup->sm_local_rand, 8); 3198c61cfe5aSMatthias Ringwald 31993deb3ec6SMatthias Ringwald // Y = dm(DHK, Rand) 3200d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH4_Y_W4_ENC; 3201d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3202f3582630SMatthias 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); 32033deb3ec6SMatthias Ringwald return; 320442134bc6SMatthias Ringwald #endif 320542134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 320642134bc6SMatthias Ringwald case SM_INITIATOR_PH3_SEND_START_ENCRYPTION: { 3207bcab6650SMatthias Ringwald // cache key before using 3208bcab6650SMatthias Ringwald sm_cache_ltk(connection, setup->sm_ltk); 3209bcab6650SMatthias Ringwald 321042134bc6SMatthias Ringwald sm_key_t stk_flipped; 321142134bc6SMatthias Ringwald reverse_128(setup->sm_ltk, stk_flipped); 321242134bc6SMatthias Ringwald connection->sm_engine_state = SM_PH2_W4_CONNECTION_ENCRYPTED; 321342134bc6SMatthias Ringwald hci_send_cmd(&hci_le_start_encryption, connection->sm_handle, 0, 0, 0, stk_flipped); 321442134bc6SMatthias Ringwald return; 321542134bc6SMatthias Ringwald } 321642134bc6SMatthias Ringwald #endif 32173deb3ec6SMatthias Ringwald 32183deb3ec6SMatthias Ringwald case SM_PH3_DISTRIBUTE_KEYS: 3219e94757aeSMatthias Ringwald // send next key 3220403280b9SMatthias Ringwald if (setup->sm_key_distribution_send_set != 0){ 3221403280b9SMatthias Ringwald sm_run_distribute_keys(connection); 3222e94757aeSMatthias Ringwald } 3223e94757aeSMatthias Ringwald 3224e94757aeSMatthias Ringwald // more to send? 3225e94757aeSMatthias Ringwald if (setup->sm_key_distribution_send_set != 0){ 32263deb3ec6SMatthias Ringwald return; 32273deb3ec6SMatthias Ringwald } 32283deb3ec6SMatthias Ringwald 32293deb3ec6SMatthias Ringwald // keys are sent 323042134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 32313deb3ec6SMatthias Ringwald // slave -> receive master keys if any 323261d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 32333deb3ec6SMatthias Ringwald sm_key_distribution_handle_all_received(connection); 3234f5020412SMatthias Ringwald sm_key_distribution_complete_responder(connection); 3235f5020412SMatthias Ringwald // start CTKD right away 3236f5020412SMatthias Ringwald continue; 32373deb3ec6SMatthias Ringwald } else { 32383deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH3_RECEIVE_KEYS; 32393deb3ec6SMatthias Ringwald } 32403deb3ec6SMatthias Ringwald } else { 32411dca9d8aSMatthias Ringwald sm_master_pairing_success(connection); 32423deb3ec6SMatthias Ringwald } 32433deb3ec6SMatthias Ringwald break; 32443deb3ec6SMatthias Ringwald 3245c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 3246c18be159SMatthias Ringwald case SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST: 3247c18be159SMatthias Ringwald // fill in sm setup (lite version of sm_init_setup) 3248c18be159SMatthias Ringwald sm_reset_setup(); 3249c18be159SMatthias Ringwald setup->sm_peer_addr_type = connection->sm_peer_addr_type; 3250c18be159SMatthias Ringwald setup->sm_m_addr_type = connection->sm_peer_addr_type; 3251c18be159SMatthias Ringwald setup->sm_s_addr_type = connection->sm_own_addr_type; 3252c18be159SMatthias Ringwald (void) memcpy(setup->sm_peer_address, connection->sm_peer_address, 6); 3253c18be159SMatthias Ringwald (void) memcpy(setup->sm_m_address, connection->sm_peer_address, 6); 3254c18be159SMatthias Ringwald (void) memcpy(setup->sm_s_address, connection->sm_own_address, 6); 3255c18be159SMatthias Ringwald setup->sm_use_secure_connections = true; 3256c18be159SMatthias Ringwald sm_ctkd_fetch_br_edr_link_key(connection); 3257c18be159SMatthias Ringwald 3258c18be159SMatthias Ringwald // Enc Key and IRK if requested 3259c18be159SMatthias Ringwald key_distribution_flags = SM_KEYDIST_ID_KEY | SM_KEYDIST_ENC_KEY; 3260c18be159SMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 3261c18be159SMatthias Ringwald // Plus signing key if supported 3262c18be159SMatthias Ringwald key_distribution_flags |= SM_KEYDIST_ID_KEY; 3263c18be159SMatthias Ringwald #endif 3264c18be159SMatthias Ringwald sm_pairing_packet_set_code(setup->sm_m_preq, SM_CODE_PAIRING_REQUEST); 3265c18be159SMatthias Ringwald sm_pairing_packet_set_io_capability(setup->sm_m_preq, 0); 3266c18be159SMatthias Ringwald sm_pairing_packet_set_oob_data_flag(setup->sm_m_preq, 0); 3267c18be159SMatthias Ringwald sm_pairing_packet_set_auth_req(setup->sm_m_preq, SM_AUTHREQ_CT2); 3268c18be159SMatthias Ringwald sm_pairing_packet_set_max_encryption_key_size(setup->sm_m_preq, sm_max_encryption_key_size); 3269c18be159SMatthias Ringwald sm_pairing_packet_set_initiator_key_distribution(setup->sm_m_preq, key_distribution_flags); 3270c18be159SMatthias Ringwald sm_pairing_packet_set_responder_key_distribution(setup->sm_m_preq, key_distribution_flags); 3271c18be159SMatthias Ringwald 3272c18be159SMatthias Ringwald // set state and send pairing response 3273c18be159SMatthias Ringwald sm_timeout_start(connection); 3274c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_INITIATOR_W4_PAIRING_RESPONSE; 3275c18be159SMatthias Ringwald sm_send_connectionless(connection, (uint8_t *) &setup->sm_m_preq, sizeof(sm_pairing_packet_t)); 3276c18be159SMatthias Ringwald break; 3277c18be159SMatthias Ringwald 3278c18be159SMatthias Ringwald case SM_BR_EDR_RESPONDER_PAIRING_REQUEST_RECEIVED: 3279c18be159SMatthias Ringwald // fill in sm setup (lite version of sm_init_setup) 3280c18be159SMatthias Ringwald sm_reset_setup(); 3281c18be159SMatthias Ringwald setup->sm_peer_addr_type = connection->sm_peer_addr_type; 3282c18be159SMatthias Ringwald setup->sm_m_addr_type = connection->sm_peer_addr_type; 3283c18be159SMatthias Ringwald setup->sm_s_addr_type = connection->sm_own_addr_type; 3284c18be159SMatthias Ringwald (void) memcpy(setup->sm_peer_address, connection->sm_peer_address, 6); 3285c18be159SMatthias Ringwald (void) memcpy(setup->sm_m_address, connection->sm_peer_address, 6); 3286c18be159SMatthias Ringwald (void) memcpy(setup->sm_s_address, connection->sm_own_address, 6); 3287c18be159SMatthias Ringwald setup->sm_use_secure_connections = true; 3288c18be159SMatthias Ringwald sm_ctkd_fetch_br_edr_link_key(connection); 3289c18be159SMatthias Ringwald (void) memcpy(&setup->sm_m_preq, &connection->sm_m_preq, sizeof(sm_pairing_packet_t)); 3290c18be159SMatthias Ringwald 3291c18be159SMatthias Ringwald // Enc Key and IRK if requested 3292c18be159SMatthias Ringwald key_distribution_flags = SM_KEYDIST_ID_KEY | SM_KEYDIST_ENC_KEY; 3293c18be159SMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 3294c18be159SMatthias Ringwald // Plus signing key if supported 3295c18be159SMatthias Ringwald key_distribution_flags |= SM_KEYDIST_ID_KEY; 3296c18be159SMatthias Ringwald #endif 3297c18be159SMatthias Ringwald // drop flags not requested by initiator 3298c18be159SMatthias Ringwald key_distribution_flags &= sm_pairing_packet_get_initiator_key_distribution(connection->sm_m_preq); 3299c18be159SMatthias Ringwald 3300c18be159SMatthias 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: 3301c18be159SMatthias Ringwald // - the IO Capability field, 3302c18be159SMatthias Ringwald // - the OOB data flag field, and 3303c18be159SMatthias Ringwald // - all bits in the Auth Req field except the CT2 bit. 3304c18be159SMatthias Ringwald sm_pairing_packet_set_code(setup->sm_s_pres, SM_CODE_PAIRING_RESPONSE); 3305c18be159SMatthias Ringwald sm_pairing_packet_set_io_capability(setup->sm_s_pres, 0); 3306c18be159SMatthias Ringwald sm_pairing_packet_set_oob_data_flag(setup->sm_s_pres, 0); 3307c18be159SMatthias Ringwald sm_pairing_packet_set_auth_req(setup->sm_s_pres, SM_AUTHREQ_CT2); 3308c18be159SMatthias Ringwald sm_pairing_packet_set_max_encryption_key_size(setup->sm_s_pres, connection->sm_actual_encryption_key_size); 3309c18be159SMatthias Ringwald sm_pairing_packet_set_initiator_key_distribution(setup->sm_s_pres, key_distribution_flags); 3310c18be159SMatthias Ringwald sm_pairing_packet_set_responder_key_distribution(setup->sm_s_pres, key_distribution_flags); 3311c18be159SMatthias Ringwald 3312c18be159SMatthias Ringwald // configure key distribution, LTK is derived locally 3313c18be159SMatthias Ringwald key_distribution_flags &= ~SM_KEYDIST_ENC_KEY; 3314c18be159SMatthias Ringwald sm_setup_key_distribution(key_distribution_flags, key_distribution_flags); 3315c18be159SMatthias Ringwald 3316c18be159SMatthias Ringwald // set state and send pairing response 3317c18be159SMatthias Ringwald sm_timeout_start(connection); 3318c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_DISTRIBUTE_KEYS; 3319c18be159SMatthias Ringwald sm_send_connectionless(connection, (uint8_t *) &setup->sm_s_pres, sizeof(sm_pairing_packet_t)); 3320c18be159SMatthias Ringwald break; 3321c18be159SMatthias Ringwald case SM_BR_EDR_DISTRIBUTE_KEYS: 332220964aa9SMatthias Ringwald // send next key 3323c18be159SMatthias Ringwald if (setup->sm_key_distribution_send_set != 0) { 3324c18be159SMatthias Ringwald sm_run_distribute_keys(connection); 332520964aa9SMatthias Ringwald } 332620964aa9SMatthias Ringwald 332720964aa9SMatthias Ringwald // more to send? 332820964aa9SMatthias Ringwald if (setup->sm_key_distribution_send_set != 0){ 3329c18be159SMatthias Ringwald return; 3330c18be159SMatthias Ringwald } 333120964aa9SMatthias Ringwald 3332c18be159SMatthias Ringwald // keys are sent 3333c18be159SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)) { 3334c18be159SMatthias Ringwald // responder -> receive master keys if there are any 333561d1a45eSMatthias Ringwald if (!sm_key_distribution_all_received()){ 3336c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_RECEIVE_KEYS; 3337c18be159SMatthias Ringwald break; 3338c18be159SMatthias Ringwald } 3339c18be159SMatthias Ringwald } 3340c18be159SMatthias Ringwald // otherwise start CTKD right away (responder and no keys to receive / initiator) 3341c18be159SMatthias Ringwald sm_ctkd_start_from_br_edr(connection); 3342c18be159SMatthias Ringwald continue; 3343c18be159SMatthias Ringwald case SM_SC_W2_CALCULATE_ILK_USING_H6: 3344c18be159SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_ILK; 3345c18be159SMatthias Ringwald h6_calculate_ilk_from_le_ltk(connection); 3346c18be159SMatthias Ringwald break; 3347c18be159SMatthias Ringwald case SM_SC_W2_CALCULATE_BR_EDR_LINK_KEY: 3348c18be159SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_BR_EDR_LINK_KEY; 3349c18be159SMatthias Ringwald h6_calculate_br_edr_link_key(connection); 3350c18be159SMatthias Ringwald break; 3351c18be159SMatthias Ringwald case SM_SC_W2_CALCULATE_ILK_USING_H7: 3352c18be159SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_ILK; 3353c18be159SMatthias Ringwald h7_calculate_ilk_from_le_ltk(connection); 3354c18be159SMatthias Ringwald break; 3355c18be159SMatthias Ringwald case SM_BR_EDR_W2_CALCULATE_ILK_USING_H6: 3356c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_W4_CALCULATE_ILK; 3357c18be159SMatthias Ringwald h6_calculate_ilk_from_br_edr(connection); 3358c18be159SMatthias Ringwald break; 3359c18be159SMatthias Ringwald case SM_BR_EDR_W2_CALCULATE_LE_LTK: 3360c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_W4_CALCULATE_LE_LTK; 3361c18be159SMatthias Ringwald h6_calculate_le_ltk(connection); 3362c18be159SMatthias Ringwald break; 3363c18be159SMatthias Ringwald case SM_BR_EDR_W2_CALCULATE_ILK_USING_H7: 3364c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_W4_CALCULATE_ILK; 3365c18be159SMatthias Ringwald h7_calculate_ilk_from_br_edr(connection); 3366c18be159SMatthias Ringwald break; 3367c18be159SMatthias Ringwald #endif 3368c18be159SMatthias Ringwald 33693deb3ec6SMatthias Ringwald default: 33703deb3ec6SMatthias Ringwald break; 33713deb3ec6SMatthias Ringwald } 33723deb3ec6SMatthias Ringwald 33733deb3ec6SMatthias Ringwald // check again if active connection was released 33747149bde5SMatthias Ringwald if (sm_active_connection_handle != HCI_CON_HANDLE_INVALID) break; 33753deb3ec6SMatthias Ringwald } 33763deb3ec6SMatthias Ringwald } 33773deb3ec6SMatthias Ringwald 3378d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3379d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_a(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, setup->sm_local_confirm, sm_handle_encryption_result_enc_b, (void *)(uintptr_t) connection->sm_handle); 3389d1a1f6a4SMatthias Ringwald } 33903deb3ec6SMatthias Ringwald 3391d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_b(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 33988314c363SMatthias Ringwald log_info_key("c1!", setup->sm_local_confirm); 33993deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_SEND_PAIRING_CONFIRM; 340070b44dd4SMatthias Ringwald sm_trigger_run(); 3401d1a1f6a4SMatthias Ringwald } 3402d1a1f6a4SMatthias Ringwald 3403d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3404d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_c(void *arg){ 3405f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 340604678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 340704678764SMatthias Ringwald 3408f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3409f3582630SMatthias Ringwald if (connection == NULL) return; 3410f3582630SMatthias Ringwald 3411d1a1f6a4SMatthias Ringwald sm_c1_t3(sm_aes128_ciphertext, setup->sm_m_address, setup->sm_s_address, setup->sm_c1_t3_value); 341204678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3413f3582630SMatthias 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); 3414d1a1f6a4SMatthias Ringwald } 3415d1a1f6a4SMatthias Ringwald 3416d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_d(void * arg){ 3417f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 341804678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 341904678764SMatthias Ringwald 3420f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3421f3582630SMatthias Ringwald if (connection == NULL) return; 3422f3582630SMatthias Ringwald 3423d1a1f6a4SMatthias Ringwald log_info_key("c1!", sm_aes128_ciphertext); 3424d1a1f6a4SMatthias Ringwald if (memcmp(setup->sm_peer_confirm, sm_aes128_ciphertext, 16) != 0){ 3425f4935286SMatthias Ringwald sm_pairing_error(connection, SM_REASON_CONFIRM_VALUE_FAILED); 342670b44dd4SMatthias Ringwald sm_trigger_run(); 34273deb3ec6SMatthias Ringwald return; 34283deb3ec6SMatthias Ringwald } 342942134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 34303deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH2_SEND_PAIRING_RANDOM; 343170b44dd4SMatthias Ringwald sm_trigger_run(); 34323deb3ec6SMatthias Ringwald } else { 3433d1a1f6a4SMatthias Ringwald sm_s1_r_prime(setup->sm_peer_random, setup->sm_local_random, sm_aes128_plaintext); 3434d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3435f3582630SMatthias 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); 34363deb3ec6SMatthias Ringwald } 34373deb3ec6SMatthias Ringwald } 3438d1a1f6a4SMatthias Ringwald 3439d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_stk(void *arg){ 344004678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 3441f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 344204678764SMatthias Ringwald 3443f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3444f3582630SMatthias Ringwald if (connection == NULL) return; 3445f3582630SMatthias Ringwald 34463deb3ec6SMatthias Ringwald sm_truncate_key(setup->sm_ltk, connection->sm_actual_encryption_key_size); 34478314c363SMatthias Ringwald log_info_key("stk", setup->sm_ltk); 344842134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 34493deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH2_SEND_LTK_REPLY; 34503deb3ec6SMatthias Ringwald } else { 34513deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH3_SEND_START_ENCRYPTION; 34523deb3ec6SMatthias Ringwald } 345370b44dd4SMatthias Ringwald sm_trigger_run(); 3454d1a1f6a4SMatthias Ringwald } 3455d1a1f6a4SMatthias Ringwald 3456d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3457d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph3_y(void *arg){ 3458f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 345904678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 346004678764SMatthias Ringwald 3461f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3462f3582630SMatthias Ringwald if (connection == NULL) return; 3463f3582630SMatthias Ringwald 3464d1a1f6a4SMatthias Ringwald setup->sm_local_y = big_endian_read_16(sm_aes128_ciphertext, 14); 34653deb3ec6SMatthias Ringwald log_info_hex16("y", setup->sm_local_y); 34663deb3ec6SMatthias Ringwald // PH3B3 - calculate EDIV 34673deb3ec6SMatthias Ringwald setup->sm_local_ediv = setup->sm_local_y ^ setup->sm_local_div; 34683deb3ec6SMatthias Ringwald log_info_hex16("ediv", setup->sm_local_ediv); 34693deb3ec6SMatthias Ringwald // PH3B4 - calculate LTK - enc 34703deb3ec6SMatthias Ringwald // LTK = d1(ER, DIV, 0)) 3471d1a1f6a4SMatthias Ringwald sm_d1_d_prime(setup->sm_local_div, 0, sm_aes128_plaintext); 347204678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3473f3582630SMatthias 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); 34743deb3ec6SMatthias Ringwald } 3475d1a1f6a4SMatthias Ringwald 34762a526f21SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 3477d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3478d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph4_y(void *arg){ 347904678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 3480f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 348104678764SMatthias Ringwald 3482f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3483f3582630SMatthias Ringwald if (connection == NULL) return; 3484f3582630SMatthias Ringwald 3485d1a1f6a4SMatthias Ringwald setup->sm_local_y = big_endian_read_16(sm_aes128_ciphertext, 14); 34863deb3ec6SMatthias Ringwald log_info_hex16("y", setup->sm_local_y); 34873deb3ec6SMatthias Ringwald 34883deb3ec6SMatthias Ringwald // PH3B3 - calculate DIV 34893deb3ec6SMatthias Ringwald setup->sm_local_div = setup->sm_local_y ^ setup->sm_local_ediv; 34903deb3ec6SMatthias Ringwald log_info_hex16("ediv", setup->sm_local_ediv); 34913deb3ec6SMatthias Ringwald // PH3B4 - calculate LTK - enc 34923deb3ec6SMatthias Ringwald // LTK = d1(ER, DIV, 0)) 3493d1a1f6a4SMatthias Ringwald sm_d1_d_prime(setup->sm_local_div, 0, sm_aes128_plaintext); 349404678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3495f3582630SMatthias 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); 34963deb3ec6SMatthias Ringwald } 34972a526f21SMatthias Ringwald #endif 3498d1a1f6a4SMatthias Ringwald 3499d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3500d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph3_ltk(void *arg){ 3501f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 350204678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 350304678764SMatthias Ringwald 3504f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3505f3582630SMatthias Ringwald if (connection == NULL) return; 3506f3582630SMatthias Ringwald 35078314c363SMatthias Ringwald log_info_key("ltk", setup->sm_ltk); 35083deb3ec6SMatthias Ringwald // calc CSRK next 3509d1a1f6a4SMatthias Ringwald sm_d1_d_prime(setup->sm_local_div, 1, sm_aes128_plaintext); 351004678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3511f3582630SMatthias 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); 3512d1a1f6a4SMatthias Ringwald } 3513d1a1f6a4SMatthias Ringwald 3514d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_csrk(void *arg){ 3515f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 351604678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 351704678764SMatthias Ringwald 3518f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3519f3582630SMatthias Ringwald if (connection == NULL) return; 3520f3582630SMatthias Ringwald 3521d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 35228314c363SMatthias Ringwald log_info_key("csrk", setup->sm_local_csrk); 35231d80f1e6SMatthias Ringwald if (setup->sm_key_distribution_send_set != 0u){ 35243deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 35253deb3ec6SMatthias Ringwald } else { 35263deb3ec6SMatthias Ringwald // no keys to send, just continue 352742134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 352861d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 3529c5a72e35SMatthias Ringwald sm_key_distribution_handle_all_received(connection); 3530c5a72e35SMatthias Ringwald sm_key_distribution_complete_responder(connection); 3531c5a72e35SMatthias Ringwald } else { 35323deb3ec6SMatthias Ringwald // slave -> receive master keys 35333deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH3_RECEIVE_KEYS; 3534c5a72e35SMatthias Ringwald } 35353deb3ec6SMatthias Ringwald } else { 3536af7ef9d1SMatthias Ringwald sm_key_distribution_complete_initiator(connection); 35373deb3ec6SMatthias Ringwald } 35382bacf595SMatthias Ringwald } 353970b44dd4SMatthias Ringwald sm_trigger_run(); 3540d1a1f6a4SMatthias Ringwald } 3541d1a1f6a4SMatthias Ringwald 354242134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 3543d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph4_ltk(void *arg){ 3544f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 354504678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 354604678764SMatthias Ringwald 3547f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3548f3582630SMatthias Ringwald if (connection == NULL) return; 3549f3582630SMatthias Ringwald 35503deb3ec6SMatthias Ringwald sm_truncate_key(setup->sm_ltk, connection->sm_actual_encryption_key_size); 35518314c363SMatthias Ringwald log_info_key("ltk", setup->sm_ltk); 3552d7471931SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH4_SEND_LTK_REPLY; 355370b44dd4SMatthias Ringwald sm_trigger_run(); 3554d1a1f6a4SMatthias Ringwald } 3555d1a1f6a4SMatthias Ringwald #endif 3556d1a1f6a4SMatthias Ringwald 3557d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_address_resolution(void *arg){ 3558d1a1f6a4SMatthias Ringwald UNUSED(arg); 3559d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 356004678764SMatthias Ringwald 3561d1a1f6a4SMatthias Ringwald // compare calulated address against connecting device 3562d1a1f6a4SMatthias Ringwald uint8_t * hash = &sm_aes128_ciphertext[13]; 3563d1a1f6a4SMatthias Ringwald if (memcmp(&sm_address_resolution_address[3], hash, 3) == 0){ 3564d1a1f6a4SMatthias Ringwald log_info("LE Device Lookup: matched resolvable private address"); 3565a66b030fSMatthias Ringwald sm_address_resolution_handle_event(ADDRESS_RESOLUTION_SUCCEEDED); 356670b44dd4SMatthias Ringwald sm_trigger_run(); 35673deb3ec6SMatthias Ringwald return; 35683deb3ec6SMatthias Ringwald } 3569d1a1f6a4SMatthias Ringwald // no match, try next 3570d1a1f6a4SMatthias Ringwald sm_address_resolution_test++; 357170b44dd4SMatthias Ringwald sm_trigger_run(); 35723deb3ec6SMatthias Ringwald } 35733deb3ec6SMatthias Ringwald 3574d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_dkg_irk(void *arg){ 3575d1a1f6a4SMatthias Ringwald UNUSED(arg); 3576d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 357704678764SMatthias Ringwald 3578d1a1f6a4SMatthias Ringwald log_info_key("irk", sm_persistent_irk); 3579d1a1f6a4SMatthias Ringwald dkg_state = DKG_CALC_DHK; 358070b44dd4SMatthias Ringwald sm_trigger_run(); 35817df18c15SMatthias Ringwald } 3582d1a1f6a4SMatthias Ringwald 3583d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_dkg_dhk(void *arg){ 3584d1a1f6a4SMatthias Ringwald UNUSED(arg); 3585d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 358604678764SMatthias Ringwald 3587d1a1f6a4SMatthias Ringwald log_info_key("dhk", sm_persistent_dhk); 3588d1a1f6a4SMatthias Ringwald dkg_state = DKG_READY; 358970b44dd4SMatthias Ringwald sm_trigger_run(); 35907df18c15SMatthias Ringwald } 3591d1a1f6a4SMatthias Ringwald 3592d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_rau(void *arg){ 3593d1a1f6a4SMatthias Ringwald UNUSED(arg); 3594d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 359504678764SMatthias Ringwald 35966535961aSMatthias Ringwald (void)memcpy(&sm_random_address[3], &sm_aes128_ciphertext[13], 3); 3597e91ddb40SMatthias Ringwald rau_state = RAU_IDLE; 3598e91ddb40SMatthias Ringwald hci_le_random_address_set(sm_random_address); 3599e91ddb40SMatthias Ringwald 360070b44dd4SMatthias Ringwald sm_trigger_run(); 360151fa0b28SMatthias Ringwald } 36027df18c15SMatthias Ringwald 3603d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_rau(void * arg){ 3604d1a1f6a4SMatthias Ringwald UNUSED(arg); 36053deb3ec6SMatthias Ringwald // non-resolvable vs. resolvable 36063deb3ec6SMatthias Ringwald switch (gap_random_adress_type){ 36073deb3ec6SMatthias Ringwald case GAP_RANDOM_ADDRESS_RESOLVABLE: 36083deb3ec6SMatthias Ringwald // resolvable: use random as prand and calc address hash 36093deb3ec6SMatthias Ringwald // "The two most significant bits of prand shall be equal to ‘0’ and ‘1" 36104ea43905SMatthias Ringwald sm_random_address[0u] &= 0x3fu; 36114ea43905SMatthias Ringwald sm_random_address[0u] |= 0x40u; 36123deb3ec6SMatthias Ringwald rau_state = RAU_GET_ENC; 36133deb3ec6SMatthias Ringwald break; 36143deb3ec6SMatthias Ringwald case GAP_RANDOM_ADDRESS_NON_RESOLVABLE: 36153deb3ec6SMatthias Ringwald default: 36163deb3ec6SMatthias Ringwald // "The two most significant bits of the address shall be equal to ‘0’"" 36174ea43905SMatthias Ringwald sm_random_address[0u] &= 0x3fu; 36182954e6c6SMatthias Ringwald rau_state = RAU_IDLE; 3619e91ddb40SMatthias Ringwald hci_le_random_address_set(sm_random_address); 36203deb3ec6SMatthias Ringwald break; 36213deb3ec6SMatthias Ringwald } 362270b44dd4SMatthias Ringwald sm_trigger_run(); 36233deb3ec6SMatthias Ringwald } 36243deb3ec6SMatthias Ringwald 3625c59d0c92SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 36266ca80073SMatthias Ringwald static void sm_handle_random_result_sc_next_send_pairing_random(void * arg){ 3627f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3628f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3629f3582630SMatthias Ringwald if (connection == NULL) return; 3630c59d0c92SMatthias Ringwald 363165a9a04eSMatthias Ringwald connection->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM; 363270b44dd4SMatthias Ringwald sm_trigger_run(); 363365a9a04eSMatthias Ringwald } 3634d1a1f6a4SMatthias Ringwald 36356ca80073SMatthias Ringwald static void sm_handle_random_result_sc_next_w2_cmac_for_confirmation(void * arg){ 36366ca80073SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 36376ca80073SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 36386ca80073SMatthias Ringwald if (connection == NULL) return; 36396ca80073SMatthias Ringwald 3640b35a3de2SMatthias Ringwald connection->sm_engine_state = SM_SC_W2_CMAC_FOR_CONFIRMATION; 364170b44dd4SMatthias Ringwald sm_trigger_run(); 3642d1a1f6a4SMatthias Ringwald } 3643f1c1783eSMatthias Ringwald #endif 3644f1c1783eSMatthias Ringwald 3645d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph2_random(void * arg){ 3646f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3647f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3648f3582630SMatthias Ringwald if (connection == NULL) return; 3649f3582630SMatthias Ringwald 3650d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_GET_ENC_A; 365170b44dd4SMatthias Ringwald sm_trigger_run(); 3652d1a1f6a4SMatthias Ringwald } 3653d1a1f6a4SMatthias Ringwald 3654d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph2_tk(void * arg){ 3655f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3656f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3657f3582630SMatthias Ringwald if (connection == NULL) return; 3658f3582630SMatthias Ringwald 3659caf15bf3SMatthias Ringwald sm_reset_tk(); 3660caf15bf3SMatthias Ringwald uint32_t tk; 36615ce1359eSMatthias Ringwald if (sm_fixed_passkey_in_display_role == 0xffffffffU){ 36623deb3ec6SMatthias Ringwald // map random to 0-999999 without speding much cycles on a modulus operation 3663d1a1f6a4SMatthias Ringwald tk = little_endian_read_32(sm_random_data,0); 36643deb3ec6SMatthias Ringwald tk = tk & 0xfffff; // 1048575 36654ea43905SMatthias Ringwald if (tk >= 999999u){ 36664ea43905SMatthias Ringwald tk = tk - 999999u; 36673deb3ec6SMatthias Ringwald } 3668caf15bf3SMatthias Ringwald } else { 3669caf15bf3SMatthias Ringwald // override with pre-defined passkey 36704b8c611fSMatthias Ringwald tk = sm_fixed_passkey_in_display_role; 3671caf15bf3SMatthias Ringwald } 3672f8fbdce0SMatthias Ringwald big_endian_store_32(setup->sm_tk, 12, tk); 367342134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 36743deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE; 36753deb3ec6SMatthias Ringwald } else { 3676b41539d5SMatthias Ringwald if (setup->sm_use_secure_connections){ 3677b41539d5SMatthias Ringwald connection->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 3678b41539d5SMatthias Ringwald } else { 36793deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 36803deb3ec6SMatthias Ringwald sm_trigger_user_response(connection); 36813deb3ec6SMatthias Ringwald // response_idle == nothing <--> sm_trigger_user_response() did not require response 36823deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ 3683f3582630SMatthias 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); 36843deb3ec6SMatthias Ringwald } 36853deb3ec6SMatthias Ringwald } 3686b41539d5SMatthias Ringwald } 368770b44dd4SMatthias Ringwald sm_trigger_run(); 36883deb3ec6SMatthias Ringwald } 3689d1a1f6a4SMatthias Ringwald 3690d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph3_div(void * arg){ 3691f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3692f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3693f3582630SMatthias Ringwald if (connection == NULL) return; 3694f3582630SMatthias Ringwald 3695d1a1f6a4SMatthias Ringwald // use 16 bit from random value as div 3696d1a1f6a4SMatthias Ringwald setup->sm_local_div = big_endian_read_16(sm_random_data, 0); 3697d1a1f6a4SMatthias Ringwald log_info_hex16("div", setup->sm_local_div); 3698d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH3_Y_GET_ENC; 369970b44dd4SMatthias Ringwald sm_trigger_run(); 3700d1a1f6a4SMatthias Ringwald } 3701d1a1f6a4SMatthias Ringwald 3702d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph3_random(void * arg){ 3703f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3704f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3705f3582630SMatthias Ringwald if (connection == NULL) return; 3706f3582630SMatthias Ringwald 3707d1a1f6a4SMatthias Ringwald reverse_64(sm_random_data, setup->sm_local_rand); 37083deb3ec6SMatthias Ringwald // no db for encryption size hack: encryption size is stored in lowest nibble of setup->sm_local_rand 37094ea43905SMatthias Ringwald setup->sm_local_rand[7u] = (setup->sm_local_rand[7u] & 0xf0u) + (connection->sm_actual_encryption_key_size - 1u); 37103deb3ec6SMatthias Ringwald // no db for authenticated flag hack: store flag in bit 4 of LSB 37114ea43905SMatthias Ringwald setup->sm_local_rand[7u] = (setup->sm_local_rand[7u] & 0xefu) + (connection->sm_connection_authenticated << 4u); 37128b3ffec5SMatthias 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); 37133deb3ec6SMatthias Ringwald } 3714899e6e02SMatthias Ringwald static void sm_validate_er_ir(void){ 3715899e6e02SMatthias Ringwald // warn about default ER/IR 37161979f09cSMatthias Ringwald bool warning = false; 3717899e6e02SMatthias Ringwald if (sm_ir_is_default()){ 37181979f09cSMatthias Ringwald warning = true; 3719899e6e02SMatthias Ringwald log_error("Persistent IR not set with sm_set_ir. Use of private addresses will cause pairing issues"); 3720899e6e02SMatthias Ringwald } 3721899e6e02SMatthias Ringwald if (sm_er_is_default()){ 37221979f09cSMatthias Ringwald warning = true; 3723899e6e02SMatthias Ringwald log_error("Persistent ER not set with sm_set_er. Legacy Pairing LTK is not secure"); 3724899e6e02SMatthias Ringwald } 372521045273SMatthias Ringwald if (warning) { 3726899e6e02SMatthias Ringwald log_error("Please configure btstack_tlv to let BTstack setup ER and IR keys"); 3727899e6e02SMatthias Ringwald } 372821045273SMatthias Ringwald } 3729899e6e02SMatthias Ringwald 3730899e6e02SMatthias Ringwald static void sm_handle_random_result_ir(void *arg){ 37311979f09cSMatthias Ringwald sm_persistent_keys_random_active = false; 37329305033eSMatthias Ringwald if (arg != NULL){ 3733899e6e02SMatthias Ringwald // key generated, store in tlv 37344ea43905SMatthias Ringwald int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16u); 3735899e6e02SMatthias Ringwald log_info("Generated IR key. Store in TLV status: %d", status); 3736e0d13a19SMilanka Ringwald UNUSED(status); 3737899e6e02SMatthias Ringwald } 3738899e6e02SMatthias Ringwald log_info_key("IR", sm_persistent_ir); 37398d9b6072SMatthias Ringwald dkg_state = DKG_CALC_IRK; 3740841468bbSMatthias Ringwald 3741841468bbSMatthias Ringwald if (test_use_fixed_local_irk){ 3742841468bbSMatthias Ringwald log_info_key("IRK", sm_persistent_irk); 3743841468bbSMatthias Ringwald dkg_state = DKG_CALC_DHK; 3744841468bbSMatthias Ringwald } 3745841468bbSMatthias Ringwald 374670b44dd4SMatthias Ringwald sm_trigger_run(); 3747899e6e02SMatthias Ringwald } 3748899e6e02SMatthias Ringwald 3749899e6e02SMatthias Ringwald static void sm_handle_random_result_er(void *arg){ 37501979f09cSMatthias Ringwald sm_persistent_keys_random_active = false; 37516643d79bSMatthias Ringwald if (arg != NULL){ 3752899e6e02SMatthias Ringwald // key generated, store in tlv 37534ea43905SMatthias Ringwald int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16u); 3754899e6e02SMatthias Ringwald log_info("Generated ER key. Store in TLV status: %d", status); 3755e0d13a19SMilanka Ringwald UNUSED(status); 3756899e6e02SMatthias Ringwald } 3757899e6e02SMatthias Ringwald log_info_key("ER", sm_persistent_er); 3758899e6e02SMatthias Ringwald 3759899e6e02SMatthias Ringwald // try load ir 37604ea43905SMatthias Ringwald int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16u); 3761899e6e02SMatthias Ringwald if (key_size == 16){ 3762899e6e02SMatthias Ringwald // ok, let's continue 3763899e6e02SMatthias Ringwald log_info("IR from TLV"); 3764899e6e02SMatthias Ringwald sm_handle_random_result_ir( NULL ); 3765899e6e02SMatthias Ringwald } else { 3766899e6e02SMatthias Ringwald // invalid, generate new random one 37671979f09cSMatthias Ringwald sm_persistent_keys_random_active = true; 3768899e6e02SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_ir, 16, &sm_handle_random_result_ir, &sm_persistent_ir); 3769899e6e02SMatthias Ringwald } 3770899e6e02SMatthias Ringwald } 37713deb3ec6SMatthias Ringwald 377250053c13SMatthias Ringwald static void sm_connection_init(sm_connection_t * sm_conn, hci_con_handle_t con_handle, uint8_t role, uint8_t peer_addr_type, bd_addr_t peer_address){ 3773f664b5e8SMatthias Ringwald 3774f664b5e8SMatthias Ringwald // connection info 3775f664b5e8SMatthias Ringwald sm_conn->sm_handle = con_handle; 3776f664b5e8SMatthias Ringwald sm_conn->sm_role = role; 377750053c13SMatthias Ringwald sm_conn->sm_peer_addr_type = peer_addr_type; 377850053c13SMatthias Ringwald memcpy(sm_conn->sm_peer_address, peer_address, 6); 3779f664b5e8SMatthias Ringwald 3780f664b5e8SMatthias Ringwald // security properties 3781f664b5e8SMatthias Ringwald sm_conn->sm_connection_encrypted = 0; 3782f664b5e8SMatthias Ringwald sm_conn->sm_connection_authenticated = 0; 3783f664b5e8SMatthias Ringwald sm_conn->sm_connection_authorization_state = AUTHORIZATION_UNKNOWN; 3784f664b5e8SMatthias Ringwald sm_conn->sm_le_db_index = -1; 3785f664b5e8SMatthias Ringwald sm_conn->sm_reencryption_active = false; 3786f664b5e8SMatthias Ringwald 3787f664b5e8SMatthias Ringwald // prepare CSRK lookup (does not involve setup) 3788f664b5e8SMatthias Ringwald sm_conn->sm_irk_lookup_state = IRK_LOOKUP_W4_READY; 3789f664b5e8SMatthias Ringwald 3790f664b5e8SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_IDLE; 3791f664b5e8SMatthias Ringwald } 3792f664b5e8SMatthias Ringwald 3793599e89daSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 3794599e89daSMatthias Ringwald static void sm_event_handle_classic_encryption_event(sm_connection_t * sm_conn, hci_con_handle_t con_handle){ 3795599e89daSMatthias Ringwald // CTKD requires BR/EDR Secure Connection 3796599e89daSMatthias Ringwald if (sm_conn->sm_connection_encrypted != 2) return; 3797599e89daSMatthias Ringwald // prepare for pairing request 3798599e89daSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 3799d44cdc4aSMatthias Ringwald log_info("CTKD: SM_BR_EDR_RESPONDER_W4_PAIRING_REQUEST"); 3800599e89daSMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_RESPONDER_W4_PAIRING_REQUEST; 3801599e89daSMatthias Ringwald } else if (sm_conn->sm_pairing_requested){ 3802599e89daSMatthias Ringwald // check if remote supports fixed channels 3803599e89daSMatthias Ringwald bool defer = true; 3804599e89daSMatthias Ringwald const hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); 3805599e89daSMatthias Ringwald if (hci_connection->l2cap_state.information_state == L2CAP_INFORMATION_STATE_DONE){ 3806599e89daSMatthias Ringwald // check if remote supports SMP over BR/EDR 3807599e89daSMatthias Ringwald if ((hci_connection->l2cap_state.fixed_channels_supported & (1 << L2CAP_CID_BR_EDR_SECURITY_MANAGER)) != 0){ 3808599e89daSMatthias Ringwald log_info("CTKD: SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST"); 3809599e89daSMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST; 3810599e89daSMatthias Ringwald } else { 3811599e89daSMatthias Ringwald defer = false; 3812599e89daSMatthias Ringwald } 3813599e89daSMatthias Ringwald } else { 3814599e89daSMatthias Ringwald // wait for fixed channel info 3815599e89daSMatthias Ringwald log_info("CTKD: SM_BR_EDR_INITIATOR_W4_FIXED_CHANNEL_MASK"); 3816599e89daSMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_INITIATOR_W4_FIXED_CHANNEL_MASK; 3817599e89daSMatthias Ringwald } 3818599e89daSMatthias Ringwald if (defer){ 3819599e89daSMatthias Ringwald hci_dedicated_bonding_defer_disconnect(con_handle, true); 3820599e89daSMatthias Ringwald } 3821599e89daSMatthias Ringwald } 3822599e89daSMatthias Ringwald } 3823599e89daSMatthias Ringwald #endif 3824599e89daSMatthias Ringwald 3825d9a7306aSMatthias Ringwald static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 38263deb3ec6SMatthias Ringwald 3827cbdfe9f7SMatthias Ringwald UNUSED(channel); // ok: there is no channel 3828cbdfe9f7SMatthias Ringwald UNUSED(size); // ok: fixed format HCI events 38299ec2630cSMatthias Ringwald 38303deb3ec6SMatthias Ringwald sm_connection_t * sm_conn; 3831711e6c80SMatthias Ringwald hci_con_handle_t con_handle; 3832fbe050beSMatthias Ringwald uint8_t status; 3833f664b5e8SMatthias Ringwald bd_addr_t addr; 3834d9f3ead5SMatthias Ringwald bd_addr_type_t addr_type; 3835f664b5e8SMatthias Ringwald 38363deb3ec6SMatthias Ringwald switch (packet_type) { 38373deb3ec6SMatthias Ringwald 38383deb3ec6SMatthias Ringwald case HCI_EVENT_PACKET: 38390e2df43fSMatthias Ringwald switch (hci_event_packet_get_type(packet)) { 38403deb3ec6SMatthias Ringwald 38413deb3ec6SMatthias Ringwald case BTSTACK_EVENT_STATE: 3842745015f6SMatthias Ringwald switch (btstack_event_state_get_state(packet)){ 3843745015f6SMatthias Ringwald case HCI_STATE_WORKING: 38443deb3ec6SMatthias Ringwald log_info("HCI Working!"); 3845899e6e02SMatthias Ringwald // setup IR/ER with TLV 3846899e6e02SMatthias Ringwald btstack_tlv_get_instance(&sm_tlv_impl, &sm_tlv_context); 38479305033eSMatthias Ringwald if (sm_tlv_impl != NULL){ 38484ea43905SMatthias Ringwald int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16u); 3849899e6e02SMatthias Ringwald if (key_size == 16){ 3850899e6e02SMatthias Ringwald // ok, let's continue 3851899e6e02SMatthias Ringwald log_info("ER from TLV"); 3852899e6e02SMatthias Ringwald sm_handle_random_result_er( NULL ); 3853899e6e02SMatthias Ringwald } else { 3854899e6e02SMatthias Ringwald // invalid, generate random one 38551979f09cSMatthias Ringwald sm_persistent_keys_random_active = true; 3856899e6e02SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_er, 16, &sm_handle_random_result_er, &sm_persistent_er); 3857899e6e02SMatthias Ringwald } 3858899e6e02SMatthias Ringwald } else { 3859899e6e02SMatthias Ringwald sm_validate_er_ir(); 38608d9b6072SMatthias Ringwald dkg_state = DKG_CALC_IRK; 3861841468bbSMatthias Ringwald 3862841468bbSMatthias Ringwald if (test_use_fixed_local_irk){ 3863841468bbSMatthias Ringwald log_info_key("IRK", sm_persistent_irk); 3864841468bbSMatthias Ringwald dkg_state = DKG_CALC_DHK; 3865841468bbSMatthias Ringwald } 3866899e6e02SMatthias Ringwald } 38671bf086daSMatthias Ringwald 386815211b85SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 386915211b85SMatthias Ringwald // trigger ECC key generation 387015211b85SMatthias Ringwald if (ec_key_generation_state == EC_KEY_GENERATION_IDLE){ 387115211b85SMatthias Ringwald sm_ec_generate_new_key(); 387215211b85SMatthias Ringwald } 387315211b85SMatthias Ringwald #endif 387415211b85SMatthias Ringwald 38751bf086daSMatthias Ringwald // restart random address updates after power cycle 38764a688bd1SMatthias Ringwald if (gap_random_adress_type == GAP_RANDOM_ADDRESS_TYPE_STATIC){ 38774a688bd1SMatthias Ringwald gap_random_address_set(sm_random_address); 38784a688bd1SMatthias Ringwald } else { 38791bf086daSMatthias Ringwald gap_random_address_set_mode(gap_random_adress_type); 38804a688bd1SMatthias Ringwald } 3881745015f6SMatthias Ringwald break; 3882745015f6SMatthias Ringwald 3883745015f6SMatthias Ringwald case HCI_STATE_OFF: 38847f775357SMatthias Ringwald case HCI_STATE_HALTING: 3885cbdd51cfSMatthias Ringwald log_info("SM: reset state"); 3886745015f6SMatthias Ringwald // stop random address update 3887745015f6SMatthias Ringwald gap_random_address_update_stop(); 3888cbdd51cfSMatthias Ringwald // reset state 3889cbdd51cfSMatthias Ringwald sm_state_reset(); 3890745015f6SMatthias Ringwald break; 3891745015f6SMatthias Ringwald 3892745015f6SMatthias Ringwald default: 3893745015f6SMatthias Ringwald break; 38943deb3ec6SMatthias Ringwald } 38953deb3ec6SMatthias Ringwald break; 3896c18be159SMatthias Ringwald 38972d095694SMatthias Ringwald #ifdef ENABLE_CLASSIC 38982d095694SMatthias Ringwald case HCI_EVENT_CONNECTION_COMPLETE: 38992d095694SMatthias Ringwald // ignore if connection failed 39002d095694SMatthias Ringwald if (hci_event_connection_complete_get_status(packet)) return; 39013deb3ec6SMatthias Ringwald 39022d095694SMatthias Ringwald con_handle = hci_event_connection_complete_get_connection_handle(packet); 39032d095694SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 39042d095694SMatthias Ringwald if (!sm_conn) break; 39052d095694SMatthias Ringwald 39062d095694SMatthias Ringwald hci_event_connection_complete_get_bd_addr(packet, addr); 39072d095694SMatthias Ringwald sm_connection_init(sm_conn, 39082d095694SMatthias Ringwald con_handle, 39092d095694SMatthias Ringwald (uint8_t) gap_get_role(con_handle), 3910f72f7944SMatthias Ringwald BD_ADDR_TYPE_LE_PUBLIC, 39112d095694SMatthias Ringwald addr); 39122d095694SMatthias Ringwald // classic connection corresponds to public le address 39132d095694SMatthias Ringwald sm_conn->sm_own_addr_type = BD_ADDR_TYPE_LE_PUBLIC; 39142d095694SMatthias Ringwald gap_local_bd_addr(sm_conn->sm_own_address); 39152d095694SMatthias Ringwald sm_conn->sm_cid = L2CAP_CID_BR_EDR_SECURITY_MANAGER; 3916c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_W4_ENCRYPTION_COMPLETE; 39172d095694SMatthias Ringwald break; 3918d44cdc4aSMatthias Ringwald 3919*401d2b30SMatthias Ringwald #endif 3920*401d2b30SMatthias Ringwald 3921*401d2b30SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 3922d44cdc4aSMatthias Ringwald case HCI_EVENT_ROLE_CHANGE: 3923d44cdc4aSMatthias Ringwald hci_event_role_change_get_bd_addr(packet, addr); 3924d44cdc4aSMatthias Ringwald sm_conn = sm_get_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL); 3925d44cdc4aSMatthias Ringwald if (sm_conn == NULL) break; 3926d44cdc4aSMatthias Ringwald sm_conn->sm_role = hci_event_role_change_get_role(packet); 3927d44cdc4aSMatthias Ringwald break; 3928c18be159SMatthias Ringwald 3929c18be159SMatthias Ringwald case HCI_EVENT_SIMPLE_PAIRING_COMPLETE: 3930c18be159SMatthias Ringwald if (hci_event_simple_pairing_complete_get_status(packet) != ERROR_CODE_SUCCESS) break; 3931c18be159SMatthias Ringwald hci_event_simple_pairing_complete_get_bd_addr(packet, addr); 3932c18be159SMatthias Ringwald sm_conn = sm_get_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL); 3933c18be159SMatthias Ringwald if (sm_conn == NULL) break; 39345f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 3935c18be159SMatthias Ringwald break; 3936c18be159SMatthias Ringwald #endif 3937c18be159SMatthias Ringwald 39389d1eff91SMatthias Ringwald case HCI_EVENT_META_GAP: 39399d1eff91SMatthias Ringwald switch (hci_event_gap_meta_get_subevent_code(packet)) { 39409d1eff91SMatthias Ringwald case GAP_SUBEVENT_LE_CONNECTION_COMPLETE: 3941f664b5e8SMatthias Ringwald // ignore if connection failed 39429d1eff91SMatthias Ringwald if (gap_subevent_le_connection_complete_get_status(packet) != ERROR_CODE_SUCCESS) break; 39433deb3ec6SMatthias Ringwald 39449d1eff91SMatthias Ringwald con_handle = gap_subevent_le_connection_complete_get_connection_handle(packet); 3945711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 39463deb3ec6SMatthias Ringwald if (!sm_conn) break; 39473deb3ec6SMatthias Ringwald 3948d9f3ead5SMatthias Ringwald // Get current peer address 3949d9f3ead5SMatthias Ringwald addr_type = gap_subevent_le_connection_complete_get_peer_address_type(packet); 3950d9f3ead5SMatthias Ringwald if (hci_is_le_identity_address_type(addr_type)){ 3951d9f3ead5SMatthias Ringwald addr_type = BD_ADDR_TYPE_LE_RANDOM; 3952d9f3ead5SMatthias Ringwald gap_subevent_le_connection_complete_get_peer_resolvable_private_address(packet, addr); 3953d9f3ead5SMatthias Ringwald } else { 39549d1eff91SMatthias Ringwald gap_subevent_le_connection_complete_get_peer_address(packet, addr); 3955d9f3ead5SMatthias Ringwald } 3956f664b5e8SMatthias Ringwald sm_connection_init(sm_conn, 3957f664b5e8SMatthias Ringwald con_handle, 39589d1eff91SMatthias Ringwald gap_subevent_le_connection_complete_get_role(packet), 3959d9f3ead5SMatthias Ringwald addr_type, 3960f664b5e8SMatthias Ringwald addr); 3961687a03c8SMatthias Ringwald sm_conn->sm_cid = L2CAP_CID_SECURITY_MANAGER_PROTOCOL; 3962f664b5e8SMatthias Ringwald 3963f664b5e8SMatthias Ringwald // track our addr used for this connection and set state 3964b6f39a74SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 39659d1eff91SMatthias Ringwald if (gap_subevent_le_connection_complete_get_role(packet) != 0){ 3966ba9fc867SMatthias Ringwald // responder - use own address from advertisements 396767bf59ffSMatthias Ringwald #ifdef ENABLE_LE_EXTENDED_ADVERTISING 396867bf59ffSMatthias Ringwald if (hci_le_extended_advertising_supported()){ 396967bf59ffSMatthias Ringwald // cache local resolvable address 397067bf59ffSMatthias Ringwald // note: will be overwritten if random or private address was used in adv set by HCI_SUBEVENT_LE_ADVERTISING_SET_TERMINATED 397167bf59ffSMatthias Ringwald sm_conn->sm_own_addr_type = BD_ADDR_TYPE_LE_RANDOM; 397267bf59ffSMatthias Ringwald gap_subevent_le_connection_complete_get_local_resolvable_private_address(packet,sm_conn->sm_own_address); 397367bf59ffSMatthias Ringwald } else 397467bf59ffSMatthias Ringwald #endif 397567bf59ffSMatthias Ringwald { 3976ba9fc867SMatthias Ringwald gap_le_get_own_advertisements_address(&sm_conn->sm_own_addr_type, sm_conn->sm_own_address); 397767bf59ffSMatthias Ringwald } 3978f664b5e8SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 3979b892db1cSMatthias Ringwald } 3980b892db1cSMatthias Ringwald #endif 3981b892db1cSMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 39829d1eff91SMatthias Ringwald if (gap_subevent_le_connection_complete_get_role(packet) == 0){ 3983ba9fc867SMatthias Ringwald // initiator - use own address from create connection 3984ba9fc867SMatthias Ringwald gap_le_get_own_connection_address(&sm_conn->sm_own_addr_type, sm_conn->sm_own_address); 39853deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 39863deb3ec6SMatthias Ringwald } 3987b892db1cSMatthias Ringwald #endif 39883deb3ec6SMatthias Ringwald break; 39899d1eff91SMatthias Ringwald default: 39909d1eff91SMatthias Ringwald break; 39919d1eff91SMatthias Ringwald } 39929d1eff91SMatthias Ringwald break; 39939d1eff91SMatthias Ringwald case HCI_EVENT_LE_META: 39949d1eff91SMatthias Ringwald switch (hci_event_le_meta_get_subevent_code(packet)) { 399567bf59ffSMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 399667bf59ffSMatthias Ringwald #ifdef ENABLE_LE_EXTENDED_ADVERTISING 399767bf59ffSMatthias Ringwald case HCI_SUBEVENT_LE_ADVERTISING_SET_TERMINATED: 399867bf59ffSMatthias Ringwald if (hci_subevent_le_advertising_set_terminated_get_status(packet) == ERROR_CODE_SUCCESS){ 399967bf59ffSMatthias Ringwald uint8_t advertising_handle = hci_subevent_le_advertising_set_terminated_get_advertising_handle(packet); 400067bf59ffSMatthias Ringwald con_handle = hci_subevent_le_advertising_set_terminated_get_connection_handle(packet); 400167bf59ffSMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 4002ebd6ff34SMatthias Ringwald if (!sm_conn) break; 4003ebd6ff34SMatthias Ringwald 400467bf59ffSMatthias Ringwald gap_le_get_own_advertising_set_address(&sm_conn->sm_own_addr_type, sm_conn->sm_own_address, advertising_handle); 400567bf59ffSMatthias Ringwald log_info("Adv set %u terminated -> use addr type %u, addr %s for con handle 0x%04x", advertising_handle, sm_conn->sm_own_addr_type, 400667bf59ffSMatthias Ringwald bd_addr_to_str(sm_conn->sm_own_address), con_handle); 400767bf59ffSMatthias Ringwald } 400867bf59ffSMatthias Ringwald break; 400967bf59ffSMatthias Ringwald #endif 401067bf59ffSMatthias Ringwald #endif 40113deb3ec6SMatthias Ringwald case HCI_SUBEVENT_LE_LONG_TERM_KEY_REQUEST: 40129d1eff91SMatthias Ringwald con_handle = hci_subevent_le_long_term_key_request_get_connection_handle(packet); 4013711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 40143deb3ec6SMatthias Ringwald if (!sm_conn) break; 40153deb3ec6SMatthias Ringwald 40163deb3ec6SMatthias Ringwald log_info("LTK Request: state %u", sm_conn->sm_engine_state); 40173deb3ec6SMatthias Ringwald if (sm_conn->sm_engine_state == SM_RESPONDER_PH2_W4_LTK_REQUEST){ 40183deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_CALC_STK; 40193deb3ec6SMatthias Ringwald break; 40203deb3ec6SMatthias Ringwald } 4021c6b7cbd9SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_LTK_REQUEST_SC){ 4022778b6aadSMatthias Ringwald // PH2 SEND LTK as we need to exchange keys in PH3 4023778b6aadSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH2_SEND_LTK_REPLY; 4024e53be891SMatthias Ringwald break; 4025e53be891SMatthias Ringwald } 40263deb3ec6SMatthias Ringwald 40273deb3ec6SMatthias Ringwald // store rand and ediv 40289c80e4ccSMatthias Ringwald reverse_64(&packet[5], sm_conn->sm_local_rand); 40299d1eff91SMatthias Ringwald sm_conn->sm_local_ediv = hci_subevent_le_long_term_key_request_get_encryption_diversifier(packet); 4030549ad5d2SMatthias Ringwald 4031549ad5d2SMatthias Ringwald // For Legacy Pairing (<=> EDIV != 0 || RAND != NULL), we need to recalculated our LTK as a 4032549ad5d2SMatthias Ringwald // potentially stored LTK is from the master 40334ea43905SMatthias Ringwald if ((sm_conn->sm_local_ediv != 0u) || !sm_is_null_random(sm_conn->sm_local_rand)){ 40346c39055aSMatthias Ringwald if (sm_reconstruct_ltk_without_le_device_db_entry){ 403506cd539fSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST; 4036549ad5d2SMatthias Ringwald break; 4037549ad5d2SMatthias Ringwald } 40386c39055aSMatthias Ringwald // additionally check if remote is in LE Device DB if requested 40396c39055aSMatthias Ringwald switch(sm_conn->sm_irk_lookup_state){ 40406c39055aSMatthias Ringwald case IRK_LOOKUP_FAILED: 40416c39055aSMatthias Ringwald log_info("LTK Request: device not in device db"); 40426c39055aSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY; 40436c39055aSMatthias Ringwald break; 40446c39055aSMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 40456c39055aSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST; 40466c39055aSMatthias Ringwald break; 40476c39055aSMatthias Ringwald default: 40486c39055aSMatthias Ringwald // wait for irk look doen 40496c39055aSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK; 40506c39055aSMatthias Ringwald break; 40516c39055aSMatthias Ringwald } 40526c39055aSMatthias Ringwald break; 40536c39055aSMatthias Ringwald } 4054549ad5d2SMatthias Ringwald 4055549ad5d2SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 405606cd539fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_RECEIVED_LTK_REQUEST; 4057549ad5d2SMatthias Ringwald #else 4058549ad5d2SMatthias Ringwald log_info("LTK Request: ediv & random are empty, but LE Secure Connections not supported"); 4059549ad5d2SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY; 4060549ad5d2SMatthias Ringwald #endif 40613deb3ec6SMatthias Ringwald break; 4062804d3e67SMatthias Ringwald 40633deb3ec6SMatthias Ringwald default: 40643deb3ec6SMatthias Ringwald break; 40653deb3ec6SMatthias Ringwald } 40663deb3ec6SMatthias Ringwald break; 40673deb3ec6SMatthias Ringwald 40683deb3ec6SMatthias Ringwald case HCI_EVENT_ENCRYPTION_CHANGE: 40698601e696SMatthias Ringwald case HCI_EVENT_ENCRYPTION_CHANGE_V2: 40703b7fd749SMatthias Ringwald con_handle = hci_event_encryption_change_get_connection_handle(packet); 4071711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 40723deb3ec6SMatthias Ringwald if (!sm_conn) break; 40733deb3ec6SMatthias Ringwald 40743b7fd749SMatthias Ringwald sm_conn->sm_connection_encrypted = hci_event_encryption_change_get_encryption_enabled(packet); 40753deb3ec6SMatthias Ringwald log_info("Encryption state change: %u, key size %u", sm_conn->sm_connection_encrypted, 40763deb3ec6SMatthias Ringwald sm_conn->sm_actual_encryption_key_size); 40773deb3ec6SMatthias Ringwald log_info("event handler, state %u", sm_conn->sm_engine_state); 407803a9359aSMatthias Ringwald 4079fbe050beSMatthias Ringwald switch (sm_conn->sm_engine_state){ 4080fbe050beSMatthias Ringwald 40815567aa60SMatthias Ringwald case SM_PH4_W4_CONNECTION_ENCRYPTED: 408203a9359aSMatthias Ringwald // encryption change event concludes re-encryption for bonded devices (even if it fails) 40831d80f1e6SMatthias Ringwald if (sm_conn->sm_connection_encrypted != 0u) { 4084fbe050beSMatthias Ringwald status = ERROR_CODE_SUCCESS; 40851d80f1e6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 40868d4eef95SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 40878d4eef95SMatthias Ringwald } else { 408803a9359aSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 40898d4eef95SMatthias Ringwald } 4090fbe050beSMatthias Ringwald } else { 4091e28291c1SMatthias Ringwald status = hci_event_encryption_change_get_status(packet); 4092cb6d7eb0SMatthias Ringwald // set state to 'RE-ENCRYPTION FAILED' to allow pairing but prevent other interactions 40933b7fd749SMatthias Ringwald // also, gap_reconnect_security_setup_active will return true 4094cb6d7eb0SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_REENCRYPTION_FAILED; 40953b7fd749SMatthias Ringwald } 4096fbe050beSMatthias Ringwald 4097fbe050beSMatthias Ringwald // emit re-encryption complete 409873102768SMatthias Ringwald sm_reencryption_complete(sm_conn, status); 4099fbe050beSMatthias Ringwald 4100c245ca32SMatthias Ringwald // notify client, if pairing was requested before 4101c245ca32SMatthias Ringwald if (sm_conn->sm_pairing_requested){ 41025f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = false; 41030ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, status, 0); 410403a9359aSMatthias Ringwald } 410503a9359aSMatthias Ringwald 41063deb3ec6SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 41073deb3ec6SMatthias Ringwald break; 4108fbe050beSMatthias Ringwald 41093deb3ec6SMatthias Ringwald case SM_PH2_W4_CONNECTION_ENCRYPTED: 4110fbe050beSMatthias Ringwald if (!sm_conn->sm_connection_encrypted) break; 411157ff4745SMatthias Ringwald // handler for HCI_EVENT_ENCRYPTION_KEY_REFRESH_COMPLETE 411257ff4745SMatthias Ringwald // contains the same code for this state 4113dd583d9fSMatthias Ringwald sm_conn->sm_connection_sc = setup->sm_use_secure_connections; 411442134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 41153deb3ec6SMatthias Ringwald // slave 411657ff4745SMatthias Ringwald if (sm_conn->sm_connection_sc){ 4117bbf8db22SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 4118bbf8db22SMatthias Ringwald } else { 4119f3582630SMatthias 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); 4120bbf8db22SMatthias Ringwald } 41213deb3ec6SMatthias Ringwald } else { 41223deb3ec6SMatthias Ringwald // master 412361d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 41243deb3ec6SMatthias Ringwald // skip receiving keys as there are none 41253deb3ec6SMatthias Ringwald sm_key_distribution_handle_all_received(sm_conn); 4126f3582630SMatthias 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); 41273deb3ec6SMatthias Ringwald } else { 41283deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS; 41293deb3ec6SMatthias Ringwald } 41303deb3ec6SMatthias Ringwald } 41313deb3ec6SMatthias Ringwald break; 4132c18be159SMatthias Ringwald 4133c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 4134c18be159SMatthias Ringwald case SM_BR_EDR_W4_ENCRYPTION_COMPLETE: 4135599e89daSMatthias Ringwald sm_event_handle_classic_encryption_event(sm_conn, con_handle); 4136c18be159SMatthias Ringwald break; 4137c18be159SMatthias Ringwald #endif 41383deb3ec6SMatthias Ringwald default: 41393deb3ec6SMatthias Ringwald break; 41403deb3ec6SMatthias Ringwald } 41413deb3ec6SMatthias Ringwald break; 41423deb3ec6SMatthias Ringwald 41433deb3ec6SMatthias Ringwald case HCI_EVENT_ENCRYPTION_KEY_REFRESH_COMPLETE: 4144711e6c80SMatthias Ringwald con_handle = little_endian_read_16(packet, 3); 4145711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 41463deb3ec6SMatthias Ringwald if (!sm_conn) break; 41473deb3ec6SMatthias Ringwald 41483deb3ec6SMatthias Ringwald log_info("Encryption key refresh complete, key size %u", sm_conn->sm_actual_encryption_key_size); 41493deb3ec6SMatthias Ringwald log_info("event handler, state %u", sm_conn->sm_engine_state); 41503deb3ec6SMatthias Ringwald // continue if part of initial pairing 41513deb3ec6SMatthias Ringwald switch (sm_conn->sm_engine_state){ 41525567aa60SMatthias Ringwald case SM_PH4_W4_CONNECTION_ENCRYPTED: 41531d80f1e6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 41545567aa60SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 41555567aa60SMatthias Ringwald } else { 41563deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 41575567aa60SMatthias Ringwald } 41583deb3ec6SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 41593deb3ec6SMatthias Ringwald break; 41603deb3ec6SMatthias Ringwald case SM_PH2_W4_CONNECTION_ENCRYPTED: 416157ff4745SMatthias Ringwald // handler for HCI_EVENT_ENCRYPTION_CHANGE 416257ff4745SMatthias Ringwald // contains the same code for this state 416357ff4745SMatthias Ringwald sm_conn->sm_connection_sc = setup->sm_use_secure_connections; 416442134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 41653deb3ec6SMatthias Ringwald // slave 416657ff4745SMatthias Ringwald if (sm_conn->sm_connection_sc){ 416757ff4745SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 416857ff4745SMatthias Ringwald } else { 4169f3582630SMatthias 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); 417057ff4745SMatthias Ringwald } 41713deb3ec6SMatthias Ringwald } else { 41723deb3ec6SMatthias Ringwald // master 417357ff4745SMatthias Ringwald if (sm_key_distribution_all_received()){ 417457ff4745SMatthias Ringwald // skip receiving keys as there are none 417557ff4745SMatthias Ringwald sm_key_distribution_handle_all_received(sm_conn); 417657ff4745SMatthias 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); 417757ff4745SMatthias Ringwald } else { 41783deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS; 41793deb3ec6SMatthias Ringwald } 418057ff4745SMatthias Ringwald } 41813deb3ec6SMatthias Ringwald break; 418294219034SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 418394219034SMatthias Ringwald case SM_BR_EDR_W4_ENCRYPTION_COMPLETE: 418494219034SMatthias Ringwald sm_event_handle_classic_encryption_event(sm_conn, con_handle); 418594219034SMatthias Ringwald break; 418694219034SMatthias Ringwald #endif 41873deb3ec6SMatthias Ringwald default: 41883deb3ec6SMatthias Ringwald break; 41893deb3ec6SMatthias Ringwald } 41903deb3ec6SMatthias Ringwald break; 41913deb3ec6SMatthias Ringwald 41923deb3ec6SMatthias Ringwald 41933deb3ec6SMatthias Ringwald case HCI_EVENT_DISCONNECTION_COMPLETE: 4194711e6c80SMatthias Ringwald con_handle = little_endian_read_16(packet, 3); 4195711e6c80SMatthias Ringwald sm_done_for_handle(con_handle); 4196711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 41973deb3ec6SMatthias Ringwald if (!sm_conn) break; 41983deb3ec6SMatthias Ringwald 419903f736b1SMatthias Ringwald // pairing failed, if it was ongoing 42007f3f442dSMatthias Ringwald switch (sm_conn->sm_engine_state){ 42017f3f442dSMatthias Ringwald case SM_GENERAL_IDLE: 42027f3f442dSMatthias Ringwald case SM_INITIATOR_CONNECTED: 42037f3f442dSMatthias Ringwald case SM_RESPONDER_IDLE: 42047f3f442dSMatthias Ringwald break; 42057f3f442dSMatthias Ringwald default: 420668a18fb9SMatthias Ringwald sm_reencryption_complete(sm_conn, ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION); 42070ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION, 0); 42087f3f442dSMatthias Ringwald break; 420903f736b1SMatthias Ringwald } 4210accbde80SMatthias Ringwald 42113deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_IDLE; 42123deb3ec6SMatthias Ringwald sm_conn->sm_handle = 0; 42133deb3ec6SMatthias Ringwald break; 42143deb3ec6SMatthias Ringwald 42153deb3ec6SMatthias Ringwald case HCI_EVENT_COMMAND_COMPLETE: 4216f7811256SMatthias Ringwald if (hci_event_command_complete_get_command_opcode(packet) == HCI_OPCODE_HCI_READ_BD_ADDR) { 42179091c5f5SMatthias Ringwald // set local addr for le device db 421833373e40SMatthias Ringwald reverse_bd_addr(&packet[OFFSET_OF_DATA_IN_COMMAND_COMPLETE + 1], addr); 42190c130b19SMatthias Ringwald le_device_db_set_local_bd_addr(addr); 422033373e40SMatthias Ringwald } 422165b44ffdSMatthias Ringwald break; 4222a036ae12SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 4223a036ae12SMatthias Ringwald case L2CAP_EVENT_INFORMATION_RESPONSE: 4224a036ae12SMatthias Ringwald con_handle = l2cap_event_information_response_get_con_handle(packet); 4225a036ae12SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 4226a036ae12SMatthias Ringwald if (!sm_conn) break; 4227a036ae12SMatthias Ringwald if (sm_conn->sm_engine_state == SM_BR_EDR_INITIATOR_W4_FIXED_CHANNEL_MASK){ 4228a036ae12SMatthias Ringwald // check if remote supports SMP over BR/EDR 4229a036ae12SMatthias Ringwald const hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); 4230a036ae12SMatthias Ringwald if ((hci_connection->l2cap_state.fixed_channels_supported & (1 << L2CAP_CID_BR_EDR_SECURITY_MANAGER)) != 0){ 4231a036ae12SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST; 4232a036ae12SMatthias Ringwald } else { 4233a036ae12SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 4234f82b8f4bSMatthias Ringwald hci_dedicated_bonding_defer_disconnect(con_handle, false); 4235a036ae12SMatthias Ringwald } 4236a036ae12SMatthias Ringwald } 4237a036ae12SMatthias Ringwald break; 4238a036ae12SMatthias Ringwald #endif 423965b44ffdSMatthias Ringwald default: 424065b44ffdSMatthias Ringwald break; 42413deb3ec6SMatthias Ringwald } 424265b44ffdSMatthias Ringwald break; 424365b44ffdSMatthias Ringwald default: 424465b44ffdSMatthias Ringwald break; 42453deb3ec6SMatthias Ringwald } 42463deb3ec6SMatthias Ringwald 42473deb3ec6SMatthias Ringwald sm_run(); 42483deb3ec6SMatthias Ringwald } 42493deb3ec6SMatthias Ringwald 42503deb3ec6SMatthias Ringwald static inline int sm_calc_actual_encryption_key_size(int other){ 42513deb3ec6SMatthias Ringwald if (other < sm_min_encryption_key_size) return 0; 42523deb3ec6SMatthias Ringwald if (other < sm_max_encryption_key_size) return other; 42533deb3ec6SMatthias Ringwald return sm_max_encryption_key_size; 42543deb3ec6SMatthias Ringwald } 42553deb3ec6SMatthias Ringwald 4256945888f5SMatthias Ringwald 425731c09488SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 42581d80f1e6SMatthias Ringwald static bool sm_just_works_or_numeric_comparison(stk_generation_method_t method){ 4259945888f5SMatthias Ringwald switch (method){ 4260945888f5SMatthias Ringwald case JUST_WORKS: 426147fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 42621d80f1e6SMatthias Ringwald return true; 4263945888f5SMatthias Ringwald default: 42641d80f1e6SMatthias Ringwald return false; 4265945888f5SMatthias Ringwald } 4266945888f5SMatthias Ringwald } 426707036a04SMatthias Ringwald // responder 4268945888f5SMatthias Ringwald 42691d80f1e6SMatthias Ringwald static bool sm_passkey_used(stk_generation_method_t method){ 4270688a08f9SMatthias Ringwald switch (method){ 4271688a08f9SMatthias Ringwald case PK_RESP_INPUT: 42721d80f1e6SMatthias Ringwald return true; 4273688a08f9SMatthias Ringwald default: 4274688a08f9SMatthias Ringwald return 0; 4275688a08f9SMatthias Ringwald } 4276688a08f9SMatthias Ringwald } 427740c5d850SMatthias Ringwald 42786777d8fdSMatthias Ringwald static bool sm_passkey_entry(stk_generation_method_t method){ 427940c5d850SMatthias Ringwald switch (method){ 428040c5d850SMatthias Ringwald case PK_RESP_INPUT: 428140c5d850SMatthias Ringwald case PK_INIT_INPUT: 428247fb4255SMatthias Ringwald case PK_BOTH_INPUT: 42836777d8fdSMatthias Ringwald return true; 428440c5d850SMatthias Ringwald default: 42856777d8fdSMatthias Ringwald return false; 428640c5d850SMatthias Ringwald } 428740c5d850SMatthias Ringwald } 428840c5d850SMatthias Ringwald 428931c09488SMatthias Ringwald #endif 4290688a08f9SMatthias Ringwald 42913deb3ec6SMatthias Ringwald /** 42923deb3ec6SMatthias Ringwald * @return ok 42933deb3ec6SMatthias Ringwald */ 42943deb3ec6SMatthias Ringwald static int sm_validate_stk_generation_method(void){ 42953deb3ec6SMatthias Ringwald // check if STK generation method is acceptable by client 42963deb3ec6SMatthias Ringwald switch (setup->sm_stk_generation_method){ 42973deb3ec6SMatthias Ringwald case JUST_WORKS: 42984ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_JUST_WORKS) != 0u; 42993deb3ec6SMatthias Ringwald case PK_RESP_INPUT: 43003deb3ec6SMatthias Ringwald case PK_INIT_INPUT: 430147fb4255SMatthias Ringwald case PK_BOTH_INPUT: 43024ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_PASSKEY) != 0u; 43033deb3ec6SMatthias Ringwald case OOB: 43044ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_OOB) != 0u; 430547fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 43064ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_NUMERIC_COMPARISON) != 0u; 43073deb3ec6SMatthias Ringwald default: 43083deb3ec6SMatthias Ringwald return 0; 43093deb3ec6SMatthias Ringwald } 43103deb3ec6SMatthias Ringwald } 43113deb3ec6SMatthias Ringwald 431236f0defaSMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 431336f0defaSMatthias Ringwald static void sm_initiator_connected_handle_security_request(sm_connection_t * sm_conn, const uint8_t *packet){ 431436f0defaSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 431536f0defaSMatthias Ringwald if (sm_sc_only_mode){ 431636f0defaSMatthias Ringwald uint8_t auth_req = packet[1]; 431736f0defaSMatthias Ringwald if ((auth_req & SM_AUTHREQ_SECURE_CONNECTION) == 0){ 431836f0defaSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_AUTHENTHICATION_REQUIREMENTS); 431936f0defaSMatthias Ringwald return; 432036f0defaSMatthias Ringwald } 432136f0defaSMatthias Ringwald } 432236f0defaSMatthias Ringwald #else 432336f0defaSMatthias Ringwald UNUSED(packet); 432436f0defaSMatthias Ringwald #endif 432536f0defaSMatthias Ringwald 432636f0defaSMatthias Ringwald int have_ltk; 432736f0defaSMatthias Ringwald uint8_t ltk[16]; 432836f0defaSMatthias Ringwald 432936f0defaSMatthias Ringwald // IRK complete? 433036f0defaSMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 433136f0defaSMatthias Ringwald case IRK_LOOKUP_FAILED: 433236f0defaSMatthias Ringwald // start pairing 433336f0defaSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 433436f0defaSMatthias Ringwald break; 433536f0defaSMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 433636f0defaSMatthias Ringwald le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); 433736f0defaSMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 433836f0defaSMatthias Ringwald log_info("central: security request - have_ltk %u, encryption %u", have_ltk, sm_conn->sm_connection_encrypted); 433936f0defaSMatthias Ringwald if (have_ltk && (sm_conn->sm_connection_encrypted == 0)){ 434036f0defaSMatthias Ringwald // start re-encrypt if we have LTK and the connection is not already encrypted 434136f0defaSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH4_HAS_LTK; 434236f0defaSMatthias Ringwald } else { 434336f0defaSMatthias Ringwald // start pairing 434436f0defaSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 434536f0defaSMatthias Ringwald } 434636f0defaSMatthias Ringwald break; 434736f0defaSMatthias Ringwald default: 434836f0defaSMatthias Ringwald // otherwise, store security request 43490dcaa15fSMatthias Ringwald sm_conn->sm_security_request_received = true; 435036f0defaSMatthias Ringwald break; 435136f0defaSMatthias Ringwald } 435236f0defaSMatthias Ringwald } 435336f0defaSMatthias Ringwald #endif 435436f0defaSMatthias Ringwald 4355f9bda154SMatthias Ringwald static uint8_t sm_pdu_validate_and_get_opcode(uint8_t packet_type, const uint8_t *packet, uint16_t size){ 43568334d3d8SMatthias Ringwald 43574c1d1092SMatthias Ringwald // size of complete sm_pdu used to validate input 43584c1d1092SMatthias Ringwald static const uint8_t sm_pdu_size[] = { 43594c1d1092SMatthias Ringwald 0, // 0x00 invalid opcode 43604c1d1092SMatthias Ringwald 7, // 0x01 pairing request 43614c1d1092SMatthias Ringwald 7, // 0x02 pairing response 43624c1d1092SMatthias Ringwald 17, // 0x03 pairing confirm 43634c1d1092SMatthias Ringwald 17, // 0x04 pairing random 43644c1d1092SMatthias Ringwald 2, // 0x05 pairing failed 43654c1d1092SMatthias Ringwald 17, // 0x06 encryption information 43667a2e6387SMatthias Ringwald 11, // 0x07 master identification 43674c1d1092SMatthias Ringwald 17, // 0x08 identification information 43684c1d1092SMatthias Ringwald 8, // 0x09 identify address information 43694c1d1092SMatthias Ringwald 17, // 0x0a signing information 43704c1d1092SMatthias Ringwald 2, // 0x0b security request 43714c1d1092SMatthias Ringwald 65, // 0x0c pairing public key 43724c1d1092SMatthias Ringwald 17, // 0x0d pairing dhk check 43734c1d1092SMatthias Ringwald 2, // 0x0e keypress notification 43744c1d1092SMatthias Ringwald }; 43753deb3ec6SMatthias Ringwald 4376f9bda154SMatthias Ringwald if (packet_type != SM_DATA_PACKET) return 0; 4377f9bda154SMatthias Ringwald if (size == 0u) return 0; 43784c1d1092SMatthias Ringwald 43794c1d1092SMatthias Ringwald uint8_t sm_pdu_code = packet[0]; 43804c1d1092SMatthias Ringwald 43814c1d1092SMatthias Ringwald // validate pdu size 4382f9bda154SMatthias Ringwald if (sm_pdu_code >= sizeof(sm_pdu_size)) return 0; 4383f9bda154SMatthias Ringwald if (sm_pdu_size[sm_pdu_code] != size) return 0; 4384f9bda154SMatthias Ringwald 4385f9bda154SMatthias Ringwald return sm_pdu_code; 4386f9bda154SMatthias Ringwald } 4387f9bda154SMatthias Ringwald 438873970ae5SMatthias Ringwald static void sm_pdu_handler(sm_connection_t *sm_conn, uint8_t sm_pdu_code, const uint8_t *packet) { 43896e46ecceSMatthias Ringwald log_debug("sm_pdu_handler: state %u, pdu 0x%02x", sm_conn->sm_engine_state, sm_pdu_code); 43906e46ecceSMatthias Ringwald 43916e46ecceSMatthias Ringwald int err; 43926e46ecceSMatthias Ringwald uint8_t max_encryption_key_size; 43936e46ecceSMatthias Ringwald UNUSED(err); 43946e46ecceSMatthias Ringwald 43953deb3ec6SMatthias Ringwald switch (sm_conn->sm_engine_state){ 43963deb3ec6SMatthias Ringwald 4397c8d0ff33SMatthias Ringwald // a sm timeout requires a new physical connection 43983deb3ec6SMatthias Ringwald case SM_GENERAL_TIMEOUT: 43993deb3ec6SMatthias Ringwald return; 44003deb3ec6SMatthias Ringwald 440142134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 440242134bc6SMatthias Ringwald 44033deb3ec6SMatthias Ringwald // Initiator 44043deb3ec6SMatthias Ringwald case SM_INITIATOR_CONNECTED: 44054c1d1092SMatthias Ringwald if ((sm_pdu_code != SM_CODE_SECURITY_REQUEST) || (sm_conn->sm_role)){ 44063deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 44073deb3ec6SMatthias Ringwald break; 44083deb3ec6SMatthias Ringwald } 440936f0defaSMatthias Ringwald sm_initiator_connected_handle_security_request(sm_conn, packet); 4410dc8ca372SMatthias Ringwald break; 44113deb3ec6SMatthias Ringwald 44123deb3ec6SMatthias Ringwald case SM_INITIATOR_PH1_W4_PAIRING_RESPONSE: 4413aacfafc3SMatthias Ringwald // Core 5, Vol 3, Part H, 2.4.6: 4414aacfafc3SMatthias Ringwald // "The master shall ignore the slave’s Security Request if the master has sent a Pairing Request 4415aacfafc3SMatthias Ringwald // without receiving a Pairing Response from the slave or if the master has initiated encryption mode setup." 4416aacfafc3SMatthias Ringwald if (sm_pdu_code == SM_CODE_SECURITY_REQUEST){ 4417aacfafc3SMatthias Ringwald log_info("Ignoring Security Request"); 4418aacfafc3SMatthias Ringwald break; 4419aacfafc3SMatthias Ringwald } 4420aacfafc3SMatthias Ringwald 4421aacfafc3SMatthias Ringwald // all other pdus are incorrect 44224c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RESPONSE){ 44233deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 44243deb3ec6SMatthias Ringwald break; 44253deb3ec6SMatthias Ringwald } 44260af429c6SMatthias Ringwald 44273deb3ec6SMatthias Ringwald // store pairing request 44286535961aSMatthias Ringwald (void)memcpy(&setup->sm_s_pres, packet, 44296535961aSMatthias Ringwald sizeof(sm_pairing_packet_t)); 4430afbd946dSMatthias Ringwald 4431afbd946dSMatthias Ringwald // validate encryption key size 4432afbd946dSMatthias Ringwald max_encryption_key_size = sm_pairing_packet_get_max_encryption_key_size(setup->sm_s_pres); 4433afbd946dSMatthias Ringwald if ((max_encryption_key_size < 7) || (max_encryption_key_size > 16)){ 4434afbd946dSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_INVALID_PARAMETERS); 4435afbd946dSMatthias Ringwald break; 4436afbd946dSMatthias Ringwald } 4437afbd946dSMatthias Ringwald 44383deb3ec6SMatthias Ringwald err = sm_stk_generation_init(sm_conn); 44390af429c6SMatthias Ringwald 44400af429c6SMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 44410af429c6SMatthias Ringwald if (0 < test_pairing_failure && test_pairing_failure < SM_REASON_DHKEY_CHECK_FAILED){ 44420af429c6SMatthias Ringwald log_info("testing_support: abort with pairing failure %u", test_pairing_failure); 44430af429c6SMatthias Ringwald err = test_pairing_failure; 44440af429c6SMatthias Ringwald } 44450af429c6SMatthias Ringwald #endif 44460af429c6SMatthias Ringwald 44479305033eSMatthias Ringwald if (err != 0){ 4448f4935286SMatthias Ringwald sm_pairing_error(sm_conn, err); 44493deb3ec6SMatthias Ringwald break; 44503deb3ec6SMatthias Ringwald } 4451b41539d5SMatthias Ringwald 4452b41539d5SMatthias Ringwald // generate random number first, if we need to show passkey 4453b41539d5SMatthias Ringwald if (setup->sm_stk_generation_method == PK_RESP_INPUT){ 4454f3582630SMatthias 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); 4455b41539d5SMatthias Ringwald break; 4456b41539d5SMatthias Ringwald } 4457b41539d5SMatthias Ringwald 4458136d331aSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4459136d331aSMatthias Ringwald if (setup->sm_use_secure_connections){ 44608cba5ca3SMatthias Ringwald // SC Numeric Comparison will trigger user response after public keys & nonces have been exchanged 44618cba5ca3SMatthias Ringwald if (setup->sm_stk_generation_method == JUST_WORKS){ 4462136d331aSMatthias Ringwald sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 4463136d331aSMatthias Ringwald sm_trigger_user_response(sm_conn); 4464136d331aSMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ 4465c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 4466136d331aSMatthias Ringwald } 44678cba5ca3SMatthias Ringwald } else { 4468c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 44698cba5ca3SMatthias Ringwald } 4470136d331aSMatthias Ringwald break; 4471136d331aSMatthias Ringwald } 4472136d331aSMatthias Ringwald #endif 44733deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 44743deb3ec6SMatthias Ringwald sm_trigger_user_response(sm_conn); 44753deb3ec6SMatthias Ringwald // response_idle == nothing <--> sm_trigger_user_response() did not require response 44763deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ 4477f3582630SMatthias 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); 44783deb3ec6SMatthias Ringwald } 44793deb3ec6SMatthias Ringwald break; 44803deb3ec6SMatthias Ringwald 44813deb3ec6SMatthias Ringwald case SM_INITIATOR_PH2_W4_PAIRING_CONFIRM: 44824c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_CONFIRM){ 44833deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 44843deb3ec6SMatthias Ringwald break; 44853deb3ec6SMatthias Ringwald } 44863deb3ec6SMatthias Ringwald 44873deb3ec6SMatthias Ringwald // store s_confirm 44889c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_confirm); 4489192365feSMatthias Ringwald 4490aa9b34e5SMatthias Ringwald // abort if s_confirm matches m_confirm 4491aa9b34e5SMatthias Ringwald if (memcmp(setup->sm_local_confirm, setup->sm_peer_confirm, 16) == 0){ 4492aa9b34e5SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4493aa9b34e5SMatthias Ringwald break; 4494aa9b34e5SMatthias Ringwald } 4495aa9b34e5SMatthias Ringwald 4496192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 4497192365feSMatthias Ringwald if (test_pairing_failure == SM_REASON_CONFIRM_VALUE_FAILED){ 4498192365feSMatthias Ringwald log_info("testing_support: reset confirm value"); 4499192365feSMatthias Ringwald memset(setup->sm_peer_confirm, 0, 16); 4500192365feSMatthias Ringwald } 4501192365feSMatthias Ringwald #endif 45023deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_SEND_PAIRING_RANDOM; 45033deb3ec6SMatthias Ringwald break; 45043deb3ec6SMatthias Ringwald 45053deb3ec6SMatthias Ringwald case SM_INITIATOR_PH2_W4_PAIRING_RANDOM: 45064c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RANDOM){ 45073deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 45083deb3ec6SMatthias Ringwald break;; 45093deb3ec6SMatthias Ringwald } 45103deb3ec6SMatthias Ringwald 45113deb3ec6SMatthias Ringwald // received random value 45129c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_random); 45133deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_C1_GET_ENC_C; 45143deb3ec6SMatthias Ringwald break; 4515dc542de1SMatthias Ringwald 4516e2a5eb63SMatthias Ringwald case SM_INITIATOR_PH4_HAS_LTK: 4517dc542de1SMatthias Ringwald case SM_PH4_W4_CONNECTION_ENCRYPTED: 4518dc542de1SMatthias Ringwald // ignore Security Request, see SM_INITIATOR_PH1_W4_PAIRING_RESPONSE above 4519dc542de1SMatthias Ringwald if (sm_pdu_code != SM_CODE_SECURITY_REQUEST){ 4520dc542de1SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4521dc542de1SMatthias Ringwald } 4522dc542de1SMatthias Ringwald break; 452342134bc6SMatthias Ringwald #endif 45243deb3ec6SMatthias Ringwald 452542134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 45263deb3ec6SMatthias Ringwald // Responder 45273deb3ec6SMatthias Ringwald case SM_RESPONDER_IDLE: 45283deb3ec6SMatthias Ringwald case SM_RESPONDER_SEND_SECURITY_REQUEST: 45293deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_W4_PAIRING_REQUEST: 45304c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_REQUEST){ 45313deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 45323deb3ec6SMatthias Ringwald break;; 45333deb3ec6SMatthias Ringwald } 45343deb3ec6SMatthias Ringwald 45353deb3ec6SMatthias Ringwald // store pairing request 4536212d735eSMatthias Ringwald (void)memcpy(&sm_conn->sm_m_preq, packet, sizeof(sm_pairing_packet_t)); 4537212d735eSMatthias Ringwald 4538afbd946dSMatthias Ringwald // validation encryption key size 4539afbd946dSMatthias Ringwald max_encryption_key_size = sm_pairing_packet_get_max_encryption_key_size(sm_conn->sm_m_preq); 4540afbd946dSMatthias Ringwald if ((max_encryption_key_size < 7) || (max_encryption_key_size > 16)){ 4541afbd946dSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_INVALID_PARAMETERS); 4542afbd946dSMatthias Ringwald break; 4543afbd946dSMatthias Ringwald } 4544afbd946dSMatthias Ringwald 4545212d735eSMatthias Ringwald // check if IRK completed 4546212d735eSMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 4547212d735eSMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 4548212d735eSMatthias Ringwald case IRK_LOOKUP_FAILED: 45493deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED; 45503deb3ec6SMatthias Ringwald break; 4551212d735eSMatthias Ringwald default: 4552212d735eSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED_W4_IRK; 4553212d735eSMatthias Ringwald break; 4554212d735eSMatthias Ringwald } 4555212d735eSMatthias Ringwald break; 455642134bc6SMatthias Ringwald #endif 45573deb3ec6SMatthias Ringwald 455827c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4559c6b7cbd9SMatthias Ringwald case SM_SC_W4_PUBLIC_KEY_COMMAND: 45604c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_PUBLIC_KEY){ 456127c32905SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 456227c32905SMatthias Ringwald break; 456327c32905SMatthias Ringwald } 4564bccf5e67SMatthias Ringwald 4565e53be891SMatthias Ringwald // store public key for DH Key calculation 4566fc5bff5fSMatthias Ringwald reverse_256(&packet[01], &setup->sm_peer_q[0]); 4567fc5bff5fSMatthias Ringwald reverse_256(&packet[33], &setup->sm_peer_q[32]); 4568bccf5e67SMatthias Ringwald 456902658749SMatthias Ringwald // CVE-2020-26558: abort pairing if remote uses the same public key 457002658749SMatthias Ringwald if (memcmp(&setup->sm_peer_q, ec_q, 64) == 0){ 457102658749SMatthias Ringwald log_info("Remote PK matches ours"); 457202658749SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 457302658749SMatthias Ringwald break; 457402658749SMatthias Ringwald } 457502658749SMatthias Ringwald 4576d1a1f6a4SMatthias Ringwald // validate public key 4577d1a1f6a4SMatthias Ringwald err = btstack_crypto_ecc_p256_validate_public_key(setup->sm_peer_q); 45789305033eSMatthias Ringwald if (err != 0){ 457902658749SMatthias Ringwald log_info("sm: peer public key invalid %x", err); 4580349d0adbSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 4581bccf5e67SMatthias Ringwald break; 4582bccf5e67SMatthias Ringwald } 4583891bb64aSMatthias Ringwald 4584d1a1f6a4SMatthias Ringwald // start calculating dhkey 4585f3582630SMatthias 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); 45863cf37b8cSMatthias Ringwald 458765a9a04eSMatthias Ringwald 458865a9a04eSMatthias Ringwald log_info("public key received, generation method %u", setup->sm_stk_generation_method); 458942134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 4590136d331aSMatthias Ringwald // responder 4591c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 4592136d331aSMatthias Ringwald } else { 4593136d331aSMatthias Ringwald // initiator 4594a1e31e9cSMatthias Ringwald // stk generation method 4595a1e31e9cSMatthias Ringwald // passkey entry: notify app to show passkey or to request passkey 4596a1e31e9cSMatthias Ringwald switch (setup->sm_stk_generation_method){ 4597a1e31e9cSMatthias Ringwald case JUST_WORKS: 459847fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 4599c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_CONFIRMATION; 4600a1e31e9cSMatthias Ringwald break; 4601a1e31e9cSMatthias Ringwald case PK_RESP_INPUT: 460207036a04SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 460307036a04SMatthias Ringwald break; 460407036a04SMatthias Ringwald case PK_INIT_INPUT: 460547fb4255SMatthias Ringwald case PK_BOTH_INPUT: 460607036a04SMatthias Ringwald if (setup->sm_user_response != SM_USER_RESPONSE_PASSKEY){ 460707036a04SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_USER_RESPONSE; 460807036a04SMatthias Ringwald break; 460907036a04SMatthias Ringwald } 4610b35a3de2SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 4611a1e31e9cSMatthias Ringwald break; 4612a1e31e9cSMatthias Ringwald case OOB: 4613d1a1f6a4SMatthias Ringwald // generate Nx 46144acf7b7bSMatthias Ringwald log_info("Generate Na"); 46156ca80073SMatthias 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); 4616a1e31e9cSMatthias Ringwald break; 46177bbeb3adSMilanka Ringwald default: 46187bbeb3adSMilanka Ringwald btstack_assert(false); 46197bbeb3adSMilanka Ringwald break; 4620a1e31e9cSMatthias Ringwald } 4621136d331aSMatthias Ringwald } 462227c32905SMatthias Ringwald break; 4623e53be891SMatthias Ringwald 4624c6b7cbd9SMatthias Ringwald case SM_SC_W4_CONFIRMATION: 46254c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_CONFIRM){ 462645a61d50SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 462745a61d50SMatthias Ringwald break; 462845a61d50SMatthias Ringwald } 462945a61d50SMatthias Ringwald // received confirm value 463045a61d50SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_confirm); 463145a61d50SMatthias Ringwald 4632192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 4633192365feSMatthias Ringwald if (test_pairing_failure == SM_REASON_CONFIRM_VALUE_FAILED){ 4634192365feSMatthias Ringwald log_info("testing_support: reset confirm value"); 4635192365feSMatthias Ringwald memset(setup->sm_peer_confirm, 0, 16); 4636192365feSMatthias Ringwald } 4637192365feSMatthias Ringwald #endif 463842134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 463945a61d50SMatthias Ringwald // responder 464007036a04SMatthias Ringwald if (sm_passkey_used(setup->sm_stk_generation_method)){ 464107036a04SMatthias Ringwald if (setup->sm_user_response != SM_USER_RESPONSE_PASSKEY){ 464207036a04SMatthias Ringwald // still waiting for passkey 464307036a04SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_USER_RESPONSE; 464407036a04SMatthias Ringwald break; 464507036a04SMatthias Ringwald } 464607036a04SMatthias Ringwald } 4647b35a3de2SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 464845a61d50SMatthias Ringwald } else { 464945a61d50SMatthias Ringwald // initiator 4650945888f5SMatthias Ringwald if (sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method)){ 46516ca80073SMatthias 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); 4652f1c1783eSMatthias Ringwald } else { 4653c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM; 465445a61d50SMatthias Ringwald } 4655f1c1783eSMatthias Ringwald } 465645a61d50SMatthias Ringwald break; 465745a61d50SMatthias Ringwald 4658c6b7cbd9SMatthias Ringwald case SM_SC_W4_PAIRING_RANDOM: 46594c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RANDOM){ 4660e53be891SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4661136d331aSMatthias Ringwald break; 4662e53be891SMatthias Ringwald } 4663e53be891SMatthias Ringwald 4664e53be891SMatthias Ringwald // received random value 4665e53be891SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_nonce); 4666e53be891SMatthias Ringwald 46675a293e6eSMatthias Ringwald // validate confirm value if Cb = f4(Pkb, Pka, Nb, z) 4668ae451ec5SMatthias Ringwald // only check for JUST WORK/NC in initiator role OR passkey entry 4669d686b2d0SMatthias Ringwald log_info("SM_SC_W4_PAIRING_RANDOM, responder: %u, just works: %u, passkey used %u, passkey entry %u", 4670d686b2d0SMatthias Ringwald IS_RESPONDER(sm_conn->sm_role), sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method), 4671d686b2d0SMatthias Ringwald sm_passkey_used(setup->sm_stk_generation_method), sm_passkey_entry(setup->sm_stk_generation_method)); 467265a9a04eSMatthias Ringwald if ( (!IS_RESPONDER(sm_conn->sm_role) && sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method)) 4673d686b2d0SMatthias Ringwald || (sm_passkey_entry(setup->sm_stk_generation_method)) ) { 4674688a08f9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION; 4675ae451ec5SMatthias Ringwald break; 46765a293e6eSMatthias Ringwald } 46776f52a196SMatthias Ringwald 46784acf7b7bSMatthias Ringwald // OOB 46794acf7b7bSMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 46804acf7b7bSMatthias Ringwald 46814acf7b7bSMatthias Ringwald // setup local random, set to zero if remote did not receive our data 46824acf7b7bSMatthias Ringwald log_info("Received nonce, setup local random ra/rb for dhkey check"); 46834acf7b7bSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 46844ea43905SMatthias Ringwald if (sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq) == 0u){ 46854acf7b7bSMatthias Ringwald log_info("Reset rb as A does not have OOB data"); 46864acf7b7bSMatthias Ringwald memset(setup->sm_rb, 0, 16); 46874acf7b7bSMatthias Ringwald } else { 46886535961aSMatthias Ringwald (void)memcpy(setup->sm_rb, sm_sc_oob_random, 16); 46894acf7b7bSMatthias Ringwald log_info("Use stored rb"); 46904acf7b7bSMatthias Ringwald log_info_hexdump(setup->sm_rb, 16); 46914acf7b7bSMatthias Ringwald } 46924acf7b7bSMatthias Ringwald } else { 46934ea43905SMatthias Ringwald if (sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres) == 0u){ 46944acf7b7bSMatthias Ringwald log_info("Reset ra as B does not have OOB data"); 46954acf7b7bSMatthias Ringwald memset(setup->sm_ra, 0, 16); 46964acf7b7bSMatthias Ringwald } else { 46976535961aSMatthias Ringwald (void)memcpy(setup->sm_ra, sm_sc_oob_random, 16); 46984acf7b7bSMatthias Ringwald log_info("Use stored ra"); 46994acf7b7bSMatthias Ringwald log_info_hexdump(setup->sm_ra, 16); 47004acf7b7bSMatthias Ringwald } 47014acf7b7bSMatthias Ringwald } 47024acf7b7bSMatthias Ringwald 4703a680ba6bSMatthias Ringwald // validate confirm value if Cb = f4(PKb, Pkb, rb, 0) for OOB if data received 47044acf7b7bSMatthias Ringwald if (setup->sm_have_oob_data){ 4705a680ba6bSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION; 4706a680ba6bSMatthias Ringwald break; 4707a680ba6bSMatthias Ringwald } 47084acf7b7bSMatthias Ringwald } 4709a680ba6bSMatthias Ringwald 4710a680ba6bSMatthias Ringwald // TODO: we only get here for Responder role with JW/NC 4711688a08f9SMatthias Ringwald sm_sc_state_after_receiving_random(sm_conn); 4712e53be891SMatthias Ringwald break; 4713e53be891SMatthias Ringwald 4714901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_G2: 4715901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_G2: 47163cf37b8cSMatthias Ringwald case SM_SC_W4_CALCULATE_DHKEY: 4717901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_SALT: 4718901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_SALT: 4719901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_MACKEY: 4720901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_MACKEY: 4721901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_LTK: 4722901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_LTK: 4723901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F6_FOR_DHKEY_CHECK: 4724c6b7cbd9SMatthias Ringwald case SM_SC_W4_DHKEY_CHECK_COMMAND: 4725901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F6_FOR_DHKEY_CHECK: 4726d08147dfSMatthias Ringwald case SM_SC_W4_USER_RESPONSE: 47274c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_DHKEY_CHECK){ 4728e53be891SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4729e53be891SMatthias Ringwald break; 4730e53be891SMatthias Ringwald } 4731e53be891SMatthias Ringwald // store DHKey Check 4732901c000fSMatthias Ringwald setup->sm_state_vars |= SM_STATE_VAR_DHKEY_COMMAND_RECEIVED; 4733e53be891SMatthias Ringwald reverse_128(&packet[01], setup->sm_peer_dhkey_check); 4734446a8c36SMatthias Ringwald 4735901c000fSMatthias Ringwald // have we been only waiting for dhkey check command? 4736901c000fSMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_DHKEY_CHECK_COMMAND){ 4737019005a0SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK; 4738bd57ffebSMatthias Ringwald } 4739bd57ffebSMatthias Ringwald break; 474027c32905SMatthias Ringwald #endif 474127c32905SMatthias Ringwald 474242134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 47433deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_W4_PAIRING_CONFIRM: 47444c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_CONFIRM){ 47453deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 474627c32905SMatthias Ringwald break; 47473deb3ec6SMatthias Ringwald } 47483deb3ec6SMatthias Ringwald 47493deb3ec6SMatthias Ringwald // received confirm value 47509c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_confirm); 47513deb3ec6SMatthias Ringwald 4752192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 4753192365feSMatthias Ringwald if (test_pairing_failure == SM_REASON_CONFIRM_VALUE_FAILED){ 4754192365feSMatthias Ringwald log_info("testing_support: reset confirm value"); 4755192365feSMatthias Ringwald memset(setup->sm_peer_confirm, 0, 16); 4756192365feSMatthias Ringwald } 4757192365feSMatthias Ringwald #endif 47583deb3ec6SMatthias Ringwald // notify client to hide shown passkey 47593deb3ec6SMatthias Ringwald if (setup->sm_stk_generation_method == PK_INIT_INPUT){ 47605611a760SMatthias 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); 47613deb3ec6SMatthias Ringwald } 47623deb3ec6SMatthias Ringwald 47633deb3ec6SMatthias Ringwald // handle user cancel pairing? 47643deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_DECLINE){ 4765f4935286SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_PASSKEY_ENTRY_FAILED); 47663deb3ec6SMatthias Ringwald break; 47673deb3ec6SMatthias Ringwald } 47683deb3ec6SMatthias Ringwald 47693deb3ec6SMatthias Ringwald // wait for user action? 47703deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_PENDING){ 47713deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 47723deb3ec6SMatthias Ringwald break; 47733deb3ec6SMatthias Ringwald } 47743deb3ec6SMatthias Ringwald 47753deb3ec6SMatthias Ringwald // calculate and send local_confirm 4776f3582630SMatthias 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); 47773deb3ec6SMatthias Ringwald break; 47783deb3ec6SMatthias Ringwald 47793deb3ec6SMatthias Ringwald case SM_RESPONDER_PH2_W4_PAIRING_RANDOM: 47804c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RANDOM){ 47813deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 47823deb3ec6SMatthias Ringwald break;; 47833deb3ec6SMatthias Ringwald } 47843deb3ec6SMatthias Ringwald 47853deb3ec6SMatthias Ringwald // received random value 47869c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_random); 47873deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_C1_GET_ENC_C; 47883deb3ec6SMatthias Ringwald break; 478942134bc6SMatthias Ringwald #endif 47903deb3ec6SMatthias Ringwald 4791672dc582SMatthias Ringwald case SM_PH2_W4_CONNECTION_ENCRYPTED: 47923deb3ec6SMatthias Ringwald case SM_PH3_RECEIVE_KEYS: 47934c1d1092SMatthias Ringwald switch(sm_pdu_code){ 47943deb3ec6SMatthias Ringwald case SM_CODE_ENCRYPTION_INFORMATION: 47953deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 47969c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_ltk); 47973deb3ec6SMatthias Ringwald break; 47983deb3ec6SMatthias Ringwald 47993deb3ec6SMatthias Ringwald case SM_CODE_MASTER_IDENTIFICATION: 48003deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 4801f8fbdce0SMatthias Ringwald setup->sm_peer_ediv = little_endian_read_16(packet, 1); 48029c80e4ccSMatthias Ringwald reverse_64(&packet[3], setup->sm_peer_rand); 48033deb3ec6SMatthias Ringwald break; 48043deb3ec6SMatthias Ringwald 48053deb3ec6SMatthias Ringwald case SM_CODE_IDENTITY_INFORMATION: 48063deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 48079c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_irk); 48083deb3ec6SMatthias Ringwald break; 48093deb3ec6SMatthias Ringwald 48103deb3ec6SMatthias Ringwald case SM_CODE_IDENTITY_ADDRESS_INFORMATION: 48113deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 48123deb3ec6SMatthias Ringwald setup->sm_peer_addr_type = packet[1]; 4813724d70a2SMatthias Ringwald reverse_bd_addr(&packet[2], setup->sm_peer_address); 48143deb3ec6SMatthias Ringwald break; 48153deb3ec6SMatthias Ringwald 48163deb3ec6SMatthias Ringwald case SM_CODE_SIGNING_INFORMATION: 48173deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 48189c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_csrk); 48193deb3ec6SMatthias Ringwald break; 48203deb3ec6SMatthias Ringwald default: 48213deb3ec6SMatthias Ringwald // Unexpected PDU 48223deb3ec6SMatthias Ringwald log_info("Unexpected PDU %u in SM_PH3_RECEIVE_KEYS", packet[0]); 48233deb3ec6SMatthias Ringwald break; 48243deb3ec6SMatthias Ringwald } 48253deb3ec6SMatthias Ringwald // done with key distribution? 482661d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 48273deb3ec6SMatthias Ringwald 48283deb3ec6SMatthias Ringwald sm_key_distribution_handle_all_received(sm_conn); 48293deb3ec6SMatthias Ringwald 483042134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 48316f7422f1SMatthias Ringwald sm_key_distribution_complete_responder(sm_conn); 48323deb3ec6SMatthias Ringwald } else { 4833625f00b2SMatthias Ringwald if (setup->sm_use_secure_connections){ 4834625f00b2SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 4835bbf8db22SMatthias Ringwald } else { 4836f3582630SMatthias 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); 4837625f00b2SMatthias Ringwald } 48383deb3ec6SMatthias Ringwald } 48393deb3ec6SMatthias Ringwald } 48403deb3ec6SMatthias Ringwald break; 4841c18be159SMatthias Ringwald 4842c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 4843b322498eSMatthias Ringwald 4844b322498eSMatthias Ringwald case SM_BR_EDR_W4_ENCRYPTION_COMPLETE: 4845b322498eSMatthias Ringwald // GAP/DM/LEP/BI-02-C - reject CTKD if P-192 encryption is used 4846b322498eSMatthias Ringwald if (sm_pdu_code == SM_CODE_PAIRING_REQUEST){ 4847b322498eSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_CROSS_TRANSPORT_KEY_DERIVATION_NOT_ALLOWED); 4848b322498eSMatthias Ringwald } 4849b322498eSMatthias Ringwald break; 4850b322498eSMatthias Ringwald 4851c18be159SMatthias Ringwald case SM_BR_EDR_INITIATOR_W4_PAIRING_RESPONSE: 4852553c9408SMatthias Ringwald 4853553c9408SMatthias Ringwald // dedicated bonding complete 4854f82b8f4bSMatthias Ringwald hci_dedicated_bonding_defer_disconnect(sm_conn->sm_handle, false); 4855553c9408SMatthias Ringwald 4856c18be159SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RESPONSE){ 4857c18be159SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4858c18be159SMatthias Ringwald break; 4859c18be159SMatthias Ringwald } 4860c18be159SMatthias Ringwald // store pairing response 4861c18be159SMatthias Ringwald (void)memcpy(&setup->sm_s_pres, packet, sizeof(sm_pairing_packet_t)); 4862c18be159SMatthias Ringwald 4863c18be159SMatthias Ringwald // validate encryption key size 4864afbd946dSMatthias Ringwald max_encryption_key_size = sm_pairing_packet_get_max_encryption_key_size(setup->sm_s_pres); 4865afbd946dSMatthias Ringwald if ((max_encryption_key_size < 7) || (max_encryption_key_size > 16)){ 4866afbd946dSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_INVALID_PARAMETERS); 4867afbd946dSMatthias Ringwald break; 4868afbd946dSMatthias Ringwald } 4869afbd946dSMatthias Ringwald sm_conn->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(max_encryption_key_size); 4870c18be159SMatthias Ringwald // SC Only mandates 128 bit key size 4871c18be159SMatthias Ringwald if (sm_sc_only_mode && (sm_conn->sm_actual_encryption_key_size < 16)) { 4872c18be159SMatthias Ringwald sm_conn->sm_actual_encryption_key_size = 0; 4873c18be159SMatthias Ringwald } 4874c18be159SMatthias Ringwald if (sm_conn->sm_actual_encryption_key_size == 0){ 4875c18be159SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_ENCRYPTION_KEY_SIZE); 4876c18be159SMatthias Ringwald break; 4877c18be159SMatthias Ringwald } 4878c18be159SMatthias Ringwald 4879c18be159SMatthias Ringwald // prepare key exchange, LTK is derived locally 4880c18be159SMatthias Ringwald sm_setup_key_distribution(sm_pairing_packet_get_initiator_key_distribution(setup->sm_s_pres) & ~SM_KEYDIST_ENC_KEY, 4881c18be159SMatthias Ringwald sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres) & ~SM_KEYDIST_ENC_KEY); 4882c18be159SMatthias Ringwald 4883c18be159SMatthias Ringwald // skip receive if there are none 488461d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 4885c18be159SMatthias Ringwald // distribute keys in run handles 'no keys to send' 4886c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_DISTRIBUTE_KEYS; 4887c18be159SMatthias Ringwald } else { 4888c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_RECEIVE_KEYS; 4889c18be159SMatthias Ringwald } 4890c18be159SMatthias Ringwald break; 4891c18be159SMatthias Ringwald 4892c18be159SMatthias Ringwald case SM_BR_EDR_RESPONDER_W4_PAIRING_REQUEST: 4893c18be159SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_REQUEST){ 4894c18be159SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4895c18be159SMatthias Ringwald break; 4896c18be159SMatthias Ringwald } 4897afbd946dSMatthias Ringwald 4898c18be159SMatthias Ringwald // store pairing request 4899c18be159SMatthias Ringwald (void)memcpy(&sm_conn->sm_m_preq, packet, sizeof(sm_pairing_packet_t)); 4900afbd946dSMatthias Ringwald 4901c18be159SMatthias Ringwald // validate encryption key size 4902f5217d52SMatthias Ringwald max_encryption_key_size = sm_pairing_packet_get_max_encryption_key_size(sm_conn->sm_m_preq); 4903afbd946dSMatthias Ringwald if ((max_encryption_key_size < 7) || (max_encryption_key_size > 16)){ 4904afbd946dSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_INVALID_PARAMETERS); 4905afbd946dSMatthias Ringwald break; 4906afbd946dSMatthias Ringwald } 4907afbd946dSMatthias Ringwald sm_conn->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(max_encryption_key_size); 4908c18be159SMatthias Ringwald // SC Only mandates 128 bit key size 4909c18be159SMatthias Ringwald if (sm_sc_only_mode && (sm_conn->sm_actual_encryption_key_size < 16)) { 4910c18be159SMatthias Ringwald sm_conn->sm_actual_encryption_key_size = 0; 4911c18be159SMatthias Ringwald } 4912c18be159SMatthias Ringwald if (sm_conn->sm_actual_encryption_key_size == 0){ 4913c18be159SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_ENCRYPTION_KEY_SIZE); 4914c18be159SMatthias Ringwald break; 4915c18be159SMatthias Ringwald } 4916c18be159SMatthias Ringwald // trigger response 49176a718a5eSMatthias Ringwald if (sm_ctkd_from_classic(sm_conn)){ 4918c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_RESPONDER_PAIRING_REQUEST_RECEIVED; 49196a718a5eSMatthias Ringwald } else { 49206a718a5eSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_CROSS_TRANSPORT_KEY_DERIVATION_NOT_ALLOWED); 49216a718a5eSMatthias Ringwald } 4922c18be159SMatthias Ringwald break; 4923c18be159SMatthias Ringwald 4924c18be159SMatthias Ringwald case SM_BR_EDR_RECEIVE_KEYS: 4925c18be159SMatthias Ringwald switch(sm_pdu_code){ 4926c18be159SMatthias Ringwald case SM_CODE_IDENTITY_INFORMATION: 4927c18be159SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 4928c18be159SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_irk); 4929c18be159SMatthias Ringwald break; 4930c18be159SMatthias Ringwald case SM_CODE_IDENTITY_ADDRESS_INFORMATION: 4931c18be159SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 4932c18be159SMatthias Ringwald setup->sm_peer_addr_type = packet[1]; 4933c18be159SMatthias Ringwald reverse_bd_addr(&packet[2], setup->sm_peer_address); 4934c18be159SMatthias Ringwald break; 4935c18be159SMatthias Ringwald case SM_CODE_SIGNING_INFORMATION: 4936c18be159SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 4937c18be159SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_csrk); 4938c18be159SMatthias Ringwald break; 4939c18be159SMatthias Ringwald default: 4940c18be159SMatthias Ringwald // Unexpected PDU 4941c18be159SMatthias Ringwald log_info("Unexpected PDU %u in SM_PH3_RECEIVE_KEYS", packet[0]); 4942c18be159SMatthias Ringwald break; 4943c18be159SMatthias Ringwald } 4944c18be159SMatthias Ringwald 4945c18be159SMatthias Ringwald // all keys received 494661d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 4947c18be159SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 4948c18be159SMatthias Ringwald // responder -> keys exchanged, derive LE LTK 4949c18be159SMatthias Ringwald sm_ctkd_start_from_br_edr(sm_conn); 4950c18be159SMatthias Ringwald } else { 4951c18be159SMatthias Ringwald // initiator -> send our keys if any 4952c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_DISTRIBUTE_KEYS; 4953c18be159SMatthias Ringwald } 4954c18be159SMatthias Ringwald } 4955c18be159SMatthias Ringwald break; 4956c18be159SMatthias Ringwald #endif 4957c18be159SMatthias Ringwald 49583deb3ec6SMatthias Ringwald default: 49593deb3ec6SMatthias Ringwald // Unexpected PDU 49603deb3ec6SMatthias Ringwald log_info("Unexpected PDU %u in state %u", packet[0], sm_conn->sm_engine_state); 49612d095694SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 49623deb3ec6SMatthias Ringwald break; 49633deb3ec6SMatthias Ringwald } 49643deb3ec6SMatthias Ringwald 496570b44dd4SMatthias Ringwald // try to send next pdu 496670b44dd4SMatthias Ringwald sm_trigger_run(); 49673deb3ec6SMatthias Ringwald } 49683deb3ec6SMatthias Ringwald 496973970ae5SMatthias Ringwald static void sm_channel_handler(uint8_t packet_type, hci_con_handle_t con_handle, uint8_t *packet, uint16_t size){ 497073970ae5SMatthias Ringwald 497173970ae5SMatthias Ringwald if ((packet_type == HCI_EVENT_PACKET) && (packet[0] == L2CAP_EVENT_CAN_SEND_NOW)){ 497273970ae5SMatthias Ringwald sm_run(); 497373970ae5SMatthias Ringwald } 497473970ae5SMatthias Ringwald 497573970ae5SMatthias Ringwald uint8_t sm_pdu_code = sm_pdu_validate_and_get_opcode(packet_type, packet, size); 497673970ae5SMatthias Ringwald if (sm_pdu_code == 0) return; 497773970ae5SMatthias Ringwald 497873970ae5SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 497973970ae5SMatthias Ringwald if (!sm_conn) return; 498073970ae5SMatthias Ringwald 498173970ae5SMatthias Ringwald if (sm_pdu_code == SM_CODE_PAIRING_FAILED){ 498273970ae5SMatthias Ringwald sm_reencryption_complete(sm_conn, ERROR_CODE_AUTHENTICATION_FAILURE); 498373970ae5SMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_AUTHENTICATION_FAILURE, packet[1]); 498473970ae5SMatthias Ringwald sm_done_for_handle(con_handle); 498573970ae5SMatthias Ringwald sm_conn->sm_engine_state = sm_conn->sm_role ? SM_RESPONDER_IDLE : SM_INITIATOR_CONNECTED; 498673970ae5SMatthias Ringwald return; 498773970ae5SMatthias Ringwald } 498873970ae5SMatthias Ringwald 498973970ae5SMatthias Ringwald if (sm_pdu_code == SM_CODE_KEYPRESS_NOTIFICATION){ 499073970ae5SMatthias Ringwald uint8_t buffer[5]; 499173970ae5SMatthias Ringwald buffer[0] = SM_EVENT_KEYPRESS_NOTIFICATION; 499273970ae5SMatthias Ringwald buffer[1] = 3; 499373970ae5SMatthias Ringwald little_endian_store_16(buffer, 2, con_handle); 499473970ae5SMatthias Ringwald buffer[4] = packet[1]; 499573970ae5SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, buffer, sizeof(buffer)); 499673970ae5SMatthias Ringwald return; 499773970ae5SMatthias Ringwald } 499873970ae5SMatthias Ringwald 499973970ae5SMatthias Ringwald sm_pdu_handler(sm_conn, sm_pdu_code, packet); 500073970ae5SMatthias Ringwald } 500173970ae5SMatthias Ringwald 50023deb3ec6SMatthias Ringwald // Security Manager Client API 5003a680ba6bSMatthias Ringwald void sm_register_oob_data_callback( int (*get_oob_data_callback)(uint8_t address_type, bd_addr_t addr, uint8_t * oob_data)){ 50043deb3ec6SMatthias Ringwald sm_get_oob_data = get_oob_data_callback; 50053deb3ec6SMatthias Ringwald } 50063deb3ec6SMatthias Ringwald 50074acf7b7bSMatthias 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)){ 5008a680ba6bSMatthias Ringwald sm_get_sc_oob_data = get_sc_oob_data_callback; 5009a680ba6bSMatthias Ringwald } 5010a680ba6bSMatthias Ringwald 5011b96d60a6SMatthias 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)){ 5012b96d60a6SMatthias Ringwald sm_get_ltk_callback = get_ltk_callback; 5013b96d60a6SMatthias Ringwald } 5014b96d60a6SMatthias Ringwald 501589a78d34SMatthias Ringwald void sm_add_event_handler(btstack_packet_callback_registration_t * callback_handler){ 501689a78d34SMatthias Ringwald btstack_linked_list_add_tail(&sm_event_handlers, (btstack_linked_item_t*) callback_handler); 501789a78d34SMatthias Ringwald } 501889a78d34SMatthias Ringwald 501967f708e0SMatthias Ringwald void sm_remove_event_handler(btstack_packet_callback_registration_t * callback_handler){ 502067f708e0SMatthias Ringwald btstack_linked_list_remove(&sm_event_handlers, (btstack_linked_item_t*) callback_handler); 502167f708e0SMatthias Ringwald } 502267f708e0SMatthias Ringwald 50233deb3ec6SMatthias Ringwald void sm_set_accepted_stk_generation_methods(uint8_t accepted_stk_generation_methods){ 50243deb3ec6SMatthias Ringwald sm_accepted_stk_generation_methods = accepted_stk_generation_methods; 50253deb3ec6SMatthias Ringwald } 50263deb3ec6SMatthias Ringwald 50273deb3ec6SMatthias Ringwald void sm_set_encryption_key_size_range(uint8_t min_size, uint8_t max_size){ 50283deb3ec6SMatthias Ringwald sm_min_encryption_key_size = min_size; 50293deb3ec6SMatthias Ringwald sm_max_encryption_key_size = max_size; 50303deb3ec6SMatthias Ringwald } 50313deb3ec6SMatthias Ringwald 50323deb3ec6SMatthias Ringwald void sm_set_authentication_requirements(uint8_t auth_req){ 503398d95509SMatthias Ringwald #ifndef ENABLE_LE_SECURE_CONNECTIONS 503498d95509SMatthias Ringwald if (auth_req & SM_AUTHREQ_SECURE_CONNECTION){ 503598d95509SMatthias Ringwald log_error("ENABLE_LE_SECURE_CONNECTIONS not defined, but requested by app. Dropping SC flag"); 503698d95509SMatthias Ringwald auth_req &= ~SM_AUTHREQ_SECURE_CONNECTION; 503798d95509SMatthias Ringwald } 503898d95509SMatthias Ringwald #endif 50393deb3ec6SMatthias Ringwald sm_auth_req = auth_req; 50403deb3ec6SMatthias Ringwald } 50413deb3ec6SMatthias Ringwald 50423deb3ec6SMatthias Ringwald void sm_set_io_capabilities(io_capability_t io_capability){ 50433deb3ec6SMatthias Ringwald sm_io_capabilities = io_capability; 50443deb3ec6SMatthias Ringwald } 50453deb3ec6SMatthias Ringwald 504642134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 5047728f6757SMatthias Ringwald void sm_set_request_security(bool enable){ 50483deb3ec6SMatthias Ringwald sm_slave_request_security = enable; 50493deb3ec6SMatthias Ringwald } 505042134bc6SMatthias Ringwald #endif 50513deb3ec6SMatthias Ringwald 50523deb3ec6SMatthias Ringwald void sm_set_er(sm_key_t er){ 50536535961aSMatthias Ringwald (void)memcpy(sm_persistent_er, er, 16); 50543deb3ec6SMatthias Ringwald } 50553deb3ec6SMatthias Ringwald 50563deb3ec6SMatthias Ringwald void sm_set_ir(sm_key_t ir){ 50576535961aSMatthias Ringwald (void)memcpy(sm_persistent_ir, ir, 16); 50583deb3ec6SMatthias Ringwald } 50593deb3ec6SMatthias Ringwald 50603deb3ec6SMatthias Ringwald // Testing support only 50613deb3ec6SMatthias Ringwald void sm_test_set_irk(sm_key_t irk){ 50626535961aSMatthias Ringwald (void)memcpy(sm_persistent_irk, irk, 16); 5063103fa6b0SMatthias Ringwald dkg_state = DKG_CALC_DHK; 5064841468bbSMatthias Ringwald test_use_fixed_local_irk = true; 50653deb3ec6SMatthias Ringwald } 50663deb3ec6SMatthias Ringwald 50673deb3ec6SMatthias Ringwald void sm_test_use_fixed_local_csrk(void){ 5068841468bbSMatthias Ringwald test_use_fixed_local_csrk = true; 50693deb3ec6SMatthias Ringwald } 50703deb3ec6SMatthias Ringwald 5071d1a1f6a4SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 5072d1a1f6a4SMatthias Ringwald static void sm_ec_generated(void * arg){ 5073d1a1f6a4SMatthias Ringwald UNUSED(arg); 5074d1a1f6a4SMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_DONE; 507534b6528fSMatthias Ringwald // trigger pairing if pending for ec key 507670b44dd4SMatthias Ringwald sm_trigger_run(); 5077d1a1f6a4SMatthias Ringwald } 5078674e5b4aSMatthias Ringwald static void sm_ec_generate_new_key(void) { 507934b6528fSMatthias Ringwald log_info("sm: generate new ec key"); 5080db88441fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS_DEBUG_KEY 5081db88441fSMatthias Ringwald // LE Secure Connections Debug Key 5082db88441fSMatthias Ringwald const uint8_t debug_key_public[64] = { 5083db88441fSMatthias Ringwald 0x20, 0xb0, 0x03, 0xd2, 0xf2, 0x97, 0xbe, 0x2c, 0x5e, 0x2c, 0x83, 0xa7, 0xe9, 0xf9, 0xa5, 0xb9, 5084db88441fSMatthias Ringwald 0xef, 0xf4, 0x91, 0x11, 0xac, 0xf4, 0xfd, 0xdb, 0xcc, 0x03, 0x01, 0x48, 0x0e, 0x35, 0x9d, 0xe6, 5085db88441fSMatthias Ringwald 0xdc, 0x80, 0x9c, 0x49, 0x65, 0x2a, 0xeb, 0x6d, 0x63, 0x32, 0x9a, 0xbf, 0x5a, 0x52, 0x15, 0x5c, 5086db88441fSMatthias Ringwald 0x76, 0x63, 0x45, 0xc2, 0x8f, 0xed, 0x30, 0x24, 0x74, 0x1c, 0x8e, 0xd0, 0x15, 0x89, 0xd2, 0x8b 5087db88441fSMatthias Ringwald }; 5088db88441fSMatthias Ringwald const uint8_t debug_key_private[32] = { 5089db88441fSMatthias Ringwald 0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, 0x74, 0xc9, 0xb3, 0xe3, 0xd2, 0x10, 0x3f, 0x50, 5090db88441fSMatthias Ringwald 0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd 5091db88441fSMatthias Ringwald }; 5092db88441fSMatthias Ringwald if (sm_sc_debug_keys_enabled) { 5093db88441fSMatthias Ringwald memcpy(ec_q, debug_key_public, 64); 5094db88441fSMatthias Ringwald btstack_crypto_ecc_p256_set_key(debug_key_public, debug_key_private); 5095db88441fSMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_DONE; 5096db88441fSMatthias Ringwald } else 5097db88441fSMatthias Ringwald #endif 5098db88441fSMatthias Ringwald { 5099674e5b4aSMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_ACTIVE; 5100674e5b4aSMatthias Ringwald btstack_crypto_ecc_p256_generate_key(&sm_crypto_ecc_p256_request, ec_q, &sm_ec_generated, NULL); 5101674e5b4aSMatthias Ringwald } 5102db88441fSMatthias Ringwald } 5103d1a1f6a4SMatthias Ringwald #endif 5104d1a1f6a4SMatthias Ringwald 5105192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 5106192365feSMatthias Ringwald void sm_test_set_pairing_failure(int reason){ 5107192365feSMatthias Ringwald test_pairing_failure = reason; 5108192365feSMatthias Ringwald } 5109192365feSMatthias Ringwald #endif 5110192365feSMatthias Ringwald 51117887cd92SMatthias Ringwald static void sm_state_reset(void) { 51127f775357SMatthias Ringwald #ifdef USE_CMAC_ENGINE 51137f775357SMatthias Ringwald sm_cmac_active = 0; 51147f775357SMatthias Ringwald #endif 51157f775357SMatthias Ringwald dkg_state = DKG_W4_WORKING; 51167f775357SMatthias Ringwald rau_state = RAU_IDLE; 51177f775357SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 51187f775357SMatthias Ringwald sm_address_resolution_test = -1; // no private address to resolve yet 51197f775357SMatthias Ringwald sm_address_resolution_mode = ADDRESS_RESOLUTION_IDLE; 51207f775357SMatthias Ringwald sm_address_resolution_general_queue = NULL; 51217f775357SMatthias Ringwald sm_active_connection_handle = HCI_CON_HANDLE_INVALID; 5122cbdd51cfSMatthias Ringwald sm_persistent_keys_random_active = false; 51237f775357SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 512415211b85SMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_IDLE; 51257f775357SMatthias Ringwald #endif 51267f775357SMatthias Ringwald } 51277f775357SMatthias Ringwald 51283deb3ec6SMatthias Ringwald void sm_init(void){ 51292d2d4d3cSMatthias Ringwald 51302d2d4d3cSMatthias Ringwald if (sm_initialized) return; 51312d2d4d3cSMatthias Ringwald 5132899e6e02SMatthias Ringwald // set default ER and IR values (should be unique - set by app or sm later using TLV) 5133899e6e02SMatthias Ringwald sm_er_ir_set_default(); 5134899e6e02SMatthias Ringwald 51353deb3ec6SMatthias Ringwald // defaults 51363deb3ec6SMatthias Ringwald sm_accepted_stk_generation_methods = SM_STK_GENERATION_METHOD_JUST_WORKS 51373deb3ec6SMatthias Ringwald | SM_STK_GENERATION_METHOD_OOB 5138b4343428SMatthias Ringwald | SM_STK_GENERATION_METHOD_PASSKEY 5139b4343428SMatthias Ringwald | SM_STK_GENERATION_METHOD_NUMERIC_COMPARISON; 5140b4343428SMatthias Ringwald 51413deb3ec6SMatthias Ringwald sm_max_encryption_key_size = 16; 51423deb3ec6SMatthias Ringwald sm_min_encryption_key_size = 7; 51433deb3ec6SMatthias Ringwald 51445ce1359eSMatthias Ringwald sm_fixed_passkey_in_display_role = 0xffffffffU; 51451979f09cSMatthias Ringwald sm_reconstruct_ltk_without_le_device_db_entry = true; 5146caf15bf3SMatthias Ringwald 51473deb3ec6SMatthias Ringwald gap_random_adress_update_period = 15 * 60 * 1000L; 51483deb3ec6SMatthias Ringwald 5149841468bbSMatthias Ringwald test_use_fixed_local_csrk = false; 51503deb3ec6SMatthias Ringwald 51517f775357SMatthias Ringwald // other 515284c0c5c7SMatthias Ringwald btstack_run_loop_set_timer_handler(&sm_run_timer, &sm_run_timer_handler); 515384c0c5c7SMatthias Ringwald 5154a036ae12SMatthias Ringwald // register for HCI Events 5155e03e489aSMatthias Ringwald hci_event_callback_registration.callback = &sm_event_packet_handler; 5156e03e489aSMatthias Ringwald hci_add_event_handler(&hci_event_callback_registration); 5157e03e489aSMatthias Ringwald 5158bad51150SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 5159a036ae12SMatthias Ringwald // register for L2CAP events 5160a036ae12SMatthias Ringwald l2cap_event_callback_registration.callback = &sm_event_packet_handler; 5161a036ae12SMatthias Ringwald l2cap_add_event_handler(&l2cap_event_callback_registration); 5162bad51150SMatthias Ringwald #endif 5163a036ae12SMatthias Ringwald 5164d1a1f6a4SMatthias Ringwald // 5165d1a1f6a4SMatthias Ringwald btstack_crypto_init(); 5166d1a1f6a4SMatthias Ringwald 516751bd74d1SMatthias Ringwald // init le_device_db 516851bd74d1SMatthias Ringwald le_device_db_init(); 516951bd74d1SMatthias Ringwald 5170b170b20fSMatthias Ringwald // and L2CAP PDUs + L2CAP_EVENT_CAN_SEND_NOW 517173970ae5SMatthias Ringwald l2cap_register_fixed_channel(sm_channel_handler, L2CAP_CID_SECURITY_MANAGER_PROTOCOL); 5172384eabd3SMatthias Ringwald #ifdef ENABLE_CLASSIC 517373970ae5SMatthias Ringwald l2cap_register_fixed_channel(sm_channel_handler, L2CAP_CID_BR_EDR_SECURITY_MANAGER); 5174384eabd3SMatthias Ringwald #endif 517527c32905SMatthias Ringwald 51767f775357SMatthias Ringwald // state 51777f775357SMatthias Ringwald sm_state_reset(); 51782d2d4d3cSMatthias Ringwald 51792d2d4d3cSMatthias Ringwald sm_initialized = true; 51803deb3ec6SMatthias Ringwald } 51813deb3ec6SMatthias Ringwald 518215537ea4SMatthias Ringwald void sm_deinit(void){ 518315537ea4SMatthias Ringwald sm_initialized = false; 518415537ea4SMatthias Ringwald btstack_run_loop_remove_timer(&sm_run_timer); 518592f8d6b6SMatthias Ringwald #if defined(ENABLE_LE_SECURE_CONNECTIONS) && defined (ENABLE_LE_SECURE_CONNECTION_DEBUG_KEY) 5186db88441fSMatthias Ringwald sm_sc_debug_keys_enabled = false; 5187db88441fSMatthias Ringwald #endif 518815537ea4SMatthias Ringwald } 518915537ea4SMatthias Ringwald 51904b8c611fSMatthias Ringwald void sm_use_fixed_passkey_in_display_role(uint32_t passkey){ 51914b8c611fSMatthias Ringwald sm_fixed_passkey_in_display_role = passkey; 5192caf15bf3SMatthias Ringwald } 5193caf15bf3SMatthias Ringwald 51946c39055aSMatthias Ringwald void sm_allow_ltk_reconstruction_without_le_device_db_entry(int allow){ 51951979f09cSMatthias Ringwald sm_reconstruct_ltk_without_le_device_db_entry = allow != 0; 51966c39055aSMatthias Ringwald } 51976c39055aSMatthias Ringwald 5198711e6c80SMatthias Ringwald static sm_connection_t * sm_get_connection_for_handle(hci_con_handle_t con_handle){ 5199711e6c80SMatthias Ringwald hci_connection_t * hci_con = hci_connection_for_handle(con_handle); 52003deb3ec6SMatthias Ringwald if (!hci_con) return NULL; 52013deb3ec6SMatthias Ringwald return &hci_con->sm_connection; 52023deb3ec6SMatthias Ringwald } 52033deb3ec6SMatthias Ringwald 5204916ea5b2SMatthias Ringwald static void sm_cache_ltk(sm_connection_t * connection, const sm_key_t ltk){ 5205916ea5b2SMatthias Ringwald hci_connection_t * hci_con = hci_connection_for_handle(connection->sm_handle); 5206916ea5b2SMatthias Ringwald btstack_assert(hci_con != NULL); 5207916ea5b2SMatthias Ringwald memcpy(hci_con->link_key, ltk, 16); 5208f728bb7bSMatthias Ringwald hci_con->link_key_type = COMBINATION_KEY; 5209916ea5b2SMatthias Ringwald } 5210916ea5b2SMatthias Ringwald 521177e2e5edSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 521277e2e5edSMatthias Ringwald static sm_connection_t * sm_get_connection_for_bd_addr_and_type(bd_addr_t address, bd_addr_type_t addr_type){ 521377e2e5edSMatthias Ringwald hci_connection_t * hci_con = hci_connection_for_bd_addr_and_type(address, addr_type); 521477e2e5edSMatthias Ringwald if (!hci_con) return NULL; 521577e2e5edSMatthias Ringwald return &hci_con->sm_connection; 521677e2e5edSMatthias Ringwald } 521777e2e5edSMatthias Ringwald #endif 521877e2e5edSMatthias Ringwald 52196bc3aba4SMatthias Ringwald // @deprecated: map onto sm_request_pairing 5220711e6c80SMatthias Ringwald void sm_send_security_request(hci_con_handle_t con_handle){ 5221711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 52223deb3ec6SMatthias Ringwald if (!sm_conn) return; 52236bc3aba4SMatthias Ringwald if (!IS_RESPONDER(sm_conn->sm_role)) return; 52246bc3aba4SMatthias Ringwald sm_request_pairing(con_handle); 52253deb3ec6SMatthias Ringwald } 52263deb3ec6SMatthias Ringwald 52273deb3ec6SMatthias Ringwald // request pairing 5228711e6c80SMatthias Ringwald void sm_request_pairing(hci_con_handle_t con_handle){ 5229711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 52303deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 52313deb3ec6SMatthias Ringwald 52327af5dcd5SMatthias Ringwald bool have_ltk; 52337af5dcd5SMatthias Ringwald uint8_t ltk[16]; 52342d68601cSMatthias Ringwald bool auth_required; 52352d68601cSMatthias Ringwald int authenticated; 52362d68601cSMatthias Ringwald bool trigger_reencryption; 52373deb3ec6SMatthias Ringwald log_info("sm_request_pairing in role %u, state %u", sm_conn->sm_role, sm_conn->sm_engine_state); 523842134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 523924c20dc4SMatthias Ringwald switch (sm_conn->sm_engine_state){ 524024c20dc4SMatthias Ringwald case SM_GENERAL_IDLE: 524124c20dc4SMatthias Ringwald case SM_RESPONDER_IDLE: 52427af5dcd5SMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 52437af5dcd5SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 52447af5dcd5SMatthias Ringwald le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); 52457af5dcd5SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 52467af5dcd5SMatthias Ringwald log_info("have ltk %u", have_ltk); 52477af5dcd5SMatthias Ringwald if (have_ltk){ 52485f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 524924c20dc4SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 52507af5dcd5SMatthias Ringwald sm_reencryption_started(sm_conn); 52517af5dcd5SMatthias Ringwald break; 52527af5dcd5SMatthias Ringwald } 52537af5dcd5SMatthias Ringwald /* fall through */ 52547af5dcd5SMatthias Ringwald 52557af5dcd5SMatthias Ringwald case IRK_LOOKUP_FAILED: 52565f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 52577af5dcd5SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 52587af5dcd5SMatthias Ringwald sm_pairing_started(sm_conn); 52597af5dcd5SMatthias Ringwald break; 52607af5dcd5SMatthias Ringwald default: 52617af5dcd5SMatthias Ringwald log_info("irk lookup pending"); 52625f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 52637af5dcd5SMatthias Ringwald break; 52647af5dcd5SMatthias Ringwald } 526524c20dc4SMatthias Ringwald break; 526624c20dc4SMatthias Ringwald default: 526724c20dc4SMatthias Ringwald break; 526824c20dc4SMatthias Ringwald } 52693deb3ec6SMatthias Ringwald } else { 52703deb3ec6SMatthias Ringwald // used as a trigger to start central/master/initiator security procedures 5271175b7faaSMatthias Ringwald switch (sm_conn->sm_engine_state){ 5272175b7faaSMatthias Ringwald case SM_INITIATOR_CONNECTED: 52733deb3ec6SMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 52743deb3ec6SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 52752d68601cSMatthias Ringwald le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, &authenticated, NULL, NULL); 5276f53ec649SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 52772d68601cSMatthias Ringwald auth_required = sm_auth_req & SM_AUTHREQ_MITM_PROTECTION; 52782d68601cSMatthias Ringwald // re-encrypt is sufficient if we have ltk and that is either already authenticated or we don't require authentication 52792d68601cSMatthias Ringwald trigger_reencryption = have_ltk && ((authenticated != 0) || (auth_required == false)); 52802d68601cSMatthias Ringwald log_info("have ltk %u, authenticated %u, auth required %u => reencrypt %u", have_ltk, authenticated, auth_required, trigger_reencryption); 52812d68601cSMatthias Ringwald if (trigger_reencryption){ 52825f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 52835567aa60SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH4_HAS_LTK; 5284c245ca32SMatthias Ringwald break; 5285f53ec649SMatthias Ringwald } 5286cf373d3aSMatthias Ringwald /* fall through */ 5287c245ca32SMatthias Ringwald 528834c39fbdSMatthias Ringwald case IRK_LOOKUP_FAILED: 52893deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 52903deb3ec6SMatthias Ringwald break; 52913deb3ec6SMatthias Ringwald default: 5292d1a1f6a4SMatthias Ringwald log_info("irk lookup pending"); 52935f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 52943deb3ec6SMatthias Ringwald break; 52953deb3ec6SMatthias Ringwald } 5296175b7faaSMatthias Ringwald break; 5297cb6d7eb0SMatthias Ringwald case SM_GENERAL_REENCRYPTION_FAILED: 5298cb6d7eb0SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 5299cb6d7eb0SMatthias Ringwald break; 5300175b7faaSMatthias Ringwald case SM_GENERAL_IDLE: 53015f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 5302175b7faaSMatthias Ringwald break; 5303175b7faaSMatthias Ringwald default: 5304175b7faaSMatthias Ringwald break; 53053deb3ec6SMatthias Ringwald } 53063deb3ec6SMatthias Ringwald } 530770b44dd4SMatthias Ringwald sm_trigger_run(); 53083deb3ec6SMatthias Ringwald } 53093deb3ec6SMatthias Ringwald 53103deb3ec6SMatthias Ringwald // called by client app on authorization request 5311711e6c80SMatthias Ringwald void sm_authorization_decline(hci_con_handle_t con_handle){ 5312711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 53133deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 53143deb3ec6SMatthias Ringwald sm_conn->sm_connection_authorization_state = AUTHORIZATION_DECLINED; 5315589f5a99SMatthias 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); 53163deb3ec6SMatthias Ringwald } 53173deb3ec6SMatthias Ringwald 5318711e6c80SMatthias Ringwald void sm_authorization_grant(hci_con_handle_t con_handle){ 5319711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 53203deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 53213deb3ec6SMatthias Ringwald sm_conn->sm_connection_authorization_state = AUTHORIZATION_GRANTED; 5322589f5a99SMatthias 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); 53233deb3ec6SMatthias Ringwald } 53243deb3ec6SMatthias Ringwald 53253deb3ec6SMatthias Ringwald // GAP Bonding API 53263deb3ec6SMatthias Ringwald 5327711e6c80SMatthias Ringwald void sm_bonding_decline(hci_con_handle_t con_handle){ 5328711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 53293deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 53303deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_DECLINE; 53310af429c6SMatthias Ringwald log_info("decline, state %u", sm_conn->sm_engine_state); 53320af429c6SMatthias Ringwald switch(sm_conn->sm_engine_state){ 53330af429c6SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 53340af429c6SMatthias Ringwald case SM_SC_W4_USER_RESPONSE: 53350af429c6SMatthias Ringwald case SM_SC_W4_CONFIRMATION: 53360af429c6SMatthias Ringwald case SM_SC_W4_PUBLIC_KEY_COMMAND: 53370af429c6SMatthias Ringwald #endif 53380af429c6SMatthias Ringwald case SM_PH1_W4_USER_RESPONSE: 5339de2fd182SMatthias Ringwald switch (setup->sm_stk_generation_method){ 5340de2fd182SMatthias Ringwald case PK_RESP_INPUT: 5341de2fd182SMatthias Ringwald case PK_INIT_INPUT: 534247fb4255SMatthias Ringwald case PK_BOTH_INPUT: 53430af429c6SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_PASSKEY_ENTRY_FAILED); 5344de2fd182SMatthias Ringwald break; 534547fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 5346de2fd182SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_NUMERIC_COMPARISON_FAILED); 5347de2fd182SMatthias Ringwald break; 5348de2fd182SMatthias Ringwald case JUST_WORKS: 5349de2fd182SMatthias Ringwald case OOB: 5350de2fd182SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_UNSPECIFIED_REASON); 5351de2fd182SMatthias Ringwald break; 53527bbeb3adSMilanka Ringwald default: 53537bbeb3adSMilanka Ringwald btstack_assert(false); 53547bbeb3adSMilanka Ringwald break; 5355de2fd182SMatthias Ringwald } 53560af429c6SMatthias Ringwald break; 53570af429c6SMatthias Ringwald default: 53580af429c6SMatthias Ringwald break; 53593deb3ec6SMatthias Ringwald } 536070b44dd4SMatthias Ringwald sm_trigger_run(); 53613deb3ec6SMatthias Ringwald } 53623deb3ec6SMatthias Ringwald 5363711e6c80SMatthias Ringwald void sm_just_works_confirm(hci_con_handle_t con_handle){ 5364711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 53653deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 53663deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_CONFIRM; 53673deb3ec6SMatthias Ringwald if (sm_conn->sm_engine_state == SM_PH1_W4_USER_RESPONSE){ 5368136d331aSMatthias Ringwald if (setup->sm_use_secure_connections){ 5369c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 5370bbf8db22SMatthias Ringwald } else { 5371f3582630SMatthias 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); 5372136d331aSMatthias Ringwald } 53733deb3ec6SMatthias Ringwald } 53740346c37cSMatthias Ringwald 53750346c37cSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 5376c6b7cbd9SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_USER_RESPONSE){ 5377dc300847SMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 5378446a8c36SMatthias Ringwald } 53790346c37cSMatthias Ringwald #endif 53800346c37cSMatthias Ringwald 538170b44dd4SMatthias Ringwald sm_trigger_run(); 53823deb3ec6SMatthias Ringwald } 53833deb3ec6SMatthias Ringwald 5384c8c46d51SMatthias Ringwald void sm_numeric_comparison_confirm(hci_con_handle_t con_handle){ 5385c8c46d51SMatthias Ringwald // for now, it's the same 5386c8c46d51SMatthias Ringwald sm_just_works_confirm(con_handle); 5387c8c46d51SMatthias Ringwald } 5388c8c46d51SMatthias Ringwald 5389711e6c80SMatthias Ringwald void sm_passkey_input(hci_con_handle_t con_handle, uint32_t passkey){ 5390711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 53913deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 53923deb3ec6SMatthias Ringwald sm_reset_tk(); 5393f8fbdce0SMatthias Ringwald big_endian_store_32(setup->sm_tk, 12, passkey); 53943deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_PASSKEY; 53953deb3ec6SMatthias Ringwald if (sm_conn->sm_engine_state == SM_PH1_W4_USER_RESPONSE){ 5396f3582630SMatthias 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); 53973deb3ec6SMatthias Ringwald } 53981c516d8fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 53996535961aSMatthias Ringwald (void)memcpy(setup->sm_ra, setup->sm_tk, 16); 54006535961aSMatthias Ringwald (void)memcpy(setup->sm_rb, setup->sm_tk, 16); 540107036a04SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_USER_RESPONSE){ 540207036a04SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 540307036a04SMatthias Ringwald } 54041c516d8fSMatthias Ringwald #endif 540570b44dd4SMatthias Ringwald sm_trigger_run(); 54063deb3ec6SMatthias Ringwald } 54073deb3ec6SMatthias Ringwald 54083d7fe1e9SMatthias Ringwald void sm_keypress_notification(hci_con_handle_t con_handle, uint8_t action){ 54093d7fe1e9SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 54103d7fe1e9SMatthias Ringwald if (!sm_conn) return; // wrong connection 54113d7fe1e9SMatthias Ringwald if (action > SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED) return; 5412dd4a08fbSMatthias Ringwald uint8_t num_actions = setup->sm_keypress_notification >> 5; 54134ea43905SMatthias Ringwald uint8_t flags = setup->sm_keypress_notification & 0x1fu; 5414dd4a08fbSMatthias Ringwald switch (action){ 5415dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_STARTED: 5416dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED: 54174ea43905SMatthias Ringwald flags |= (1u << action); 5418dd4a08fbSMatthias Ringwald break; 5419dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_CLEARED: 5420dd4a08fbSMatthias Ringwald // clear counter, keypress & erased flags + set passkey cleared 54214ea43905SMatthias Ringwald flags = (flags & 0x19u) | (1u << SM_KEYPRESS_PASSKEY_CLEARED); 5422dd4a08fbSMatthias Ringwald break; 5423dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ENTERED: 54241d80f1e6SMatthias Ringwald if ((flags & (1u << SM_KEYPRESS_PASSKEY_DIGIT_ERASED)) != 0u){ 5425dd4a08fbSMatthias Ringwald // erase actions queued 5426dd4a08fbSMatthias Ringwald num_actions--; 54274ea43905SMatthias Ringwald if (num_actions == 0u){ 5428dd4a08fbSMatthias Ringwald // clear counter, keypress & erased flags 54294ea43905SMatthias Ringwald flags &= 0x19u; 5430dd4a08fbSMatthias Ringwald } 5431dd4a08fbSMatthias Ringwald break; 5432dd4a08fbSMatthias Ringwald } 5433dd4a08fbSMatthias Ringwald num_actions++; 54344ea43905SMatthias Ringwald flags |= (1u << SM_KEYPRESS_PASSKEY_DIGIT_ENTERED); 5435dd4a08fbSMatthias Ringwald break; 5436dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ERASED: 54371d80f1e6SMatthias Ringwald if ((flags & (1u << SM_KEYPRESS_PASSKEY_DIGIT_ENTERED)) != 0u){ 5438dd4a08fbSMatthias Ringwald // enter actions queued 5439dd4a08fbSMatthias Ringwald num_actions--; 54404ea43905SMatthias Ringwald if (num_actions == 0u){ 5441dd4a08fbSMatthias Ringwald // clear counter, keypress & erased flags 54424ea43905SMatthias Ringwald flags &= 0x19u; 5443dd4a08fbSMatthias Ringwald } 5444dd4a08fbSMatthias Ringwald break; 5445dd4a08fbSMatthias Ringwald } 5446dd4a08fbSMatthias Ringwald num_actions++; 54474ea43905SMatthias Ringwald flags |= (1u << SM_KEYPRESS_PASSKEY_DIGIT_ERASED); 5448dd4a08fbSMatthias Ringwald break; 5449dd4a08fbSMatthias Ringwald default: 5450dd4a08fbSMatthias Ringwald break; 5451dd4a08fbSMatthias Ringwald } 5452dd4a08fbSMatthias Ringwald setup->sm_keypress_notification = (num_actions << 5) | flags; 545370b44dd4SMatthias Ringwald sm_trigger_run(); 54543d7fe1e9SMatthias Ringwald } 54553d7fe1e9SMatthias Ringwald 5456c59d0c92SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 5457d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_oob(void * arg){ 5458d1a1f6a4SMatthias Ringwald UNUSED(arg); 5459d1a1f6a4SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_W2_CALC_CONFIRM; 546070b44dd4SMatthias Ringwald sm_trigger_run(); 5461d1a1f6a4SMatthias Ringwald } 5462c59d0c92SMatthias Ringwald uint8_t sm_generate_sc_oob_data(void (*callback)(const uint8_t * confirm_value, const uint8_t * random_value)){ 54638334d3d8SMatthias Ringwald 54648334d3d8SMatthias Ringwald static btstack_crypto_random_t sm_crypto_random_oob_request; 54658334d3d8SMatthias Ringwald 5466c59d0c92SMatthias Ringwald if (sm_sc_oob_state != SM_SC_OOB_IDLE) return ERROR_CODE_COMMAND_DISALLOWED; 5467c59d0c92SMatthias Ringwald sm_sc_oob_callback = callback; 5468d1a1f6a4SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_W4_RANDOM; 5469d1a1f6a4SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_oob_request, sm_sc_oob_random, 16, &sm_handle_random_result_oob, NULL); 5470c59d0c92SMatthias Ringwald return 0; 5471c59d0c92SMatthias Ringwald } 5472c59d0c92SMatthias Ringwald #endif 5473c59d0c92SMatthias Ringwald 54743deb3ec6SMatthias Ringwald /** 5475ba394633SMatthias Ringwald * @brief Get Identity Resolving state 5476ba394633SMatthias Ringwald * @param con_handle 5477ba394633SMatthias Ringwald * @return irk_lookup_state_t 5478ba394633SMatthias Ringwald */ 5479ba394633SMatthias Ringwald irk_lookup_state_t sm_identity_resolving_state(hci_con_handle_t con_handle){ 5480ba394633SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 5481ba394633SMatthias Ringwald if (!sm_conn) return IRK_LOOKUP_IDLE; 5482ba394633SMatthias Ringwald return sm_conn->sm_irk_lookup_state; 5483ba394633SMatthias Ringwald } 5484ba394633SMatthias Ringwald 5485ba394633SMatthias Ringwald /** 54863deb3ec6SMatthias Ringwald * @brief Identify device in LE Device DB 54873deb3ec6SMatthias Ringwald * @param handle 54886b65794dSMilanka Ringwald * @return index from le_device_db or -1 if not found/identified 54893deb3ec6SMatthias Ringwald */ 5490711e6c80SMatthias Ringwald int sm_le_device_index(hci_con_handle_t con_handle ){ 5491711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 54923deb3ec6SMatthias Ringwald if (!sm_conn) return -1; 54933deb3ec6SMatthias Ringwald return sm_conn->sm_le_db_index; 54943deb3ec6SMatthias Ringwald } 54953deb3ec6SMatthias Ringwald 5496916ea5b2SMatthias Ringwald uint8_t sm_get_ltk(hci_con_handle_t con_handle, sm_key_t ltk){ 5497916ea5b2SMatthias Ringwald hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); 5498916ea5b2SMatthias Ringwald if (hci_connection == NULL){ 5499916ea5b2SMatthias Ringwald return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 5500916ea5b2SMatthias Ringwald } 5501f728bb7bSMatthias Ringwald if (hci_connection->link_key_type == INVALID_LINK_KEY){ 5502916ea5b2SMatthias Ringwald return ERROR_CODE_PIN_OR_KEY_MISSING; 5503916ea5b2SMatthias Ringwald } 5504916ea5b2SMatthias Ringwald memcpy(ltk, hci_connection->link_key, 16); 5505916ea5b2SMatthias Ringwald return ERROR_CODE_SUCCESS; 5506916ea5b2SMatthias Ringwald } 5507916ea5b2SMatthias Ringwald 55088f57b085SMatthias Ringwald static int gap_random_address_type_requires_updates(void){ 550947ba4de1SMatthias Ringwald switch (gap_random_adress_type){ 551047ba4de1SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_OFF: 551147ba4de1SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_STATIC: 551247ba4de1SMatthias Ringwald return 0; 551347ba4de1SMatthias Ringwald default: 55148f57b085SMatthias Ringwald return 1; 55158f57b085SMatthias Ringwald } 551647ba4de1SMatthias Ringwald } 5517d70217a2SMatthias Ringwald 551833373e40SMatthias Ringwald static uint8_t own_address_type(void){ 5519b95a5a35SMatthias Ringwald switch (gap_random_adress_type){ 5520b95a5a35SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_OFF: 5521b95a5a35SMatthias Ringwald return BD_ADDR_TYPE_LE_PUBLIC; 5522b95a5a35SMatthias Ringwald default: 5523b95a5a35SMatthias Ringwald return BD_ADDR_TYPE_LE_RANDOM; 5524b95a5a35SMatthias Ringwald } 552533373e40SMatthias Ringwald } 55268f57b085SMatthias Ringwald 55273deb3ec6SMatthias Ringwald // GAP LE API 55283deb3ec6SMatthias Ringwald void gap_random_address_set_mode(gap_random_address_type_t random_address_type){ 55293deb3ec6SMatthias Ringwald gap_random_address_update_stop(); 55303deb3ec6SMatthias Ringwald gap_random_adress_type = random_address_type; 5531b95a5a35SMatthias Ringwald hci_le_set_own_address_type(own_address_type()); 55328f57b085SMatthias Ringwald if (!gap_random_address_type_requires_updates()) return; 55333deb3ec6SMatthias Ringwald gap_random_address_update_start(); 55343deb3ec6SMatthias Ringwald gap_random_address_trigger(); 55353deb3ec6SMatthias Ringwald } 55363deb3ec6SMatthias Ringwald 55373deb3ec6SMatthias Ringwald gap_random_address_type_t gap_random_address_get_mode(void){ 55383deb3ec6SMatthias Ringwald return gap_random_adress_type; 55393deb3ec6SMatthias Ringwald } 55403deb3ec6SMatthias Ringwald 55413deb3ec6SMatthias Ringwald void gap_random_address_set_update_period(int period_ms){ 55423deb3ec6SMatthias Ringwald gap_random_adress_update_period = period_ms; 55438f57b085SMatthias Ringwald if (!gap_random_address_type_requires_updates()) return; 55443deb3ec6SMatthias Ringwald gap_random_address_update_stop(); 55453deb3ec6SMatthias Ringwald gap_random_address_update_start(); 55463deb3ec6SMatthias Ringwald } 55473deb3ec6SMatthias Ringwald 5548667ba9d1SMatthias Ringwald void gap_random_address_set(const bd_addr_t addr){ 55498f57b085SMatthias Ringwald gap_random_address_set_mode(GAP_RANDOM_ADDRESS_TYPE_STATIC); 55506535961aSMatthias Ringwald (void)memcpy(sm_random_address, addr, 6); 555163d302e8SMatthias Ringwald // assert msb bits are set to '11' 555263d302e8SMatthias Ringwald sm_random_address[0] |= 0xc0; 555363d302e8SMatthias Ringwald hci_le_random_address_set(sm_random_address); 55547e252622SMatthias Ringwald } 55557e252622SMatthias Ringwald 5556d70217a2SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 55573deb3ec6SMatthias Ringwald /* 55583deb3ec6SMatthias Ringwald * @brief Set Advertisement Paramters 55593deb3ec6SMatthias Ringwald * @param adv_int_min 55603deb3ec6SMatthias Ringwald * @param adv_int_max 55613deb3ec6SMatthias Ringwald * @param adv_type 55623deb3ec6SMatthias Ringwald * @param direct_address_type 55633deb3ec6SMatthias Ringwald * @param direct_address 55643deb3ec6SMatthias Ringwald * @param channel_map 55653deb3ec6SMatthias Ringwald * @param filter_policy 55663deb3ec6SMatthias Ringwald * 55673deb3ec6SMatthias Ringwald * @note own_address_type is used from gap_random_address_set_mode 55683deb3ec6SMatthias Ringwald */ 55693deb3ec6SMatthias Ringwald void gap_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, 55703deb3ec6SMatthias Ringwald uint8_t direct_address_typ, bd_addr_t direct_address, uint8_t channel_map, uint8_t filter_policy){ 5571b95a5a35SMatthias Ringwald hci_le_advertisements_set_params(adv_int_min, adv_int_max, adv_type, 55723deb3ec6SMatthias Ringwald direct_address_typ, direct_address, channel_map, filter_policy); 55733deb3ec6SMatthias Ringwald } 5574d70217a2SMatthias Ringwald #endif 5575dcd6c9b5SMatthias Ringwald 5576c7ceba59SMatthias Ringwald bool gap_reconnect_security_setup_active(hci_con_handle_t con_handle){ 5577dcd6c9b5SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 5578dcd6c9b5SMatthias Ringwald // wrong connection 5579c7ceba59SMatthias Ringwald if (!sm_conn) return false; 5580dcd6c9b5SMatthias Ringwald // already encrypted 5581c7ceba59SMatthias Ringwald if (sm_conn->sm_connection_encrypted) return false; 5582dcd6c9b5SMatthias Ringwald // irk status? 5583dcd6c9b5SMatthias Ringwald switch(sm_conn->sm_irk_lookup_state){ 5584dcd6c9b5SMatthias Ringwald case IRK_LOOKUP_FAILED: 5585dcd6c9b5SMatthias Ringwald // done, cannot setup encryption 5586c7ceba59SMatthias Ringwald return false; 5587dcd6c9b5SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 5588dcd6c9b5SMatthias Ringwald break; 5589dcd6c9b5SMatthias Ringwald default: 5590dcd6c9b5SMatthias Ringwald // IR Lookup pending 5591c7ceba59SMatthias Ringwald return true; 5592dcd6c9b5SMatthias Ringwald } 5593f0674e22SMatthias Ringwald // IRK Lookup Succeeded, re-encryption should be initiated. When done, state gets reset or indicates failure 5594c7ceba59SMatthias Ringwald if (sm_conn->sm_engine_state == SM_GENERAL_REENCRYPTION_FAILED) return false; 5595c7ceba59SMatthias Ringwald if (sm_conn->sm_role != 0){ 5596b15d5ceaSMatthias Ringwald return sm_conn->sm_engine_state != SM_RESPONDER_IDLE; 5597b15d5ceaSMatthias Ringwald } else { 5598dcd6c9b5SMatthias Ringwald return sm_conn->sm_engine_state != SM_INITIATOR_CONNECTED; 5599dcd6c9b5SMatthias Ringwald } 5600b15d5ceaSMatthias Ringwald } 56013cdbe9dbSMatthias Ringwald 56023cdbe9dbSMatthias Ringwald void sm_set_secure_connections_only_mode(bool enable){ 56033cdbe9dbSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 56043cdbe9dbSMatthias Ringwald sm_sc_only_mode = enable; 56053cdbe9dbSMatthias Ringwald #else 56063cdbe9dbSMatthias Ringwald // SC Only mode not possible without support for SC 56073cdbe9dbSMatthias Ringwald btstack_assert(enable == false); 56083cdbe9dbSMatthias Ringwald #endif 56093cdbe9dbSMatthias Ringwald } 5610052bbdc5SMatthias Ringwald 561192f8d6b6SMatthias Ringwald #if defined(ENABLE_LE_SECURE_CONNECTIONS) && defined (ENABLE_LE_SECURE_CONNECTION_DEBUG_KEY) 5612db88441fSMatthias Ringwald void sm_test_enable_secure_connections_debug_keys(void) { 5613db88441fSMatthias Ringwald log_info("Enable LE Secure Connection Debug Keys for testing"); 5614db88441fSMatthias Ringwald sm_sc_debug_keys_enabled = true; 5615db88441fSMatthias Ringwald // set debug key 5616db88441fSMatthias Ringwald sm_ec_generate_new_key(); 5617db88441fSMatthias Ringwald } 5618db88441fSMatthias Ringwald #endif 5619db88441fSMatthias Ringwald 5620052bbdc5SMatthias Ringwald const uint8_t * gap_get_persistent_irk(void){ 5621052bbdc5SMatthias Ringwald return sm_persistent_irk; 5622052bbdc5SMatthias Ringwald } 56234f384501SMatthias Ringwald 56244f384501SMatthias Ringwald void gap_delete_bonding(bd_addr_type_t address_type, bd_addr_t address){ 562522cb578bSMatthias Ringwald int index = sm_le_device_db_index_lookup(address_type, address); 562622cb578bSMatthias Ringwald if (index >= 0){ 562722cb578bSMatthias Ringwald sm_remove_le_device_db_entry(index); 56284f384501SMatthias Ringwald } 56294f384501SMatthias Ringwald } 5630