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){ 437cc95824cSDirk Helbig UNUSED(name); 438cc95824cSDirk Helbig UNUSED(value); 4393deb3ec6SMatthias Ringwald log_info("%-6s 0x%04x", name, value); 4403deb3ec6SMatthias Ringwald } 4413deb3ec6SMatthias Ringwald 4421fbd72c5SMatthias Ringwald // static inline uint8_t sm_pairing_packet_get_code(sm_pairing_packet_t packet){ 4431fbd72c5SMatthias Ringwald // return packet[0]; 4441fbd72c5SMatthias Ringwald // } 4451fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_io_capability(sm_pairing_packet_t packet){ 4461fbd72c5SMatthias Ringwald return packet[1]; 4471fbd72c5SMatthias Ringwald } 4481fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_oob_data_flag(sm_pairing_packet_t packet){ 4491fbd72c5SMatthias Ringwald return packet[2]; 4501fbd72c5SMatthias Ringwald } 4511fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_auth_req(sm_pairing_packet_t packet){ 4521fbd72c5SMatthias Ringwald return packet[3]; 4531fbd72c5SMatthias Ringwald } 4541fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_max_encryption_key_size(sm_pairing_packet_t packet){ 4551fbd72c5SMatthias Ringwald return packet[4]; 4561fbd72c5SMatthias Ringwald } 4571fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_initiator_key_distribution(sm_pairing_packet_t packet){ 4581fbd72c5SMatthias Ringwald return packet[5]; 4591fbd72c5SMatthias Ringwald } 4601fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_responder_key_distribution(sm_pairing_packet_t packet){ 4611fbd72c5SMatthias Ringwald return packet[6]; 4621fbd72c5SMatthias Ringwald } 4631fbd72c5SMatthias Ringwald 4641fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_code(sm_pairing_packet_t packet, uint8_t code){ 4651fbd72c5SMatthias Ringwald packet[0] = code; 4661fbd72c5SMatthias Ringwald } 4671fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_io_capability(sm_pairing_packet_t packet, uint8_t io_capability){ 4681fbd72c5SMatthias Ringwald packet[1] = io_capability; 4691fbd72c5SMatthias Ringwald } 4701fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_oob_data_flag(sm_pairing_packet_t packet, uint8_t oob_data_flag){ 4711fbd72c5SMatthias Ringwald packet[2] = oob_data_flag; 4721fbd72c5SMatthias Ringwald } 4731fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_auth_req(sm_pairing_packet_t packet, uint8_t auth_req){ 4741fbd72c5SMatthias Ringwald packet[3] = auth_req; 4751fbd72c5SMatthias Ringwald } 4761fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_max_encryption_key_size(sm_pairing_packet_t packet, uint8_t max_encryption_key_size){ 4771fbd72c5SMatthias Ringwald packet[4] = max_encryption_key_size; 4781fbd72c5SMatthias Ringwald } 4791fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_initiator_key_distribution(sm_pairing_packet_t packet, uint8_t initiator_key_distribution){ 4801fbd72c5SMatthias Ringwald packet[5] = initiator_key_distribution; 4811fbd72c5SMatthias Ringwald } 4821fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_responder_key_distribution(sm_pairing_packet_t packet, uint8_t responder_key_distribution){ 4831fbd72c5SMatthias Ringwald packet[6] = responder_key_distribution; 4841fbd72c5SMatthias Ringwald } 4851fbd72c5SMatthias Ringwald 4861979f09cSMatthias Ringwald static bool sm_is_null_random(uint8_t random[8]){ 48724c4191dSMatthias Ringwald return btstack_is_null(random, 8); 4883764b551SMatthias Ringwald } 4893764b551SMatthias Ringwald 4901979f09cSMatthias Ringwald static bool sm_is_null_key(uint8_t * key){ 49124c4191dSMatthias Ringwald return btstack_is_null(key, 16); 4923764b551SMatthias Ringwald } 4933764b551SMatthias Ringwald 4941c34405fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4951c34405fSMatthias Ringwald static bool sm_is_ff(const uint8_t * buffer, uint16_t size){ 4961c34405fSMatthias Ringwald uint16_t i; 4971c34405fSMatthias Ringwald for (i=0; i < size ; i++){ 4981c34405fSMatthias Ringwald if (buffer[i] != 0xff) { 4991c34405fSMatthias Ringwald return false; 5001c34405fSMatthias Ringwald } 5011c34405fSMatthias Ringwald } 5021c34405fSMatthias Ringwald return true; 5031c34405fSMatthias Ringwald } 5041c34405fSMatthias Ringwald #endif 5051c34405fSMatthias Ringwald 50670b44dd4SMatthias Ringwald // sm_trigger_run allows to schedule callback from main run loop // reduces stack depth 50770b44dd4SMatthias Ringwald static void sm_run_timer_handler(btstack_timer_source_t * ts){ 50870b44dd4SMatthias Ringwald UNUSED(ts); 50970b44dd4SMatthias Ringwald sm_run(); 51070b44dd4SMatthias Ringwald } 51170b44dd4SMatthias Ringwald static void sm_trigger_run(void){ 5122d2d4d3cSMatthias Ringwald if (!sm_initialized) return; 51384c0c5c7SMatthias Ringwald (void)btstack_run_loop_remove_timer(&sm_run_timer); 51470b44dd4SMatthias Ringwald btstack_run_loop_set_timer(&sm_run_timer, 0); 51570b44dd4SMatthias Ringwald btstack_run_loop_add_timer(&sm_run_timer); 51670b44dd4SMatthias Ringwald } 51770b44dd4SMatthias Ringwald 5183deb3ec6SMatthias Ringwald // Key utils 5193deb3ec6SMatthias Ringwald static void sm_reset_tk(void){ 5203deb3ec6SMatthias Ringwald int i; 5213deb3ec6SMatthias Ringwald for (i=0;i<16;i++){ 5223deb3ec6SMatthias Ringwald setup->sm_tk[i] = 0; 5233deb3ec6SMatthias Ringwald } 5243deb3ec6SMatthias Ringwald } 5253deb3ec6SMatthias Ringwald 5263deb3ec6SMatthias Ringwald // "For example, if a 128-bit encryption key is 0x123456789ABCDEF0123456789ABCDEF0 5273deb3ec6SMatthias Ringwald // and it is reduced to 7 octets (56 bits), then the resulting key is 0x0000000000000000003456789ABCDEF0."" 5283deb3ec6SMatthias Ringwald static void sm_truncate_key(sm_key_t key, int max_encryption_size){ 5293deb3ec6SMatthias Ringwald int i; 5303deb3ec6SMatthias Ringwald for (i = max_encryption_size ; i < 16 ; i++){ 5313deb3ec6SMatthias Ringwald key[15-i] = 0; 5323deb3ec6SMatthias Ringwald } 5333deb3ec6SMatthias Ringwald } 5343deb3ec6SMatthias Ringwald 535899e6e02SMatthias Ringwald // ER / IR checks 53621045273SMatthias Ringwald static void sm_er_ir_set_default(void){ 537899e6e02SMatthias Ringwald int i; 538899e6e02SMatthias Ringwald for (i=0;i<16;i++){ 539899e6e02SMatthias Ringwald sm_persistent_er[i] = 0x30 + i; 540899e6e02SMatthias Ringwald sm_persistent_ir[i] = 0x90 + i; 541899e6e02SMatthias Ringwald } 542899e6e02SMatthias Ringwald } 543899e6e02SMatthias Ringwald 5441d80f1e6SMatthias Ringwald static bool sm_er_is_default(void){ 545899e6e02SMatthias Ringwald int i; 546899e6e02SMatthias Ringwald for (i=0;i<16;i++){ 5471d80f1e6SMatthias Ringwald if (sm_persistent_er[i] != (0x30+i)) return true; 548899e6e02SMatthias Ringwald } 5491d80f1e6SMatthias Ringwald return false; 550899e6e02SMatthias Ringwald } 551899e6e02SMatthias Ringwald 5521d80f1e6SMatthias Ringwald static bool sm_ir_is_default(void){ 553899e6e02SMatthias Ringwald int i; 554899e6e02SMatthias Ringwald for (i=0;i<16;i++){ 5551d80f1e6SMatthias Ringwald if (sm_persistent_ir[i] != (0x90+i)) return true; 556899e6e02SMatthias Ringwald } 5571d80f1e6SMatthias Ringwald return false; 558899e6e02SMatthias Ringwald } 559899e6e02SMatthias Ringwald 56073102768SMatthias Ringwald static void sm_dispatch_event(uint8_t packet_type, uint16_t channel, uint8_t * packet, uint16_t size){ 56173102768SMatthias Ringwald UNUSED(channel); 56273102768SMatthias Ringwald 56373102768SMatthias Ringwald // log event 5649da9850bSMatthias Ringwald hci_dump_btstack_event(packet, size); 56573102768SMatthias Ringwald // dispatch to all event handlers 56673102768SMatthias Ringwald btstack_linked_list_iterator_t it; 56773102768SMatthias Ringwald btstack_linked_list_iterator_init(&it, &sm_event_handlers); 56873102768SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&it)){ 56973102768SMatthias Ringwald btstack_packet_callback_registration_t * entry = (btstack_packet_callback_registration_t*) btstack_linked_list_iterator_next(&it); 57073102768SMatthias Ringwald entry->callback(packet_type, 0, packet, size); 57173102768SMatthias Ringwald } 57273102768SMatthias Ringwald } 57373102768SMatthias Ringwald 57473102768SMatthias 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){ 57573102768SMatthias Ringwald event[0] = type; 57673102768SMatthias Ringwald event[1] = event_size - 2; 57773102768SMatthias Ringwald little_endian_store_16(event, 2, con_handle); 57873102768SMatthias Ringwald event[4] = addr_type; 57973102768SMatthias Ringwald reverse_bd_addr(address, &event[5]); 58073102768SMatthias Ringwald } 58173102768SMatthias Ringwald 58273102768SMatthias Ringwald static void sm_notify_client_base(uint8_t type, hci_con_handle_t con_handle, uint8_t addr_type, bd_addr_t address){ 58373102768SMatthias Ringwald uint8_t event[11]; 58473102768SMatthias Ringwald sm_setup_event_base(event, sizeof(event), type, con_handle, addr_type, address); 58573102768SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, event, sizeof(event)); 58673102768SMatthias Ringwald } 58773102768SMatthias Ringwald 58873102768SMatthias 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){ 58973102768SMatthias Ringwald // fetch addr and addr type from db, only called for valid entries 59073102768SMatthias Ringwald bd_addr_t identity_address; 59173102768SMatthias Ringwald int identity_address_type; 59273102768SMatthias Ringwald le_device_db_info(index, &identity_address_type, identity_address, NULL); 59373102768SMatthias Ringwald 59473102768SMatthias Ringwald uint8_t event[20]; 59573102768SMatthias Ringwald sm_setup_event_base(event, sizeof(event), type, con_handle, addr_type, address); 59673102768SMatthias Ringwald event[11] = identity_address_type; 59773102768SMatthias Ringwald reverse_bd_addr(identity_address, &event[12]); 59873102768SMatthias Ringwald little_endian_store_16(event, 18, index); 59973102768SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, event, sizeof(event)); 60073102768SMatthias Ringwald } 60173102768SMatthias Ringwald 60273102768SMatthias 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){ 60373102768SMatthias Ringwald uint8_t event[12]; 60473102768SMatthias Ringwald sm_setup_event_base(event, sizeof(event), type, con_handle, addr_type, address); 60573102768SMatthias Ringwald event[11] = status; 60673102768SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, (uint8_t*) &event, sizeof(event)); 60773102768SMatthias Ringwald } 60873102768SMatthias Ringwald 60973102768SMatthias Ringwald 61073102768SMatthias Ringwald static void sm_reencryption_started(sm_connection_t * sm_conn){ 61173102768SMatthias Ringwald 6123ab61f77SMatthias Ringwald if (sm_conn->sm_reencryption_active) return; 6133ab61f77SMatthias Ringwald 6147b001f4eSMatthias Ringwald sm_conn->sm_reencryption_active = true; 61573102768SMatthias Ringwald 61673102768SMatthias Ringwald int identity_addr_type; 61773102768SMatthias Ringwald bd_addr_t identity_addr; 6183c0e26deSMatthias Ringwald if (sm_conn->sm_le_db_index >= 0){ 6193c0e26deSMatthias Ringwald // fetch addr and addr type from db, only called for valid entries 62073102768SMatthias Ringwald le_device_db_info(sm_conn->sm_le_db_index, &identity_addr_type, identity_addr, NULL); 6213c0e26deSMatthias Ringwald } else { 6223c0e26deSMatthias Ringwald // for legacy pairing with LTK re-construction, use current peer addr 6233c0e26deSMatthias Ringwald identity_addr_type = sm_conn->sm_peer_addr_type; 624d5529700SMatthias Ringwald // cppcheck-suppress uninitvar ; identity_addr is reported as uninitialized although it's the destination of the memcpy 6253c0e26deSMatthias Ringwald memcpy(identity_addr, sm_conn->sm_peer_address, 6); 6263c0e26deSMatthias Ringwald } 62773102768SMatthias Ringwald 62873102768SMatthias Ringwald sm_notify_client_base(SM_EVENT_REENCRYPTION_STARTED, sm_conn->sm_handle, identity_addr_type, identity_addr); 62973102768SMatthias Ringwald } 63073102768SMatthias Ringwald 63173102768SMatthias Ringwald static void sm_reencryption_complete(sm_connection_t * sm_conn, uint8_t status){ 63273102768SMatthias Ringwald 63360be5b21SMatthias Ringwald if (!sm_conn->sm_reencryption_active) return; 63460be5b21SMatthias Ringwald 6357b001f4eSMatthias Ringwald sm_conn->sm_reencryption_active = false; 63673102768SMatthias Ringwald 63773102768SMatthias Ringwald int identity_addr_type; 63873102768SMatthias Ringwald bd_addr_t identity_addr; 6393c0e26deSMatthias Ringwald if (sm_conn->sm_le_db_index >= 0){ 6403c0e26deSMatthias Ringwald // fetch addr and addr type from db, only called for valid entries 64173102768SMatthias Ringwald le_device_db_info(sm_conn->sm_le_db_index, &identity_addr_type, identity_addr, NULL); 6423c0e26deSMatthias Ringwald } else { 6433c0e26deSMatthias Ringwald // for legacy pairing with LTK re-construction, use current peer addr 6443c0e26deSMatthias Ringwald identity_addr_type = sm_conn->sm_peer_addr_type; 645d5529700SMatthias Ringwald // cppcheck-suppress uninitvar ; identity_addr is reported as uninitialized although it's the destination of the memcpy 6463c0e26deSMatthias Ringwald memcpy(identity_addr, sm_conn->sm_peer_address, 6); 6473c0e26deSMatthias Ringwald } 64873102768SMatthias Ringwald 64973102768SMatthias Ringwald sm_notify_client_status(SM_EVENT_REENCRYPTION_COMPLETE, sm_conn->sm_handle, identity_addr_type, identity_addr, status); 65073102768SMatthias Ringwald } 65173102768SMatthias Ringwald 652d3c12277SMatthias Ringwald static void sm_pairing_started(sm_connection_t * sm_conn){ 653d3c12277SMatthias Ringwald 654d3c12277SMatthias Ringwald if (sm_conn->sm_pairing_active) return; 655d3c12277SMatthias Ringwald 656d3c12277SMatthias Ringwald sm_conn->sm_pairing_active = true; 657d3c12277SMatthias Ringwald 658d3c12277SMatthias Ringwald uint8_t event[11]; 659d3c12277SMatthias 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); 660d3c12277SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, (uint8_t*) &event, sizeof(event)); 661d3c12277SMatthias Ringwald } 662d3c12277SMatthias Ringwald 6630ccf6c9cSMatthias Ringwald static void sm_pairing_complete(sm_connection_t * sm_conn, uint8_t status, uint8_t reason){ 664f61072f5SMatthias Ringwald 665d77906ffSMatthias Ringwald if (!sm_conn->sm_pairing_active) return; 666d77906ffSMatthias Ringwald 66769f82ad8SMatthias Ringwald sm_conn->sm_pairing_active = false; 66869f82ad8SMatthias Ringwald 6690ccf6c9cSMatthias Ringwald uint8_t event[13]; 6700ccf6c9cSMatthias 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); 6710ccf6c9cSMatthias Ringwald event[11] = status; 6720ccf6c9cSMatthias Ringwald event[12] = reason; 6730ccf6c9cSMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, (uint8_t*) &event, sizeof(event)); 6740ccf6c9cSMatthias Ringwald } 6750ccf6c9cSMatthias Ringwald 6763deb3ec6SMatthias Ringwald // SMP Timeout implementation 6773deb3ec6SMatthias Ringwald 6783deb3ec6SMatthias Ringwald // Upon transmission of the Pairing Request command or reception of the Pairing Request command, 6793deb3ec6SMatthias Ringwald // the Security Manager Timer shall be reset and started. 6803deb3ec6SMatthias Ringwald // 6813deb3ec6SMatthias Ringwald // The Security Manager Timer shall be reset when an L2CAP SMP command is queued for transmission. 6823deb3ec6SMatthias Ringwald // 6833deb3ec6SMatthias Ringwald // If the Security Manager Timer reaches 30 seconds, the procedure shall be considered to have failed, 6843deb3ec6SMatthias Ringwald // and the local higher layer shall be notified. No further SMP commands shall be sent over the L2CAP 6853deb3ec6SMatthias Ringwald // Security Manager Channel. A new SM procedure shall only be performed when a new physical link has been 6863deb3ec6SMatthias Ringwald // established. 6873deb3ec6SMatthias Ringwald 688ec820d77SMatthias Ringwald static void sm_timeout_handler(btstack_timer_source_t * timer){ 6893deb3ec6SMatthias Ringwald log_info("SM timeout"); 690c5b64319SMatthias Ringwald sm_connection_t * sm_conn = (sm_connection_t*) btstack_run_loop_get_timer_context(timer); 6913deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_TIMEOUT; 69268a18fb9SMatthias Ringwald sm_reencryption_complete(sm_conn, ERROR_CODE_CONNECTION_TIMEOUT); 6930ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_CONNECTION_TIMEOUT, 0); 6943deb3ec6SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 6953deb3ec6SMatthias Ringwald 6963deb3ec6SMatthias Ringwald // trigger handling of next ready connection 6973deb3ec6SMatthias Ringwald sm_run(); 6983deb3ec6SMatthias Ringwald } 6993deb3ec6SMatthias Ringwald static void sm_timeout_start(sm_connection_t * sm_conn){ 700528a4a3bSMatthias Ringwald btstack_run_loop_remove_timer(&setup->sm_timeout); 70191a977e8SMatthias Ringwald btstack_run_loop_set_timer_context(&setup->sm_timeout, sm_conn); 702528a4a3bSMatthias Ringwald btstack_run_loop_set_timer_handler(&setup->sm_timeout, sm_timeout_handler); 703528a4a3bSMatthias Ringwald btstack_run_loop_set_timer(&setup->sm_timeout, 30000); // 30 seconds sm timeout 704528a4a3bSMatthias Ringwald btstack_run_loop_add_timer(&setup->sm_timeout); 7053deb3ec6SMatthias Ringwald } 7063deb3ec6SMatthias Ringwald static void sm_timeout_stop(void){ 707528a4a3bSMatthias Ringwald btstack_run_loop_remove_timer(&setup->sm_timeout); 7083deb3ec6SMatthias Ringwald } 7093deb3ec6SMatthias Ringwald static void sm_timeout_reset(sm_connection_t * sm_conn){ 7103deb3ec6SMatthias Ringwald sm_timeout_stop(); 7113deb3ec6SMatthias Ringwald sm_timeout_start(sm_conn); 7123deb3ec6SMatthias Ringwald } 7133deb3ec6SMatthias Ringwald 7143deb3ec6SMatthias Ringwald // end of sm timeout 7153deb3ec6SMatthias Ringwald 7163deb3ec6SMatthias Ringwald // GAP Random Address updates 7173deb3ec6SMatthias Ringwald static gap_random_address_type_t gap_random_adress_type; 718ec820d77SMatthias Ringwald static btstack_timer_source_t gap_random_address_update_timer; 7193deb3ec6SMatthias Ringwald static uint32_t gap_random_adress_update_period; 7203deb3ec6SMatthias Ringwald 7213deb3ec6SMatthias Ringwald static void gap_random_address_trigger(void){ 722899e6e02SMatthias Ringwald log_info("gap_random_address_trigger, state %u", rau_state); 723d1a1f6a4SMatthias Ringwald if (rau_state != RAU_IDLE) return; 724fbd4e238SMatthias Ringwald rau_state = RAU_GET_RANDOM; 72570b44dd4SMatthias Ringwald sm_trigger_run(); 7263deb3ec6SMatthias Ringwald } 7273deb3ec6SMatthias Ringwald 728ec820d77SMatthias Ringwald static void gap_random_address_update_handler(btstack_timer_source_t * timer){ 7299ec2630cSMatthias Ringwald UNUSED(timer); 7309ec2630cSMatthias Ringwald 7313deb3ec6SMatthias Ringwald log_info("GAP Random Address Update due"); 732528a4a3bSMatthias Ringwald btstack_run_loop_set_timer(&gap_random_address_update_timer, gap_random_adress_update_period); 733528a4a3bSMatthias Ringwald btstack_run_loop_add_timer(&gap_random_address_update_timer); 7343deb3ec6SMatthias Ringwald gap_random_address_trigger(); 7353deb3ec6SMatthias Ringwald } 7363deb3ec6SMatthias Ringwald 7373deb3ec6SMatthias Ringwald static void gap_random_address_update_start(void){ 738528a4a3bSMatthias Ringwald btstack_run_loop_set_timer_handler(&gap_random_address_update_timer, gap_random_address_update_handler); 739528a4a3bSMatthias Ringwald btstack_run_loop_set_timer(&gap_random_address_update_timer, gap_random_adress_update_period); 740528a4a3bSMatthias Ringwald btstack_run_loop_add_timer(&gap_random_address_update_timer); 7413deb3ec6SMatthias Ringwald } 7423deb3ec6SMatthias Ringwald 7433deb3ec6SMatthias Ringwald static void gap_random_address_update_stop(void){ 744528a4a3bSMatthias Ringwald btstack_run_loop_remove_timer(&gap_random_address_update_timer); 7453deb3ec6SMatthias Ringwald } 7463deb3ec6SMatthias Ringwald 7473deb3ec6SMatthias Ringwald // ah(k,r) helper 7483deb3ec6SMatthias Ringwald // r = padding || r 7493deb3ec6SMatthias Ringwald // r - 24 bit value 7504a6806f3SMatthias Ringwald static void sm_ah_r_prime(uint8_t r[3], uint8_t * r_prime){ 7513deb3ec6SMatthias Ringwald // r'= padding || r 7523deb3ec6SMatthias Ringwald memset(r_prime, 0, 16); 7536535961aSMatthias Ringwald (void)memcpy(&r_prime[13], r, 3); 7543deb3ec6SMatthias Ringwald } 7553deb3ec6SMatthias Ringwald 7563deb3ec6SMatthias Ringwald // d1 helper 7573deb3ec6SMatthias Ringwald // d' = padding || r || d 7583deb3ec6SMatthias Ringwald // d,r - 16 bit values 7594a6806f3SMatthias Ringwald static void sm_d1_d_prime(uint16_t d, uint16_t r, uint8_t * d1_prime){ 7603deb3ec6SMatthias Ringwald // d'= padding || r || d 7613deb3ec6SMatthias Ringwald memset(d1_prime, 0, 16); 762f8fbdce0SMatthias Ringwald big_endian_store_16(d1_prime, 12, r); 763f8fbdce0SMatthias Ringwald big_endian_store_16(d1_prime, 14, d); 7643deb3ec6SMatthias Ringwald } 7653deb3ec6SMatthias Ringwald 7663deb3ec6SMatthias Ringwald // calculate arguments for first AES128 operation in C1 function 7674a6806f3SMatthias 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){ 7683deb3ec6SMatthias Ringwald 7693deb3ec6SMatthias Ringwald // p1 = pres || preq || rat’ || iat’ 7703deb3ec6SMatthias Ringwald // "The octet of iat’ becomes the least significant octet of p1 and the most signifi- 7713deb3ec6SMatthias Ringwald // cant octet of pres becomes the most significant octet of p1. 7723deb3ec6SMatthias Ringwald // For example, if the 8-bit iat’ is 0x01, the 8-bit rat’ is 0x00, the 56-bit preq 7733deb3ec6SMatthias Ringwald // is 0x07071000000101 and the 56 bit pres is 0x05000800000302 then 7743deb3ec6SMatthias Ringwald // p1 is 0x05000800000302070710000001010001." 7753deb3ec6SMatthias Ringwald 7763deb3ec6SMatthias Ringwald sm_key_t p1; 7779c80e4ccSMatthias Ringwald reverse_56(pres, &p1[0]); 7789c80e4ccSMatthias Ringwald reverse_56(preq, &p1[7]); 7793deb3ec6SMatthias Ringwald p1[14] = rat; 7803deb3ec6SMatthias Ringwald p1[15] = iat; 7818314c363SMatthias Ringwald log_info_key("p1", p1); 7828314c363SMatthias Ringwald log_info_key("r", r); 7833deb3ec6SMatthias Ringwald 7843deb3ec6SMatthias Ringwald // t1 = r xor p1 7853deb3ec6SMatthias Ringwald int i; 7863deb3ec6SMatthias Ringwald for (i=0;i<16;i++){ 7873deb3ec6SMatthias Ringwald t1[i] = r[i] ^ p1[i]; 7883deb3ec6SMatthias Ringwald } 7898314c363SMatthias Ringwald log_info_key("t1", t1); 7903deb3ec6SMatthias Ringwald } 7913deb3ec6SMatthias Ringwald 7923deb3ec6SMatthias Ringwald // calculate arguments for second AES128 operation in C1 function 7934a6806f3SMatthias Ringwald static void sm_c1_t3(sm_key_t t2, bd_addr_t ia, bd_addr_t ra, uint8_t * t3){ 7943deb3ec6SMatthias Ringwald // p2 = padding || ia || ra 7953deb3ec6SMatthias Ringwald // "The least significant octet of ra becomes the least significant octet of p2 and 7963deb3ec6SMatthias Ringwald // the most significant octet of padding becomes the most significant octet of p2. 7973deb3ec6SMatthias Ringwald // For example, if 48-bit ia is 0xA1A2A3A4A5A6 and the 48-bit ra is 7983deb3ec6SMatthias Ringwald // 0xB1B2B3B4B5B6 then p2 is 0x00000000A1A2A3A4A5A6B1B2B3B4B5B6. 7993deb3ec6SMatthias Ringwald 8003deb3ec6SMatthias Ringwald sm_key_t p2; 801d5529700SMatthias Ringwald // cppcheck-suppress uninitvar ; p2 is reported as uninitialized 8023deb3ec6SMatthias Ringwald memset(p2, 0, 16); 8036535961aSMatthias Ringwald (void)memcpy(&p2[4], ia, 6); 8046535961aSMatthias Ringwald (void)memcpy(&p2[10], ra, 6); 8058314c363SMatthias Ringwald log_info_key("p2", p2); 8063deb3ec6SMatthias Ringwald 8073deb3ec6SMatthias Ringwald // c1 = e(k, t2_xor_p2) 8083deb3ec6SMatthias Ringwald int i; 8093deb3ec6SMatthias Ringwald for (i=0;i<16;i++){ 8103deb3ec6SMatthias Ringwald t3[i] = t2[i] ^ p2[i]; 8113deb3ec6SMatthias Ringwald } 8128314c363SMatthias Ringwald log_info_key("t3", t3); 8133deb3ec6SMatthias Ringwald } 8143deb3ec6SMatthias Ringwald 8154a6806f3SMatthias Ringwald static void sm_s1_r_prime(sm_key_t r1, sm_key_t r2, uint8_t * r_prime){ 8168314c363SMatthias Ringwald log_info_key("r1", r1); 8178314c363SMatthias Ringwald log_info_key("r2", r2); 8186535961aSMatthias Ringwald (void)memcpy(&r_prime[8], &r2[8], 8); 8196535961aSMatthias Ringwald (void)memcpy(&r_prime[0], &r1[8], 8); 8203deb3ec6SMatthias Ringwald } 8213deb3ec6SMatthias Ringwald 822fbe050beSMatthias Ringwald 8233deb3ec6SMatthias Ringwald // decide on stk generation based on 8243deb3ec6SMatthias Ringwald // - pairing request 8253deb3ec6SMatthias Ringwald // - io capabilities 8263deb3ec6SMatthias Ringwald // - OOB data availability 8273deb3ec6SMatthias Ringwald static void sm_setup_tk(void){ 8283deb3ec6SMatthias Ringwald 8298334d3d8SMatthias Ringwald // horizontal: initiator capabilities 8308334d3d8SMatthias Ringwald // vertial: responder capabilities 8318334d3d8SMatthias Ringwald static const stk_generation_method_t stk_generation_method [5] [5] = { 8328334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, PK_INIT_INPUT, JUST_WORKS, PK_INIT_INPUT }, 8338334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, PK_INIT_INPUT, JUST_WORKS, PK_INIT_INPUT }, 8348334d3d8SMatthias Ringwald { PK_RESP_INPUT, PK_RESP_INPUT, PK_BOTH_INPUT, JUST_WORKS, PK_RESP_INPUT }, 8358334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS }, 8368334d3d8SMatthias Ringwald { PK_RESP_INPUT, PK_RESP_INPUT, PK_INIT_INPUT, JUST_WORKS, PK_RESP_INPUT }, 8378334d3d8SMatthias Ringwald }; 8388334d3d8SMatthias Ringwald 8398334d3d8SMatthias Ringwald // uses numeric comparison if one side has DisplayYesNo and KeyboardDisplay combinations 8408334d3d8SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 8418334d3d8SMatthias Ringwald static const stk_generation_method_t stk_generation_method_with_secure_connection[5][5] = { 8428334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, PK_INIT_INPUT, JUST_WORKS, PK_INIT_INPUT }, 8438334d3d8SMatthias Ringwald { JUST_WORKS, NUMERIC_COMPARISON, PK_INIT_INPUT, JUST_WORKS, NUMERIC_COMPARISON }, 8448334d3d8SMatthias Ringwald { PK_RESP_INPUT, PK_RESP_INPUT, PK_BOTH_INPUT, JUST_WORKS, PK_RESP_INPUT }, 8458334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS }, 8468334d3d8SMatthias Ringwald { PK_RESP_INPUT, NUMERIC_COMPARISON, PK_INIT_INPUT, JUST_WORKS, NUMERIC_COMPARISON }, 8478334d3d8SMatthias Ringwald }; 8488334d3d8SMatthias Ringwald #endif 8498334d3d8SMatthias Ringwald 8503deb3ec6SMatthias Ringwald // default: just works 8513deb3ec6SMatthias Ringwald setup->sm_stk_generation_method = JUST_WORKS; 8523deb3ec6SMatthias Ringwald 85327c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 85427c32905SMatthias Ringwald setup->sm_use_secure_connections = ( sm_pairing_packet_get_auth_req(setup->sm_m_preq) 85527c32905SMatthias Ringwald & sm_pairing_packet_get_auth_req(setup->sm_s_pres) 8564ea43905SMatthias Ringwald & SM_AUTHREQ_SECURE_CONNECTION ) != 0u; 85727c32905SMatthias Ringwald #else 8586777d8fdSMatthias Ringwald setup->sm_use_secure_connections = false; 85927c32905SMatthias Ringwald #endif 86098d95509SMatthias Ringwald log_info("Secure pairing: %u", setup->sm_use_secure_connections); 86127c32905SMatthias Ringwald 86265a9a04eSMatthias Ringwald 86365a9a04eSMatthias Ringwald // decide if OOB will be used based on SC vs. Legacy and oob flags 8641979f09cSMatthias Ringwald bool use_oob; 86565a9a04eSMatthias Ringwald if (setup->sm_use_secure_connections){ 86665a9a04eSMatthias Ringwald // In LE Secure Connections pairing, the out of band method is used if at least 86765a9a04eSMatthias Ringwald // one device has the peer device's out of band authentication data available. 8681979f09cSMatthias 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; 86965a9a04eSMatthias Ringwald } else { 87065a9a04eSMatthias Ringwald // In LE legacy pairing, the out of band method is used if both the devices have 87165a9a04eSMatthias Ringwald // the other device's out of band authentication data available. 8721979f09cSMatthias 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; 87365a9a04eSMatthias Ringwald } 87465a9a04eSMatthias Ringwald if (use_oob){ 87565a9a04eSMatthias Ringwald log_info("SM: have OOB data"); 87665a9a04eSMatthias Ringwald log_info_key("OOB", setup->sm_tk); 87765a9a04eSMatthias Ringwald setup->sm_stk_generation_method = OOB; 87865a9a04eSMatthias Ringwald return; 87965a9a04eSMatthias Ringwald } 88065a9a04eSMatthias Ringwald 88127c32905SMatthias Ringwald // If both devices have not set the MITM option in the Authentication Requirements 88227c32905SMatthias Ringwald // Flags, then the IO capabilities shall be ignored and the Just Works association 88327c32905SMatthias Ringwald // model shall be used. 8844ea43905SMatthias Ringwald if (((sm_pairing_packet_get_auth_req(setup->sm_m_preq) & SM_AUTHREQ_MITM_PROTECTION) == 0u) 8854ea43905SMatthias Ringwald && ((sm_pairing_packet_get_auth_req(setup->sm_s_pres) & SM_AUTHREQ_MITM_PROTECTION) == 0u)){ 88627c32905SMatthias Ringwald log_info("SM: MITM not required by both -> JUST WORKS"); 88727c32905SMatthias Ringwald return; 88827c32905SMatthias Ringwald } 88927c32905SMatthias Ringwald 8903deb3ec6SMatthias Ringwald // Reset TK as it has been setup in sm_init_setup 8913deb3ec6SMatthias Ringwald sm_reset_tk(); 8923deb3ec6SMatthias Ringwald 8933deb3ec6SMatthias Ringwald // Also use just works if unknown io capabilites 8948da2e96dSMatthias 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)){ 8953deb3ec6SMatthias Ringwald return; 8963deb3ec6SMatthias Ringwald } 8973deb3ec6SMatthias Ringwald 8983deb3ec6SMatthias Ringwald // Otherwise the IO capabilities of the devices shall be used to determine the 8993deb3ec6SMatthias Ringwald // pairing method as defined in Table 2.4. 90027c32905SMatthias Ringwald // see http://stackoverflow.com/a/1052837/393697 for how to specify pointer to 2-dimensional array 90127c32905SMatthias Ringwald const stk_generation_method_t (*generation_method)[5] = stk_generation_method; 90227c32905SMatthias Ringwald 90327c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 904c6b7cbd9SMatthias Ringwald // table not define by default 90527c32905SMatthias Ringwald if (setup->sm_use_secure_connections){ 90627c32905SMatthias Ringwald generation_method = stk_generation_method_with_secure_connection; 90727c32905SMatthias Ringwald } 90827c32905SMatthias Ringwald #endif 90927c32905SMatthias 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)]; 91027c32905SMatthias Ringwald 9113deb3ec6SMatthias Ringwald log_info("sm_setup_tk: master io cap: %u, slave io cap: %u -> method %u", 9121ad129beSMatthias 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); 9133deb3ec6SMatthias Ringwald } 9143deb3ec6SMatthias Ringwald 9153deb3ec6SMatthias Ringwald static int sm_key_distribution_flags_for_set(uint8_t key_set){ 9163deb3ec6SMatthias Ringwald int flags = 0; 917f688bdb8SMatthias Ringwald if ((key_set & SM_KEYDIST_ENC_KEY) != 0u){ 9183deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 9193deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 9203deb3ec6SMatthias Ringwald } 921f688bdb8SMatthias Ringwald if ((key_set & SM_KEYDIST_ID_KEY) != 0u){ 9223deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 9233deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 9243deb3ec6SMatthias Ringwald } 925f688bdb8SMatthias Ringwald if ((key_set & SM_KEYDIST_SIGN) != 0u){ 9263deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 9273deb3ec6SMatthias Ringwald } 9283deb3ec6SMatthias Ringwald return flags; 9293deb3ec6SMatthias Ringwald } 9303deb3ec6SMatthias Ringwald 9319a90d41aSMatthias Ringwald static void sm_setup_key_distribution(uint8_t keys_to_send, uint8_t keys_to_receive){ 9323deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set = 0; 9339a90d41aSMatthias Ringwald setup->sm_key_distribution_expected_set = sm_key_distribution_flags_for_set(keys_to_receive); 9349a90d41aSMatthias Ringwald setup->sm_key_distribution_send_set = sm_key_distribution_flags_for_set(keys_to_send); 935715a43d1SMatthias Ringwald setup->sm_key_distribution_sent_set = 0; 9369790be5fSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 937715a43d1SMatthias Ringwald setup->sm_le_device_index = -1; 9389790be5fSMatthias Ringwald #endif 9393deb3ec6SMatthias Ringwald } 9403deb3ec6SMatthias Ringwald 9413deb3ec6SMatthias Ringwald // CSRK Key Lookup 9423deb3ec6SMatthias Ringwald 9433deb3ec6SMatthias Ringwald 9441d80f1e6SMatthias Ringwald static bool sm_address_resolution_idle(void){ 9453deb3ec6SMatthias Ringwald return sm_address_resolution_mode == ADDRESS_RESOLUTION_IDLE; 9463deb3ec6SMatthias Ringwald } 9473deb3ec6SMatthias Ringwald 948711e6c80SMatthias 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){ 9496535961aSMatthias Ringwald (void)memcpy(sm_address_resolution_address, addr, 6); 9503deb3ec6SMatthias Ringwald sm_address_resolution_addr_type = addr_type; 9513deb3ec6SMatthias Ringwald sm_address_resolution_test = 0; 9523deb3ec6SMatthias Ringwald sm_address_resolution_mode = mode; 9533deb3ec6SMatthias Ringwald sm_address_resolution_context = context; 954711e6c80SMatthias Ringwald sm_notify_client_base(SM_EVENT_IDENTITY_RESOLVING_STARTED, con_handle, addr_type, addr); 9553deb3ec6SMatthias Ringwald } 9563deb3ec6SMatthias Ringwald 9573deb3ec6SMatthias Ringwald int sm_address_resolution_lookup(uint8_t address_type, bd_addr_t address){ 9583deb3ec6SMatthias Ringwald // check if already in list 959665d90f2SMatthias Ringwald btstack_linked_list_iterator_t it; 9603deb3ec6SMatthias Ringwald sm_lookup_entry_t * entry; 961665d90f2SMatthias Ringwald btstack_linked_list_iterator_init(&it, &sm_address_resolution_general_queue); 962665d90f2SMatthias Ringwald while(btstack_linked_list_iterator_has_next(&it)){ 963665d90f2SMatthias Ringwald entry = (sm_lookup_entry_t *) btstack_linked_list_iterator_next(&it); 9643deb3ec6SMatthias Ringwald if (entry->address_type != address_type) continue; 965f688bdb8SMatthias Ringwald if (memcmp(entry->address, address, 6) != 0) continue; 9663deb3ec6SMatthias Ringwald // already in list 9673deb3ec6SMatthias Ringwald return BTSTACK_BUSY; 9683deb3ec6SMatthias Ringwald } 9693deb3ec6SMatthias Ringwald entry = btstack_memory_sm_lookup_entry_get(); 9703deb3ec6SMatthias Ringwald if (!entry) return BTSTACK_MEMORY_ALLOC_FAILED; 9713deb3ec6SMatthias Ringwald entry->address_type = (bd_addr_type_t) address_type; 9726535961aSMatthias Ringwald (void)memcpy(entry->address, address, 6); 973665d90f2SMatthias Ringwald btstack_linked_list_add(&sm_address_resolution_general_queue, (btstack_linked_item_t *) entry); 97470b44dd4SMatthias Ringwald sm_trigger_run(); 9753deb3ec6SMatthias Ringwald return 0; 9763deb3ec6SMatthias Ringwald } 9773deb3ec6SMatthias Ringwald 978d1a1f6a4SMatthias Ringwald // CMAC calculation using AES Engineq 979d1a1f6a4SMatthias Ringwald #ifdef USE_CMAC_ENGINE 980514d35fcSMatthias Ringwald 981d1a1f6a4SMatthias Ringwald static void sm_cmac_done_trampoline(void * arg){ 982d1a1f6a4SMatthias Ringwald UNUSED(arg); 983d1a1f6a4SMatthias Ringwald sm_cmac_active = 0; 984d1a1f6a4SMatthias Ringwald (*sm_cmac_done_callback)(sm_cmac_hash); 98570b44dd4SMatthias Ringwald sm_trigger_run(); 9863deb3ec6SMatthias Ringwald } 987514d35fcSMatthias Ringwald 9884dfd504aSMatthias Ringwald int sm_cmac_ready(void){ 9894ea43905SMatthias Ringwald return sm_cmac_active == 0u; 9903deb3ec6SMatthias Ringwald } 9916d80b495SMatthias Ringwald #endif 9923deb3ec6SMatthias Ringwald 9936d80b495SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 994514d35fcSMatthias Ringwald // generic cmac calculation 995d1a1f6a4SMatthias 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)){ 996d1a1f6a4SMatthias Ringwald sm_cmac_active = 1; 997d1a1f6a4SMatthias Ringwald sm_cmac_done_callback = done_callback; 998d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_cmac_message(&sm_cmac_request, key, message_len, message, sm_cmac_hash, sm_cmac_done_trampoline, NULL); 9993deb3ec6SMatthias Ringwald } 10007a766ebfSMatthias Ringwald #endif 10013deb3ec6SMatthias Ringwald 1002514d35fcSMatthias Ringwald // cmac for ATT Message signing 10037a766ebfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 1004d1a1f6a4SMatthias Ringwald 1005d1a1f6a4SMatthias 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)){ 1006d1a1f6a4SMatthias Ringwald sm_cmac_active = 1; 1007d1a1f6a4SMatthias Ringwald sm_cmac_done_callback = done_callback; 1008d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_cmac_generator(&sm_cmac_request, key, message_len, get_byte_callback, sm_cmac_hash, sm_cmac_done_trampoline, NULL); 1009d1a1f6a4SMatthias Ringwald } 1010d1a1f6a4SMatthias Ringwald 10114dfd504aSMatthias Ringwald static uint8_t sm_cmac_signed_write_message_get_byte(uint16_t offset){ 1012d1a1f6a4SMatthias Ringwald if (offset >= sm_cmac_signed_write_message_len) { 1013d1a1f6a4SMatthias Ringwald log_error("sm_cmac_signed_write_message_get_byte. out of bounds, access %u, len %u", offset, sm_cmac_signed_write_message_len); 10144dfd504aSMatthias Ringwald return 0; 10154dfd504aSMatthias Ringwald } 10164dfd504aSMatthias Ringwald 1017d1a1f6a4SMatthias Ringwald offset = sm_cmac_signed_write_message_len - 1 - offset; 10184dfd504aSMatthias Ringwald 1019d1a1f6a4SMatthias Ringwald // sm_cmac_signed_write_header[3] | message[] | sm_cmac_signed_write_sign_counter[4] 10204dfd504aSMatthias Ringwald if (offset < 3){ 1021d1a1f6a4SMatthias Ringwald return sm_cmac_signed_write_header[offset]; 10224dfd504aSMatthias Ringwald } 1023d1a1f6a4SMatthias Ringwald int actual_message_len_incl_header = sm_cmac_signed_write_message_len - 4; 10244dfd504aSMatthias Ringwald if (offset < actual_message_len_incl_header){ 1025d1a1f6a4SMatthias Ringwald return sm_cmac_signed_write_message[offset - 3]; 10264dfd504aSMatthias Ringwald } 1027d1a1f6a4SMatthias Ringwald return sm_cmac_signed_write_sign_counter[offset - actual_message_len_incl_header]; 10284dfd504aSMatthias Ringwald } 10294dfd504aSMatthias Ringwald 10304dfd504aSMatthias 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)){ 1031514d35fcSMatthias Ringwald // ATT Message Signing 1032d1a1f6a4SMatthias Ringwald sm_cmac_signed_write_header[0] = opcode; 1033d1a1f6a4SMatthias Ringwald little_endian_store_16(sm_cmac_signed_write_header, 1, con_handle); 1034d1a1f6a4SMatthias Ringwald little_endian_store_32(sm_cmac_signed_write_sign_counter, 0, sign_counter); 1035514d35fcSMatthias Ringwald uint16_t total_message_len = 3 + message_len + 4; // incl. virtually prepended att opcode, handle and appended sign_counter in LE 1036d1a1f6a4SMatthias Ringwald sm_cmac_signed_write_message = message; 1037d1a1f6a4SMatthias Ringwald sm_cmac_signed_write_message_len = total_message_len; 1038d1a1f6a4SMatthias Ringwald sm_cmac_generator_start(k, total_message_len, &sm_cmac_signed_write_message_get_byte, done_handler); 10393deb3ec6SMatthias Ringwald } 10407a766ebfSMatthias Ringwald #endif 10413deb3ec6SMatthias Ringwald 1042ea9b6796SMatthias Ringwald static void sm_trigger_user_response_basic(sm_connection_t * sm_conn, uint8_t event_type){ 1043ea9b6796SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_PENDING; 10445baa755bSMatthias Ringwald uint8_t event[12]; 1045f6a153d5SMatthias 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); 10465baa755bSMatthias Ringwald event[11] = setup->sm_use_secure_connections ? 1 : 0; 1047f6a153d5SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, event, sizeof(event)); 1048ea9b6796SMatthias Ringwald } 1049ea9b6796SMatthias Ringwald 105074b4d42aSMatthias Ringwald static void sm_trigger_user_response_passkey(sm_connection_t * sm_conn, uint8_t event_type){ 10515baa755bSMatthias Ringwald uint8_t event[16]; 1052f6a153d5SMatthias Ringwald uint32_t passkey = big_endian_read_32(setup->sm_tk, 12); 105374b4d42aSMatthias Ringwald sm_setup_event_base(event, sizeof(event), event_type, sm_conn->sm_handle, 1054f6a153d5SMatthias Ringwald sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address); 10555baa755bSMatthias Ringwald event[11] = setup->sm_use_secure_connections ? 1 : 0; 10565baa755bSMatthias Ringwald little_endian_store_32(event, 12, passkey); 1057f6a153d5SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, event, sizeof(event)); 1058ea9b6796SMatthias Ringwald } 1059ea9b6796SMatthias Ringwald 10603deb3ec6SMatthias Ringwald static void sm_trigger_user_response(sm_connection_t * sm_conn){ 1061446a8c36SMatthias Ringwald // notify client for: JUST WORKS confirm, Numeric comparison confirm, PASSKEY display or input 10623deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_IDLE; 1063d77906ffSMatthias Ringwald sm_conn->sm_pairing_active = true; 10643deb3ec6SMatthias Ringwald switch (setup->sm_stk_generation_method){ 10653deb3ec6SMatthias Ringwald case PK_RESP_INPUT: 106642134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1067ea9b6796SMatthias Ringwald sm_trigger_user_response_basic(sm_conn, SM_EVENT_PASSKEY_INPUT_NUMBER); 10683deb3ec6SMatthias Ringwald } else { 106974b4d42aSMatthias Ringwald sm_trigger_user_response_passkey(sm_conn, SM_EVENT_PASSKEY_DISPLAY_NUMBER); 10703deb3ec6SMatthias Ringwald } 10713deb3ec6SMatthias Ringwald break; 10723deb3ec6SMatthias Ringwald case PK_INIT_INPUT: 107342134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 107474b4d42aSMatthias Ringwald sm_trigger_user_response_passkey(sm_conn, SM_EVENT_PASSKEY_DISPLAY_NUMBER); 10753deb3ec6SMatthias Ringwald } else { 1076ea9b6796SMatthias Ringwald sm_trigger_user_response_basic(sm_conn, SM_EVENT_PASSKEY_INPUT_NUMBER); 10773deb3ec6SMatthias Ringwald } 10783deb3ec6SMatthias Ringwald break; 107947fb4255SMatthias Ringwald case PK_BOTH_INPUT: 1080ea9b6796SMatthias Ringwald sm_trigger_user_response_basic(sm_conn, SM_EVENT_PASSKEY_INPUT_NUMBER); 10813deb3ec6SMatthias Ringwald break; 108247fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 108374b4d42aSMatthias Ringwald sm_trigger_user_response_passkey(sm_conn, SM_EVENT_NUMERIC_COMPARISON_REQUEST); 108427c32905SMatthias Ringwald break; 10853deb3ec6SMatthias Ringwald case JUST_WORKS: 1086ea9b6796SMatthias Ringwald sm_trigger_user_response_basic(sm_conn, SM_EVENT_JUST_WORKS_REQUEST); 10873deb3ec6SMatthias Ringwald break; 10883deb3ec6SMatthias Ringwald case OOB: 10893deb3ec6SMatthias Ringwald // client already provided OOB data, let's skip notification. 10903deb3ec6SMatthias Ringwald break; 10917bbeb3adSMilanka Ringwald default: 10927bbeb3adSMilanka Ringwald btstack_assert(false); 10937bbeb3adSMilanka Ringwald break; 10943deb3ec6SMatthias Ringwald } 10953deb3ec6SMatthias Ringwald } 10963deb3ec6SMatthias Ringwald 109761d1a45eSMatthias Ringwald static bool sm_key_distribution_all_received(void) { 10985fa700b1SMatthias 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); 1099b2296177SMatthias Ringwald return (setup->sm_key_distribution_expected_set & setup->sm_key_distribution_received_set) == setup->sm_key_distribution_expected_set; 11003deb3ec6SMatthias Ringwald } 11013deb3ec6SMatthias Ringwald 1102711e6c80SMatthias Ringwald static void sm_done_for_handle(hci_con_handle_t con_handle){ 11037149bde5SMatthias Ringwald if (sm_active_connection_handle == con_handle){ 11043deb3ec6SMatthias Ringwald sm_timeout_stop(); 11057149bde5SMatthias Ringwald sm_active_connection_handle = HCI_CON_HANDLE_INVALID; 1106711e6c80SMatthias Ringwald log_info("sm: connection 0x%x released setup context", con_handle); 1107c085d9ffSMatthias Ringwald 1108c085d9ffSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 1109c085d9ffSMatthias Ringwald // generate new ec key after each pairing (that used it) 1110c085d9ffSMatthias Ringwald if (setup->sm_use_secure_connections){ 1111c085d9ffSMatthias Ringwald sm_ec_generate_new_key(); 1112c085d9ffSMatthias Ringwald } 1113c085d9ffSMatthias Ringwald #endif 11143deb3ec6SMatthias Ringwald } 11153deb3ec6SMatthias Ringwald } 11163deb3ec6SMatthias Ringwald 11177d1c0c3aSMatthias Ringwald static void sm_master_pairing_success(sm_connection_t *connection) {// master -> all done 11181dca9d8aSMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_CONNECTED; 11190ccf6c9cSMatthias Ringwald sm_pairing_complete(connection, ERROR_CODE_SUCCESS, 0); 11201dca9d8aSMatthias Ringwald sm_done_for_handle(connection->sm_handle); 11211dca9d8aSMatthias Ringwald } 11221dca9d8aSMatthias Ringwald 11233deb3ec6SMatthias Ringwald static int sm_key_distribution_flags_for_auth_req(void){ 1124bb09604fSMatthias Ringwald 1125bb09604fSMatthias Ringwald int flags = SM_KEYDIST_ID_KEY; 1126f688bdb8SMatthias Ringwald if ((sm_auth_req & SM_AUTHREQ_BONDING) != 0u){ 1127bb09604fSMatthias Ringwald // encryption and signing information only if bonding requested 11283deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_ENC_KEY; 1129bb09604fSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 1130bb09604fSMatthias Ringwald flags |= SM_KEYDIST_SIGN; 1131bb09604fSMatthias Ringwald #endif 11327ece0eaaSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 1133b2072c76SMatthias Ringwald // LinkKey for CTKD requires SC and BR/EDR Support 1134b2072c76SMatthias Ringwald if (hci_classic_supported() && ((sm_auth_req & SM_AUTHREQ_SECURE_CONNECTION) != 0)){ 11357ece0eaaSMatthias Ringwald flags |= SM_KEYDIST_LINK_KEY; 11367ece0eaaSMatthias Ringwald } 11377ece0eaaSMatthias Ringwald #endif 11383deb3ec6SMatthias Ringwald } 11393deb3ec6SMatthias Ringwald return flags; 11403deb3ec6SMatthias Ringwald } 11413deb3ec6SMatthias Ringwald 1142d7471931SMatthias Ringwald static void sm_reset_setup(void){ 11433deb3ec6SMatthias Ringwald // fill in sm setup 1144901c000fSMatthias Ringwald setup->sm_state_vars = 0; 1145dd4a08fbSMatthias Ringwald setup->sm_keypress_notification = 0; 1146d0ea782aSMatthias Ringwald setup->sm_have_oob_data = 0; 11473deb3ec6SMatthias Ringwald sm_reset_tk(); 1148d7471931SMatthias Ringwald } 1149d7471931SMatthias Ringwald 1150d7471931SMatthias Ringwald static void sm_init_setup(sm_connection_t * sm_conn){ 1151d7471931SMatthias Ringwald // fill in sm setup 11523deb3ec6SMatthias Ringwald setup->sm_peer_addr_type = sm_conn->sm_peer_addr_type; 11536535961aSMatthias Ringwald (void)memcpy(setup->sm_peer_address, sm_conn->sm_peer_address, 6); 11543deb3ec6SMatthias Ringwald 1155a680ba6bSMatthias Ringwald // query client for Legacy Pairing OOB data 11569305033eSMatthias Ringwald if (sm_get_oob_data != NULL) { 1157a680ba6bSMatthias Ringwald setup->sm_have_oob_data = (*sm_get_oob_data)(sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address, setup->sm_tk); 11583deb3ec6SMatthias Ringwald } 11593deb3ec6SMatthias Ringwald 1160a680ba6bSMatthias Ringwald // if available and SC supported, also ask for SC OOB Data 1161a680ba6bSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 11624acf7b7bSMatthias Ringwald memset(setup->sm_ra, 0, 16); 11634acf7b7bSMatthias Ringwald memset(setup->sm_rb, 0, 16); 1164a680ba6bSMatthias Ringwald if (setup->sm_have_oob_data && (sm_auth_req & SM_AUTHREQ_SECURE_CONNECTION)){ 11659305033eSMatthias Ringwald if (sm_get_sc_oob_data != NULL){ 11664acf7b7bSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1167a680ba6bSMatthias Ringwald setup->sm_have_oob_data = (*sm_get_sc_oob_data)( 1168a680ba6bSMatthias Ringwald sm_conn->sm_peer_addr_type, 1169a680ba6bSMatthias Ringwald sm_conn->sm_peer_address, 1170a680ba6bSMatthias Ringwald setup->sm_peer_confirm, 11714acf7b7bSMatthias Ringwald setup->sm_ra); 11724acf7b7bSMatthias Ringwald } else { 11734acf7b7bSMatthias Ringwald setup->sm_have_oob_data = (*sm_get_sc_oob_data)( 11744acf7b7bSMatthias Ringwald sm_conn->sm_peer_addr_type, 11754acf7b7bSMatthias Ringwald sm_conn->sm_peer_address, 11764acf7b7bSMatthias Ringwald setup->sm_peer_confirm, 11774acf7b7bSMatthias Ringwald setup->sm_rb); 11784acf7b7bSMatthias Ringwald } 1179a680ba6bSMatthias Ringwald } else { 1180a680ba6bSMatthias Ringwald setup->sm_have_oob_data = 0; 1181a680ba6bSMatthias Ringwald } 1182a680ba6bSMatthias Ringwald } 1183a680ba6bSMatthias Ringwald #endif 1184a680ba6bSMatthias Ringwald 11853deb3ec6SMatthias Ringwald sm_pairing_packet_t * local_packet; 118642134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 11873deb3ec6SMatthias Ringwald // slave 11883deb3ec6SMatthias Ringwald local_packet = &setup->sm_s_pres; 11893deb3ec6SMatthias Ringwald setup->sm_m_addr_type = sm_conn->sm_peer_addr_type; 1190d5314cbeSMatthias Ringwald setup->sm_s_addr_type = sm_conn->sm_own_addr_type; 11916535961aSMatthias Ringwald (void)memcpy(setup->sm_m_address, sm_conn->sm_peer_address, 6); 1192d5314cbeSMatthias Ringwald (void)memcpy(setup->sm_s_address, sm_conn->sm_own_address, 6); 11933deb3ec6SMatthias Ringwald } else { 11943deb3ec6SMatthias Ringwald // master 11953deb3ec6SMatthias Ringwald local_packet = &setup->sm_m_preq; 11963deb3ec6SMatthias Ringwald setup->sm_s_addr_type = sm_conn->sm_peer_addr_type; 1197d5314cbeSMatthias Ringwald setup->sm_m_addr_type = sm_conn->sm_own_addr_type; 11986535961aSMatthias Ringwald (void)memcpy(setup->sm_s_address, sm_conn->sm_peer_address, 6); 1199d5314cbeSMatthias Ringwald (void)memcpy(setup->sm_m_address, sm_conn->sm_own_address, 6); 12003deb3ec6SMatthias Ringwald 1201d0ea782aSMatthias Ringwald uint8_t key_distribution_flags = sm_key_distribution_flags_for_auth_req(); 12021ad129beSMatthias Ringwald sm_pairing_packet_set_initiator_key_distribution(setup->sm_m_preq, key_distribution_flags); 12031ad129beSMatthias Ringwald sm_pairing_packet_set_responder_key_distribution(setup->sm_m_preq, key_distribution_flags); 12043deb3ec6SMatthias Ringwald } 12053deb3ec6SMatthias Ringwald 12064361507fSMatthias Ringwald log_info("our address %s type %u", bd_addr_to_str(sm_conn->sm_own_address), sm_conn->sm_own_addr_type); 12074361507fSMatthias Ringwald log_info("peer address %s type %u", bd_addr_to_str(sm_conn->sm_peer_address), sm_conn->sm_peer_addr_type); 12084361507fSMatthias Ringwald 120957132f12SMatthias Ringwald uint8_t auth_req = sm_auth_req & ~SM_AUTHREQ_CT2; 1210d0ea782aSMatthias Ringwald uint8_t max_encryption_key_size = sm_max_encryption_key_size; 12112c041b42SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 12122c041b42SMatthias Ringwald // enable SC for SC only mode 12132c041b42SMatthias Ringwald if (sm_sc_only_mode){ 12142c041b42SMatthias Ringwald auth_req |= SM_AUTHREQ_SECURE_CONNECTION; 1215d0ea782aSMatthias Ringwald max_encryption_key_size = 16; 12162c041b42SMatthias Ringwald } 12172c041b42SMatthias Ringwald #endif 121857132f12SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 121957132f12SMatthias Ringwald // set CT2 if SC + Bonding + CTKD 122057132f12SMatthias Ringwald const uint8_t auth_req_for_ct2 = SM_AUTHREQ_SECURE_CONNECTION | SM_AUTHREQ_BONDING; 122157132f12SMatthias Ringwald if ((auth_req & auth_req_for_ct2) == auth_req_for_ct2){ 122257132f12SMatthias Ringwald auth_req |= SM_AUTHREQ_CT2; 122357132f12SMatthias Ringwald } 122457132f12SMatthias Ringwald #endif 12251ad129beSMatthias Ringwald sm_pairing_packet_set_io_capability(*local_packet, sm_io_capabilities); 1226a680ba6bSMatthias Ringwald sm_pairing_packet_set_oob_data_flag(*local_packet, setup->sm_have_oob_data); 1227df86eb96SMatthias Ringwald sm_pairing_packet_set_auth_req(*local_packet, auth_req); 1228d0ea782aSMatthias Ringwald sm_pairing_packet_set_max_encryption_key_size(*local_packet, max_encryption_key_size); 12293deb3ec6SMatthias Ringwald } 12303deb3ec6SMatthias Ringwald 12313deb3ec6SMatthias Ringwald static int sm_stk_generation_init(sm_connection_t * sm_conn){ 12323deb3ec6SMatthias Ringwald 12333deb3ec6SMatthias Ringwald sm_pairing_packet_t * remote_packet; 12349a90d41aSMatthias Ringwald uint8_t keys_to_send; 12359a90d41aSMatthias Ringwald uint8_t keys_to_receive; 123642134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 123752f9cf63SMatthias Ringwald // slave / responder 12383deb3ec6SMatthias Ringwald remote_packet = &setup->sm_m_preq; 12399a90d41aSMatthias Ringwald keys_to_send = sm_pairing_packet_get_responder_key_distribution(setup->sm_m_preq); 12409a90d41aSMatthias Ringwald keys_to_receive = sm_pairing_packet_get_initiator_key_distribution(setup->sm_m_preq); 12413deb3ec6SMatthias Ringwald } else { 12423deb3ec6SMatthias Ringwald // master / initiator 12433deb3ec6SMatthias Ringwald remote_packet = &setup->sm_s_pres; 12449a90d41aSMatthias Ringwald keys_to_send = sm_pairing_packet_get_initiator_key_distribution(setup->sm_s_pres); 12459a90d41aSMatthias Ringwald keys_to_receive = sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres); 12463deb3ec6SMatthias Ringwald } 12473deb3ec6SMatthias Ringwald 12483deb3ec6SMatthias Ringwald // check key size 12492c041b42SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 12502c041b42SMatthias Ringwald // SC Only mandates 128 bit key size 12512c041b42SMatthias Ringwald if (sm_sc_only_mode && (sm_pairing_packet_get_max_encryption_key_size(*remote_packet) < 16)) { 12522c041b42SMatthias Ringwald return SM_REASON_ENCRYPTION_KEY_SIZE; 12532c041b42SMatthias Ringwald } 12542c041b42SMatthias Ringwald #endif 12551ad129beSMatthias Ringwald sm_conn->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(sm_pairing_packet_get_max_encryption_key_size(*remote_packet)); 12564ea43905SMatthias Ringwald if (sm_conn->sm_actual_encryption_key_size == 0u) return SM_REASON_ENCRYPTION_KEY_SIZE; 12573deb3ec6SMatthias Ringwald 1258eddc894fSMatthias Ringwald // decide on STK generation method / SC 12593deb3ec6SMatthias Ringwald sm_setup_tk(); 12603deb3ec6SMatthias Ringwald log_info("SMP: generation method %u", setup->sm_stk_generation_method); 12613deb3ec6SMatthias Ringwald 12623deb3ec6SMatthias Ringwald // check if STK generation method is acceptable by client 12633deb3ec6SMatthias Ringwald if (!sm_validate_stk_generation_method()) return SM_REASON_AUTHENTHICATION_REQUIREMENTS; 12643deb3ec6SMatthias Ringwald 1265eddc894fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 12662c041b42SMatthias Ringwald // Check LE SC Only mode 12673cdbe9dbSMatthias Ringwald if (sm_sc_only_mode && (setup->sm_use_secure_connections == false)){ 12683cdbe9dbSMatthias Ringwald log_info("SC Only mode active but SC not possible"); 12693cdbe9dbSMatthias Ringwald return SM_REASON_AUTHENTHICATION_REQUIREMENTS; 12703cdbe9dbSMatthias Ringwald } 12713cdbe9dbSMatthias Ringwald 12729a90d41aSMatthias Ringwald // LTK (= encryption information & master identification) only used exchanged for LE Legacy Connection 1273eddc894fSMatthias Ringwald if (setup->sm_use_secure_connections){ 12749a90d41aSMatthias Ringwald keys_to_send &= ~SM_KEYDIST_ENC_KEY; 12759a90d41aSMatthias Ringwald keys_to_receive &= ~SM_KEYDIST_ENC_KEY; 1276eddc894fSMatthias Ringwald } 1277eddc894fSMatthias Ringwald #endif 1278eddc894fSMatthias Ringwald 127952f9cf63SMatthias Ringwald // identical to responder 12809a90d41aSMatthias Ringwald sm_setup_key_distribution(keys_to_send, keys_to_receive); 128152f9cf63SMatthias Ringwald 12823deb3ec6SMatthias Ringwald // JUST WORKS doens't provide authentication 1283c1ab6cc1SMatthias Ringwald sm_conn->sm_connection_authenticated = (setup->sm_stk_generation_method == JUST_WORKS) ? 0 : 1; 12843deb3ec6SMatthias Ringwald 12853deb3ec6SMatthias Ringwald return 0; 12863deb3ec6SMatthias Ringwald } 12873deb3ec6SMatthias Ringwald 12883deb3ec6SMatthias Ringwald static void sm_address_resolution_handle_event(address_resolution_event_t event){ 12893deb3ec6SMatthias Ringwald 12903deb3ec6SMatthias Ringwald // cache and reset context 12913deb3ec6SMatthias Ringwald int matched_device_id = sm_address_resolution_test; 12923deb3ec6SMatthias Ringwald address_resolution_mode_t mode = sm_address_resolution_mode; 12933deb3ec6SMatthias Ringwald void * context = sm_address_resolution_context; 12943deb3ec6SMatthias Ringwald 12953deb3ec6SMatthias Ringwald // reset context 12963deb3ec6SMatthias Ringwald sm_address_resolution_mode = ADDRESS_RESOLUTION_IDLE; 12973deb3ec6SMatthias Ringwald sm_address_resolution_context = NULL; 12983deb3ec6SMatthias Ringwald sm_address_resolution_test = -1; 12993deb3ec6SMatthias Ringwald 130045d80b08SMatthias Ringwald hci_con_handle_t con_handle = HCI_CON_HANDLE_INVALID; 13013deb3ec6SMatthias Ringwald sm_connection_t * sm_connection; 1302d2e90122SMatthias Ringwald sm_key_t ltk; 13031979f09cSMatthias Ringwald bool have_ltk; 130445d80b08SMatthias Ringwald int authenticated; 13056c44b759SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 13061979f09cSMatthias Ringwald bool trigger_pairing; 130742134bc6SMatthias Ringwald #endif 130845d80b08SMatthias Ringwald 13093deb3ec6SMatthias Ringwald switch (mode){ 13103deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_GENERAL: 13113deb3ec6SMatthias Ringwald break; 13123deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_FOR_CONNECTION: 13133deb3ec6SMatthias Ringwald sm_connection = (sm_connection_t *) context; 1314711e6c80SMatthias Ringwald con_handle = sm_connection->sm_handle; 13156c44b759SMatthias Ringwald 13166c44b759SMatthias Ringwald // have ltk -> start encryption / send security request 13176c44b759SMatthias Ringwald // Core 5, Vol 3, Part C, 10.3.2 Initiating a Service Request 13186c44b759SMatthias Ringwald // "When a bond has been created between two devices, any reconnection should result in the local device 13196c44b759SMatthias Ringwald // enabling or requesting encryption with the remote device before initiating any service request." 13206c44b759SMatthias Ringwald 13213deb3ec6SMatthias Ringwald switch (event){ 1322a66b030fSMatthias Ringwald case ADDRESS_RESOLUTION_SUCCEEDED: 13233deb3ec6SMatthias Ringwald sm_connection->sm_irk_lookup_state = IRK_LOOKUP_SUCCEEDED; 13243deb3ec6SMatthias Ringwald sm_connection->sm_le_db_index = matched_device_id; 1325a66b030fSMatthias Ringwald log_info("ADDRESS_RESOLUTION_SUCCEEDED, index %d", sm_connection->sm_le_db_index); 13266c44b759SMatthias Ringwald 13272d68601cSMatthias Ringwald le_device_db_encryption_get(sm_connection->sm_le_db_index, NULL, NULL, ltk, NULL, &authenticated, NULL, NULL); 13286c44b759SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 13296c44b759SMatthias Ringwald 1330f688bdb8SMatthias Ringwald if (IS_RESPONDER(sm_connection->sm_role)) { 13316c44b759SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 1332212d735eSMatthias Ringwald // IRK required before, continue 13336c39055aSMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK){ 13346c39055aSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST; 13356c39055aSMatthias Ringwald break; 13366c39055aSMatthias Ringwald } 1337434260a1SMatthias Ringwald // Pairing request before, continue 1338212d735eSMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED_W4_IRK){ 1339212d735eSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED; 1340212d735eSMatthias Ringwald break; 1341212d735eSMatthias Ringwald } 1342728f6757SMatthias Ringwald bool trigger_security_request = sm_connection->sm_pairing_requested || sm_slave_request_security; 13435f3874afSMatthias Ringwald sm_connection->sm_pairing_requested = false; 13446c44b759SMatthias Ringwald #ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 13457af5dcd5SMatthias Ringwald // trigger security request for Proactive Authentication if LTK available 13467af5dcd5SMatthias Ringwald trigger_security_request = trigger_security_request || have_ltk; 13476c44b759SMatthias Ringwald #endif 13487af5dcd5SMatthias Ringwald 13497af5dcd5SMatthias Ringwald log_info("peripheral: pairing request local %u, have_ltk %u => trigger_security_request %u", 13505f3874afSMatthias Ringwald (int) sm_connection->sm_pairing_requested, (int) have_ltk, trigger_security_request); 13517af5dcd5SMatthias Ringwald 13527af5dcd5SMatthias Ringwald if (trigger_security_request){ 13537af5dcd5SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 13547af5dcd5SMatthias Ringwald if (have_ltk){ 13557af5dcd5SMatthias Ringwald sm_reencryption_started(sm_connection); 13567af5dcd5SMatthias Ringwald } else { 13577af5dcd5SMatthias Ringwald sm_pairing_started(sm_connection); 13587af5dcd5SMatthias Ringwald } 13597af5dcd5SMatthias Ringwald sm_trigger_run(); 13606c44b759SMatthias Ringwald } 13616c44b759SMatthias Ringwald #endif 13626c44b759SMatthias Ringwald } else { 13636c44b759SMatthias Ringwald 136442134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 13656c44b759SMatthias Ringwald // check if pairing already requested and reset requests 13666c44b759SMatthias Ringwald trigger_pairing = sm_connection->sm_pairing_requested || sm_connection->sm_security_request_received; 13672d68601cSMatthias Ringwald bool auth_required = sm_auth_req & SM_AUTHREQ_MITM_PROTECTION; 13682d68601cSMatthias Ringwald 13696c44b759SMatthias Ringwald log_info("central: pairing request local %u, remote %u => trigger_pairing %u. have_ltk %u", 13705f3874afSMatthias Ringwald (int) sm_connection->sm_pairing_requested, (int) sm_connection->sm_security_request_received, (int) trigger_pairing, (int) have_ltk); 13710dcaa15fSMatthias Ringwald sm_connection->sm_security_request_received = false; 13725f3874afSMatthias Ringwald sm_connection->sm_pairing_requested = false; 137332bc5d65SMatthias Ringwald bool trigger_reencryption = false; 1374c245ca32SMatthias Ringwald 1375d4af1595SMatthias Ringwald if (have_ltk){ 13762d68601cSMatthias Ringwald if (trigger_pairing){ 13772d68601cSMatthias Ringwald // if pairing is requested, re-encryption is sufficient, if ltk is already authenticated or we don't require authentication 13782d68601cSMatthias Ringwald trigger_reencryption = (authenticated != 0) || (auth_required == false); 13792d68601cSMatthias Ringwald } else { 13806a43f611SMatthias Ringwald #ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 1381b187cc61SMatthias Ringwald trigger_reencryption = true; 138232bc5d65SMatthias Ringwald #else 138332bc5d65SMatthias Ringwald log_info("central: defer enabling encryption for bonded device"); 138432bc5d65SMatthias Ringwald #endif 138532bc5d65SMatthias Ringwald } 13862d68601cSMatthias Ringwald } 138732bc5d65SMatthias Ringwald 138832bc5d65SMatthias Ringwald if (trigger_reencryption){ 13896c44b759SMatthias Ringwald log_info("central: enable encryption for bonded device"); 13905567aa60SMatthias Ringwald sm_connection->sm_engine_state = SM_INITIATOR_PH4_HAS_LTK; 1391d4af1595SMatthias Ringwald break; 1392d4af1595SMatthias Ringwald } 13936c44b759SMatthias Ringwald 13946c44b759SMatthias Ringwald // pairing_request -> send pairing request 13956c44b759SMatthias Ringwald if (trigger_pairing){ 13963deb3ec6SMatthias Ringwald sm_connection->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 1397d4af1595SMatthias Ringwald break; 13983deb3ec6SMatthias Ringwald } 139942134bc6SMatthias Ringwald #endif 1400298ab52bSMatthias Ringwald } 14013deb3ec6SMatthias Ringwald break; 14023deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_FAILED: 14033deb3ec6SMatthias Ringwald sm_connection->sm_irk_lookup_state = IRK_LOOKUP_FAILED; 1404f688bdb8SMatthias Ringwald if (IS_RESPONDER(sm_connection->sm_role)) { 14057af5dcd5SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 14066c39055aSMatthias Ringwald // LTK request received before, IRK required -> negative LTK reply 14076c39055aSMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK){ 14086c39055aSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY; 14096c39055aSMatthias Ringwald } 1410434260a1SMatthias Ringwald // Pairing request before, continue 1411434260a1SMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED_W4_IRK){ 1412434260a1SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED; 1413434260a1SMatthias Ringwald break; 1414434260a1SMatthias Ringwald } 14157af5dcd5SMatthias Ringwald // send security request if requested 1416728f6757SMatthias Ringwald bool trigger_security_request = sm_connection->sm_pairing_requested || sm_slave_request_security; 14175f3874afSMatthias Ringwald sm_connection->sm_pairing_requested = false; 14187af5dcd5SMatthias Ringwald if (trigger_security_request){ 14197af5dcd5SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 14207af5dcd5SMatthias Ringwald sm_pairing_started(sm_connection); 14217af5dcd5SMatthias Ringwald } 14226c39055aSMatthias Ringwald break; 14237af5dcd5SMatthias Ringwald #endif 14246c39055aSMatthias Ringwald } 142542134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 14265f3874afSMatthias Ringwald if ((sm_connection->sm_pairing_requested == false) && (sm_connection->sm_security_request_received == false)) break; 14270dcaa15fSMatthias Ringwald sm_connection->sm_security_request_received = false; 14285f3874afSMatthias Ringwald sm_connection->sm_pairing_requested = false; 14293deb3ec6SMatthias Ringwald sm_connection->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 143042134bc6SMatthias Ringwald #endif 14313deb3ec6SMatthias Ringwald break; 14327bbeb3adSMilanka Ringwald 14337bbeb3adSMilanka Ringwald default: 14347bbeb3adSMilanka Ringwald btstack_assert(false); 14357bbeb3adSMilanka Ringwald break; 14363deb3ec6SMatthias Ringwald } 14373deb3ec6SMatthias Ringwald break; 14383deb3ec6SMatthias Ringwald default: 14393deb3ec6SMatthias Ringwald break; 14403deb3ec6SMatthias Ringwald } 14413deb3ec6SMatthias Ringwald 14423deb3ec6SMatthias Ringwald switch (event){ 1443a66b030fSMatthias Ringwald case ADDRESS_RESOLUTION_SUCCEEDED: 1444711e6c80SMatthias Ringwald sm_notify_client_index(SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED, con_handle, sm_address_resolution_addr_type, sm_address_resolution_address, matched_device_id); 14453deb3ec6SMatthias Ringwald break; 14463deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_FAILED: 1447711e6c80SMatthias Ringwald sm_notify_client_base(SM_EVENT_IDENTITY_RESOLVING_FAILED, con_handle, sm_address_resolution_addr_type, sm_address_resolution_address); 14483deb3ec6SMatthias Ringwald break; 14497bbeb3adSMilanka Ringwald default: 14507bbeb3adSMilanka Ringwald btstack_assert(false); 14517bbeb3adSMilanka Ringwald break; 14523deb3ec6SMatthias Ringwald } 14533deb3ec6SMatthias Ringwald } 14543deb3ec6SMatthias Ringwald 145555f09f49SMatthias Ringwald static void sm_store_bonding_information(sm_connection_t * sm_conn){ 14563deb3ec6SMatthias Ringwald int le_db_index = -1; 14573deb3ec6SMatthias Ringwald 14583deb3ec6SMatthias Ringwald // lookup device based on IRK 1459f688bdb8SMatthias Ringwald if ((setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION) != 0u){ 14603deb3ec6SMatthias Ringwald int i; 1461092ec58eSMatthias Ringwald for (i=0; i < le_device_db_max_count(); i++){ 14623deb3ec6SMatthias Ringwald sm_key_t irk; 14633deb3ec6SMatthias Ringwald bd_addr_t address; 1464c7e2c1a5SMatthias Ringwald int address_type = BD_ADDR_TYPE_UNKNOWN; 14653deb3ec6SMatthias Ringwald le_device_db_info(i, &address_type, address, irk); 1466adf5eaa9SMatthias Ringwald // skip unused entries 1467c7e2c1a5SMatthias Ringwald if (address_type == BD_ADDR_TYPE_UNKNOWN) continue; 146811d10bdaSMatthias Ringwald // compare Identity Address 146911d10bdaSMatthias Ringwald if (memcmp(address, setup->sm_peer_address, 6) != 0) continue; 147011d10bdaSMatthias Ringwald // compare Identity Resolving Key 1471c7e2c1a5SMatthias Ringwald if (memcmp(irk, setup->sm_peer_irk, 16) != 0) continue; 1472c7e2c1a5SMatthias Ringwald 14733deb3ec6SMatthias Ringwald log_info("sm: device found for IRK, updating"); 14743deb3ec6SMatthias Ringwald le_db_index = i; 14753deb3ec6SMatthias Ringwald break; 14763deb3ec6SMatthias Ringwald } 1477c7e2c1a5SMatthias Ringwald } else { 1478c7e2c1a5SMatthias Ringwald // assert IRK is set to zero 1479c7e2c1a5SMatthias Ringwald memset(setup->sm_peer_irk, 0, 16); 14803deb3ec6SMatthias Ringwald } 14813deb3ec6SMatthias Ringwald 14823deb3ec6SMatthias Ringwald // if not found, lookup via public address if possible 14833deb3ec6SMatthias Ringwald log_info("sm peer addr type %u, peer addres %s", setup->sm_peer_addr_type, bd_addr_to_str(setup->sm_peer_address)); 1484c1ab6cc1SMatthias Ringwald if ((le_db_index < 0) && (setup->sm_peer_addr_type == BD_ADDR_TYPE_LE_PUBLIC)){ 14853deb3ec6SMatthias Ringwald int i; 1486092ec58eSMatthias Ringwald for (i=0; i < le_device_db_max_count(); i++){ 14873deb3ec6SMatthias Ringwald bd_addr_t address; 1488adf5eaa9SMatthias Ringwald int address_type = BD_ADDR_TYPE_UNKNOWN; 14893deb3ec6SMatthias Ringwald le_device_db_info(i, &address_type, address, NULL); 1490adf5eaa9SMatthias Ringwald // skip unused entries 1491adf5eaa9SMatthias Ringwald if (address_type == BD_ADDR_TYPE_UNKNOWN) continue; 14923deb3ec6SMatthias Ringwald log_info("device %u, sm peer addr type %u, peer addres %s", i, address_type, bd_addr_to_str(address)); 14935df9dc78SMatthias Ringwald if ((address_type == BD_ADDR_TYPE_LE_PUBLIC) && (memcmp(address, setup->sm_peer_address, 6) == 0)){ 14943deb3ec6SMatthias Ringwald log_info("sm: device found for public address, updating"); 14953deb3ec6SMatthias Ringwald le_db_index = i; 14963deb3ec6SMatthias Ringwald break; 14973deb3ec6SMatthias Ringwald } 14983deb3ec6SMatthias Ringwald } 14993deb3ec6SMatthias Ringwald } 15003deb3ec6SMatthias Ringwald 15013deb3ec6SMatthias Ringwald // if not found, add to db 150202b02cffSMatthias Ringwald bool new_to_le_device_db = false; 15033deb3ec6SMatthias Ringwald if (le_db_index < 0) { 15043deb3ec6SMatthias Ringwald le_db_index = le_device_db_add(setup->sm_peer_addr_type, setup->sm_peer_address, setup->sm_peer_irk); 150502b02cffSMatthias Ringwald new_to_le_device_db = true; 15063deb3ec6SMatthias Ringwald } 15073deb3ec6SMatthias Ringwald 15083deb3ec6SMatthias Ringwald if (le_db_index >= 0){ 15093deb3ec6SMatthias Ringwald 151002b02cffSMatthias Ringwald #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION 151102b02cffSMatthias Ringwald if (!new_to_le_device_db){ 151202b02cffSMatthias Ringwald hci_remove_le_device_db_entry_from_resolving_list(le_db_index); 151302b02cffSMatthias Ringwald } 151402b02cffSMatthias Ringwald hci_load_le_device_db_entry_into_resolving_list(le_db_index); 151502b02cffSMatthias Ringwald #else 151602b02cffSMatthias Ringwald UNUSED(new_to_le_device_db); 151702b02cffSMatthias Ringwald #endif 151802b02cffSMatthias Ringwald 151948163929SMatthias 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); 1520e1086030SMatthias Ringwald sm_conn->sm_irk_lookup_state = IRK_LOOKUP_SUCCEEDED; 15217710ebd2SMatthias Ringwald sm_conn->sm_le_db_index = le_db_index; 152248163929SMatthias Ringwald 1523eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 15243deb3ec6SMatthias Ringwald // store local CSRK 1525715a43d1SMatthias Ringwald setup->sm_le_device_index = le_db_index; 1526715a43d1SMatthias Ringwald if ((setup->sm_key_distribution_sent_set) & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION){ 15273deb3ec6SMatthias Ringwald log_info("sm: store local CSRK"); 15283deb3ec6SMatthias Ringwald le_device_db_local_csrk_set(le_db_index, setup->sm_local_csrk); 15293deb3ec6SMatthias Ringwald le_device_db_local_counter_set(le_db_index, 0); 15303deb3ec6SMatthias Ringwald } 15313deb3ec6SMatthias Ringwald 15323deb3ec6SMatthias Ringwald // store remote CSRK 15333deb3ec6SMatthias Ringwald if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION){ 15343deb3ec6SMatthias Ringwald log_info("sm: store remote CSRK"); 15353deb3ec6SMatthias Ringwald le_device_db_remote_csrk_set(le_db_index, setup->sm_peer_csrk); 15363deb3ec6SMatthias Ringwald le_device_db_remote_counter_set(le_db_index, 0); 15373deb3ec6SMatthias Ringwald } 1538eda85fbfSMatthias Ringwald #endif 153978f44163SMatthias Ringwald // store encryption information for secure connections: LTK generated by ECDH 154078f44163SMatthias Ringwald if (setup->sm_use_secure_connections){ 1541e6343eb6SMatthias Ringwald log_info("sm: store SC LTK (key size %u, authenticated %u)", sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated); 154278f44163SMatthias Ringwald uint8_t zero_rand[8]; 154378f44163SMatthias Ringwald memset(zero_rand, 0, 8); 154478f44163SMatthias Ringwald le_device_db_encryption_set(le_db_index, 0, zero_rand, setup->sm_ltk, sm_conn->sm_actual_encryption_key_size, 15453dc3a67dSMatthias Ringwald sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED, 1); 154678f44163SMatthias Ringwald } 154778f44163SMatthias Ringwald 1548e6343eb6SMatthias Ringwald // store encryption information for legacy pairing: peer LTK, EDIV, RAND 154978f44163SMatthias Ringwald else if ( (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION) 155078f44163SMatthias Ringwald && (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_MASTER_IDENTIFICATION )){ 1551e6343eb6SMatthias Ringwald log_info("sm: set encryption information (key size %u, authenticated %u)", sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated); 15523deb3ec6SMatthias Ringwald le_device_db_encryption_set(le_db_index, setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk, 15533dc3a67dSMatthias Ringwald sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED, 0); 155478f44163SMatthias Ringwald 15553deb3ec6SMatthias Ringwald } 15563deb3ec6SMatthias Ringwald } 155755f09f49SMatthias Ringwald } 155855f09f49SMatthias Ringwald 15598980298aSMatthias Ringwald static void sm_pairing_error(sm_connection_t * sm_conn, uint8_t reason){ 15608980298aSMatthias Ringwald sm_conn->sm_pairing_failed_reason = reason; 15618980298aSMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_SEND_PAIRING_FAILED; 15628980298aSMatthias Ringwald } 15638980298aSMatthias Ringwald 156422cb578bSMatthias Ringwald static int sm_le_device_db_index_lookup(bd_addr_type_t address_type, bd_addr_t address){ 15651a55487aSMatthias Ringwald int i; 15661a55487aSMatthias Ringwald for (i=0; i < le_device_db_max_count(); i++){ 156722cb578bSMatthias Ringwald bd_addr_t db_address; 156822cb578bSMatthias Ringwald int db_address_type = BD_ADDR_TYPE_UNKNOWN; 156922cb578bSMatthias Ringwald le_device_db_info(i, &db_address_type, db_address, NULL); 15701a55487aSMatthias Ringwald // skip unused entries 15711a55487aSMatthias Ringwald if (address_type == BD_ADDR_TYPE_UNKNOWN) continue; 15723548b7cbSDirk Helbig if ((address_type == (unsigned int)db_address_type) && (memcmp(address, db_address, 6) == 0)){ 15731a55487aSMatthias Ringwald return i; 15741a55487aSMatthias Ringwald } 15751a55487aSMatthias Ringwald } 15761a55487aSMatthias Ringwald return -1; 15771a55487aSMatthias Ringwald } 15781a55487aSMatthias Ringwald 15792e08b70bSMatthias Ringwald static void sm_remove_le_device_db_entry(uint16_t i) { 15802e08b70bSMatthias Ringwald le_device_db_remove(i); 1581672dc582SMatthias Ringwald #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION 1582672dc582SMatthias Ringwald // to remove an entry from the resolving list requires its identity address, which was already deleted 1583672dc582SMatthias Ringwald // fully reload resolving list instead 1584672dc582SMatthias Ringwald gap_load_resolving_list_from_le_device_db(); 1585672dc582SMatthias Ringwald #endif 15862e08b70bSMatthias Ringwald } 15872e08b70bSMatthias Ringwald 15888980298aSMatthias Ringwald static uint8_t sm_key_distribution_validate_received(sm_connection_t * sm_conn){ 1589cc95824cSDirk Helbig UNUSED(sm_conn); 1590cc95824cSDirk Helbig 15911a55487aSMatthias Ringwald // if identity is provided, abort if we have bonding with same address but different irk 1592f688bdb8SMatthias Ringwald if ((setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION) != 0u){ 159322cb578bSMatthias Ringwald int index = sm_le_device_db_index_lookup(BD_ADDR_TYPE_LE_PUBLIC, setup->sm_peer_address); 15941a55487aSMatthias Ringwald if (index >= 0){ 15951a55487aSMatthias Ringwald sm_key_t irk; 15961a55487aSMatthias Ringwald le_device_db_info(index, NULL, NULL, irk); 15971a55487aSMatthias Ringwald if (memcmp(irk, setup->sm_peer_irk, 16) != 0){ 15981a55487aSMatthias Ringwald // IRK doesn't match, delete bonding information 15991a55487aSMatthias 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); 16009202d845SMatthias Ringwald sm_remove_le_device_db_entry(index); 16011a55487aSMatthias Ringwald } 16021a55487aSMatthias Ringwald } 16031a55487aSMatthias Ringwald } 16048980298aSMatthias Ringwald return 0; 16058980298aSMatthias Ringwald } 16068980298aSMatthias Ringwald 160755f09f49SMatthias Ringwald static void sm_key_distribution_handle_all_received(sm_connection_t * sm_conn){ 160855f09f49SMatthias Ringwald 16098980298aSMatthias Ringwald // abort pairing if received keys are not valid 16108980298aSMatthias Ringwald uint8_t reason = sm_key_distribution_validate_received(sm_conn); 16118980298aSMatthias Ringwald if (reason != 0){ 16128980298aSMatthias Ringwald sm_pairing_error(sm_conn, reason); 16138980298aSMatthias Ringwald return; 16148980298aSMatthias Ringwald } 16158980298aSMatthias Ringwald 161655f09f49SMatthias Ringwald // only store pairing information if both sides are bondable, i.e., the bonadble flag is set 161755f09f49SMatthias Ringwald bool bonding_enabled = (sm_pairing_packet_get_auth_req(setup->sm_m_preq) 161855f09f49SMatthias Ringwald & sm_pairing_packet_get_auth_req(setup->sm_s_pres) 161955f09f49SMatthias Ringwald & SM_AUTHREQ_BONDING ) != 0u; 162055f09f49SMatthias Ringwald 162155f09f49SMatthias Ringwald if (bonding_enabled){ 162255f09f49SMatthias Ringwald sm_store_bonding_information(sm_conn); 162327ef8bc8SMatthias Ringwald } else { 162427ef8bc8SMatthias Ringwald log_info("Ignoring received keys, bonding not enabled"); 162527ef8bc8SMatthias Ringwald } 16263deb3ec6SMatthias Ringwald } 16273deb3ec6SMatthias Ringwald 1628688a08f9SMatthias Ringwald static inline void sm_pdu_received_in_wrong_state(sm_connection_t * sm_conn){ 1629688a08f9SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_UNSPECIFIED_REASON); 1630688a08f9SMatthias Ringwald } 1631688a08f9SMatthias Ringwald 16329af0f475SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 1633688a08f9SMatthias Ringwald 1634dc300847SMatthias Ringwald static void sm_sc_prepare_dhkey_check(sm_connection_t * sm_conn); 16351d80f1e6SMatthias Ringwald static bool sm_passkey_used(stk_generation_method_t method); 16361d80f1e6SMatthias Ringwald static bool sm_just_works_or_numeric_comparison(stk_generation_method_t method); 16372419120aSMatthias Ringwald static void sm_sc_generate_nx_for_send_random(sm_connection_t * sm_conn); 1638dc300847SMatthias Ringwald 1639b35a3de2SMatthias Ringwald static void sm_sc_start_calculating_local_confirm(sm_connection_t * sm_conn){ 1640b90c4e75SMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 16411f9d84e9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CONFIRMATION; 1642b90c4e75SMatthias Ringwald } else { 1643b90c4e75SMatthias 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); 1644b35a3de2SMatthias Ringwald } 1645b35a3de2SMatthias Ringwald } 1646b35a3de2SMatthias Ringwald 1647688a08f9SMatthias Ringwald static void sm_sc_state_after_receiving_random(sm_connection_t * sm_conn){ 164842134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1649688a08f9SMatthias Ringwald // Responder 16504acf7b7bSMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 16512419120aSMatthias Ringwald sm_sc_generate_nx_for_send_random(sm_conn); 16524acf7b7bSMatthias Ringwald } else { 1653688a08f9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM; 16544acf7b7bSMatthias Ringwald } 1655688a08f9SMatthias Ringwald } else { 1656688a08f9SMatthias Ringwald // Initiator role 1657688a08f9SMatthias Ringwald switch (setup->sm_stk_generation_method){ 1658688a08f9SMatthias Ringwald case JUST_WORKS: 1659dc300847SMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 1660688a08f9SMatthias Ringwald break; 1661688a08f9SMatthias Ringwald 166247fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 1663bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_G2; 1664688a08f9SMatthias Ringwald break; 1665688a08f9SMatthias Ringwald case PK_INIT_INPUT: 1666688a08f9SMatthias Ringwald case PK_RESP_INPUT: 166747fb4255SMatthias Ringwald case PK_BOTH_INPUT: 16684ea43905SMatthias Ringwald if (setup->sm_passkey_bit < 20u) { 1669b35a3de2SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 1670688a08f9SMatthias Ringwald } else { 1671dc300847SMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 1672688a08f9SMatthias Ringwald } 1673688a08f9SMatthias Ringwald break; 1674688a08f9SMatthias Ringwald case OOB: 167565a9a04eSMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 1676688a08f9SMatthias Ringwald break; 16777bbeb3adSMilanka Ringwald default: 16787bbeb3adSMilanka Ringwald btstack_assert(false); 16797bbeb3adSMilanka Ringwald break; 1680688a08f9SMatthias Ringwald } 1681688a08f9SMatthias Ringwald } 1682688a08f9SMatthias Ringwald } 1683688a08f9SMatthias Ringwald 1684aec94140SMatthias Ringwald static void sm_sc_cmac_done(uint8_t * hash){ 1685688a08f9SMatthias Ringwald log_info("sm_sc_cmac_done: "); 1686688a08f9SMatthias Ringwald log_info_hexdump(hash, 16); 1687688a08f9SMatthias Ringwald 1688c59d0c92SMatthias Ringwald if (sm_sc_oob_state == SM_SC_OOB_W4_CONFIRM){ 1689c59d0c92SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_IDLE; 1690a680ba6bSMatthias Ringwald (*sm_sc_oob_callback)(hash, sm_sc_oob_random); 1691c59d0c92SMatthias Ringwald return; 1692c59d0c92SMatthias Ringwald } 1693c59d0c92SMatthias Ringwald 1694bd57ffebSMatthias Ringwald sm_connection_t * sm_conn = sm_cmac_connection; 1695bd57ffebSMatthias Ringwald sm_cmac_connection = NULL; 16966857ad8fSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 16972bacf595SMatthias Ringwald link_key_type_t link_key_type; 1698b4f65634SMatthias Ringwald #endif 1699bd57ffebSMatthias Ringwald 1700bd57ffebSMatthias Ringwald switch (sm_conn->sm_engine_state){ 1701aec94140SMatthias Ringwald case SM_SC_W4_CMAC_FOR_CONFIRMATION: 17026535961aSMatthias Ringwald (void)memcpy(setup->sm_local_confirm, hash, 16); 1703bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_CONFIRMATION; 1704aec94140SMatthias Ringwald break; 1705688a08f9SMatthias Ringwald case SM_SC_W4_CMAC_FOR_CHECK_CONFIRMATION: 1706688a08f9SMatthias Ringwald // check 1707688a08f9SMatthias Ringwald if (0 != memcmp(hash, setup->sm_peer_confirm, 16)){ 1708bd57ffebSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_CONFIRM_VALUE_FAILED); 1709688a08f9SMatthias Ringwald break; 1710688a08f9SMatthias Ringwald } 17112419120aSMatthias Ringwald // for OOB, C is verified before generating and sending random Nonce 17122419120aSMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 17132419120aSMatthias Ringwald sm_sc_generate_nx_for_send_random(sm_conn); 17142419120aSMatthias Ringwald } else { 1715bd57ffebSMatthias Ringwald sm_sc_state_after_receiving_random(sm_conn); 17162419120aSMatthias Ringwald } 1717688a08f9SMatthias Ringwald break; 1718901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_G2: { 1719901c000fSMatthias Ringwald uint32_t vab = big_endian_read_32(hash, 12) % 1000000; 1720901c000fSMatthias Ringwald big_endian_store_32(setup->sm_tk, 12, vab); 1721901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_USER_RESPONSE; 1722901c000fSMatthias Ringwald sm_trigger_user_response(sm_conn); 1723019005a0SMatthias Ringwald break; 1724019005a0SMatthias Ringwald } 17250346c37cSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_SALT: 17266535961aSMatthias Ringwald (void)memcpy(setup->sm_t, hash, 16); 1727bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_MACKEY; 17280346c37cSMatthias Ringwald break; 17290346c37cSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_MACKEY: 17306535961aSMatthias Ringwald (void)memcpy(setup->sm_mackey, hash, 16); 1731bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_LTK; 17320346c37cSMatthias Ringwald break; 17330346c37cSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_LTK: 1734b18300a6SMatthias Ringwald // truncate sm_ltk, but keep full LTK for cross-transport key derivation in sm_local_ltk 1735b18300a6SMatthias Ringwald // Errata Service Release to the Bluetooth Specification: ESR09 1736b18300a6SMatthias Ringwald // E6405 – Cross transport key derivation from a key of size less than 128 bits 1737b18300a6SMatthias Ringwald // Note: When the BR/EDR link key is being derived from the LTK, the derivation is done before the LTK gets masked." 17386535961aSMatthias Ringwald (void)memcpy(setup->sm_ltk, hash, 16); 17396535961aSMatthias Ringwald (void)memcpy(setup->sm_local_ltk, hash, 16); 1740893e9333SMatthias Ringwald sm_truncate_key(setup->sm_ltk, sm_conn->sm_actual_encryption_key_size); 1741bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F6_FOR_DHKEY_CHECK; 1742019005a0SMatthias Ringwald break; 1743901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F6_FOR_DHKEY_CHECK: 17446535961aSMatthias Ringwald (void)memcpy(setup->sm_local_dhkey_check, hash, 16); 174542134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1746901c000fSMatthias Ringwald // responder 1747f688bdb8SMatthias Ringwald if ((setup->sm_state_vars & SM_STATE_VAR_DHKEY_COMMAND_RECEIVED) != 0u){ 1748901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK; 1749901c000fSMatthias Ringwald } else { 1750901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_DHKEY_CHECK_COMMAND; 1751901c000fSMatthias Ringwald } 1752901c000fSMatthias Ringwald } else { 1753901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_DHKEY_CHECK_COMMAND; 1754901c000fSMatthias Ringwald } 1755901c000fSMatthias Ringwald break; 1756901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK: 1757901c000fSMatthias Ringwald if (0 != memcmp(hash, setup->sm_peer_dhkey_check, 16) ){ 1758901c000fSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 1759aec94140SMatthias Ringwald break; 1760aec94140SMatthias Ringwald } 176142134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1762901c000fSMatthias Ringwald // responder 1763901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_DHKEY_CHECK_COMMAND; 1764901c000fSMatthias Ringwald } else { 1765901c000fSMatthias Ringwald // initiator 1766901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH3_SEND_START_ENCRYPTION; 1767bd57ffebSMatthias Ringwald } 1768901c000fSMatthias Ringwald break; 17696857ad8fSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 177057132f12SMatthias Ringwald case SM_SC_W4_CALCULATE_ILK: 17716535961aSMatthias Ringwald (void)memcpy(setup->sm_t, hash, 16); 177257132f12SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_BR_EDR_LINK_KEY; 17732bacf595SMatthias Ringwald break; 177457132f12SMatthias Ringwald case SM_SC_W4_CALCULATE_BR_EDR_LINK_KEY: 17752bacf595SMatthias Ringwald reverse_128(hash, setup->sm_t); 17762bacf595SMatthias Ringwald link_key_type = sm_conn->sm_connection_authenticated ? 17772bacf595SMatthias Ringwald AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256 : UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256; 17788974e43fSMatthias Ringwald log_info("Derived classic link key from LE using h6, type %u", (int) link_key_type); 177955160b1cSMatthias Ringwald gap_store_link_key_for_bd_addr(setup->sm_peer_address, setup->sm_t, link_key_type); 17808974e43fSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 17812bacf595SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 17822bacf595SMatthias Ringwald } else { 17832bacf595SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 17842bacf595SMatthias Ringwald } 17850ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_SUCCESS, 0); 17862bacf595SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 17872bacf595SMatthias Ringwald break; 1788e0a03c85SMatthias Ringwald case SM_BR_EDR_W4_CALCULATE_ILK: 1789e0a03c85SMatthias Ringwald (void)memcpy(setup->sm_t, hash, 16); 1790e0a03c85SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_W2_CALCULATE_LE_LTK; 1791e0a03c85SMatthias Ringwald break; 1792e0a03c85SMatthias Ringwald case SM_BR_EDR_W4_CALCULATE_LE_LTK: 1793e0a03c85SMatthias Ringwald log_info("Derived LE LTK from BR/EDR Link Key"); 1794e0a03c85SMatthias Ringwald log_info_key("Link Key", hash); 1795e0a03c85SMatthias Ringwald (void)memcpy(setup->sm_ltk, hash, 16); 1796e0a03c85SMatthias Ringwald sm_truncate_key(setup->sm_ltk, sm_conn->sm_actual_encryption_key_size); 1797e0a03c85SMatthias Ringwald sm_conn->sm_connection_authenticated = setup->sm_link_key_type == AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256; 1798e0a03c85SMatthias Ringwald sm_store_bonding_information(sm_conn); 1799c18be159SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 1800e0a03c85SMatthias Ringwald break; 1801bdb14b0eSMatthias Ringwald #endif 1802bd57ffebSMatthias Ringwald default: 1803bd57ffebSMatthias Ringwald log_error("sm_sc_cmac_done in state %u", sm_conn->sm_engine_state); 1804bd57ffebSMatthias Ringwald break; 1805bd57ffebSMatthias Ringwald } 180670b44dd4SMatthias Ringwald sm_trigger_run(); 1807aec94140SMatthias Ringwald } 1808aec94140SMatthias Ringwald 1809688a08f9SMatthias 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){ 1810dc300847SMatthias Ringwald const uint16_t message_len = 65; 1811aec94140SMatthias Ringwald sm_cmac_connection = sm_conn; 18126535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, u, 32); 18136535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 32, v, 32); 1814aec94140SMatthias Ringwald sm_cmac_sc_buffer[64] = z; 1815aec94140SMatthias Ringwald log_info("f4 key"); 1816aec94140SMatthias Ringwald log_info_hexdump(x, 16); 1817aec94140SMatthias Ringwald log_info("f4 message"); 1818dc300847SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1819d1a1f6a4SMatthias Ringwald sm_cmac_message_start(x, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 1820aec94140SMatthias Ringwald } 1821aec94140SMatthias Ringwald 18220346c37cSMatthias Ringwald static const uint8_t f5_key_id[] = { 0x62, 0x74, 0x6c, 0x65 }; 18230346c37cSMatthias Ringwald static const uint8_t f5_length[] = { 0x01, 0x00}; 18240346c37cSMatthias Ringwald 18250346c37cSMatthias Ringwald static void f5_calculate_salt(sm_connection_t * sm_conn){ 18268334d3d8SMatthias Ringwald 18278334d3d8SMatthias Ringwald static const sm_key_t f5_salt = { 0x6C ,0x88, 0x83, 0x91, 0xAA, 0xF5, 0xA5, 0x38, 0x60, 0x37, 0x0B, 0xDB, 0x5A, 0x60, 0x83, 0xBE}; 18288334d3d8SMatthias Ringwald 182940c5d850SMatthias Ringwald log_info("f5_calculate_salt"); 18300346c37cSMatthias Ringwald // calculate salt for f5 18310346c37cSMatthias Ringwald const uint16_t message_len = 32; 18320346c37cSMatthias Ringwald sm_cmac_connection = sm_conn; 18336535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, setup->sm_dhkey, message_len); 1834d1a1f6a4SMatthias Ringwald sm_cmac_message_start(f5_salt, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 18350346c37cSMatthias Ringwald } 18360346c37cSMatthias Ringwald 18370346c37cSMatthias 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){ 18380346c37cSMatthias Ringwald const uint16_t message_len = 53; 18390346c37cSMatthias Ringwald sm_cmac_connection = sm_conn; 18400346c37cSMatthias Ringwald 18410346c37cSMatthias Ringwald // f5(W, N1, N2, A1, A2) = AES-CMACT (Counter = 0 || keyID || N1 || N2|| A1|| A2 || Length = 256) -- this is the MacKey 18420346c37cSMatthias Ringwald sm_cmac_sc_buffer[0] = 0; 18436535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 01, f5_key_id, 4); 18446535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 05, n1, 16); 18456535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 21, n2, 16); 18466535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 37, a1, 7); 18476535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 44, a2, 7); 18486535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 51, f5_length, 2); 18490346c37cSMatthias Ringwald log_info("f5 key"); 18500346c37cSMatthias Ringwald log_info_hexdump(t, 16); 18510346c37cSMatthias Ringwald log_info("f5 message for MacKey"); 18520346c37cSMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1853d1a1f6a4SMatthias Ringwald sm_cmac_message_start(t, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 18540346c37cSMatthias Ringwald } 18550346c37cSMatthias Ringwald 18560346c37cSMatthias Ringwald static void f5_calculate_mackey(sm_connection_t * sm_conn){ 18570346c37cSMatthias Ringwald sm_key56_t bd_addr_master, bd_addr_slave; 18580346c37cSMatthias Ringwald bd_addr_master[0] = setup->sm_m_addr_type; 18590346c37cSMatthias Ringwald bd_addr_slave[0] = setup->sm_s_addr_type; 18606535961aSMatthias Ringwald (void)memcpy(&bd_addr_master[1], setup->sm_m_address, 6); 18616535961aSMatthias Ringwald (void)memcpy(&bd_addr_slave[1], setup->sm_s_address, 6); 186242134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 18630346c37cSMatthias Ringwald // responder 18640346c37cSMatthias Ringwald f5_mackkey(sm_conn, setup->sm_t, setup->sm_peer_nonce, setup->sm_local_nonce, bd_addr_master, bd_addr_slave); 18650346c37cSMatthias Ringwald } else { 18660346c37cSMatthias Ringwald // initiator 18670346c37cSMatthias Ringwald f5_mackkey(sm_conn, setup->sm_t, setup->sm_local_nonce, setup->sm_peer_nonce, bd_addr_master, bd_addr_slave); 18680346c37cSMatthias Ringwald } 18690346c37cSMatthias Ringwald } 18700346c37cSMatthias Ringwald 18710346c37cSMatthias Ringwald // note: must be called right after f5_mackey, as sm_cmac_buffer[1..52] will be reused 18720346c37cSMatthias Ringwald static inline void f5_ltk(sm_connection_t * sm_conn, sm_key_t t){ 18730346c37cSMatthias Ringwald const uint16_t message_len = 53; 18740346c37cSMatthias Ringwald sm_cmac_connection = sm_conn; 18750346c37cSMatthias Ringwald sm_cmac_sc_buffer[0] = 1; 18760346c37cSMatthias Ringwald // 1..52 setup before 18770346c37cSMatthias Ringwald log_info("f5 key"); 18780346c37cSMatthias Ringwald log_info_hexdump(t, 16); 18790346c37cSMatthias Ringwald log_info("f5 message for LTK"); 18800346c37cSMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1881d1a1f6a4SMatthias Ringwald sm_cmac_message_start(t, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 18820346c37cSMatthias Ringwald } 1883f92edc8eSMatthias Ringwald 18840346c37cSMatthias Ringwald static void f5_calculate_ltk(sm_connection_t * sm_conn){ 18850346c37cSMatthias Ringwald f5_ltk(sm_conn, setup->sm_t); 18860346c37cSMatthias Ringwald } 18870346c37cSMatthias Ringwald 188831f061fbSMatthias 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){ 18896535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, n1, 16); 18906535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 16, n2, 16); 18916535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 32, r, 16); 18926535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 48, io_cap, 3); 18936535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 51, a1, 7); 18946535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 58, a2, 7); 189531f061fbSMatthias Ringwald } 189631f061fbSMatthias Ringwald 189731f061fbSMatthias Ringwald static void f6_engine(sm_connection_t * sm_conn, const sm_key_t w){ 189831f061fbSMatthias Ringwald const uint16_t message_len = 65; 189931f061fbSMatthias Ringwald sm_cmac_connection = sm_conn; 1900dc300847SMatthias Ringwald log_info("f6 key"); 1901dc300847SMatthias Ringwald log_info_hexdump(w, 16); 1902dc300847SMatthias Ringwald log_info("f6 message"); 1903dc300847SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1904d1a1f6a4SMatthias Ringwald sm_cmac_message_start(w, 65, sm_cmac_sc_buffer, &sm_sc_cmac_done); 1905dc300847SMatthias Ringwald } 1906dc300847SMatthias Ringwald 1907f92edc8eSMatthias Ringwald // g2(U, V, X, Y) = AES-CMACX(U || V || Y) mod 2^32 1908f92edc8eSMatthias Ringwald // - U is 256 bits 1909f92edc8eSMatthias Ringwald // - V is 256 bits 1910f92edc8eSMatthias Ringwald // - X is 128 bits 1911f92edc8eSMatthias Ringwald // - Y is 128 bits 1912bd57ffebSMatthias 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){ 1913bd57ffebSMatthias Ringwald const uint16_t message_len = 80; 1914bd57ffebSMatthias Ringwald sm_cmac_connection = sm_conn; 19156535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, u, 32); 19166535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 32, v, 32); 19176535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 64, y, 16); 1918f92edc8eSMatthias Ringwald log_info("g2 key"); 1919f92edc8eSMatthias Ringwald log_info_hexdump(x, 16); 1920f92edc8eSMatthias Ringwald log_info("g2 message"); 19212bacf595SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1922d1a1f6a4SMatthias Ringwald sm_cmac_message_start(x, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 1923f92edc8eSMatthias Ringwald } 1924f92edc8eSMatthias Ringwald 1925b35a3de2SMatthias Ringwald static void g2_calculate(sm_connection_t * sm_conn) { 1926f92edc8eSMatthias Ringwald // calc Va if numeric comparison 192742134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1928f92edc8eSMatthias Ringwald // responder 1929fc5bff5fSMatthias Ringwald g2_engine(sm_conn, setup->sm_peer_q, ec_q, setup->sm_peer_nonce, setup->sm_local_nonce);; 1930f92edc8eSMatthias Ringwald } else { 1931f92edc8eSMatthias Ringwald // initiator 1932fc5bff5fSMatthias Ringwald g2_engine(sm_conn, ec_q, setup->sm_peer_q, setup->sm_local_nonce, setup->sm_peer_nonce); 1933f92edc8eSMatthias Ringwald } 1934f92edc8eSMatthias Ringwald } 1935f92edc8eSMatthias Ringwald 1936945888f5SMatthias Ringwald static void sm_sc_calculate_local_confirm(sm_connection_t * sm_conn){ 19379af0f475SMatthias Ringwald uint8_t z = 0; 193840c5d850SMatthias Ringwald if (sm_passkey_entry(setup->sm_stk_generation_method)){ 19399af0f475SMatthias Ringwald // some form of passkey 19409af0f475SMatthias Ringwald uint32_t pk = big_endian_read_32(setup->sm_tk, 12); 19414ea43905SMatthias Ringwald z = 0x80u | ((pk >> setup->sm_passkey_bit) & 1u); 19429af0f475SMatthias Ringwald setup->sm_passkey_bit++; 19439af0f475SMatthias Ringwald } 1944fc5bff5fSMatthias Ringwald f4_engine(sm_conn, ec_q, setup->sm_peer_q, setup->sm_local_nonce, z); 19459af0f475SMatthias Ringwald } 1946688a08f9SMatthias Ringwald 1947688a08f9SMatthias Ringwald static void sm_sc_calculate_remote_confirm(sm_connection_t * sm_conn){ 1948a680ba6bSMatthias Ringwald // OOB 1949a680ba6bSMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 19504acf7b7bSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 19514acf7b7bSMatthias Ringwald f4_engine(sm_conn, setup->sm_peer_q, setup->sm_peer_q, setup->sm_ra, 0); 19524acf7b7bSMatthias Ringwald } else { 19534acf7b7bSMatthias Ringwald f4_engine(sm_conn, setup->sm_peer_q, setup->sm_peer_q, setup->sm_rb, 0); 19544acf7b7bSMatthias Ringwald } 1955a680ba6bSMatthias Ringwald return; 1956a680ba6bSMatthias Ringwald } 1957a680ba6bSMatthias Ringwald 1958688a08f9SMatthias Ringwald uint8_t z = 0; 195940c5d850SMatthias Ringwald if (sm_passkey_entry(setup->sm_stk_generation_method)){ 1960688a08f9SMatthias Ringwald // some form of passkey 1961688a08f9SMatthias Ringwald uint32_t pk = big_endian_read_32(setup->sm_tk, 12); 1962688a08f9SMatthias Ringwald // sm_passkey_bit was increased before sending confirm value 19634ea43905SMatthias Ringwald z = 0x80u | ((pk >> (setup->sm_passkey_bit-1u)) & 1u); 1964688a08f9SMatthias Ringwald } 1965fc5bff5fSMatthias Ringwald f4_engine(sm_conn, setup->sm_peer_q, ec_q, setup->sm_peer_nonce, z); 1966688a08f9SMatthias Ringwald } 1967688a08f9SMatthias Ringwald 19680346c37cSMatthias Ringwald static void sm_sc_prepare_dhkey_check(sm_connection_t * sm_conn){ 1969f688bdb8SMatthias Ringwald log_info("sm_sc_prepare_dhkey_check, DHKEY calculated %u", (setup->sm_state_vars & SM_STATE_VAR_DHKEY_CALCULATED) != 0 ? 1 : 0); 19703cf37b8cSMatthias Ringwald 1971f688bdb8SMatthias Ringwald if ((setup->sm_state_vars & SM_STATE_VAR_DHKEY_CALCULATED) != 0u){ 19723cf37b8cSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_SALT; 19733cf37b8cSMatthias Ringwald } else { 19743cf37b8cSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_CALCULATE_DHKEY; 19753cf37b8cSMatthias Ringwald } 1976d1a1f6a4SMatthias Ringwald } 19773cf37b8cSMatthias Ringwald 1978d1a1f6a4SMatthias Ringwald static void sm_sc_dhkey_calculated(void * arg){ 1979f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 1980f3582630SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 1981f3582630SMatthias Ringwald if (sm_conn == NULL) return; 1982f3582630SMatthias Ringwald 19831c34405fSMatthias Ringwald // check for invalid public key detected by Controller 19841c34405fSMatthias Ringwald if (sm_is_ff(setup->sm_dhkey, 32)){ 19851c34405fSMatthias Ringwald log_info("sm: peer public key invalid"); 19861c34405fSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 19871c34405fSMatthias Ringwald return; 19881c34405fSMatthias Ringwald } 19891c34405fSMatthias Ringwald 1990d1a1f6a4SMatthias Ringwald log_info("dhkey"); 1991d1a1f6a4SMatthias Ringwald log_info_hexdump(&setup->sm_dhkey[0], 32); 1992d1a1f6a4SMatthias Ringwald setup->sm_state_vars |= SM_STATE_VAR_DHKEY_CALCULATED; 1993d1a1f6a4SMatthias Ringwald // trigger next step 1994d1a1f6a4SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_CALCULATE_DHKEY){ 1995d1a1f6a4SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_SALT; 1996d1a1f6a4SMatthias Ringwald } 199770b44dd4SMatthias Ringwald sm_trigger_run(); 1998dc300847SMatthias Ringwald } 1999dc300847SMatthias Ringwald 2000dc300847SMatthias Ringwald static void sm_sc_calculate_f6_for_dhkey_check(sm_connection_t * sm_conn){ 2001dc300847SMatthias Ringwald // calculate DHKCheck 2002dc300847SMatthias Ringwald sm_key56_t bd_addr_master, bd_addr_slave; 2003dc300847SMatthias Ringwald bd_addr_master[0] = setup->sm_m_addr_type; 2004dc300847SMatthias Ringwald bd_addr_slave[0] = setup->sm_s_addr_type; 20056535961aSMatthias Ringwald (void)memcpy(&bd_addr_master[1], setup->sm_m_address, 6); 20066535961aSMatthias Ringwald (void)memcpy(&bd_addr_slave[1], setup->sm_s_address, 6); 2007dc300847SMatthias Ringwald uint8_t iocap_a[3]; 2008dc300847SMatthias Ringwald iocap_a[0] = sm_pairing_packet_get_auth_req(setup->sm_m_preq); 2009dc300847SMatthias Ringwald iocap_a[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq); 2010dc300847SMatthias Ringwald iocap_a[2] = sm_pairing_packet_get_io_capability(setup->sm_m_preq); 2011dc300847SMatthias Ringwald uint8_t iocap_b[3]; 2012dc300847SMatthias Ringwald iocap_b[0] = sm_pairing_packet_get_auth_req(setup->sm_s_pres); 2013dc300847SMatthias Ringwald iocap_b[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres); 2014dc300847SMatthias Ringwald iocap_b[2] = sm_pairing_packet_get_io_capability(setup->sm_s_pres); 201542134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 2016dc300847SMatthias Ringwald // responder 201731f061fbSMatthias Ringwald f6_setup(setup->sm_local_nonce, setup->sm_peer_nonce, setup->sm_ra, iocap_b, bd_addr_slave, bd_addr_master); 201831f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2019dc300847SMatthias Ringwald } else { 2020dc300847SMatthias Ringwald // initiator 202131f061fbSMatthias Ringwald f6_setup( setup->sm_local_nonce, setup->sm_peer_nonce, setup->sm_rb, iocap_a, bd_addr_master, bd_addr_slave); 202231f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2023dc300847SMatthias Ringwald } 2024dc300847SMatthias Ringwald } 2025dc300847SMatthias Ringwald 2026019005a0SMatthias Ringwald static void sm_sc_calculate_f6_to_verify_dhkey_check(sm_connection_t * sm_conn){ 2027019005a0SMatthias Ringwald // validate E = f6() 2028019005a0SMatthias Ringwald sm_key56_t bd_addr_master, bd_addr_slave; 2029019005a0SMatthias Ringwald bd_addr_master[0] = setup->sm_m_addr_type; 2030019005a0SMatthias Ringwald bd_addr_slave[0] = setup->sm_s_addr_type; 20316535961aSMatthias Ringwald (void)memcpy(&bd_addr_master[1], setup->sm_m_address, 6); 20326535961aSMatthias Ringwald (void)memcpy(&bd_addr_slave[1], setup->sm_s_address, 6); 2033019005a0SMatthias Ringwald 2034019005a0SMatthias Ringwald uint8_t iocap_a[3]; 2035019005a0SMatthias Ringwald iocap_a[0] = sm_pairing_packet_get_auth_req(setup->sm_m_preq); 2036019005a0SMatthias Ringwald iocap_a[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq); 2037019005a0SMatthias Ringwald iocap_a[2] = sm_pairing_packet_get_io_capability(setup->sm_m_preq); 2038019005a0SMatthias Ringwald uint8_t iocap_b[3]; 2039019005a0SMatthias Ringwald iocap_b[0] = sm_pairing_packet_get_auth_req(setup->sm_s_pres); 2040019005a0SMatthias Ringwald iocap_b[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres); 2041019005a0SMatthias Ringwald iocap_b[2] = sm_pairing_packet_get_io_capability(setup->sm_s_pres); 204242134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 2043019005a0SMatthias Ringwald // responder 204431f061fbSMatthias Ringwald f6_setup(setup->sm_peer_nonce, setup->sm_local_nonce, setup->sm_rb, iocap_a, bd_addr_master, bd_addr_slave); 204531f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2046019005a0SMatthias Ringwald } else { 2047019005a0SMatthias Ringwald // initiator 204831f061fbSMatthias Ringwald f6_setup(setup->sm_peer_nonce, setup->sm_local_nonce, setup->sm_ra, iocap_b, bd_addr_slave, bd_addr_master); 204931f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2050019005a0SMatthias Ringwald } 2051019005a0SMatthias Ringwald } 20522bacf595SMatthias Ringwald 20532419120aSMatthias Ringwald static void sm_sc_generate_nx_for_send_random(sm_connection_t * sm_conn){ 20542419120aSMatthias Ringwald // generate Nx 20552419120aSMatthias Ringwald log_info("Generate N%c", IS_RESPONDER(sm_conn->sm_role) ? 'b' : 'a'); 20562419120aSMatthias 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); 20572419120aSMatthias Ringwald } 20582419120aSMatthias Ringwald 205955c62cf5SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 20602bacf595SMatthias Ringwald 20612bacf595SMatthias Ringwald // 20622bacf595SMatthias Ringwald // Link Key Conversion Function h6 20632bacf595SMatthias Ringwald // 206457132f12SMatthias Ringwald // h6(W, keyID) = AES-CMAC_W(keyID) 20652bacf595SMatthias Ringwald // - W is 128 bits 20662bacf595SMatthias Ringwald // - keyID is 32 bits 20672bacf595SMatthias Ringwald static void h6_engine(sm_connection_t * sm_conn, const sm_key_t w, const uint32_t key_id){ 20682bacf595SMatthias Ringwald const uint16_t message_len = 4; 20692bacf595SMatthias Ringwald sm_cmac_connection = sm_conn; 20702bacf595SMatthias Ringwald big_endian_store_32(sm_cmac_sc_buffer, 0, key_id); 20712bacf595SMatthias Ringwald log_info("h6 key"); 20722bacf595SMatthias Ringwald log_info_hexdump(w, 16); 20732bacf595SMatthias Ringwald log_info("h6 message"); 20742bacf595SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 2075d1a1f6a4SMatthias Ringwald sm_cmac_message_start(w, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 20762bacf595SMatthias Ringwald } 207757132f12SMatthias Ringwald // 207857132f12SMatthias Ringwald // Link Key Conversion Function h7 207957132f12SMatthias Ringwald // 208057132f12SMatthias Ringwald // h7(SALT, W) = AES-CMAC_SALT(W) 208157132f12SMatthias Ringwald // - SALT is 128 bits 208257132f12SMatthias Ringwald // - W is 128 bits 208357132f12SMatthias Ringwald static void h7_engine(sm_connection_t * sm_conn, const sm_key_t salt, const sm_key_t w) { 208457132f12SMatthias Ringwald const uint16_t message_len = 16; 208557132f12SMatthias Ringwald sm_cmac_connection = sm_conn; 208657132f12SMatthias Ringwald log_info("h7 key"); 208757132f12SMatthias Ringwald log_info_hexdump(salt, 16); 208857132f12SMatthias Ringwald log_info("h7 message"); 208957132f12SMatthias Ringwald log_info_hexdump(w, 16); 209057132f12SMatthias Ringwald sm_cmac_message_start(salt, message_len, w, &sm_sc_cmac_done); 209157132f12SMatthias Ringwald } 20922bacf595SMatthias Ringwald 2093b18300a6SMatthias Ringwald // For SC, setup->sm_local_ltk holds full LTK (sm_ltk is already truncated) 2094b18300a6SMatthias Ringwald // Errata Service Release to the Bluetooth Specification: ESR09 2095b18300a6SMatthias Ringwald // E6405 – Cross transport key derivation from a key of size less than 128 bits 2096b18300a6SMatthias Ringwald // "Note: When the BR/EDR link key is being derived from the LTK, the derivation is done before the LTK gets masked." 209757132f12SMatthias Ringwald 2098c82679c3SMatthias Ringwald static void h6_calculate_ilk_from_le_ltk(sm_connection_t * sm_conn){ 2099b18300a6SMatthias Ringwald h6_engine(sm_conn, setup->sm_local_ltk, 0x746D7031); // "tmp1" 21002bacf595SMatthias Ringwald } 21012bacf595SMatthias Ringwald 2102e0a03c85SMatthias Ringwald static void h6_calculate_ilk_from_br_edr(sm_connection_t * sm_conn){ 2103e0a03c85SMatthias Ringwald h6_engine(sm_conn, setup->sm_link_key, 0x746D7032); // "tmp2" 2104e0a03c85SMatthias Ringwald } 2105e0a03c85SMatthias Ringwald 21062bacf595SMatthias Ringwald static void h6_calculate_br_edr_link_key(sm_connection_t * sm_conn){ 21072bacf595SMatthias Ringwald h6_engine(sm_conn, setup->sm_t, 0x6c656272); // "lebr" 21082bacf595SMatthias Ringwald } 21092bacf595SMatthias Ringwald 2110e0a03c85SMatthias Ringwald static void h6_calculate_le_ltk(sm_connection_t * sm_conn){ 2111e0a03c85SMatthias Ringwald h6_engine(sm_conn, setup->sm_t, 0x62726C65); // "brle" 2112e0a03c85SMatthias Ringwald } 2113e0a03c85SMatthias Ringwald 2114c82679c3SMatthias Ringwald static void h7_calculate_ilk_from_le_ltk(sm_connection_t * sm_conn){ 211557132f12SMatthias Ringwald const uint8_t salt[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x6D, 0x70, 0x31}; // "tmp1" 211657132f12SMatthias Ringwald h7_engine(sm_conn, salt, setup->sm_local_ltk); 211757132f12SMatthias Ringwald } 2118e0a03c85SMatthias Ringwald 2119e0a03c85SMatthias Ringwald static void h7_calculate_ilk_from_br_edr(sm_connection_t * sm_conn){ 2120e0a03c85SMatthias Ringwald const uint8_t salt[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x6D, 0x70, 0x32}; // "tmp2" 2121e0a03c85SMatthias Ringwald h7_engine(sm_conn, salt, setup->sm_link_key); 2122e0a03c85SMatthias Ringwald } 2123e0a03c85SMatthias Ringwald 2124c18be159SMatthias Ringwald static void sm_ctkd_fetch_br_edr_link_key(sm_connection_t * sm_conn){ 2125e0a03c85SMatthias Ringwald hci_connection_t * hci_connection = hci_connection_for_handle(sm_conn->sm_handle); 2126e0a03c85SMatthias Ringwald btstack_assert(hci_connection != NULL); 2127e0a03c85SMatthias Ringwald reverse_128(hci_connection->link_key, setup->sm_link_key); 2128e0a03c85SMatthias Ringwald setup->sm_link_key_type = hci_connection->link_key_type; 2129e0a03c85SMatthias Ringwald } 2130e0a03c85SMatthias Ringwald 213113aed524SMatthias Ringwald static void sm_ctkd_start_from_br_edr(sm_connection_t * sm_conn){ 213213aed524SMatthias Ringwald // only derive LTK if EncKey is set by both 213313aed524SMatthias Ringwald bool derive_ltk = (sm_pairing_packet_get_initiator_key_distribution(setup->sm_s_pres) & 213413aed524SMatthias Ringwald sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres) & SM_KEYDIST_ENC_KEY) != 0; 213513aed524SMatthias Ringwald if (derive_ltk){ 2136c18be159SMatthias 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; 213713aed524SMatthias Ringwald sm_conn->sm_engine_state = use_h7 ? SM_BR_EDR_W2_CALCULATE_ILK_USING_H7 : SM_BR_EDR_W2_CALCULATE_ILK_USING_H6; 213813aed524SMatthias Ringwald } else { 213913aed524SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 214013aed524SMatthias Ringwald } 2141c18be159SMatthias Ringwald } 2142c18be159SMatthias Ringwald 21439af0f475SMatthias Ringwald #endif 21449af0f475SMatthias Ringwald 214555c62cf5SMatthias Ringwald #endif 214655c62cf5SMatthias Ringwald 2147613da3deSMatthias Ringwald // key management legacy connections: 2148613da3deSMatthias Ringwald // - potentially two different LTKs based on direction. each device stores LTK provided by peer 2149613da3deSMatthias Ringwald // - master stores LTK, EDIV, RAND. responder optionally stored master LTK (only if it needs to reconnect) 2150613da3deSMatthias Ringwald // - initiators reconnects: initiator uses stored LTK, EDIV, RAND generated by responder 2151613da3deSMatthias Ringwald // - responder reconnects: responder uses LTK receveived from master 2152613da3deSMatthias Ringwald 2153613da3deSMatthias Ringwald // key management secure connections: 2154613da3deSMatthias Ringwald // - both devices store same LTK from ECDH key exchange. 2155613da3deSMatthias Ringwald 215642134bc6SMatthias Ringwald #if defined(ENABLE_LE_SECURE_CONNECTIONS) || defined(ENABLE_LE_CENTRAL) 21575829ebe2SMatthias Ringwald static void sm_load_security_info(sm_connection_t * sm_connection){ 21585829ebe2SMatthias Ringwald int encryption_key_size; 21595829ebe2SMatthias Ringwald int authenticated; 21605829ebe2SMatthias Ringwald int authorized; 21613dc3a67dSMatthias Ringwald int secure_connection; 21625829ebe2SMatthias Ringwald 21635829ebe2SMatthias Ringwald // fetch data from device db - incl. authenticated/authorized/key size. Note all sm_connection_X require encryption enabled 21645829ebe2SMatthias Ringwald le_device_db_encryption_get(sm_connection->sm_le_db_index, &setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk, 21653dc3a67dSMatthias Ringwald &encryption_key_size, &authenticated, &authorized, &secure_connection); 21663dc3a67dSMatthias 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); 21675829ebe2SMatthias Ringwald sm_connection->sm_actual_encryption_key_size = encryption_key_size; 21685829ebe2SMatthias Ringwald sm_connection->sm_connection_authenticated = authenticated; 21695829ebe2SMatthias Ringwald sm_connection->sm_connection_authorization_state = authorized ? AUTHORIZATION_GRANTED : AUTHORIZATION_UNKNOWN; 2170d7dbf891SMatthias Ringwald sm_connection->sm_connection_sc = secure_connection != 0; 21715829ebe2SMatthias Ringwald } 217242134bc6SMatthias Ringwald #endif 2173bd57ffebSMatthias Ringwald 217442134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 217559066796SMatthias Ringwald static void sm_start_calculating_ltk_from_ediv_and_rand(sm_connection_t * sm_connection){ 21766535961aSMatthias Ringwald (void)memcpy(setup->sm_local_rand, sm_connection->sm_local_rand, 8); 217759066796SMatthias Ringwald setup->sm_local_ediv = sm_connection->sm_local_ediv; 217859066796SMatthias Ringwald // re-establish used key encryption size 217959066796SMatthias Ringwald // no db for encryption size hack: encryption size is stored in lowest nibble of setup->sm_local_rand 21804ea43905SMatthias Ringwald sm_connection->sm_actual_encryption_key_size = (setup->sm_local_rand[7u] & 0x0fu) + 1u; 218159066796SMatthias Ringwald // no db for authenticated flag hack: flag is stored in bit 4 of LSB 21824ea43905SMatthias Ringwald sm_connection->sm_connection_authenticated = (setup->sm_local_rand[7u] & 0x10u) >> 4u; 21833dc3a67dSMatthias Ringwald // Legacy paring -> not SC 2184d7dbf891SMatthias Ringwald sm_connection->sm_connection_sc = false; 218559066796SMatthias Ringwald log_info("sm: received ltk request with key size %u, authenticated %u", 218659066796SMatthias Ringwald sm_connection->sm_actual_encryption_key_size, sm_connection->sm_connection_authenticated); 218759066796SMatthias Ringwald } 218842134bc6SMatthias Ringwald #endif 218959066796SMatthias Ringwald 21903deb3ec6SMatthias Ringwald // distributed key generation 2191d7f1c72eSMatthias Ringwald static bool sm_run_dpkg(void){ 21923deb3ec6SMatthias Ringwald switch (dkg_state){ 21933deb3ec6SMatthias Ringwald case DKG_CALC_IRK: 21943deb3ec6SMatthias Ringwald // already busy? 21953deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_IDLE) { 2196d1a1f6a4SMatthias Ringwald log_info("DKG_CALC_IRK started"); 21973deb3ec6SMatthias Ringwald // IRK = d1(IR, 1, 0) 2198d1a1f6a4SMatthias Ringwald sm_d1_d_prime(1, 0, sm_aes128_plaintext); // plaintext = d1 prime 2199d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2200d1a1f6a4SMatthias 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); 2201d7f1c72eSMatthias Ringwald return true; 22023deb3ec6SMatthias Ringwald } 22033deb3ec6SMatthias Ringwald break; 22043deb3ec6SMatthias Ringwald case DKG_CALC_DHK: 22053deb3ec6SMatthias Ringwald // already busy? 22063deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_IDLE) { 2207d1a1f6a4SMatthias Ringwald log_info("DKG_CALC_DHK started"); 22083deb3ec6SMatthias Ringwald // DHK = d1(IR, 3, 0) 2209d1a1f6a4SMatthias Ringwald sm_d1_d_prime(3, 0, sm_aes128_plaintext); // plaintext = d1 prime 2210d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2211d1a1f6a4SMatthias 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); 2212d7f1c72eSMatthias Ringwald return true; 22133deb3ec6SMatthias Ringwald } 22143deb3ec6SMatthias Ringwald break; 22153deb3ec6SMatthias Ringwald default: 22163deb3ec6SMatthias Ringwald break; 22173deb3ec6SMatthias Ringwald } 2218d7f1c72eSMatthias Ringwald return false; 2219d7f1c72eSMatthias Ringwald } 22203deb3ec6SMatthias Ringwald 22213deb3ec6SMatthias Ringwald // random address updates 2222d7f1c72eSMatthias Ringwald static bool sm_run_rau(void){ 22233deb3ec6SMatthias Ringwald switch (rau_state){ 2224fbd4e238SMatthias Ringwald case RAU_GET_RANDOM: 2225fbd4e238SMatthias Ringwald rau_state = RAU_W4_RANDOM; 22265b4dd597SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_address, 6, &sm_handle_random_result_rau, NULL); 2227d7f1c72eSMatthias Ringwald return true; 22283deb3ec6SMatthias Ringwald case RAU_GET_ENC: 22293deb3ec6SMatthias Ringwald // already busy? 22303deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_IDLE) { 2231d1a1f6a4SMatthias Ringwald sm_ah_r_prime(sm_random_address, sm_aes128_plaintext); 2232d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2233d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_irk, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_rau, NULL); 2234d7f1c72eSMatthias Ringwald return true; 22353deb3ec6SMatthias Ringwald } 22363deb3ec6SMatthias Ringwald break; 22373deb3ec6SMatthias Ringwald default: 22383deb3ec6SMatthias Ringwald break; 22393deb3ec6SMatthias Ringwald } 2240d7f1c72eSMatthias Ringwald return false; 2241d7f1c72eSMatthias Ringwald } 22423deb3ec6SMatthias Ringwald 224351258968SMatthias Ringwald // device lookup with IRK 224451258968SMatthias Ringwald static bool sm_run_irk_lookup(void){ 2245d7f1c72eSMatthias Ringwald btstack_linked_list_iterator_t it; 2246d7f1c72eSMatthias Ringwald 224751258968SMatthias Ringwald // -- if IRK lookup ready, find connection that require csrk lookup 22483deb3ec6SMatthias Ringwald if (sm_address_resolution_idle()){ 22493deb3ec6SMatthias Ringwald hci_connections_get_iterator(&it); 2250665d90f2SMatthias Ringwald while(btstack_linked_list_iterator_has_next(&it)){ 2251665d90f2SMatthias Ringwald hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 22523deb3ec6SMatthias Ringwald sm_connection_t * sm_connection = &hci_connection->sm_connection; 22533deb3ec6SMatthias Ringwald if (sm_connection->sm_irk_lookup_state == IRK_LOOKUP_W4_READY){ 22543deb3ec6SMatthias Ringwald // and start lookup 22553deb3ec6SMatthias 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); 22563deb3ec6SMatthias Ringwald sm_connection->sm_irk_lookup_state = IRK_LOOKUP_STARTED; 22573deb3ec6SMatthias Ringwald break; 22583deb3ec6SMatthias Ringwald } 22593deb3ec6SMatthias Ringwald } 22603deb3ec6SMatthias Ringwald } 22613deb3ec6SMatthias Ringwald 22623deb3ec6SMatthias Ringwald // -- if csrk lookup ready, resolved addresses for received addresses 22633deb3ec6SMatthias Ringwald if (sm_address_resolution_idle()) { 2264665d90f2SMatthias Ringwald if (!btstack_linked_list_empty(&sm_address_resolution_general_queue)){ 22653deb3ec6SMatthias Ringwald sm_lookup_entry_t * entry = (sm_lookup_entry_t *) sm_address_resolution_general_queue; 2266665d90f2SMatthias Ringwald btstack_linked_list_remove(&sm_address_resolution_general_queue, (btstack_linked_item_t *) entry); 22673deb3ec6SMatthias Ringwald sm_address_resolution_start_lookup(entry->address_type, 0, entry->address, ADDRESS_RESOLUTION_GENERAL, NULL); 22683deb3ec6SMatthias Ringwald btstack_memory_sm_lookup_entry_free(entry); 22693deb3ec6SMatthias Ringwald } 22703deb3ec6SMatthias Ringwald } 22713deb3ec6SMatthias Ringwald 2272ca685291SMatthias Ringwald // -- Continue with device lookup by public or resolvable private address 22733deb3ec6SMatthias Ringwald if (!sm_address_resolution_idle()){ 227472d2978cSMatthias Ringwald bool started_aes128 = false; 2275092ec58eSMatthias Ringwald while (sm_address_resolution_test < le_device_db_max_count()){ 2276adf5eaa9SMatthias Ringwald int addr_type = BD_ADDR_TYPE_UNKNOWN; 22773deb3ec6SMatthias Ringwald bd_addr_t addr; 22783deb3ec6SMatthias Ringwald sm_key_t irk; 22793deb3ec6SMatthias Ringwald le_device_db_info(sm_address_resolution_test, &addr_type, addr, irk); 22803deb3ec6SMatthias Ringwald 2281adf5eaa9SMatthias Ringwald // skip unused entries 2282adf5eaa9SMatthias Ringwald if (addr_type == BD_ADDR_TYPE_UNKNOWN){ 2283adf5eaa9SMatthias Ringwald sm_address_resolution_test++; 2284adf5eaa9SMatthias Ringwald continue; 2285adf5eaa9SMatthias Ringwald } 2286adf5eaa9SMatthias Ringwald 2287c2b94d32SMatthias Ringwald log_info("LE Device Lookup: device %u of %u - type %u, %s", sm_address_resolution_test, 2288c2b94d32SMatthias Ringwald le_device_db_max_count(), addr_type, bd_addr_to_str(addr)); 2289ca685291SMatthias Ringwald 2290c2b94d32SMatthias Ringwald // map resolved identity addresses to regular addresses 2291515f33beSMatthias Ringwald int regular_addr_type = sm_address_resolution_addr_type & 1; 2292515f33beSMatthias Ringwald if ((regular_addr_type == addr_type) && (memcmp(addr, sm_address_resolution_address, 6) == 0)){ 2293ca685291SMatthias Ringwald log_info("LE Device Lookup: found by { addr_type, address} "); 2294a66b030fSMatthias Ringwald sm_address_resolution_handle_event(ADDRESS_RESOLUTION_SUCCEEDED); 22953deb3ec6SMatthias Ringwald break; 22963deb3ec6SMatthias Ringwald } 22973deb3ec6SMatthias Ringwald 2298c2b94d32SMatthias Ringwald // if connection type is not random (i.e. public or resolved identity), it must be a different entry 2299c2b94d32SMatthias Ringwald if (sm_address_resolution_addr_type != BD_ADDR_TYPE_LE_RANDOM){ 23003deb3ec6SMatthias Ringwald sm_address_resolution_test++; 23013deb3ec6SMatthias Ringwald continue; 23023deb3ec6SMatthias Ringwald } 23033deb3ec6SMatthias Ringwald 23048cc81b50SMatthias Ringwald // skip AH if no IRK 23058cc81b50SMatthias Ringwald if (sm_is_null_key(irk)){ 23068cc81b50SMatthias Ringwald sm_address_resolution_test++; 23078cc81b50SMatthias Ringwald continue; 23088cc81b50SMatthias Ringwald } 23098cc81b50SMatthias Ringwald 23103deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 23113deb3ec6SMatthias Ringwald 23123deb3ec6SMatthias Ringwald log_info("LE Device Lookup: calculate AH"); 23138314c363SMatthias Ringwald log_info_key("IRK", irk); 23143deb3ec6SMatthias Ringwald 23156535961aSMatthias Ringwald (void)memcpy(sm_aes128_key, irk, 16); 2316d1a1f6a4SMatthias Ringwald sm_ah_r_prime(sm_address_resolution_address, sm_aes128_plaintext); 2317d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2318d1a1f6a4SMatthias 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); 231972d2978cSMatthias Ringwald started_aes128 = true; 232072d2978cSMatthias Ringwald break; 232172d2978cSMatthias Ringwald } 232272d2978cSMatthias Ringwald 232372d2978cSMatthias Ringwald if (started_aes128){ 2324d7f1c72eSMatthias Ringwald return true; 23253deb3ec6SMatthias Ringwald } 23263deb3ec6SMatthias Ringwald 2327092ec58eSMatthias Ringwald if (sm_address_resolution_test >= le_device_db_max_count()){ 23283deb3ec6SMatthias Ringwald log_info("LE Device Lookup: not found"); 23293deb3ec6SMatthias Ringwald sm_address_resolution_handle_event(ADDRESS_RESOLUTION_FAILED); 23303deb3ec6SMatthias Ringwald } 23313deb3ec6SMatthias Ringwald } 2332d7f1c72eSMatthias Ringwald return false; 2333d7f1c72eSMatthias Ringwald } 23343deb3ec6SMatthias Ringwald 2335d7f1c72eSMatthias Ringwald // SC OOB 2336d7f1c72eSMatthias Ringwald static bool sm_run_oob(void){ 2337c59d0c92SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2338c59d0c92SMatthias Ringwald switch (sm_sc_oob_state){ 2339c59d0c92SMatthias Ringwald case SM_SC_OOB_W2_CALC_CONFIRM: 2340c59d0c92SMatthias Ringwald if (!sm_cmac_ready()) break; 2341c59d0c92SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_W4_CONFIRM; 2342c59d0c92SMatthias Ringwald f4_engine(NULL, ec_q, ec_q, sm_sc_oob_random, 0); 2343d7f1c72eSMatthias Ringwald return true; 2344c59d0c92SMatthias Ringwald default: 2345c59d0c92SMatthias Ringwald break; 2346c59d0c92SMatthias Ringwald } 2347c59d0c92SMatthias Ringwald #endif 2348d7f1c72eSMatthias Ringwald return false; 2349d7f1c72eSMatthias Ringwald } 2350275aafe8SMatthias Ringwald 2351687a03c8SMatthias Ringwald static void sm_send_connectionless(sm_connection_t * sm_connection, const uint8_t * buffer, uint16_t size){ 2352687a03c8SMatthias Ringwald l2cap_send_connectionless(sm_connection->sm_handle, sm_connection->sm_cid, (uint8_t*) buffer, size); 2353687a03c8SMatthias Ringwald } 2354687a03c8SMatthias Ringwald 235541d32297SMatthias Ringwald // handle basic actions that don't requires the full context 2356d7f1c72eSMatthias Ringwald static bool sm_run_basic(void){ 2357d7f1c72eSMatthias Ringwald btstack_linked_list_iterator_t it; 235841d32297SMatthias Ringwald hci_connections_get_iterator(&it); 2359e9af1bf6SMatthias Ringwald while(btstack_linked_list_iterator_has_next(&it)){ 236041d32297SMatthias Ringwald hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 236141d32297SMatthias Ringwald sm_connection_t * sm_connection = &hci_connection->sm_connection; 236241d32297SMatthias Ringwald switch(sm_connection->sm_engine_state){ 2363f4935286SMatthias Ringwald 2364f4935286SMatthias Ringwald // general 2365f4935286SMatthias Ringwald case SM_GENERAL_SEND_PAIRING_FAILED: { 2366f4935286SMatthias Ringwald uint8_t buffer[2]; 2367f4935286SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_FAILED; 2368f4935286SMatthias Ringwald buffer[1] = sm_connection->sm_pairing_failed_reason; 2369f4935286SMatthias Ringwald sm_connection->sm_engine_state = sm_connection->sm_role ? SM_RESPONDER_IDLE : SM_INITIATOR_CONNECTED; 2370687a03c8SMatthias Ringwald sm_send_connectionless(sm_connection, (uint8_t*) buffer, sizeof(buffer)); 2371f4935286SMatthias Ringwald sm_pairing_complete(sm_connection, ERROR_CODE_AUTHENTICATION_FAILURE, sm_connection->sm_pairing_failed_reason); 2372f4935286SMatthias Ringwald sm_done_for_handle(sm_connection->sm_handle); 2373f4935286SMatthias Ringwald break; 2374f4935286SMatthias Ringwald } 2375f4935286SMatthias Ringwald 237641d32297SMatthias Ringwald // responder side 237741d32297SMatthias Ringwald case SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY: 237841d32297SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_IDLE; 237941d32297SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_negative_reply, sm_connection->sm_handle); 2380d7f1c72eSMatthias Ringwald return true; 23814b8b5afeSMatthias Ringwald 23824b8b5afeSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 23834b8b5afeSMatthias Ringwald case SM_SC_RECEIVED_LTK_REQUEST: 23844b8b5afeSMatthias Ringwald switch (sm_connection->sm_irk_lookup_state){ 23854b8b5afeSMatthias Ringwald case IRK_LOOKUP_FAILED: 2386e9af1bf6SMatthias Ringwald log_info("LTK Request: IRK Lookup Failed)"); 23874b8b5afeSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_IDLE; 23884b8b5afeSMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_negative_reply, sm_connection->sm_handle); 2389d7f1c72eSMatthias Ringwald return true; 23904b8b5afeSMatthias Ringwald default: 23914b8b5afeSMatthias Ringwald break; 23924b8b5afeSMatthias Ringwald } 23934b8b5afeSMatthias Ringwald break; 23944b8b5afeSMatthias Ringwald #endif 239541d32297SMatthias Ringwald default: 239641d32297SMatthias Ringwald break; 239741d32297SMatthias Ringwald } 239841d32297SMatthias Ringwald } 2399d7f1c72eSMatthias Ringwald return false; 2400d7f1c72eSMatthias Ringwald } 24013deb3ec6SMatthias Ringwald 2402d7f1c72eSMatthias Ringwald static void sm_run_activate_connection(void){ 24033deb3ec6SMatthias Ringwald // Find connections that requires setup context and make active if no other is locked 2404d7f1c72eSMatthias Ringwald btstack_linked_list_iterator_t it; 24053deb3ec6SMatthias Ringwald hci_connections_get_iterator(&it); 24067149bde5SMatthias Ringwald while((sm_active_connection_handle == HCI_CON_HANDLE_INVALID) && btstack_linked_list_iterator_has_next(&it)){ 2407665d90f2SMatthias Ringwald hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 24083deb3ec6SMatthias Ringwald sm_connection_t * sm_connection = &hci_connection->sm_connection; 24093deb3ec6SMatthias Ringwald // - if no connection locked and we're ready/waiting for setup context, fetch it and start 24101979f09cSMatthias Ringwald bool done = true; 241134b6528fSMatthias Ringwald 241234b6528fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 241334b6528fSMatthias Ringwald // assert ec key is ready 2414505f1c30SMatthias Ringwald if ( (sm_connection->sm_engine_state == SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED) 2415178e8c1bSMatthias Ringwald || (sm_connection->sm_engine_state == SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST) 2416178e8c1bSMatthias Ringwald || (sm_connection->sm_engine_state == SM_RESPONDER_SEND_SECURITY_REQUEST)){ 241734b6528fSMatthias Ringwald if (ec_key_generation_state == EC_KEY_GENERATION_IDLE){ 241834b6528fSMatthias Ringwald sm_ec_generate_new_key(); 241934b6528fSMatthias Ringwald } 242034b6528fSMatthias Ringwald if (ec_key_generation_state != EC_KEY_GENERATION_DONE){ 242134b6528fSMatthias Ringwald continue; 242234b6528fSMatthias Ringwald } 242334b6528fSMatthias Ringwald } 242434b6528fSMatthias Ringwald #endif 242534b6528fSMatthias Ringwald 24263deb3ec6SMatthias Ringwald switch (sm_connection->sm_engine_state) { 242742134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 24283deb3ec6SMatthias Ringwald case SM_RESPONDER_SEND_SECURITY_REQUEST: 24293deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED: 243042134bc6SMatthias Ringwald case SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST: 2431549ad5d2SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 243206cd539fSMatthias Ringwald case SM_SC_RECEIVED_LTK_REQUEST: 243387014f74SMatthias Ringwald #endif 243487014f74SMatthias Ringwald #endif 243534c39fbdSMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 24365567aa60SMatthias Ringwald case SM_INITIATOR_PH4_HAS_LTK: 243734c39fbdSMatthias Ringwald case SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST: 2438549ad5d2SMatthias Ringwald #endif 2439c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 2440c18be159SMatthias Ringwald case SM_BR_EDR_RESPONDER_PAIRING_REQUEST_RECEIVED: 2441c18be159SMatthias Ringwald case SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST: 2442c18be159SMatthias Ringwald #endif 244387014f74SMatthias Ringwald // just lock context 244487014f74SMatthias Ringwald break; 24453deb3ec6SMatthias Ringwald default: 24461979f09cSMatthias Ringwald done = false; 24473deb3ec6SMatthias Ringwald break; 24483deb3ec6SMatthias Ringwald } 24493deb3ec6SMatthias Ringwald if (done){ 24507149bde5SMatthias Ringwald sm_active_connection_handle = sm_connection->sm_handle; 24517149bde5SMatthias 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); 24523deb3ec6SMatthias Ringwald } 24533deb3ec6SMatthias Ringwald } 2454d7f1c72eSMatthias Ringwald } 2455d7f1c72eSMatthias Ringwald 2456403280b9SMatthias Ringwald static void sm_run_send_keypress_notification(sm_connection_t * connection){ 2457403280b9SMatthias Ringwald int i; 2458403280b9SMatthias Ringwald uint8_t flags = setup->sm_keypress_notification & 0x1fu; 2459403280b9SMatthias Ringwald uint8_t num_actions = setup->sm_keypress_notification >> 5; 2460403280b9SMatthias Ringwald uint8_t action = 0; 2461403280b9SMatthias Ringwald for (i=SM_KEYPRESS_PASSKEY_ENTRY_STARTED;i<=SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED;i++){ 24621d80f1e6SMatthias Ringwald if ((flags & (1u<<i)) != 0u){ 2463403280b9SMatthias Ringwald bool clear_flag = true; 2464403280b9SMatthias Ringwald switch (i){ 2465403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_STARTED: 2466403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_CLEARED: 2467403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED: 2468403280b9SMatthias Ringwald default: 2469403280b9SMatthias Ringwald break; 2470403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ENTERED: 2471403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ERASED: 2472403280b9SMatthias Ringwald num_actions--; 2473403280b9SMatthias Ringwald clear_flag = num_actions == 0u; 2474403280b9SMatthias Ringwald break; 2475403280b9SMatthias Ringwald } 2476403280b9SMatthias Ringwald if (clear_flag){ 2477403280b9SMatthias Ringwald flags &= ~(1<<i); 2478403280b9SMatthias Ringwald } 2479403280b9SMatthias Ringwald action = i; 2480403280b9SMatthias Ringwald break; 2481403280b9SMatthias Ringwald } 2482403280b9SMatthias Ringwald } 2483403280b9SMatthias Ringwald setup->sm_keypress_notification = (num_actions << 5) | flags; 2484403280b9SMatthias Ringwald 2485403280b9SMatthias Ringwald // send keypress notification 2486403280b9SMatthias Ringwald uint8_t buffer[2]; 2487403280b9SMatthias Ringwald buffer[0] = SM_CODE_KEYPRESS_NOTIFICATION; 2488403280b9SMatthias Ringwald buffer[1] = action; 2489687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2490403280b9SMatthias Ringwald 2491403280b9SMatthias Ringwald // try 2492384eabd3SMatthias Ringwald l2cap_request_can_send_fix_channel_now_event(sm_active_connection_handle, connection->sm_cid); 2493403280b9SMatthias Ringwald } 2494403280b9SMatthias Ringwald 2495403280b9SMatthias Ringwald static void sm_run_distribute_keys(sm_connection_t * connection){ 24961d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION) != 0u){ 2497403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 2498403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 2499403280b9SMatthias Ringwald uint8_t buffer[17]; 2500403280b9SMatthias Ringwald buffer[0] = SM_CODE_ENCRYPTION_INFORMATION; 2501403280b9SMatthias Ringwald reverse_128(setup->sm_ltk, &buffer[1]); 2502687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2503403280b9SMatthias Ringwald sm_timeout_reset(connection); 2504403280b9SMatthias Ringwald return; 2505403280b9SMatthias Ringwald } 25061d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_MASTER_IDENTIFICATION) != 0u){ 2507403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 2508403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 2509403280b9SMatthias Ringwald uint8_t buffer[11]; 2510403280b9SMatthias Ringwald buffer[0] = SM_CODE_MASTER_IDENTIFICATION; 2511403280b9SMatthias Ringwald little_endian_store_16(buffer, 1, setup->sm_local_ediv); 2512403280b9SMatthias Ringwald reverse_64(setup->sm_local_rand, &buffer[3]); 2513687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2514403280b9SMatthias Ringwald sm_timeout_reset(connection); 2515403280b9SMatthias Ringwald return; 2516403280b9SMatthias Ringwald } 25171d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION) != 0u){ 2518403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 2519403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 2520403280b9SMatthias Ringwald uint8_t buffer[17]; 2521403280b9SMatthias Ringwald buffer[0] = SM_CODE_IDENTITY_INFORMATION; 2522403280b9SMatthias Ringwald reverse_128(sm_persistent_irk, &buffer[1]); 2523687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2524403280b9SMatthias Ringwald sm_timeout_reset(connection); 2525403280b9SMatthias Ringwald return; 2526403280b9SMatthias Ringwald } 25271d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION) != 0u){ 2528403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 2529403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 2530403280b9SMatthias Ringwald bd_addr_t local_address; 2531403280b9SMatthias Ringwald uint8_t buffer[8]; 2532403280b9SMatthias Ringwald buffer[0] = SM_CODE_IDENTITY_ADDRESS_INFORMATION; 2533403280b9SMatthias Ringwald switch (gap_random_address_get_mode()){ 2534403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_OFF: 2535403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_STATIC: 2536403280b9SMatthias Ringwald // public or static random 2537403280b9SMatthias Ringwald gap_le_get_own_address(&buffer[1], local_address); 2538403280b9SMatthias Ringwald break; 2539403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_NON_RESOLVABLE: 2540403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_RESOLVABLE: 2541403280b9SMatthias Ringwald // fallback to public 2542403280b9SMatthias Ringwald gap_local_bd_addr(local_address); 2543403280b9SMatthias Ringwald buffer[1] = 0; 2544403280b9SMatthias Ringwald break; 2545403280b9SMatthias Ringwald default: 2546403280b9SMatthias Ringwald btstack_assert(false); 2547403280b9SMatthias Ringwald break; 2548403280b9SMatthias Ringwald } 2549403280b9SMatthias Ringwald reverse_bd_addr(local_address, &buffer[2]); 2550687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2551403280b9SMatthias Ringwald sm_timeout_reset(connection); 2552403280b9SMatthias Ringwald return; 2553403280b9SMatthias Ringwald } 25541d80f1e6SMatthias Ringwald if ((setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION) != 0u){ 2555403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 2556403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 2557403280b9SMatthias Ringwald 2558403280b9SMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 2559403280b9SMatthias Ringwald // hack to reproduce test runs 2560403280b9SMatthias Ringwald if (test_use_fixed_local_csrk){ 2561403280b9SMatthias Ringwald memset(setup->sm_local_csrk, 0xcc, 16); 2562403280b9SMatthias Ringwald } 2563403280b9SMatthias Ringwald 2564403280b9SMatthias Ringwald // store local CSRK 2565403280b9SMatthias Ringwald if (setup->sm_le_device_index >= 0){ 2566403280b9SMatthias Ringwald log_info("sm: store local CSRK"); 2567403280b9SMatthias Ringwald le_device_db_local_csrk_set(setup->sm_le_device_index, setup->sm_local_csrk); 2568403280b9SMatthias Ringwald le_device_db_local_counter_set(setup->sm_le_device_index, 0); 2569403280b9SMatthias Ringwald } 2570403280b9SMatthias Ringwald #endif 2571403280b9SMatthias Ringwald 2572403280b9SMatthias Ringwald uint8_t buffer[17]; 2573403280b9SMatthias Ringwald buffer[0] = SM_CODE_SIGNING_INFORMATION; 2574403280b9SMatthias Ringwald reverse_128(setup->sm_local_csrk, &buffer[1]); 2575687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2576403280b9SMatthias Ringwald sm_timeout_reset(connection); 2577403280b9SMatthias Ringwald return; 2578403280b9SMatthias Ringwald } 2579403280b9SMatthias Ringwald btstack_assert(false); 2580403280b9SMatthias Ringwald } 2581403280b9SMatthias Ringwald 2582bbd73538SMatthias Ringwald static bool sm_ctkd_from_le(sm_connection_t *sm_connection) { 2583bbd73538SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 2584bbd73538SMatthias Ringwald // requirements to derive link key from LE: 2585bbd73538SMatthias Ringwald // - use secure connections 2586bbd73538SMatthias Ringwald if (setup->sm_use_secure_connections == 0) return false; 2587bbd73538SMatthias Ringwald // - bonding needs to be enabled: 2588bbd73538SMatthias 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; 2589bbd73538SMatthias Ringwald if (!bonding_enabled) return false; 2590bbd73538SMatthias Ringwald // - need identity address / public addr 2591bbd73538SMatthias 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); 2592bbd73538SMatthias Ringwald if (!have_identity_address_info) return false; 2593bbd73538SMatthias 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) 2594bbd73538SMatthias Ringwald // this requirement is motivated by BLURtooth paper. The paper recommends to not overwrite keys at all. 2595bbd73538SMatthias Ringwald // If SC is authenticated, we consider it safe to overwrite a stored key. 2596bbd73538SMatthias 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. 2597bbd73538SMatthias Ringwald uint8_t link_key[16]; 2598bbd73538SMatthias Ringwald link_key_type_t link_key_type; 2599bbd73538SMatthias Ringwald bool have_link_key = gap_get_link_key_for_bd_addr(setup->sm_peer_address, link_key, &link_key_type); 26007040ba26SMatthias Ringwald bool link_key_authenticated = gap_authenticated_for_link_key_type(link_key_type); 2601bbd73538SMatthias Ringwald bool derived_key_authenticated = sm_connection->sm_connection_authenticated != 0; 2602bbd73538SMatthias Ringwald if (have_link_key && link_key_authenticated && !derived_key_authenticated) { 2603bbd73538SMatthias Ringwald return false; 2604bbd73538SMatthias Ringwald } 2605bbd73538SMatthias Ringwald // get started (all of the above are true) 2606bbd73538SMatthias Ringwald return true; 2607bbd73538SMatthias Ringwald #else 2608bbd73538SMatthias Ringwald UNUSED(sm_connection); 2609bbd73538SMatthias Ringwald return false; 2610bbd73538SMatthias Ringwald #endif 2611bbd73538SMatthias Ringwald } 2612bbd73538SMatthias Ringwald 26136a718a5eSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 26146a718a5eSMatthias Ringwald static bool sm_ctkd_from_classic(sm_connection_t * sm_connection){ 26156a718a5eSMatthias Ringwald hci_connection_t * hci_connection = hci_connection_for_handle(sm_connection->sm_handle); 26166a718a5eSMatthias Ringwald btstack_assert(hci_connection != NULL); 26176a718a5eSMatthias Ringwald // requirements to derive ltk from BR/EDR: 26186a718a5eSMatthias Ringwald // - BR/EDR uses secure connections 26196a718a5eSMatthias Ringwald if (gap_secure_connection_for_link_key_type(hci_connection->link_key_type) == false) return false; 26206a718a5eSMatthias 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) 26216a718a5eSMatthias Ringwald bool link_key_authenticated = gap_authenticated_for_link_key_type(hci_connection->link_key_type); 26226a718a5eSMatthias Ringwald if (link_key_authenticated) return true; 26236a718a5eSMatthias Ringwald int index = sm_le_device_db_index_lookup(BD_ADDR_TYPE_LE_PUBLIC, hci_connection->address); 26246a718a5eSMatthias Ringwald if (index >= 0){ 26256a718a5eSMatthias Ringwald int ltk_authenticated; 26266a718a5eSMatthias Ringwald sm_key_t ltk; 26276a718a5eSMatthias Ringwald le_device_db_encryption_get(sm_connection->sm_le_db_index, NULL, NULL, ltk, NULL, <k_authenticated, NULL, NULL); 26286a718a5eSMatthias Ringwald bool have_ltk = !sm_is_null_key(ltk); 26296a718a5eSMatthias Ringwald if (have_ltk && ltk_authenticated) return false; 26306a718a5eSMatthias Ringwald } 26316a718a5eSMatthias Ringwald return true; 26326a718a5eSMatthias Ringwald } 26336a718a5eSMatthias Ringwald #endif 26346a718a5eSMatthias Ringwald 26356f7422f1SMatthias Ringwald static void sm_key_distribution_complete_responder(sm_connection_t * connection){ 26366f7422f1SMatthias Ringwald if (sm_ctkd_from_le(connection)){ 26376f7422f1SMatthias 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; 26386f7422f1SMatthias Ringwald connection->sm_engine_state = use_h7 ? SM_SC_W2_CALCULATE_ILK_USING_H7 : SM_SC_W2_CALCULATE_ILK_USING_H6; 26396f7422f1SMatthias Ringwald } else { 26406f7422f1SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_IDLE; 26416f7422f1SMatthias Ringwald sm_pairing_complete(connection, ERROR_CODE_SUCCESS, 0); 26426f7422f1SMatthias Ringwald sm_done_for_handle(connection->sm_handle); 26436f7422f1SMatthias Ringwald } 26446f7422f1SMatthias Ringwald } 26456f7422f1SMatthias Ringwald 2646af7ef9d1SMatthias Ringwald static void sm_key_distribution_complete_initiator(sm_connection_t * connection){ 2647af7ef9d1SMatthias Ringwald if (sm_ctkd_from_le(connection)){ 2648af7ef9d1SMatthias 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; 2649af7ef9d1SMatthias Ringwald connection->sm_engine_state = use_h7 ? SM_SC_W2_CALCULATE_ILK_USING_H7 : SM_SC_W2_CALCULATE_ILK_USING_H6; 2650af7ef9d1SMatthias Ringwald } else { 2651af7ef9d1SMatthias Ringwald sm_master_pairing_success(connection); 2652af7ef9d1SMatthias Ringwald } 2653af7ef9d1SMatthias Ringwald } 2654af7ef9d1SMatthias Ringwald 2655b919f264SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2656b919f264SMatthias Ringwald static void sm_run_state_sc_send_confirmation(sm_connection_t *connection) { 2657b919f264SMatthias Ringwald uint8_t buffer[17]; 2658b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_CONFIRM; 2659b919f264SMatthias Ringwald reverse_128(setup->sm_local_confirm, &buffer[1]); 2660b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2661b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2662b919f264SMatthias Ringwald } else { 2663b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2664b919f264SMatthias Ringwald } 2665b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2666b919f264SMatthias Ringwald sm_timeout_reset(connection); 2667b919f264SMatthias Ringwald } 2668b919f264SMatthias Ringwald 2669b919f264SMatthias Ringwald static void sm_run_state_sc_send_pairing_random(sm_connection_t *connection) { 2670b919f264SMatthias Ringwald uint8_t buffer[17]; 2671b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_RANDOM; 2672b919f264SMatthias Ringwald reverse_128(setup->sm_local_nonce, &buffer[1]); 2673b919f264SMatthias Ringwald log_info("stk method %u, bit num: %u", setup->sm_stk_generation_method, setup->sm_passkey_bit); 2674b919f264SMatthias Ringwald if (sm_passkey_entry(setup->sm_stk_generation_method) && (setup->sm_passkey_bit < 20u)){ 2675b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM A"); 2676b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2677b919f264SMatthias Ringwald // responder 2678b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2679b919f264SMatthias Ringwald } else { 2680b919f264SMatthias Ringwald // initiator 2681b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2682b919f264SMatthias Ringwald } 2683b919f264SMatthias Ringwald } else { 2684b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM B"); 2685b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2686b919f264SMatthias Ringwald // responder 2687b919f264SMatthias Ringwald if (setup->sm_stk_generation_method == NUMERIC_COMPARISON){ 2688b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM B1"); 2689b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W2_CALCULATE_G2; 2690b919f264SMatthias Ringwald } else { 2691b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM B2"); 2692b919f264SMatthias Ringwald sm_sc_prepare_dhkey_check(connection); 2693b919f264SMatthias Ringwald } 2694b919f264SMatthias Ringwald } else { 2695b919f264SMatthias Ringwald // initiator 2696b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2697b919f264SMatthias Ringwald } 2698b919f264SMatthias Ringwald } 2699b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2700b919f264SMatthias Ringwald sm_timeout_reset(connection); 2701b919f264SMatthias Ringwald } 2702b919f264SMatthias Ringwald 2703b919f264SMatthias Ringwald static void sm_run_state_sc_send_dhkey_check_command(sm_connection_t *connection) { 2704b919f264SMatthias Ringwald uint8_t buffer[17]; 2705b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_DHKEY_CHECK; 2706b919f264SMatthias Ringwald reverse_128(setup->sm_local_dhkey_check, &buffer[1]); 2707b919f264SMatthias Ringwald 2708b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2709b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_LTK_REQUEST_SC; 2710b919f264SMatthias Ringwald } else { 2711b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_DHKEY_CHECK_COMMAND; 2712b919f264SMatthias Ringwald } 2713b919f264SMatthias Ringwald 2714b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2715b919f264SMatthias Ringwald sm_timeout_reset(connection); 2716b919f264SMatthias Ringwald } 2717b919f264SMatthias Ringwald 2718b919f264SMatthias Ringwald static void sm_run_state_sc_send_public_key_command(sm_connection_t *connection) { 2719b919f264SMatthias Ringwald bool trigger_user_response = false; 2720b919f264SMatthias Ringwald bool trigger_start_calculating_local_confirm = false; 2721b919f264SMatthias Ringwald uint8_t buffer[65]; 2722b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_PUBLIC_KEY; 2723b919f264SMatthias Ringwald // 2724b919f264SMatthias Ringwald reverse_256(&ec_q[0], &buffer[1]); 2725b919f264SMatthias Ringwald reverse_256(&ec_q[32], &buffer[33]); 2726b919f264SMatthias Ringwald 2727b919f264SMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 2728b919f264SMatthias Ringwald if (test_pairing_failure == SM_REASON_DHKEY_CHECK_FAILED){ 2729b919f264SMatthias Ringwald log_info("testing_support: invalidating public key"); 2730b919f264SMatthias Ringwald // flip single bit of public key coordinate 2731b919f264SMatthias Ringwald buffer[1] ^= 1; 2732b919f264SMatthias Ringwald } 2733b919f264SMatthias Ringwald #endif 2734b919f264SMatthias Ringwald 2735b919f264SMatthias Ringwald // stk generation method 2736b919f264SMatthias Ringwald // passkey entry: notify app to show passkey or to request passkey 2737b919f264SMatthias Ringwald switch (setup->sm_stk_generation_method){ 2738b919f264SMatthias Ringwald case JUST_WORKS: 2739b919f264SMatthias Ringwald case NUMERIC_COMPARISON: 2740b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2741b919f264SMatthias Ringwald // responder 2742b919f264SMatthias Ringwald trigger_start_calculating_local_confirm = true; 2743b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_LOCAL_NONCE; 2744b919f264SMatthias Ringwald } else { 2745b919f264SMatthias Ringwald // initiator 2746b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2747b919f264SMatthias Ringwald } 2748b919f264SMatthias Ringwald break; 2749b919f264SMatthias Ringwald case PK_INIT_INPUT: 2750b919f264SMatthias Ringwald case PK_RESP_INPUT: 2751b919f264SMatthias Ringwald case PK_BOTH_INPUT: 2752b919f264SMatthias Ringwald // use random TK for display 2753b919f264SMatthias Ringwald (void)memcpy(setup->sm_ra, setup->sm_tk, 16); 2754b919f264SMatthias Ringwald (void)memcpy(setup->sm_rb, setup->sm_tk, 16); 2755b919f264SMatthias Ringwald setup->sm_passkey_bit = 0; 2756b919f264SMatthias Ringwald 2757b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2758b919f264SMatthias Ringwald // responder 2759b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2760b919f264SMatthias Ringwald } else { 2761b919f264SMatthias Ringwald // initiator 2762b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2763b919f264SMatthias Ringwald } 2764b919f264SMatthias Ringwald trigger_user_response = true; 2765b919f264SMatthias Ringwald break; 2766b919f264SMatthias Ringwald case OOB: 2767b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2768b919f264SMatthias Ringwald // responder 2769b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2770b919f264SMatthias Ringwald } else { 2771b919f264SMatthias Ringwald // initiator 2772b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2773b919f264SMatthias Ringwald } 2774b919f264SMatthias Ringwald break; 2775b919f264SMatthias Ringwald default: 2776b919f264SMatthias Ringwald btstack_assert(false); 2777b919f264SMatthias Ringwald break; 2778b919f264SMatthias Ringwald } 2779b919f264SMatthias Ringwald 2780b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2781b919f264SMatthias Ringwald sm_timeout_reset(connection); 2782b919f264SMatthias Ringwald 2783b919f264SMatthias Ringwald // trigger user response and calc confirm after sending pdu 2784b919f264SMatthias Ringwald if (trigger_user_response){ 2785b919f264SMatthias Ringwald sm_trigger_user_response(connection); 2786b919f264SMatthias Ringwald } 2787b919f264SMatthias Ringwald if (trigger_start_calculating_local_confirm){ 2788b919f264SMatthias Ringwald sm_sc_start_calculating_local_confirm(connection); 2789b919f264SMatthias Ringwald } 2790b919f264SMatthias Ringwald } 2791b919f264SMatthias Ringwald #endif 2792b919f264SMatthias Ringwald 2793de42cac5SMatthias Ringwald static bool sm_run_non_connection_logic(void){ 2794de42cac5SMatthias Ringwald bool done;; 2795de42cac5SMatthias Ringwald 2796de42cac5SMatthias Ringwald done = sm_run_dpkg(); 2797de42cac5SMatthias Ringwald if (done) return true; 2798de42cac5SMatthias Ringwald 2799de42cac5SMatthias Ringwald done = sm_run_rau(); 2800de42cac5SMatthias Ringwald if (done) return true; 2801de42cac5SMatthias Ringwald 280251258968SMatthias Ringwald done = sm_run_irk_lookup(); 2803de42cac5SMatthias Ringwald if (done) return true; 2804de42cac5SMatthias Ringwald 2805de42cac5SMatthias Ringwald done = sm_run_oob(); 2806de42cac5SMatthias Ringwald return done; 2807de42cac5SMatthias Ringwald } 2808b919f264SMatthias Ringwald 2809d7f1c72eSMatthias Ringwald static void sm_run(void){ 2810d7f1c72eSMatthias Ringwald 2811d7f1c72eSMatthias Ringwald // assert that stack has already bootet 2812d7f1c72eSMatthias Ringwald if (hci_get_state() != HCI_STATE_WORKING) return; 2813d7f1c72eSMatthias Ringwald 2814d7f1c72eSMatthias Ringwald // assert that we can send at least commands 2815d7f1c72eSMatthias Ringwald if (!hci_can_send_command_packet_now()) return; 2816d7f1c72eSMatthias Ringwald 2817d7f1c72eSMatthias Ringwald // pause until IR/ER are ready 2818d7f1c72eSMatthias Ringwald if (sm_persistent_keys_random_active) return; 2819d7f1c72eSMatthias Ringwald 2820d7f1c72eSMatthias Ringwald // non-connection related behaviour 2821de42cac5SMatthias Ringwald bool done = sm_run_non_connection_logic(); 2822d7f1c72eSMatthias Ringwald if (done) return; 2823d7f1c72eSMatthias Ringwald 2824d7f1c72eSMatthias Ringwald // assert that we can send at least commands - cmd might have been sent by crypto engine 2825d7f1c72eSMatthias Ringwald if (!hci_can_send_command_packet_now()) return; 2826d7f1c72eSMatthias Ringwald 2827d7f1c72eSMatthias Ringwald // handle basic actions that don't requires the full context 2828d7f1c72eSMatthias Ringwald done = sm_run_basic(); 2829d7f1c72eSMatthias Ringwald if (done) return; 2830d7f1c72eSMatthias Ringwald 2831d7f1c72eSMatthias Ringwald // 2832d7f1c72eSMatthias Ringwald // active connection handling 2833d7f1c72eSMatthias Ringwald // -- use loop to handle next connection if lock on setup context is released 2834d7f1c72eSMatthias Ringwald 2835d7f1c72eSMatthias Ringwald while (true) { 2836d7f1c72eSMatthias Ringwald 2837d7f1c72eSMatthias Ringwald sm_run_activate_connection(); 2838d7f1c72eSMatthias Ringwald 2839d7f1c72eSMatthias Ringwald if (sm_active_connection_handle == HCI_CON_HANDLE_INVALID) return; 28403deb3ec6SMatthias Ringwald 28413deb3ec6SMatthias Ringwald // 28423deb3ec6SMatthias Ringwald // active connection handling 28433deb3ec6SMatthias Ringwald // 28443deb3ec6SMatthias Ringwald 28453cf37b8cSMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(sm_active_connection_handle); 28463cf37b8cSMatthias Ringwald if (!connection) { 28473cf37b8cSMatthias Ringwald log_info("no connection for handle 0x%04x", sm_active_connection_handle); 28483cf37b8cSMatthias Ringwald return; 28493cf37b8cSMatthias Ringwald } 28503cf37b8cSMatthias Ringwald 28513deb3ec6SMatthias Ringwald // assert that we could send a SM PDU - not needed for all of the following 2852384eabd3SMatthias Ringwald if (!l2cap_can_send_fixed_channel_packet_now(sm_active_connection_handle, connection->sm_cid)) { 28537149bde5SMatthias Ringwald log_info("cannot send now, requesting can send now event"); 2854384eabd3SMatthias Ringwald l2cap_request_can_send_fix_channel_now_event(sm_active_connection_handle, connection->sm_cid); 2855b170b20fSMatthias Ringwald return; 2856b170b20fSMatthias Ringwald } 28573deb3ec6SMatthias Ringwald 28583d7fe1e9SMatthias Ringwald // send keypress notifications 28591d80f1e6SMatthias Ringwald if (setup->sm_keypress_notification != 0u){ 2860403280b9SMatthias Ringwald sm_run_send_keypress_notification(connection); 2861d7471931SMatthias Ringwald return; 28623d7fe1e9SMatthias Ringwald } 28633d7fe1e9SMatthias Ringwald 2864f7ea4423SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2865234022e5SMatthias Ringwald // assert that sm cmac engine is ready 2866234022e5SMatthias Ringwald if (sm_cmac_ready() == false){ 2867234022e5SMatthias Ringwald break; 2868234022e5SMatthias Ringwald } 2869f7ea4423SMatthias Ringwald #endif 2870234022e5SMatthias Ringwald 28712e7060d6SMatthias Ringwald // initialize to avoid 'maybe used uninitialized' error 28722e7060d6SMatthias Ringwald int key_distribution_flags = 0; 287342134bc6SMatthias Ringwald UNUSED(key_distribution_flags); 2874b6f39a74SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 2875b6afa23eSMatthias Ringwald int err; 28769b75de03SMatthias Ringwald bool have_ltk; 28779b75de03SMatthias Ringwald uint8_t ltk[16]; 2878b6f39a74SMatthias Ringwald #endif 28793deb3ec6SMatthias Ringwald 28803deb3ec6SMatthias Ringwald log_info("sm_run: state %u", connection->sm_engine_state); 28813deb3ec6SMatthias Ringwald switch (connection->sm_engine_state){ 28823deb3ec6SMatthias Ringwald 2883f32b7a88SMatthias Ringwald // secure connections, initiator + responding states 2884aec94140SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2885aec94140SMatthias Ringwald case SM_SC_W2_CMAC_FOR_CONFIRMATION: 2886aec94140SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CMAC_FOR_CONFIRMATION; 2887aec94140SMatthias Ringwald sm_sc_calculate_local_confirm(connection); 2888aec94140SMatthias Ringwald break; 2889688a08f9SMatthias Ringwald case SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION: 2890688a08f9SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CMAC_FOR_CHECK_CONFIRMATION; 2891688a08f9SMatthias Ringwald sm_sc_calculate_remote_confirm(connection); 2892688a08f9SMatthias Ringwald break; 2893dc300847SMatthias Ringwald case SM_SC_W2_CALCULATE_F6_FOR_DHKEY_CHECK: 2894dc300847SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F6_FOR_DHKEY_CHECK; 2895dc300847SMatthias Ringwald sm_sc_calculate_f6_for_dhkey_check(connection); 2896dc300847SMatthias Ringwald break; 2897019005a0SMatthias Ringwald case SM_SC_W2_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK: 2898019005a0SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK; 28990346c37cSMatthias Ringwald sm_sc_calculate_f6_to_verify_dhkey_check(connection); 29000346c37cSMatthias Ringwald break; 29010346c37cSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_SALT: 29020346c37cSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F5_SALT; 29030346c37cSMatthias Ringwald f5_calculate_salt(connection); 29040346c37cSMatthias Ringwald break; 29050346c37cSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_MACKEY: 29060346c37cSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F5_MACKEY; 29070346c37cSMatthias Ringwald f5_calculate_mackey(connection); 29080346c37cSMatthias Ringwald break; 29090346c37cSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_LTK: 29100346c37cSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F5_LTK; 29110346c37cSMatthias Ringwald f5_calculate_ltk(connection); 2912019005a0SMatthias Ringwald break; 2913bd57ffebSMatthias Ringwald case SM_SC_W2_CALCULATE_G2: 2914bd57ffebSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_G2; 2915b35a3de2SMatthias Ringwald g2_calculate(connection); 2916bd57ffebSMatthias Ringwald break; 2917e0a03c85SMatthias Ringwald #endif 2918e0a03c85SMatthias Ringwald 291942134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 29203deb3ec6SMatthias Ringwald // initiator side 2921f32b7a88SMatthias Ringwald 29225567aa60SMatthias Ringwald case SM_INITIATOR_PH4_HAS_LTK: { 2923f32b7a88SMatthias Ringwald sm_reset_setup(); 2924f32b7a88SMatthias Ringwald sm_load_security_info(connection); 2925f32b7a88SMatthias Ringwald 2926bcab6650SMatthias Ringwald // cache key before using 2927f76e733aSMatthias Ringwald sm_cache_ltk(connection, setup->sm_peer_ltk); 2928bcab6650SMatthias Ringwald 29293deb3ec6SMatthias Ringwald sm_key_t peer_ltk_flipped; 29309c80e4ccSMatthias Ringwald reverse_128(setup->sm_peer_ltk, peer_ltk_flipped); 29315567aa60SMatthias Ringwald connection->sm_engine_state = SM_PH4_W4_CONNECTION_ENCRYPTED; 29323deb3ec6SMatthias Ringwald log_info("sm: hci_le_start_encryption ediv 0x%04x", setup->sm_peer_ediv); 2933c9b8fdd9SMatthias Ringwald uint32_t rand_high = big_endian_read_32(setup->sm_peer_rand, 0); 2934c9b8fdd9SMatthias Ringwald uint32_t rand_low = big_endian_read_32(setup->sm_peer_rand, 4); 29353deb3ec6SMatthias Ringwald hci_send_cmd(&hci_le_start_encryption, connection->sm_handle,rand_low, rand_high, setup->sm_peer_ediv, peer_ltk_flipped); 293649c9e430SMatthias Ringwald 293749c9e430SMatthias Ringwald // notify after sending 293849c9e430SMatthias Ringwald sm_reencryption_started(connection); 29393deb3ec6SMatthias Ringwald return; 29403deb3ec6SMatthias Ringwald } 29413deb3ec6SMatthias Ringwald 2942b26f445fSMatthias Ringwald case SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST: 2943b26f445fSMatthias Ringwald sm_reset_setup(); 2944b26f445fSMatthias Ringwald sm_init_setup(connection); 2945b26f445fSMatthias Ringwald 29461ad129beSMatthias Ringwald sm_pairing_packet_set_code(setup->sm_m_preq, SM_CODE_PAIRING_REQUEST); 29473deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH1_W4_PAIRING_RESPONSE; 2948687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) &setup->sm_m_preq, sizeof(sm_pairing_packet_t)); 29493deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 295049c9e430SMatthias Ringwald 295149c9e430SMatthias Ringwald // notify after sending 295249c9e430SMatthias Ringwald sm_pairing_started(connection); 29533deb3ec6SMatthias Ringwald break; 295442134bc6SMatthias Ringwald #endif 29553deb3ec6SMatthias Ringwald 295627c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2957b919f264SMatthias Ringwald case SM_SC_SEND_PUBLIC_KEY_COMMAND: 2958b919f264SMatthias Ringwald sm_run_state_sc_send_public_key_command(connection); 295945a61d50SMatthias Ringwald break; 2960b919f264SMatthias Ringwald case SM_SC_SEND_CONFIRMATION: 2961b919f264SMatthias Ringwald sm_run_state_sc_send_confirmation(connection); 296245a61d50SMatthias Ringwald break; 2963b919f264SMatthias Ringwald case SM_SC_SEND_PAIRING_RANDOM: 2964b919f264SMatthias Ringwald sm_run_state_sc_send_pairing_random(connection); 296545a61d50SMatthias Ringwald break; 2966b919f264SMatthias Ringwald case SM_SC_SEND_DHKEY_CHECK_COMMAND: 2967b919f264SMatthias Ringwald sm_run_state_sc_send_dhkey_check_command(connection); 29687bbeb3adSMilanka Ringwald break; 2969e53be891SMatthias Ringwald #endif 297042134bc6SMatthias Ringwald 297142134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 2972dd12a62bSMatthias Ringwald 297387014f74SMatthias Ringwald case SM_RESPONDER_SEND_SECURITY_REQUEST: { 297487014f74SMatthias Ringwald const uint8_t buffer[2] = {SM_CODE_SECURITY_REQUEST, sm_auth_req}; 297587014f74SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH1_W4_PAIRING_REQUEST; 2976687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t *) buffer, sizeof(buffer)); 2977c8d0ff33SMatthias Ringwald sm_timeout_start(connection); 297887014f74SMatthias Ringwald break; 297987014f74SMatthias Ringwald } 298087014f74SMatthias Ringwald 298138196718SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 298238196718SMatthias Ringwald case SM_SC_RECEIVED_LTK_REQUEST: 298338196718SMatthias Ringwald switch (connection->sm_irk_lookup_state){ 298438196718SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 298538196718SMatthias Ringwald // assuming Secure Connection, we have a stored LTK and the EDIV/RAND are null 298638196718SMatthias Ringwald // start using context by loading security info 298738196718SMatthias Ringwald sm_reset_setup(); 298838196718SMatthias Ringwald sm_load_security_info(connection); 298938196718SMatthias Ringwald if ((setup->sm_peer_ediv == 0u) && sm_is_null_random(setup->sm_peer_rand) && !sm_is_null_key(setup->sm_peer_ltk)){ 299038196718SMatthias Ringwald (void)memcpy(setup->sm_ltk, setup->sm_peer_ltk, 16); 299138196718SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH4_SEND_LTK_REPLY; 299242646f38SMatthias Ringwald sm_reencryption_started(connection); 299338196718SMatthias Ringwald sm_trigger_run(); 299438196718SMatthias Ringwald break; 299538196718SMatthias Ringwald } 299638196718SMatthias Ringwald log_info("LTK Request: ediv & random are empty, but no stored LTK (IRK Lookup Succeeded)"); 299738196718SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_IDLE; 299838196718SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_negative_reply, connection->sm_handle); 299938196718SMatthias Ringwald return; 300038196718SMatthias Ringwald default: 300138196718SMatthias Ringwald // just wait until IRK lookup is completed 300238196718SMatthias Ringwald break; 300338196718SMatthias Ringwald } 300438196718SMatthias Ringwald break; 300538196718SMatthias Ringwald #endif /* ENABLE_LE_SECURE_CONNECTIONS */ 300638196718SMatthias Ringwald 3007b6afa23eSMatthias Ringwald case SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED: 3008b6afa23eSMatthias Ringwald sm_reset_setup(); 30099b75de03SMatthias Ringwald 30109b75de03SMatthias Ringwald // handle Pairing Request with LTK available 30119b75de03SMatthias Ringwald switch (connection->sm_irk_lookup_state) { 30129b75de03SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 30139b75de03SMatthias Ringwald le_device_db_encryption_get(connection->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); 30149b75de03SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 30159b75de03SMatthias Ringwald if (have_ltk){ 30169b75de03SMatthias Ringwald log_info("pairing request but LTK available"); 301719a40772SMatthias Ringwald // emit re-encryption start/fail sequence 30189b75de03SMatthias Ringwald sm_reencryption_started(connection); 30199b75de03SMatthias Ringwald sm_reencryption_complete(connection, ERROR_CODE_PIN_OR_KEY_MISSING); 30209b75de03SMatthias Ringwald } 30219b75de03SMatthias Ringwald break; 30229b75de03SMatthias Ringwald default: 30239b75de03SMatthias Ringwald break; 30249b75de03SMatthias Ringwald } 30259b75de03SMatthias Ringwald 3026b6afa23eSMatthias Ringwald sm_init_setup(connection); 302739543d07SMatthias Ringwald 3028b6afa23eSMatthias Ringwald // recover pairing request 3029b6afa23eSMatthias Ringwald (void)memcpy(&setup->sm_m_preq, &connection->sm_m_preq, sizeof(sm_pairing_packet_t)); 3030b6afa23eSMatthias Ringwald err = sm_stk_generation_init(connection); 3031b6afa23eSMatthias Ringwald 3032b6afa23eSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 3033b6afa23eSMatthias Ringwald if ((0 < test_pairing_failure) && (test_pairing_failure < SM_REASON_DHKEY_CHECK_FAILED)){ 3034b6afa23eSMatthias Ringwald log_info("testing_support: respond with pairing failure %u", test_pairing_failure); 3035b6afa23eSMatthias Ringwald err = test_pairing_failure; 3036b6afa23eSMatthias Ringwald } 3037b6afa23eSMatthias Ringwald #endif 30389305033eSMatthias Ringwald if (err != 0){ 303949c9e430SMatthias Ringwald // emit pairing started/failed sequence 304049c9e430SMatthias Ringwald sm_pairing_started(connection); 3041f4935286SMatthias Ringwald sm_pairing_error(connection, err); 3042b6afa23eSMatthias Ringwald sm_trigger_run(); 3043b6afa23eSMatthias Ringwald break; 3044b6afa23eSMatthias Ringwald } 3045b6afa23eSMatthias Ringwald 3046b6afa23eSMatthias Ringwald sm_timeout_start(connection); 3047b6afa23eSMatthias Ringwald 3048b6afa23eSMatthias Ringwald // generate random number first, if we need to show passkey, otherwise send response 3049b6afa23eSMatthias Ringwald if (setup->sm_stk_generation_method == PK_INIT_INPUT){ 3050b6afa23eSMatthias 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); 3051b6afa23eSMatthias Ringwald break; 3052b6afa23eSMatthias Ringwald } 3053b6afa23eSMatthias Ringwald 3054b6afa23eSMatthias Ringwald /* fall through */ 3055b6afa23eSMatthias Ringwald 30563deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE: 30571ad129beSMatthias Ringwald sm_pairing_packet_set_code(setup->sm_s_pres,SM_CODE_PAIRING_RESPONSE); 3058f55bd529SMatthias Ringwald 3059f55bd529SMatthias Ringwald // start with initiator key dist flags 30603deb3ec6SMatthias Ringwald key_distribution_flags = sm_key_distribution_flags_for_auth_req(); 30611ad129beSMatthias Ringwald 3062f55bd529SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 3063b2072c76SMatthias Ringwald // LTK (= encryption information & master identification) only exchanged for LE Legacy Connection 3064f55bd529SMatthias Ringwald if (setup->sm_use_secure_connections){ 3065f55bd529SMatthias Ringwald key_distribution_flags &= ~SM_KEYDIST_ENC_KEY; 3066f55bd529SMatthias Ringwald } 3067f55bd529SMatthias Ringwald #endif 3068f55bd529SMatthias Ringwald // setup in response 3069f55bd529SMatthias 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); 3070f55bd529SMatthias 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); 3071f55bd529SMatthias Ringwald 3072f55bd529SMatthias Ringwald // update key distribution after ENC was dropped 30739a90d41aSMatthias 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)); 3074f55bd529SMatthias Ringwald 307527c32905SMatthias Ringwald if (setup->sm_use_secure_connections){ 3076c6b7cbd9SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 30770b8af2a5SMatthias Ringwald } else { 30780b8af2a5SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH1_W4_PAIRING_CONFIRM; 307927c32905SMatthias Ringwald } 30800b8af2a5SMatthias Ringwald 3081687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) &setup->sm_s_pres, sizeof(sm_pairing_packet_t)); 30823deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 308349c9e430SMatthias Ringwald 308449c9e430SMatthias Ringwald // notify after sending 308549c9e430SMatthias Ringwald sm_pairing_started(connection); 308649c9e430SMatthias Ringwald 3087446a8c36SMatthias Ringwald // SC Numeric Comparison will trigger user response after public keys & nonces have been exchanged 3088c1ab6cc1SMatthias Ringwald if (!setup->sm_use_secure_connections || (setup->sm_stk_generation_method == JUST_WORKS)){ 30893deb3ec6SMatthias Ringwald sm_trigger_user_response(connection); 3090446a8c36SMatthias Ringwald } 30913deb3ec6SMatthias Ringwald return; 309242134bc6SMatthias Ringwald #endif 30933deb3ec6SMatthias Ringwald 30943deb3ec6SMatthias Ringwald case SM_PH2_SEND_PAIRING_RANDOM: { 30953deb3ec6SMatthias Ringwald uint8_t buffer[17]; 30963deb3ec6SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_RANDOM; 30979c80e4ccSMatthias Ringwald reverse_128(setup->sm_local_random, &buffer[1]); 309842134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 30993deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH2_W4_LTK_REQUEST; 31003deb3ec6SMatthias Ringwald } else { 31013deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH2_W4_PAIRING_RANDOM; 31023deb3ec6SMatthias Ringwald } 3103687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 31043deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 31053deb3ec6SMatthias Ringwald break; 31063deb3ec6SMatthias Ringwald } 31073deb3ec6SMatthias Ringwald 3108d1a1f6a4SMatthias Ringwald case SM_PH2_C1_GET_ENC_A: 31093deb3ec6SMatthias Ringwald // already busy? 31103deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 3111d1a1f6a4SMatthias Ringwald // calculate confirm using aes128 engine - step 1 3112d1a1f6a4SMatthias 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); 3113d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_W4_ENC_A; 3114d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3115f3582630SMatthias 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); 31163deb3ec6SMatthias Ringwald break; 31173deb3ec6SMatthias Ringwald 31183deb3ec6SMatthias Ringwald case SM_PH2_C1_GET_ENC_C: 31193deb3ec6SMatthias Ringwald // already busy? 31203deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31213deb3ec6SMatthias Ringwald // calculate m_confirm using aes128 engine - step 1 3122d1a1f6a4SMatthias 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); 3123d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_W4_ENC_C; 3124d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3125f3582630SMatthias 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); 31263deb3ec6SMatthias Ringwald break; 3127d1a1f6a4SMatthias Ringwald 31283deb3ec6SMatthias Ringwald case SM_PH2_CALC_STK: 31293deb3ec6SMatthias Ringwald // already busy? 31303deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31313deb3ec6SMatthias Ringwald // calculate STK 313242134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 3133d1a1f6a4SMatthias Ringwald sm_s1_r_prime(setup->sm_local_random, setup->sm_peer_random, sm_aes128_plaintext); 31343deb3ec6SMatthias Ringwald } else { 3135d1a1f6a4SMatthias Ringwald sm_s1_r_prime(setup->sm_peer_random, setup->sm_local_random, sm_aes128_plaintext); 31363deb3ec6SMatthias Ringwald } 3137d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_W4_STK; 3138d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3139f3582630SMatthias 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); 31403deb3ec6SMatthias Ringwald break; 3141d1a1f6a4SMatthias Ringwald 31423deb3ec6SMatthias Ringwald case SM_PH3_Y_GET_ENC: 31433deb3ec6SMatthias Ringwald // already busy? 31443deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31453deb3ec6SMatthias Ringwald // PH3B2 - calculate Y from - enc 31469ad0dd7cSMatthias Ringwald 31479ad0dd7cSMatthias Ringwald // dm helper (was sm_dm_r_prime) 31489ad0dd7cSMatthias Ringwald // r' = padding || r 31499ad0dd7cSMatthias Ringwald // r - 64 bit value 31509ad0dd7cSMatthias Ringwald memset(&sm_aes128_plaintext[0], 0, 8); 31516535961aSMatthias Ringwald (void)memcpy(&sm_aes128_plaintext[8], setup->sm_local_rand, 8); 31529ad0dd7cSMatthias Ringwald 31533deb3ec6SMatthias Ringwald // Y = dm(DHK, Rand) 3154d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH3_Y_W4_ENC; 3155d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3156f3582630SMatthias 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); 3157d1a1f6a4SMatthias Ringwald break; 3158d1a1f6a4SMatthias Ringwald 31593deb3ec6SMatthias Ringwald case SM_PH2_C1_SEND_PAIRING_CONFIRM: { 31603deb3ec6SMatthias Ringwald uint8_t buffer[17]; 31613deb3ec6SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_CONFIRM; 31629c80e4ccSMatthias Ringwald reverse_128(setup->sm_local_confirm, &buffer[1]); 316342134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 31643deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH2_W4_PAIRING_RANDOM; 31653deb3ec6SMatthias Ringwald } else { 31663deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH2_W4_PAIRING_CONFIRM; 31673deb3ec6SMatthias Ringwald } 3168687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 31693deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 31703deb3ec6SMatthias Ringwald return; 31713deb3ec6SMatthias Ringwald } 317242134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 31733deb3ec6SMatthias Ringwald case SM_RESPONDER_PH2_SEND_LTK_REPLY: { 3174916ea5b2SMatthias Ringwald // cache key before using 3175916ea5b2SMatthias Ringwald sm_cache_ltk(connection, setup->sm_ltk); 31763deb3ec6SMatthias Ringwald sm_key_t stk_flipped; 31779c80e4ccSMatthias Ringwald reverse_128(setup->sm_ltk, stk_flipped); 31783deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH2_W4_CONNECTION_ENCRYPTED; 31793deb3ec6SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_request_reply, connection->sm_handle, stk_flipped); 31803deb3ec6SMatthias Ringwald return; 31813deb3ec6SMatthias Ringwald } 3182d7471931SMatthias Ringwald case SM_RESPONDER_PH4_SEND_LTK_REPLY: { 3183b96d60a6SMatthias Ringwald // allow to override LTK 3184b96d60a6SMatthias Ringwald if (sm_get_ltk_callback != NULL){ 3185b96d60a6SMatthias Ringwald (void)(*sm_get_ltk_callback)(connection->sm_handle, connection->sm_peer_addr_type, connection->sm_peer_address, setup->sm_ltk); 3186b96d60a6SMatthias Ringwald } 3187916ea5b2SMatthias Ringwald // cache key before using 3188916ea5b2SMatthias Ringwald sm_cache_ltk(connection, setup->sm_ltk); 31893deb3ec6SMatthias Ringwald sm_key_t ltk_flipped; 31909c80e4ccSMatthias Ringwald reverse_128(setup->sm_ltk, ltk_flipped); 31915567aa60SMatthias Ringwald connection->sm_engine_state = SM_PH4_W4_CONNECTION_ENCRYPTED; 31923deb3ec6SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_request_reply, connection->sm_handle, ltk_flipped); 31933deb3ec6SMatthias Ringwald return; 31943deb3ec6SMatthias Ringwald } 3195dd12a62bSMatthias Ringwald 3196dd12a62bSMatthias Ringwald case SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST: 31973deb3ec6SMatthias Ringwald // already busy? 31983deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31993deb3ec6SMatthias Ringwald log_info("LTK Request: recalculating with ediv 0x%04x", setup->sm_local_ediv); 3200c61cfe5aSMatthias Ringwald 3201dd12a62bSMatthias Ringwald sm_reset_setup(); 3202dd12a62bSMatthias Ringwald sm_start_calculating_ltk_from_ediv_and_rand(connection); 3203dd12a62bSMatthias Ringwald 320442646f38SMatthias Ringwald sm_reencryption_started(connection); 320542646f38SMatthias Ringwald 3206c61cfe5aSMatthias Ringwald // dm helper (was sm_dm_r_prime) 3207c61cfe5aSMatthias Ringwald // r' = padding || r 3208c61cfe5aSMatthias Ringwald // r - 64 bit value 3209c61cfe5aSMatthias Ringwald memset(&sm_aes128_plaintext[0], 0, 8); 32106535961aSMatthias Ringwald (void)memcpy(&sm_aes128_plaintext[8], setup->sm_local_rand, 8); 3211c61cfe5aSMatthias Ringwald 32123deb3ec6SMatthias Ringwald // Y = dm(DHK, Rand) 3213d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH4_Y_W4_ENC; 3214d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3215f3582630SMatthias 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); 32163deb3ec6SMatthias Ringwald return; 321742134bc6SMatthias Ringwald #endif 321842134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 321942134bc6SMatthias Ringwald case SM_INITIATOR_PH3_SEND_START_ENCRYPTION: { 3220bcab6650SMatthias Ringwald // cache key before using 3221bcab6650SMatthias Ringwald sm_cache_ltk(connection, setup->sm_ltk); 3222bcab6650SMatthias Ringwald 322342134bc6SMatthias Ringwald sm_key_t stk_flipped; 322442134bc6SMatthias Ringwald reverse_128(setup->sm_ltk, stk_flipped); 322542134bc6SMatthias Ringwald connection->sm_engine_state = SM_PH2_W4_CONNECTION_ENCRYPTED; 322642134bc6SMatthias Ringwald hci_send_cmd(&hci_le_start_encryption, connection->sm_handle, 0, 0, 0, stk_flipped); 322742134bc6SMatthias Ringwald return; 322842134bc6SMatthias Ringwald } 322942134bc6SMatthias Ringwald #endif 32303deb3ec6SMatthias Ringwald 32313deb3ec6SMatthias Ringwald case SM_PH3_DISTRIBUTE_KEYS: 3232e94757aeSMatthias Ringwald // send next key 3233403280b9SMatthias Ringwald if (setup->sm_key_distribution_send_set != 0){ 3234403280b9SMatthias Ringwald sm_run_distribute_keys(connection); 3235e94757aeSMatthias Ringwald } 3236e94757aeSMatthias Ringwald 3237e94757aeSMatthias Ringwald // more to send? 3238e94757aeSMatthias Ringwald if (setup->sm_key_distribution_send_set != 0){ 32393deb3ec6SMatthias Ringwald return; 32403deb3ec6SMatthias Ringwald } 32413deb3ec6SMatthias Ringwald 32423deb3ec6SMatthias Ringwald // keys are sent 324342134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 32443deb3ec6SMatthias Ringwald // slave -> receive master keys if any 324561d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 32463deb3ec6SMatthias Ringwald sm_key_distribution_handle_all_received(connection); 3247f5020412SMatthias Ringwald sm_key_distribution_complete_responder(connection); 3248f5020412SMatthias Ringwald // start CTKD right away 3249f5020412SMatthias Ringwald continue; 32503deb3ec6SMatthias Ringwald } else { 32513deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH3_RECEIVE_KEYS; 32523deb3ec6SMatthias Ringwald } 32533deb3ec6SMatthias Ringwald } else { 32541dca9d8aSMatthias Ringwald sm_master_pairing_success(connection); 32553deb3ec6SMatthias Ringwald } 32563deb3ec6SMatthias Ringwald break; 32573deb3ec6SMatthias Ringwald 3258c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 3259c18be159SMatthias Ringwald case SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST: 3260c18be159SMatthias Ringwald // fill in sm setup (lite version of sm_init_setup) 3261c18be159SMatthias Ringwald sm_reset_setup(); 3262c18be159SMatthias Ringwald setup->sm_peer_addr_type = connection->sm_peer_addr_type; 3263c18be159SMatthias Ringwald setup->sm_m_addr_type = connection->sm_peer_addr_type; 3264c18be159SMatthias Ringwald setup->sm_s_addr_type = connection->sm_own_addr_type; 3265c18be159SMatthias Ringwald (void) memcpy(setup->sm_peer_address, connection->sm_peer_address, 6); 3266c18be159SMatthias Ringwald (void) memcpy(setup->sm_m_address, connection->sm_peer_address, 6); 3267c18be159SMatthias Ringwald (void) memcpy(setup->sm_s_address, connection->sm_own_address, 6); 3268c18be159SMatthias Ringwald setup->sm_use_secure_connections = true; 3269c18be159SMatthias Ringwald sm_ctkd_fetch_br_edr_link_key(connection); 3270c18be159SMatthias Ringwald 3271c18be159SMatthias Ringwald // Enc Key and IRK if requested 3272c18be159SMatthias Ringwald key_distribution_flags = SM_KEYDIST_ID_KEY | SM_KEYDIST_ENC_KEY; 3273c18be159SMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 3274c18be159SMatthias Ringwald // Plus signing key if supported 3275c18be159SMatthias Ringwald key_distribution_flags |= SM_KEYDIST_ID_KEY; 3276c18be159SMatthias Ringwald #endif 3277c18be159SMatthias Ringwald sm_pairing_packet_set_code(setup->sm_m_preq, SM_CODE_PAIRING_REQUEST); 3278c18be159SMatthias Ringwald sm_pairing_packet_set_io_capability(setup->sm_m_preq, 0); 3279c18be159SMatthias Ringwald sm_pairing_packet_set_oob_data_flag(setup->sm_m_preq, 0); 3280c18be159SMatthias Ringwald sm_pairing_packet_set_auth_req(setup->sm_m_preq, SM_AUTHREQ_CT2); 3281c18be159SMatthias Ringwald sm_pairing_packet_set_max_encryption_key_size(setup->sm_m_preq, sm_max_encryption_key_size); 3282c18be159SMatthias Ringwald sm_pairing_packet_set_initiator_key_distribution(setup->sm_m_preq, key_distribution_flags); 3283c18be159SMatthias Ringwald sm_pairing_packet_set_responder_key_distribution(setup->sm_m_preq, key_distribution_flags); 3284c18be159SMatthias Ringwald 3285c18be159SMatthias Ringwald // set state and send pairing response 3286c18be159SMatthias Ringwald sm_timeout_start(connection); 3287c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_INITIATOR_W4_PAIRING_RESPONSE; 3288c18be159SMatthias Ringwald sm_send_connectionless(connection, (uint8_t *) &setup->sm_m_preq, sizeof(sm_pairing_packet_t)); 3289c18be159SMatthias Ringwald break; 3290c18be159SMatthias Ringwald 3291c18be159SMatthias Ringwald case SM_BR_EDR_RESPONDER_PAIRING_REQUEST_RECEIVED: 3292c18be159SMatthias Ringwald // fill in sm setup (lite version of sm_init_setup) 3293c18be159SMatthias Ringwald sm_reset_setup(); 3294c18be159SMatthias Ringwald setup->sm_peer_addr_type = connection->sm_peer_addr_type; 3295c18be159SMatthias Ringwald setup->sm_m_addr_type = connection->sm_peer_addr_type; 3296c18be159SMatthias Ringwald setup->sm_s_addr_type = connection->sm_own_addr_type; 3297c18be159SMatthias Ringwald (void) memcpy(setup->sm_peer_address, connection->sm_peer_address, 6); 3298c18be159SMatthias Ringwald (void) memcpy(setup->sm_m_address, connection->sm_peer_address, 6); 3299c18be159SMatthias Ringwald (void) memcpy(setup->sm_s_address, connection->sm_own_address, 6); 3300c18be159SMatthias Ringwald setup->sm_use_secure_connections = true; 3301c18be159SMatthias Ringwald sm_ctkd_fetch_br_edr_link_key(connection); 3302c18be159SMatthias Ringwald (void) memcpy(&setup->sm_m_preq, &connection->sm_m_preq, sizeof(sm_pairing_packet_t)); 3303c18be159SMatthias Ringwald 3304c18be159SMatthias Ringwald // Enc Key and IRK if requested 3305c18be159SMatthias Ringwald key_distribution_flags = SM_KEYDIST_ID_KEY | SM_KEYDIST_ENC_KEY; 3306c18be159SMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 3307c18be159SMatthias Ringwald // Plus signing key if supported 3308c18be159SMatthias Ringwald key_distribution_flags |= SM_KEYDIST_ID_KEY; 3309c18be159SMatthias Ringwald #endif 3310c18be159SMatthias Ringwald // drop flags not requested by initiator 3311c18be159SMatthias Ringwald key_distribution_flags &= sm_pairing_packet_get_initiator_key_distribution(connection->sm_m_preq); 3312c18be159SMatthias Ringwald 3313c18be159SMatthias 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: 3314c18be159SMatthias Ringwald // - the IO Capability field, 3315c18be159SMatthias Ringwald // - the OOB data flag field, and 3316c18be159SMatthias Ringwald // - all bits in the Auth Req field except the CT2 bit. 3317c18be159SMatthias Ringwald sm_pairing_packet_set_code(setup->sm_s_pres, SM_CODE_PAIRING_RESPONSE); 3318c18be159SMatthias Ringwald sm_pairing_packet_set_io_capability(setup->sm_s_pres, 0); 3319c18be159SMatthias Ringwald sm_pairing_packet_set_oob_data_flag(setup->sm_s_pres, 0); 3320c18be159SMatthias Ringwald sm_pairing_packet_set_auth_req(setup->sm_s_pres, SM_AUTHREQ_CT2); 3321c18be159SMatthias Ringwald sm_pairing_packet_set_max_encryption_key_size(setup->sm_s_pres, connection->sm_actual_encryption_key_size); 3322c18be159SMatthias Ringwald sm_pairing_packet_set_initiator_key_distribution(setup->sm_s_pres, key_distribution_flags); 3323c18be159SMatthias Ringwald sm_pairing_packet_set_responder_key_distribution(setup->sm_s_pres, key_distribution_flags); 3324c18be159SMatthias Ringwald 3325c18be159SMatthias Ringwald // configure key distribution, LTK is derived locally 3326c18be159SMatthias Ringwald key_distribution_flags &= ~SM_KEYDIST_ENC_KEY; 3327c18be159SMatthias Ringwald sm_setup_key_distribution(key_distribution_flags, key_distribution_flags); 3328c18be159SMatthias Ringwald 3329c18be159SMatthias Ringwald // set state and send pairing response 3330c18be159SMatthias Ringwald sm_timeout_start(connection); 3331c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_DISTRIBUTE_KEYS; 3332c18be159SMatthias Ringwald sm_send_connectionless(connection, (uint8_t *) &setup->sm_s_pres, sizeof(sm_pairing_packet_t)); 3333c18be159SMatthias Ringwald break; 3334c18be159SMatthias Ringwald case SM_BR_EDR_DISTRIBUTE_KEYS: 333520964aa9SMatthias Ringwald // send next key 3336c18be159SMatthias Ringwald if (setup->sm_key_distribution_send_set != 0) { 3337c18be159SMatthias Ringwald sm_run_distribute_keys(connection); 333820964aa9SMatthias Ringwald } 333920964aa9SMatthias Ringwald 334020964aa9SMatthias Ringwald // more to send? 334120964aa9SMatthias Ringwald if (setup->sm_key_distribution_send_set != 0){ 3342c18be159SMatthias Ringwald return; 3343c18be159SMatthias Ringwald } 334420964aa9SMatthias Ringwald 3345c18be159SMatthias Ringwald // keys are sent 3346c18be159SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)) { 3347c18be159SMatthias Ringwald // responder -> receive master keys if there are any 334861d1a45eSMatthias Ringwald if (!sm_key_distribution_all_received()){ 3349c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_RECEIVE_KEYS; 3350c18be159SMatthias Ringwald break; 3351c18be159SMatthias Ringwald } 3352c18be159SMatthias Ringwald } 3353c18be159SMatthias Ringwald // otherwise start CTKD right away (responder and no keys to receive / initiator) 3354c18be159SMatthias Ringwald sm_ctkd_start_from_br_edr(connection); 3355c18be159SMatthias Ringwald continue; 3356c18be159SMatthias Ringwald case SM_SC_W2_CALCULATE_ILK_USING_H6: 3357c18be159SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_ILK; 3358c18be159SMatthias Ringwald h6_calculate_ilk_from_le_ltk(connection); 3359c18be159SMatthias Ringwald break; 3360c18be159SMatthias Ringwald case SM_SC_W2_CALCULATE_BR_EDR_LINK_KEY: 3361c18be159SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_BR_EDR_LINK_KEY; 3362c18be159SMatthias Ringwald h6_calculate_br_edr_link_key(connection); 3363c18be159SMatthias Ringwald break; 3364c18be159SMatthias Ringwald case SM_SC_W2_CALCULATE_ILK_USING_H7: 3365c18be159SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_ILK; 3366c18be159SMatthias Ringwald h7_calculate_ilk_from_le_ltk(connection); 3367c18be159SMatthias Ringwald break; 3368c18be159SMatthias Ringwald case SM_BR_EDR_W2_CALCULATE_ILK_USING_H6: 3369c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_W4_CALCULATE_ILK; 3370c18be159SMatthias Ringwald h6_calculate_ilk_from_br_edr(connection); 3371c18be159SMatthias Ringwald break; 3372c18be159SMatthias Ringwald case SM_BR_EDR_W2_CALCULATE_LE_LTK: 3373c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_W4_CALCULATE_LE_LTK; 3374c18be159SMatthias Ringwald h6_calculate_le_ltk(connection); 3375c18be159SMatthias Ringwald break; 3376c18be159SMatthias Ringwald case SM_BR_EDR_W2_CALCULATE_ILK_USING_H7: 3377c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_W4_CALCULATE_ILK; 3378c18be159SMatthias Ringwald h7_calculate_ilk_from_br_edr(connection); 3379c18be159SMatthias Ringwald break; 3380c18be159SMatthias Ringwald #endif 3381c18be159SMatthias Ringwald 33823deb3ec6SMatthias Ringwald default: 33833deb3ec6SMatthias Ringwald break; 33843deb3ec6SMatthias Ringwald } 33853deb3ec6SMatthias Ringwald 33863deb3ec6SMatthias Ringwald // check again if active connection was released 33877149bde5SMatthias Ringwald if (sm_active_connection_handle != HCI_CON_HANDLE_INVALID) break; 33883deb3ec6SMatthias Ringwald } 33893deb3ec6SMatthias Ringwald } 33903deb3ec6SMatthias Ringwald 3391d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3392d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_a(void *arg){ 3393f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 339404678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 339504678764SMatthias Ringwald 3396f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3397f3582630SMatthias Ringwald if (connection == NULL) return; 3398f3582630SMatthias Ringwald 3399d1a1f6a4SMatthias Ringwald sm_c1_t3(sm_aes128_ciphertext, setup->sm_m_address, setup->sm_s_address, setup->sm_c1_t3_value); 340004678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3401f3582630SMatthias 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); 3402d1a1f6a4SMatthias Ringwald } 34033deb3ec6SMatthias Ringwald 3404d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_b(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 34118314c363SMatthias Ringwald log_info_key("c1!", setup->sm_local_confirm); 34123deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_SEND_PAIRING_CONFIRM; 341370b44dd4SMatthias Ringwald sm_trigger_run(); 3414d1a1f6a4SMatthias Ringwald } 3415d1a1f6a4SMatthias Ringwald 3416d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3417d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_c(void *arg){ 3418f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 341904678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 342004678764SMatthias Ringwald 3421f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3422f3582630SMatthias Ringwald if (connection == NULL) return; 3423f3582630SMatthias Ringwald 3424d1a1f6a4SMatthias Ringwald sm_c1_t3(sm_aes128_ciphertext, setup->sm_m_address, setup->sm_s_address, setup->sm_c1_t3_value); 342504678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3426f3582630SMatthias 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); 3427d1a1f6a4SMatthias Ringwald } 3428d1a1f6a4SMatthias Ringwald 3429d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_d(void * arg){ 3430f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 343104678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 343204678764SMatthias Ringwald 3433f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3434f3582630SMatthias Ringwald if (connection == NULL) return; 3435f3582630SMatthias Ringwald 3436d1a1f6a4SMatthias Ringwald log_info_key("c1!", sm_aes128_ciphertext); 3437d1a1f6a4SMatthias Ringwald if (memcmp(setup->sm_peer_confirm, sm_aes128_ciphertext, 16) != 0){ 3438f4935286SMatthias Ringwald sm_pairing_error(connection, SM_REASON_CONFIRM_VALUE_FAILED); 343970b44dd4SMatthias Ringwald sm_trigger_run(); 34403deb3ec6SMatthias Ringwald return; 34413deb3ec6SMatthias Ringwald } 344242134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 34433deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH2_SEND_PAIRING_RANDOM; 344470b44dd4SMatthias Ringwald sm_trigger_run(); 34453deb3ec6SMatthias Ringwald } else { 3446d1a1f6a4SMatthias Ringwald sm_s1_r_prime(setup->sm_peer_random, setup->sm_local_random, sm_aes128_plaintext); 3447d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3448f3582630SMatthias 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); 34493deb3ec6SMatthias Ringwald } 34503deb3ec6SMatthias Ringwald } 3451d1a1f6a4SMatthias Ringwald 3452d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_stk(void *arg){ 345304678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 3454f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 345504678764SMatthias Ringwald 3456f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3457f3582630SMatthias Ringwald if (connection == NULL) return; 3458f3582630SMatthias Ringwald 34593deb3ec6SMatthias Ringwald sm_truncate_key(setup->sm_ltk, connection->sm_actual_encryption_key_size); 34608314c363SMatthias Ringwald log_info_key("stk", setup->sm_ltk); 346142134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 34623deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH2_SEND_LTK_REPLY; 34633deb3ec6SMatthias Ringwald } else { 34643deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH3_SEND_START_ENCRYPTION; 34653deb3ec6SMatthias Ringwald } 346670b44dd4SMatthias Ringwald sm_trigger_run(); 3467d1a1f6a4SMatthias Ringwald } 3468d1a1f6a4SMatthias Ringwald 3469d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3470d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph3_y(void *arg){ 3471f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 347204678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 347304678764SMatthias Ringwald 3474f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3475f3582630SMatthias Ringwald if (connection == NULL) return; 3476f3582630SMatthias Ringwald 3477d1a1f6a4SMatthias Ringwald setup->sm_local_y = big_endian_read_16(sm_aes128_ciphertext, 14); 34783deb3ec6SMatthias Ringwald log_info_hex16("y", setup->sm_local_y); 34793deb3ec6SMatthias Ringwald // PH3B3 - calculate EDIV 34803deb3ec6SMatthias Ringwald setup->sm_local_ediv = setup->sm_local_y ^ setup->sm_local_div; 34813deb3ec6SMatthias Ringwald log_info_hex16("ediv", setup->sm_local_ediv); 34823deb3ec6SMatthias Ringwald // PH3B4 - calculate LTK - enc 34833deb3ec6SMatthias Ringwald // LTK = d1(ER, DIV, 0)) 3484d1a1f6a4SMatthias Ringwald sm_d1_d_prime(setup->sm_local_div, 0, sm_aes128_plaintext); 348504678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3486f3582630SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_er, sm_aes128_plaintext, setup->sm_ltk, sm_handle_encryption_result_enc_ph3_ltk, (void *)(uintptr_t) connection->sm_handle); 34873deb3ec6SMatthias Ringwald } 3488d1a1f6a4SMatthias Ringwald 34892a526f21SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 3490d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3491d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph4_y(void *arg){ 349204678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 3493f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 349404678764SMatthias Ringwald 3495f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3496f3582630SMatthias Ringwald if (connection == NULL) return; 3497f3582630SMatthias Ringwald 3498d1a1f6a4SMatthias Ringwald setup->sm_local_y = big_endian_read_16(sm_aes128_ciphertext, 14); 34993deb3ec6SMatthias Ringwald log_info_hex16("y", setup->sm_local_y); 35003deb3ec6SMatthias Ringwald 35013deb3ec6SMatthias Ringwald // PH3B3 - calculate DIV 35023deb3ec6SMatthias Ringwald setup->sm_local_div = setup->sm_local_y ^ setup->sm_local_ediv; 35033deb3ec6SMatthias Ringwald log_info_hex16("ediv", setup->sm_local_ediv); 35043deb3ec6SMatthias Ringwald // PH3B4 - calculate LTK - enc 35053deb3ec6SMatthias Ringwald // LTK = d1(ER, DIV, 0)) 3506d1a1f6a4SMatthias Ringwald sm_d1_d_prime(setup->sm_local_div, 0, sm_aes128_plaintext); 350704678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3508f3582630SMatthias 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); 35093deb3ec6SMatthias Ringwald } 35102a526f21SMatthias Ringwald #endif 3511d1a1f6a4SMatthias Ringwald 3512d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3513d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph3_ltk(void *arg){ 3514f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 351504678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 351604678764SMatthias Ringwald 3517f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3518f3582630SMatthias Ringwald if (connection == NULL) return; 3519f3582630SMatthias Ringwald 35208314c363SMatthias Ringwald log_info_key("ltk", setup->sm_ltk); 35213deb3ec6SMatthias Ringwald // calc CSRK next 3522d1a1f6a4SMatthias Ringwald sm_d1_d_prime(setup->sm_local_div, 1, sm_aes128_plaintext); 352304678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3524f3582630SMatthias 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); 3525d1a1f6a4SMatthias Ringwald } 3526d1a1f6a4SMatthias Ringwald 3527d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_csrk(void *arg){ 3528f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 352904678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 353004678764SMatthias Ringwald 3531f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3532f3582630SMatthias Ringwald if (connection == NULL) return; 3533f3582630SMatthias Ringwald 3534d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 35358314c363SMatthias Ringwald log_info_key("csrk", setup->sm_local_csrk); 35361d80f1e6SMatthias Ringwald if (setup->sm_key_distribution_send_set != 0u){ 35373deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 35383deb3ec6SMatthias Ringwald } else { 35393deb3ec6SMatthias Ringwald // no keys to send, just continue 354042134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 354161d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 3542c5a72e35SMatthias Ringwald sm_key_distribution_handle_all_received(connection); 3543c5a72e35SMatthias Ringwald sm_key_distribution_complete_responder(connection); 3544c5a72e35SMatthias Ringwald } else { 35453deb3ec6SMatthias Ringwald // slave -> receive master keys 35463deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH3_RECEIVE_KEYS; 3547c5a72e35SMatthias Ringwald } 35483deb3ec6SMatthias Ringwald } else { 3549af7ef9d1SMatthias Ringwald sm_key_distribution_complete_initiator(connection); 35503deb3ec6SMatthias Ringwald } 35512bacf595SMatthias Ringwald } 355270b44dd4SMatthias Ringwald sm_trigger_run(); 3553d1a1f6a4SMatthias Ringwald } 3554d1a1f6a4SMatthias Ringwald 355542134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 3556d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph4_ltk(void *arg){ 3557f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 355804678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 355904678764SMatthias Ringwald 3560f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3561f3582630SMatthias Ringwald if (connection == NULL) return; 3562f3582630SMatthias Ringwald 35633deb3ec6SMatthias Ringwald sm_truncate_key(setup->sm_ltk, connection->sm_actual_encryption_key_size); 35648314c363SMatthias Ringwald log_info_key("ltk", setup->sm_ltk); 3565d7471931SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH4_SEND_LTK_REPLY; 356670b44dd4SMatthias Ringwald sm_trigger_run(); 3567d1a1f6a4SMatthias Ringwald } 3568d1a1f6a4SMatthias Ringwald #endif 3569d1a1f6a4SMatthias Ringwald 3570d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_address_resolution(void *arg){ 3571d1a1f6a4SMatthias Ringwald UNUSED(arg); 3572d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 357304678764SMatthias Ringwald 3574d1a1f6a4SMatthias Ringwald // compare calulated address against connecting device 3575d1a1f6a4SMatthias Ringwald uint8_t * hash = &sm_aes128_ciphertext[13]; 3576d1a1f6a4SMatthias Ringwald if (memcmp(&sm_address_resolution_address[3], hash, 3) == 0){ 3577d1a1f6a4SMatthias Ringwald log_info("LE Device Lookup: matched resolvable private address"); 3578a66b030fSMatthias Ringwald sm_address_resolution_handle_event(ADDRESS_RESOLUTION_SUCCEEDED); 357970b44dd4SMatthias Ringwald sm_trigger_run(); 35803deb3ec6SMatthias Ringwald return; 35813deb3ec6SMatthias Ringwald } 3582d1a1f6a4SMatthias Ringwald // no match, try next 3583d1a1f6a4SMatthias Ringwald sm_address_resolution_test++; 358470b44dd4SMatthias Ringwald sm_trigger_run(); 35853deb3ec6SMatthias Ringwald } 35863deb3ec6SMatthias Ringwald 3587d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_dkg_irk(void *arg){ 3588d1a1f6a4SMatthias Ringwald UNUSED(arg); 3589d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 359004678764SMatthias Ringwald 3591d1a1f6a4SMatthias Ringwald log_info_key("irk", sm_persistent_irk); 3592d1a1f6a4SMatthias Ringwald dkg_state = DKG_CALC_DHK; 359370b44dd4SMatthias Ringwald sm_trigger_run(); 35947df18c15SMatthias Ringwald } 3595d1a1f6a4SMatthias Ringwald 3596d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_dkg_dhk(void *arg){ 3597d1a1f6a4SMatthias Ringwald UNUSED(arg); 3598d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 359904678764SMatthias Ringwald 3600d1a1f6a4SMatthias Ringwald log_info_key("dhk", sm_persistent_dhk); 3601d1a1f6a4SMatthias Ringwald dkg_state = DKG_READY; 360270b44dd4SMatthias Ringwald sm_trigger_run(); 36037df18c15SMatthias Ringwald } 3604d1a1f6a4SMatthias Ringwald 3605d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_rau(void *arg){ 3606d1a1f6a4SMatthias Ringwald UNUSED(arg); 3607d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 360804678764SMatthias Ringwald 36096535961aSMatthias Ringwald (void)memcpy(&sm_random_address[3], &sm_aes128_ciphertext[13], 3); 3610e91ddb40SMatthias Ringwald rau_state = RAU_IDLE; 3611e91ddb40SMatthias Ringwald hci_le_random_address_set(sm_random_address); 3612e91ddb40SMatthias Ringwald 361370b44dd4SMatthias Ringwald sm_trigger_run(); 361451fa0b28SMatthias Ringwald } 36157df18c15SMatthias Ringwald 3616d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_rau(void * arg){ 3617d1a1f6a4SMatthias Ringwald UNUSED(arg); 36183deb3ec6SMatthias Ringwald // non-resolvable vs. resolvable 36193deb3ec6SMatthias Ringwald switch (gap_random_adress_type){ 36203deb3ec6SMatthias Ringwald case GAP_RANDOM_ADDRESS_RESOLVABLE: 36213deb3ec6SMatthias Ringwald // resolvable: use random as prand and calc address hash 36223deb3ec6SMatthias Ringwald // "The two most significant bits of prand shall be equal to ‘0’ and ‘1" 36234ea43905SMatthias Ringwald sm_random_address[0u] &= 0x3fu; 36244ea43905SMatthias Ringwald sm_random_address[0u] |= 0x40u; 36253deb3ec6SMatthias Ringwald rau_state = RAU_GET_ENC; 36263deb3ec6SMatthias Ringwald break; 36273deb3ec6SMatthias Ringwald case GAP_RANDOM_ADDRESS_NON_RESOLVABLE: 36283deb3ec6SMatthias Ringwald default: 36293deb3ec6SMatthias Ringwald // "The two most significant bits of the address shall be equal to ‘0’"" 36304ea43905SMatthias Ringwald sm_random_address[0u] &= 0x3fu; 36312954e6c6SMatthias Ringwald rau_state = RAU_IDLE; 3632e91ddb40SMatthias Ringwald hci_le_random_address_set(sm_random_address); 36333deb3ec6SMatthias Ringwald break; 36343deb3ec6SMatthias Ringwald } 363570b44dd4SMatthias Ringwald sm_trigger_run(); 36363deb3ec6SMatthias Ringwald } 36373deb3ec6SMatthias Ringwald 3638c59d0c92SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 36396ca80073SMatthias Ringwald static void sm_handle_random_result_sc_next_send_pairing_random(void * arg){ 3640f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3641f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3642f3582630SMatthias Ringwald if (connection == NULL) return; 3643c59d0c92SMatthias Ringwald 364465a9a04eSMatthias Ringwald connection->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM; 364570b44dd4SMatthias Ringwald sm_trigger_run(); 364665a9a04eSMatthias Ringwald } 3647d1a1f6a4SMatthias Ringwald 36486ca80073SMatthias Ringwald static void sm_handle_random_result_sc_next_w2_cmac_for_confirmation(void * arg){ 36496ca80073SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 36506ca80073SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 36516ca80073SMatthias Ringwald if (connection == NULL) return; 36526ca80073SMatthias Ringwald 3653b35a3de2SMatthias Ringwald connection->sm_engine_state = SM_SC_W2_CMAC_FOR_CONFIRMATION; 365470b44dd4SMatthias Ringwald sm_trigger_run(); 3655d1a1f6a4SMatthias Ringwald } 3656f1c1783eSMatthias Ringwald #endif 3657f1c1783eSMatthias Ringwald 3658d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph2_random(void * arg){ 3659f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3660f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3661f3582630SMatthias Ringwald if (connection == NULL) return; 3662f3582630SMatthias Ringwald 3663d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_GET_ENC_A; 366470b44dd4SMatthias Ringwald sm_trigger_run(); 3665d1a1f6a4SMatthias Ringwald } 3666d1a1f6a4SMatthias Ringwald 3667d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph2_tk(void * arg){ 3668f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3669f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3670f3582630SMatthias Ringwald if (connection == NULL) return; 3671f3582630SMatthias Ringwald 3672caf15bf3SMatthias Ringwald sm_reset_tk(); 3673caf15bf3SMatthias Ringwald uint32_t tk; 36745ce1359eSMatthias Ringwald if (sm_fixed_passkey_in_display_role == 0xffffffffU){ 36753deb3ec6SMatthias Ringwald // map random to 0-999999 without speding much cycles on a modulus operation 3676d1a1f6a4SMatthias Ringwald tk = little_endian_read_32(sm_random_data,0); 36773deb3ec6SMatthias Ringwald tk = tk & 0xfffff; // 1048575 36784ea43905SMatthias Ringwald if (tk >= 999999u){ 36794ea43905SMatthias Ringwald tk = tk - 999999u; 36803deb3ec6SMatthias Ringwald } 3681caf15bf3SMatthias Ringwald } else { 3682caf15bf3SMatthias Ringwald // override with pre-defined passkey 36834b8c611fSMatthias Ringwald tk = sm_fixed_passkey_in_display_role; 3684caf15bf3SMatthias Ringwald } 3685f8fbdce0SMatthias Ringwald big_endian_store_32(setup->sm_tk, 12, tk); 368642134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 36873deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE; 36883deb3ec6SMatthias Ringwald } else { 3689b41539d5SMatthias Ringwald if (setup->sm_use_secure_connections){ 3690b41539d5SMatthias Ringwald connection->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 3691b41539d5SMatthias Ringwald } else { 36923deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 36933deb3ec6SMatthias Ringwald sm_trigger_user_response(connection); 36943deb3ec6SMatthias Ringwald // response_idle == nothing <--> sm_trigger_user_response() did not require response 36953deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ 3696f3582630SMatthias 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); 36973deb3ec6SMatthias Ringwald } 36983deb3ec6SMatthias Ringwald } 3699b41539d5SMatthias Ringwald } 370070b44dd4SMatthias Ringwald sm_trigger_run(); 37013deb3ec6SMatthias Ringwald } 3702d1a1f6a4SMatthias Ringwald 3703d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph3_div(void * arg){ 3704f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3705f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3706f3582630SMatthias Ringwald if (connection == NULL) return; 3707f3582630SMatthias Ringwald 3708d1a1f6a4SMatthias Ringwald // use 16 bit from random value as div 3709d1a1f6a4SMatthias Ringwald setup->sm_local_div = big_endian_read_16(sm_random_data, 0); 3710d1a1f6a4SMatthias Ringwald log_info_hex16("div", setup->sm_local_div); 3711d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH3_Y_GET_ENC; 371270b44dd4SMatthias Ringwald sm_trigger_run(); 3713d1a1f6a4SMatthias Ringwald } 3714d1a1f6a4SMatthias Ringwald 3715d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph3_random(void * arg){ 3716f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3717f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3718f3582630SMatthias Ringwald if (connection == NULL) return; 3719f3582630SMatthias Ringwald 3720d1a1f6a4SMatthias Ringwald reverse_64(sm_random_data, setup->sm_local_rand); 37213deb3ec6SMatthias Ringwald // no db for encryption size hack: encryption size is stored in lowest nibble of setup->sm_local_rand 37224ea43905SMatthias Ringwald setup->sm_local_rand[7u] = (setup->sm_local_rand[7u] & 0xf0u) + (connection->sm_actual_encryption_key_size - 1u); 37233deb3ec6SMatthias Ringwald // no db for authenticated flag hack: store flag in bit 4 of LSB 37244ea43905SMatthias Ringwald setup->sm_local_rand[7u] = (setup->sm_local_rand[7u] & 0xefu) + (connection->sm_connection_authenticated << 4u); 37258b3ffec5SMatthias 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); 37263deb3ec6SMatthias Ringwald } 3727899e6e02SMatthias Ringwald static void sm_validate_er_ir(void){ 3728899e6e02SMatthias Ringwald // warn about default ER/IR 37291979f09cSMatthias Ringwald bool warning = false; 3730899e6e02SMatthias Ringwald if (sm_ir_is_default()){ 37311979f09cSMatthias Ringwald warning = true; 3732899e6e02SMatthias Ringwald log_error("Persistent IR not set with sm_set_ir. Use of private addresses will cause pairing issues"); 3733899e6e02SMatthias Ringwald } 3734899e6e02SMatthias Ringwald if (sm_er_is_default()){ 37351979f09cSMatthias Ringwald warning = true; 3736899e6e02SMatthias Ringwald log_error("Persistent ER not set with sm_set_er. Legacy Pairing LTK is not secure"); 3737899e6e02SMatthias Ringwald } 373821045273SMatthias Ringwald if (warning) { 3739899e6e02SMatthias Ringwald log_error("Please configure btstack_tlv to let BTstack setup ER and IR keys"); 3740899e6e02SMatthias Ringwald } 374121045273SMatthias Ringwald } 3742899e6e02SMatthias Ringwald 3743899e6e02SMatthias Ringwald static void sm_handle_random_result_ir(void *arg){ 37441979f09cSMatthias Ringwald sm_persistent_keys_random_active = false; 37459305033eSMatthias Ringwald if (arg != NULL){ 3746899e6e02SMatthias Ringwald // key generated, store in tlv 37474ea43905SMatthias Ringwald int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16u); 3748899e6e02SMatthias Ringwald log_info("Generated IR key. Store in TLV status: %d", status); 3749e0d13a19SMilanka Ringwald UNUSED(status); 3750899e6e02SMatthias Ringwald } 3751899e6e02SMatthias Ringwald log_info_key("IR", sm_persistent_ir); 37528d9b6072SMatthias Ringwald dkg_state = DKG_CALC_IRK; 3753841468bbSMatthias Ringwald 3754841468bbSMatthias Ringwald if (test_use_fixed_local_irk){ 3755841468bbSMatthias Ringwald log_info_key("IRK", sm_persistent_irk); 3756841468bbSMatthias Ringwald dkg_state = DKG_CALC_DHK; 3757841468bbSMatthias Ringwald } 3758841468bbSMatthias Ringwald 375970b44dd4SMatthias Ringwald sm_trigger_run(); 3760899e6e02SMatthias Ringwald } 3761899e6e02SMatthias Ringwald 3762899e6e02SMatthias Ringwald static void sm_handle_random_result_er(void *arg){ 37631979f09cSMatthias Ringwald sm_persistent_keys_random_active = false; 37646643d79bSMatthias Ringwald if (arg != NULL){ 3765899e6e02SMatthias Ringwald // key generated, store in tlv 37664ea43905SMatthias Ringwald int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16u); 3767899e6e02SMatthias Ringwald log_info("Generated ER key. Store in TLV status: %d", status); 3768e0d13a19SMilanka Ringwald UNUSED(status); 3769899e6e02SMatthias Ringwald } 3770899e6e02SMatthias Ringwald log_info_key("ER", sm_persistent_er); 3771899e6e02SMatthias Ringwald 3772899e6e02SMatthias Ringwald // try load ir 37734ea43905SMatthias Ringwald int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16u); 3774899e6e02SMatthias Ringwald if (key_size == 16){ 3775899e6e02SMatthias Ringwald // ok, let's continue 3776899e6e02SMatthias Ringwald log_info("IR from TLV"); 3777899e6e02SMatthias Ringwald sm_handle_random_result_ir( NULL ); 3778899e6e02SMatthias Ringwald } else { 3779899e6e02SMatthias Ringwald // invalid, generate new random one 37801979f09cSMatthias Ringwald sm_persistent_keys_random_active = true; 3781899e6e02SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_ir, 16, &sm_handle_random_result_ir, &sm_persistent_ir); 3782899e6e02SMatthias Ringwald } 3783899e6e02SMatthias Ringwald } 37843deb3ec6SMatthias Ringwald 378550053c13SMatthias 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){ 3786f664b5e8SMatthias Ringwald 3787f664b5e8SMatthias Ringwald // connection info 3788f664b5e8SMatthias Ringwald sm_conn->sm_handle = con_handle; 3789f664b5e8SMatthias Ringwald sm_conn->sm_role = role; 379050053c13SMatthias Ringwald sm_conn->sm_peer_addr_type = peer_addr_type; 379150053c13SMatthias Ringwald memcpy(sm_conn->sm_peer_address, peer_address, 6); 3792f664b5e8SMatthias Ringwald 3793f664b5e8SMatthias Ringwald // security properties 3794f664b5e8SMatthias Ringwald sm_conn->sm_connection_encrypted = 0; 3795f664b5e8SMatthias Ringwald sm_conn->sm_connection_authenticated = 0; 3796f664b5e8SMatthias Ringwald sm_conn->sm_connection_authorization_state = AUTHORIZATION_UNKNOWN; 3797f664b5e8SMatthias Ringwald sm_conn->sm_le_db_index = -1; 3798f664b5e8SMatthias Ringwald sm_conn->sm_reencryption_active = false; 3799f664b5e8SMatthias Ringwald 3800f664b5e8SMatthias Ringwald // prepare CSRK lookup (does not involve setup) 3801f664b5e8SMatthias Ringwald sm_conn->sm_irk_lookup_state = IRK_LOOKUP_W4_READY; 3802f664b5e8SMatthias Ringwald 3803f664b5e8SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_IDLE; 3804f664b5e8SMatthias Ringwald } 3805f664b5e8SMatthias Ringwald 3806599e89daSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 3807599e89daSMatthias Ringwald static void sm_event_handle_classic_encryption_event(sm_connection_t * sm_conn, hci_con_handle_t con_handle){ 3808599e89daSMatthias Ringwald // CTKD requires BR/EDR Secure Connection 3809599e89daSMatthias Ringwald if (sm_conn->sm_connection_encrypted != 2) return; 3810599e89daSMatthias Ringwald // prepare for pairing request 3811599e89daSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 3812d44cdc4aSMatthias Ringwald log_info("CTKD: SM_BR_EDR_RESPONDER_W4_PAIRING_REQUEST"); 3813599e89daSMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_RESPONDER_W4_PAIRING_REQUEST; 3814599e89daSMatthias Ringwald } else if (sm_conn->sm_pairing_requested){ 3815599e89daSMatthias Ringwald // check if remote supports fixed channels 3816599e89daSMatthias Ringwald bool defer = true; 3817599e89daSMatthias Ringwald const hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); 3818599e89daSMatthias Ringwald if (hci_connection->l2cap_state.information_state == L2CAP_INFORMATION_STATE_DONE){ 3819599e89daSMatthias Ringwald // check if remote supports SMP over BR/EDR 3820599e89daSMatthias Ringwald if ((hci_connection->l2cap_state.fixed_channels_supported & (1 << L2CAP_CID_BR_EDR_SECURITY_MANAGER)) != 0){ 3821599e89daSMatthias Ringwald log_info("CTKD: SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST"); 3822599e89daSMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST; 3823599e89daSMatthias Ringwald } else { 3824599e89daSMatthias Ringwald defer = false; 3825599e89daSMatthias Ringwald } 3826599e89daSMatthias Ringwald } else { 3827599e89daSMatthias Ringwald // wait for fixed channel info 3828599e89daSMatthias Ringwald log_info("CTKD: SM_BR_EDR_INITIATOR_W4_FIXED_CHANNEL_MASK"); 3829599e89daSMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_INITIATOR_W4_FIXED_CHANNEL_MASK; 3830599e89daSMatthias Ringwald } 3831599e89daSMatthias Ringwald if (defer){ 3832599e89daSMatthias Ringwald hci_dedicated_bonding_defer_disconnect(con_handle, true); 3833599e89daSMatthias Ringwald } 3834599e89daSMatthias Ringwald } 3835599e89daSMatthias Ringwald } 3836599e89daSMatthias Ringwald #endif 3837599e89daSMatthias Ringwald 3838d9a7306aSMatthias Ringwald static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 38393deb3ec6SMatthias Ringwald 3840cbdfe9f7SMatthias Ringwald UNUSED(channel); // ok: there is no channel 3841cbdfe9f7SMatthias Ringwald UNUSED(size); // ok: fixed format HCI events 38429ec2630cSMatthias Ringwald 38433deb3ec6SMatthias Ringwald sm_connection_t * sm_conn; 3844711e6c80SMatthias Ringwald hci_con_handle_t con_handle; 3845fbe050beSMatthias Ringwald uint8_t status; 3846f664b5e8SMatthias Ringwald bd_addr_t addr; 3847d9f3ead5SMatthias Ringwald bd_addr_type_t addr_type; 3848f664b5e8SMatthias Ringwald 38493deb3ec6SMatthias Ringwald switch (packet_type) { 38503deb3ec6SMatthias Ringwald 38513deb3ec6SMatthias Ringwald case HCI_EVENT_PACKET: 38520e2df43fSMatthias Ringwald switch (hci_event_packet_get_type(packet)) { 38533deb3ec6SMatthias Ringwald 38543deb3ec6SMatthias Ringwald case BTSTACK_EVENT_STATE: 3855745015f6SMatthias Ringwald switch (btstack_event_state_get_state(packet)){ 3856745015f6SMatthias Ringwald case HCI_STATE_WORKING: 38573deb3ec6SMatthias Ringwald log_info("HCI Working!"); 3858899e6e02SMatthias Ringwald // setup IR/ER with TLV 3859899e6e02SMatthias Ringwald btstack_tlv_get_instance(&sm_tlv_impl, &sm_tlv_context); 38609305033eSMatthias Ringwald if (sm_tlv_impl != NULL){ 38614ea43905SMatthias Ringwald int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16u); 3862899e6e02SMatthias Ringwald if (key_size == 16){ 3863899e6e02SMatthias Ringwald // ok, let's continue 3864899e6e02SMatthias Ringwald log_info("ER from TLV"); 3865899e6e02SMatthias Ringwald sm_handle_random_result_er( NULL ); 3866899e6e02SMatthias Ringwald } else { 3867899e6e02SMatthias Ringwald // invalid, generate random one 38681979f09cSMatthias Ringwald sm_persistent_keys_random_active = true; 3869899e6e02SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_er, 16, &sm_handle_random_result_er, &sm_persistent_er); 3870899e6e02SMatthias Ringwald } 3871899e6e02SMatthias Ringwald } else { 3872899e6e02SMatthias Ringwald sm_validate_er_ir(); 38738d9b6072SMatthias Ringwald dkg_state = DKG_CALC_IRK; 3874841468bbSMatthias Ringwald 3875841468bbSMatthias Ringwald if (test_use_fixed_local_irk){ 3876841468bbSMatthias Ringwald log_info_key("IRK", sm_persistent_irk); 3877841468bbSMatthias Ringwald dkg_state = DKG_CALC_DHK; 3878841468bbSMatthias Ringwald } 3879899e6e02SMatthias Ringwald } 38801bf086daSMatthias Ringwald 388115211b85SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 388215211b85SMatthias Ringwald // trigger ECC key generation 388315211b85SMatthias Ringwald if (ec_key_generation_state == EC_KEY_GENERATION_IDLE){ 388415211b85SMatthias Ringwald sm_ec_generate_new_key(); 388515211b85SMatthias Ringwald } 388615211b85SMatthias Ringwald #endif 388715211b85SMatthias Ringwald 38881bf086daSMatthias Ringwald // restart random address updates after power cycle 38894a688bd1SMatthias Ringwald if (gap_random_adress_type == GAP_RANDOM_ADDRESS_TYPE_STATIC){ 38904a688bd1SMatthias Ringwald gap_random_address_set(sm_random_address); 38914a688bd1SMatthias Ringwald } else { 38921bf086daSMatthias Ringwald gap_random_address_set_mode(gap_random_adress_type); 38934a688bd1SMatthias Ringwald } 3894745015f6SMatthias Ringwald break; 3895745015f6SMatthias Ringwald 3896745015f6SMatthias Ringwald case HCI_STATE_OFF: 38977f775357SMatthias Ringwald case HCI_STATE_HALTING: 3898cbdd51cfSMatthias Ringwald log_info("SM: reset state"); 3899745015f6SMatthias Ringwald // stop random address update 3900745015f6SMatthias Ringwald gap_random_address_update_stop(); 3901cbdd51cfSMatthias Ringwald // reset state 3902cbdd51cfSMatthias Ringwald sm_state_reset(); 3903745015f6SMatthias Ringwald break; 3904745015f6SMatthias Ringwald 3905745015f6SMatthias Ringwald default: 3906745015f6SMatthias Ringwald break; 39073deb3ec6SMatthias Ringwald } 39083deb3ec6SMatthias Ringwald break; 3909c18be159SMatthias Ringwald 39102d095694SMatthias Ringwald #ifdef ENABLE_CLASSIC 39112d095694SMatthias Ringwald case HCI_EVENT_CONNECTION_COMPLETE: 39122d095694SMatthias Ringwald // ignore if connection failed 39132d095694SMatthias Ringwald if (hci_event_connection_complete_get_status(packet)) return; 39143deb3ec6SMatthias Ringwald 39152d095694SMatthias Ringwald con_handle = hci_event_connection_complete_get_connection_handle(packet); 39162d095694SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 39172d095694SMatthias Ringwald if (!sm_conn) break; 39182d095694SMatthias Ringwald 39192d095694SMatthias Ringwald hci_event_connection_complete_get_bd_addr(packet, addr); 39202d095694SMatthias Ringwald sm_connection_init(sm_conn, 39212d095694SMatthias Ringwald con_handle, 39222d095694SMatthias Ringwald (uint8_t) gap_get_role(con_handle), 3923f72f7944SMatthias Ringwald BD_ADDR_TYPE_LE_PUBLIC, 39242d095694SMatthias Ringwald addr); 39252d095694SMatthias Ringwald // classic connection corresponds to public le address 39262d095694SMatthias Ringwald sm_conn->sm_own_addr_type = BD_ADDR_TYPE_LE_PUBLIC; 39272d095694SMatthias Ringwald gap_local_bd_addr(sm_conn->sm_own_address); 39282d095694SMatthias Ringwald sm_conn->sm_cid = L2CAP_CID_BR_EDR_SECURITY_MANAGER; 3929c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_W4_ENCRYPTION_COMPLETE; 39302d095694SMatthias Ringwald break; 3931d44cdc4aSMatthias Ringwald 3932401d2b30SMatthias Ringwald #endif 3933401d2b30SMatthias Ringwald 3934401d2b30SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 3935d44cdc4aSMatthias Ringwald case HCI_EVENT_ROLE_CHANGE: 3936d44cdc4aSMatthias Ringwald hci_event_role_change_get_bd_addr(packet, addr); 3937d44cdc4aSMatthias Ringwald sm_conn = sm_get_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL); 3938d44cdc4aSMatthias Ringwald if (sm_conn == NULL) break; 3939d44cdc4aSMatthias Ringwald sm_conn->sm_role = hci_event_role_change_get_role(packet); 3940d44cdc4aSMatthias Ringwald break; 3941c18be159SMatthias Ringwald 3942c18be159SMatthias Ringwald case HCI_EVENT_SIMPLE_PAIRING_COMPLETE: 3943c18be159SMatthias Ringwald if (hci_event_simple_pairing_complete_get_status(packet) != ERROR_CODE_SUCCESS) break; 3944c18be159SMatthias Ringwald hci_event_simple_pairing_complete_get_bd_addr(packet, addr); 3945c18be159SMatthias Ringwald sm_conn = sm_get_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL); 3946c18be159SMatthias Ringwald if (sm_conn == NULL) break; 39475f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 3948c18be159SMatthias Ringwald break; 3949c18be159SMatthias Ringwald #endif 3950c18be159SMatthias Ringwald 39519d1eff91SMatthias Ringwald case HCI_EVENT_META_GAP: 39529d1eff91SMatthias Ringwald switch (hci_event_gap_meta_get_subevent_code(packet)) { 39539d1eff91SMatthias Ringwald case GAP_SUBEVENT_LE_CONNECTION_COMPLETE: 3954f664b5e8SMatthias Ringwald // ignore if connection failed 39559d1eff91SMatthias Ringwald if (gap_subevent_le_connection_complete_get_status(packet) != ERROR_CODE_SUCCESS) break; 39563deb3ec6SMatthias Ringwald 39579d1eff91SMatthias Ringwald con_handle = gap_subevent_le_connection_complete_get_connection_handle(packet); 3958711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 39593deb3ec6SMatthias Ringwald if (!sm_conn) break; 39603deb3ec6SMatthias Ringwald 3961d9f3ead5SMatthias Ringwald // Get current peer address 3962d9f3ead5SMatthias Ringwald addr_type = gap_subevent_le_connection_complete_get_peer_address_type(packet); 3963d9f3ead5SMatthias Ringwald if (hci_is_le_identity_address_type(addr_type)){ 3964d9f3ead5SMatthias Ringwald addr_type = BD_ADDR_TYPE_LE_RANDOM; 3965d9f3ead5SMatthias Ringwald gap_subevent_le_connection_complete_get_peer_resolvable_private_address(packet, addr); 3966d9f3ead5SMatthias Ringwald } else { 39679d1eff91SMatthias Ringwald gap_subevent_le_connection_complete_get_peer_address(packet, addr); 3968d9f3ead5SMatthias Ringwald } 3969f664b5e8SMatthias Ringwald sm_connection_init(sm_conn, 3970f664b5e8SMatthias Ringwald con_handle, 39719d1eff91SMatthias Ringwald gap_subevent_le_connection_complete_get_role(packet), 3972d9f3ead5SMatthias Ringwald addr_type, 3973f664b5e8SMatthias Ringwald addr); 3974687a03c8SMatthias Ringwald sm_conn->sm_cid = L2CAP_CID_SECURITY_MANAGER_PROTOCOL; 3975f664b5e8SMatthias Ringwald 3976f664b5e8SMatthias Ringwald // track our addr used for this connection and set state 3977b6f39a74SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 39789d1eff91SMatthias Ringwald if (gap_subevent_le_connection_complete_get_role(packet) != 0){ 3979ba9fc867SMatthias Ringwald // responder - use own address from advertisements 398067bf59ffSMatthias Ringwald #ifdef ENABLE_LE_EXTENDED_ADVERTISING 398167bf59ffSMatthias Ringwald if (hci_le_extended_advertising_supported()){ 398267bf59ffSMatthias Ringwald // cache local resolvable address 398367bf59ffSMatthias Ringwald // note: will be overwritten if random or private address was used in adv set by HCI_SUBEVENT_LE_ADVERTISING_SET_TERMINATED 398467bf59ffSMatthias Ringwald sm_conn->sm_own_addr_type = BD_ADDR_TYPE_LE_RANDOM; 398567bf59ffSMatthias Ringwald gap_subevent_le_connection_complete_get_local_resolvable_private_address(packet,sm_conn->sm_own_address); 398667bf59ffSMatthias Ringwald } else 398767bf59ffSMatthias Ringwald #endif 398867bf59ffSMatthias Ringwald { 3989ba9fc867SMatthias Ringwald gap_le_get_own_advertisements_address(&sm_conn->sm_own_addr_type, sm_conn->sm_own_address); 399067bf59ffSMatthias Ringwald } 3991f664b5e8SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 3992b892db1cSMatthias Ringwald } 3993b892db1cSMatthias Ringwald #endif 3994b892db1cSMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 39959d1eff91SMatthias Ringwald if (gap_subevent_le_connection_complete_get_role(packet) == 0){ 3996ba9fc867SMatthias Ringwald // initiator - use own address from create connection 3997ba9fc867SMatthias Ringwald gap_le_get_own_connection_address(&sm_conn->sm_own_addr_type, sm_conn->sm_own_address); 39983deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 39993deb3ec6SMatthias Ringwald } 4000b892db1cSMatthias Ringwald #endif 40013deb3ec6SMatthias Ringwald break; 40029d1eff91SMatthias Ringwald default: 40039d1eff91SMatthias Ringwald break; 40049d1eff91SMatthias Ringwald } 40059d1eff91SMatthias Ringwald break; 40069d1eff91SMatthias Ringwald case HCI_EVENT_LE_META: 40079d1eff91SMatthias Ringwald switch (hci_event_le_meta_get_subevent_code(packet)) { 400867bf59ffSMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 400967bf59ffSMatthias Ringwald #ifdef ENABLE_LE_EXTENDED_ADVERTISING 401067bf59ffSMatthias Ringwald case HCI_SUBEVENT_LE_ADVERTISING_SET_TERMINATED: 401167bf59ffSMatthias Ringwald if (hci_subevent_le_advertising_set_terminated_get_status(packet) == ERROR_CODE_SUCCESS){ 401267bf59ffSMatthias Ringwald uint8_t advertising_handle = hci_subevent_le_advertising_set_terminated_get_advertising_handle(packet); 401367bf59ffSMatthias Ringwald con_handle = hci_subevent_le_advertising_set_terminated_get_connection_handle(packet); 401467bf59ffSMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 4015ebd6ff34SMatthias Ringwald if (!sm_conn) break; 4016ebd6ff34SMatthias Ringwald 401767bf59ffSMatthias Ringwald gap_le_get_own_advertising_set_address(&sm_conn->sm_own_addr_type, sm_conn->sm_own_address, advertising_handle); 401867bf59ffSMatthias 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, 401967bf59ffSMatthias Ringwald bd_addr_to_str(sm_conn->sm_own_address), con_handle); 402067bf59ffSMatthias Ringwald } 402167bf59ffSMatthias Ringwald break; 402267bf59ffSMatthias Ringwald #endif 402367bf59ffSMatthias Ringwald #endif 40243deb3ec6SMatthias Ringwald case HCI_SUBEVENT_LE_LONG_TERM_KEY_REQUEST: 40259d1eff91SMatthias Ringwald con_handle = hci_subevent_le_long_term_key_request_get_connection_handle(packet); 4026711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 40273deb3ec6SMatthias Ringwald if (!sm_conn) break; 40283deb3ec6SMatthias Ringwald 40293deb3ec6SMatthias Ringwald log_info("LTK Request: state %u", sm_conn->sm_engine_state); 40303deb3ec6SMatthias Ringwald if (sm_conn->sm_engine_state == SM_RESPONDER_PH2_W4_LTK_REQUEST){ 40313deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_CALC_STK; 40323deb3ec6SMatthias Ringwald break; 40333deb3ec6SMatthias Ringwald } 4034c6b7cbd9SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_LTK_REQUEST_SC){ 4035778b6aadSMatthias Ringwald // PH2 SEND LTK as we need to exchange keys in PH3 4036778b6aadSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH2_SEND_LTK_REPLY; 4037e53be891SMatthias Ringwald break; 4038e53be891SMatthias Ringwald } 40393deb3ec6SMatthias Ringwald 40403deb3ec6SMatthias Ringwald // store rand and ediv 40419c80e4ccSMatthias Ringwald reverse_64(&packet[5], sm_conn->sm_local_rand); 40429d1eff91SMatthias Ringwald sm_conn->sm_local_ediv = hci_subevent_le_long_term_key_request_get_encryption_diversifier(packet); 4043549ad5d2SMatthias Ringwald 4044549ad5d2SMatthias Ringwald // For Legacy Pairing (<=> EDIV != 0 || RAND != NULL), we need to recalculated our LTK as a 4045549ad5d2SMatthias Ringwald // potentially stored LTK is from the master 40464ea43905SMatthias Ringwald if ((sm_conn->sm_local_ediv != 0u) || !sm_is_null_random(sm_conn->sm_local_rand)){ 40476c39055aSMatthias Ringwald if (sm_reconstruct_ltk_without_le_device_db_entry){ 404806cd539fSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST; 4049549ad5d2SMatthias Ringwald break; 4050549ad5d2SMatthias Ringwald } 40516c39055aSMatthias Ringwald // additionally check if remote is in LE Device DB if requested 40526c39055aSMatthias Ringwald switch(sm_conn->sm_irk_lookup_state){ 40536c39055aSMatthias Ringwald case IRK_LOOKUP_FAILED: 40546c39055aSMatthias Ringwald log_info("LTK Request: device not in device db"); 40556c39055aSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY; 40566c39055aSMatthias Ringwald break; 40576c39055aSMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 40586c39055aSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST; 40596c39055aSMatthias Ringwald break; 40606c39055aSMatthias Ringwald default: 40616c39055aSMatthias Ringwald // wait for irk look doen 40626c39055aSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK; 40636c39055aSMatthias Ringwald break; 40646c39055aSMatthias Ringwald } 40656c39055aSMatthias Ringwald break; 40666c39055aSMatthias Ringwald } 4067549ad5d2SMatthias Ringwald 4068549ad5d2SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 406906cd539fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_RECEIVED_LTK_REQUEST; 4070549ad5d2SMatthias Ringwald #else 4071549ad5d2SMatthias Ringwald log_info("LTK Request: ediv & random are empty, but LE Secure Connections not supported"); 4072549ad5d2SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY; 4073549ad5d2SMatthias Ringwald #endif 40743deb3ec6SMatthias Ringwald break; 4075804d3e67SMatthias Ringwald 40763deb3ec6SMatthias Ringwald default: 40773deb3ec6SMatthias Ringwald break; 40783deb3ec6SMatthias Ringwald } 40793deb3ec6SMatthias Ringwald break; 40803deb3ec6SMatthias Ringwald 40813deb3ec6SMatthias Ringwald case HCI_EVENT_ENCRYPTION_CHANGE: 40828601e696SMatthias Ringwald case HCI_EVENT_ENCRYPTION_CHANGE_V2: 40833b7fd749SMatthias Ringwald con_handle = hci_event_encryption_change_get_connection_handle(packet); 4084711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 40853deb3ec6SMatthias Ringwald if (!sm_conn) break; 40863deb3ec6SMatthias Ringwald 40873b7fd749SMatthias Ringwald sm_conn->sm_connection_encrypted = hci_event_encryption_change_get_encryption_enabled(packet); 40883deb3ec6SMatthias Ringwald log_info("Encryption state change: %u, key size %u", sm_conn->sm_connection_encrypted, 40893deb3ec6SMatthias Ringwald sm_conn->sm_actual_encryption_key_size); 40903deb3ec6SMatthias Ringwald log_info("event handler, state %u", sm_conn->sm_engine_state); 409103a9359aSMatthias Ringwald 4092fbe050beSMatthias Ringwald switch (sm_conn->sm_engine_state){ 4093fbe050beSMatthias Ringwald 40945567aa60SMatthias Ringwald case SM_PH4_W4_CONNECTION_ENCRYPTED: 409503a9359aSMatthias Ringwald // encryption change event concludes re-encryption for bonded devices (even if it fails) 40961d80f1e6SMatthias Ringwald if (sm_conn->sm_connection_encrypted != 0u) { 4097fbe050beSMatthias Ringwald status = ERROR_CODE_SUCCESS; 40981d80f1e6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 40998d4eef95SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 41008d4eef95SMatthias Ringwald } else { 410103a9359aSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 41028d4eef95SMatthias Ringwald } 4103fbe050beSMatthias Ringwald } else { 4104e28291c1SMatthias Ringwald status = hci_event_encryption_change_get_status(packet); 4105cb6d7eb0SMatthias Ringwald // set state to 'RE-ENCRYPTION FAILED' to allow pairing but prevent other interactions 41063b7fd749SMatthias Ringwald // also, gap_reconnect_security_setup_active will return true 4107cb6d7eb0SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_REENCRYPTION_FAILED; 41083b7fd749SMatthias Ringwald } 4109fbe050beSMatthias Ringwald 4110fbe050beSMatthias Ringwald // emit re-encryption complete 411173102768SMatthias Ringwald sm_reencryption_complete(sm_conn, status); 4112fbe050beSMatthias Ringwald 4113c245ca32SMatthias Ringwald // notify client, if pairing was requested before 4114c245ca32SMatthias Ringwald if (sm_conn->sm_pairing_requested){ 41155f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = false; 41160ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, status, 0); 411703a9359aSMatthias Ringwald } 411803a9359aSMatthias Ringwald 41193deb3ec6SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 41203deb3ec6SMatthias Ringwald break; 4121fbe050beSMatthias Ringwald 41223deb3ec6SMatthias Ringwald case SM_PH2_W4_CONNECTION_ENCRYPTED: 4123fbe050beSMatthias Ringwald if (!sm_conn->sm_connection_encrypted) break; 412457ff4745SMatthias Ringwald // handler for HCI_EVENT_ENCRYPTION_KEY_REFRESH_COMPLETE 412557ff4745SMatthias Ringwald // contains the same code for this state 4126dd583d9fSMatthias Ringwald sm_conn->sm_connection_sc = setup->sm_use_secure_connections; 412742134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 41283deb3ec6SMatthias Ringwald // slave 412957ff4745SMatthias Ringwald if (sm_conn->sm_connection_sc){ 4130bbf8db22SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 4131bbf8db22SMatthias Ringwald } else { 4132f3582630SMatthias 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); 4133bbf8db22SMatthias Ringwald } 41343deb3ec6SMatthias Ringwald } else { 41353deb3ec6SMatthias Ringwald // master 413661d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 41373deb3ec6SMatthias Ringwald // skip receiving keys as there are none 41383deb3ec6SMatthias Ringwald sm_key_distribution_handle_all_received(sm_conn); 4139f3582630SMatthias 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); 41403deb3ec6SMatthias Ringwald } else { 41413deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS; 41423deb3ec6SMatthias Ringwald } 41433deb3ec6SMatthias Ringwald } 41443deb3ec6SMatthias Ringwald break; 4145c18be159SMatthias Ringwald 4146c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 4147c18be159SMatthias Ringwald case SM_BR_EDR_W4_ENCRYPTION_COMPLETE: 4148599e89daSMatthias Ringwald sm_event_handle_classic_encryption_event(sm_conn, con_handle); 4149c18be159SMatthias Ringwald break; 4150c18be159SMatthias Ringwald #endif 41513deb3ec6SMatthias Ringwald default: 41523deb3ec6SMatthias Ringwald break; 41533deb3ec6SMatthias Ringwald } 41543deb3ec6SMatthias Ringwald break; 41553deb3ec6SMatthias Ringwald 41563deb3ec6SMatthias Ringwald case HCI_EVENT_ENCRYPTION_KEY_REFRESH_COMPLETE: 4157711e6c80SMatthias Ringwald con_handle = little_endian_read_16(packet, 3); 4158711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 41593deb3ec6SMatthias Ringwald if (!sm_conn) break; 41603deb3ec6SMatthias Ringwald 41613deb3ec6SMatthias Ringwald log_info("Encryption key refresh complete, key size %u", sm_conn->sm_actual_encryption_key_size); 41623deb3ec6SMatthias Ringwald log_info("event handler, state %u", sm_conn->sm_engine_state); 41633deb3ec6SMatthias Ringwald // continue if part of initial pairing 41643deb3ec6SMatthias Ringwald switch (sm_conn->sm_engine_state){ 41655567aa60SMatthias Ringwald case SM_PH4_W4_CONNECTION_ENCRYPTED: 41661d80f1e6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 41675567aa60SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 41685567aa60SMatthias Ringwald } else { 41693deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 41705567aa60SMatthias Ringwald } 41713deb3ec6SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 41723deb3ec6SMatthias Ringwald break; 41733deb3ec6SMatthias Ringwald case SM_PH2_W4_CONNECTION_ENCRYPTED: 417457ff4745SMatthias Ringwald // handler for HCI_EVENT_ENCRYPTION_CHANGE 417557ff4745SMatthias Ringwald // contains the same code for this state 417657ff4745SMatthias Ringwald sm_conn->sm_connection_sc = setup->sm_use_secure_connections; 417742134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 41783deb3ec6SMatthias Ringwald // slave 417957ff4745SMatthias Ringwald if (sm_conn->sm_connection_sc){ 418057ff4745SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 418157ff4745SMatthias Ringwald } else { 4182f3582630SMatthias 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); 418357ff4745SMatthias Ringwald } 41843deb3ec6SMatthias Ringwald } else { 41853deb3ec6SMatthias Ringwald // master 418657ff4745SMatthias Ringwald if (sm_key_distribution_all_received()){ 418757ff4745SMatthias Ringwald // skip receiving keys as there are none 418857ff4745SMatthias Ringwald sm_key_distribution_handle_all_received(sm_conn); 418957ff4745SMatthias 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); 419057ff4745SMatthias Ringwald } else { 41913deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS; 41923deb3ec6SMatthias Ringwald } 419357ff4745SMatthias Ringwald } 41943deb3ec6SMatthias Ringwald break; 419594219034SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 419694219034SMatthias Ringwald case SM_BR_EDR_W4_ENCRYPTION_COMPLETE: 419794219034SMatthias Ringwald sm_event_handle_classic_encryption_event(sm_conn, con_handle); 419894219034SMatthias Ringwald break; 419994219034SMatthias Ringwald #endif 42003deb3ec6SMatthias Ringwald default: 42013deb3ec6SMatthias Ringwald break; 42023deb3ec6SMatthias Ringwald } 42033deb3ec6SMatthias Ringwald break; 42043deb3ec6SMatthias Ringwald 42053deb3ec6SMatthias Ringwald 42063deb3ec6SMatthias Ringwald case HCI_EVENT_DISCONNECTION_COMPLETE: 4207711e6c80SMatthias Ringwald con_handle = little_endian_read_16(packet, 3); 4208711e6c80SMatthias Ringwald sm_done_for_handle(con_handle); 4209711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 42103deb3ec6SMatthias Ringwald if (!sm_conn) break; 42113deb3ec6SMatthias Ringwald 421203f736b1SMatthias Ringwald // pairing failed, if it was ongoing 42137f3f442dSMatthias Ringwald switch (sm_conn->sm_engine_state){ 42147f3f442dSMatthias Ringwald case SM_GENERAL_IDLE: 42157f3f442dSMatthias Ringwald case SM_INITIATOR_CONNECTED: 42167f3f442dSMatthias Ringwald case SM_RESPONDER_IDLE: 42177f3f442dSMatthias Ringwald break; 42187f3f442dSMatthias Ringwald default: 421968a18fb9SMatthias Ringwald sm_reencryption_complete(sm_conn, ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION); 42200ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION, 0); 42217f3f442dSMatthias Ringwald break; 422203f736b1SMatthias Ringwald } 4223accbde80SMatthias Ringwald 42243deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_IDLE; 42253deb3ec6SMatthias Ringwald sm_conn->sm_handle = 0; 42263deb3ec6SMatthias Ringwald break; 42273deb3ec6SMatthias Ringwald 42283deb3ec6SMatthias Ringwald case HCI_EVENT_COMMAND_COMPLETE: 4229f7811256SMatthias Ringwald if (hci_event_command_complete_get_command_opcode(packet) == HCI_OPCODE_HCI_READ_BD_ADDR) { 42309091c5f5SMatthias Ringwald // set local addr for le device db 423133373e40SMatthias Ringwald reverse_bd_addr(&packet[OFFSET_OF_DATA_IN_COMMAND_COMPLETE + 1], addr); 42320c130b19SMatthias Ringwald le_device_db_set_local_bd_addr(addr); 423333373e40SMatthias Ringwald } 423465b44ffdSMatthias Ringwald break; 4235a036ae12SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 4236a036ae12SMatthias Ringwald case L2CAP_EVENT_INFORMATION_RESPONSE: 4237a036ae12SMatthias Ringwald con_handle = l2cap_event_information_response_get_con_handle(packet); 4238a036ae12SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 4239a036ae12SMatthias Ringwald if (!sm_conn) break; 4240a036ae12SMatthias Ringwald if (sm_conn->sm_engine_state == SM_BR_EDR_INITIATOR_W4_FIXED_CHANNEL_MASK){ 4241a036ae12SMatthias Ringwald // check if remote supports SMP over BR/EDR 4242a036ae12SMatthias Ringwald const hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); 4243a036ae12SMatthias Ringwald if ((hci_connection->l2cap_state.fixed_channels_supported & (1 << L2CAP_CID_BR_EDR_SECURITY_MANAGER)) != 0){ 4244a036ae12SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST; 4245a036ae12SMatthias Ringwald } else { 4246a036ae12SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 4247f82b8f4bSMatthias Ringwald hci_dedicated_bonding_defer_disconnect(con_handle, false); 4248a036ae12SMatthias Ringwald } 4249a036ae12SMatthias Ringwald } 4250a036ae12SMatthias Ringwald break; 4251a036ae12SMatthias Ringwald #endif 425265b44ffdSMatthias Ringwald default: 425365b44ffdSMatthias Ringwald break; 42543deb3ec6SMatthias Ringwald } 425565b44ffdSMatthias Ringwald break; 425665b44ffdSMatthias Ringwald default: 425765b44ffdSMatthias Ringwald break; 42583deb3ec6SMatthias Ringwald } 42593deb3ec6SMatthias Ringwald 42603deb3ec6SMatthias Ringwald sm_run(); 42613deb3ec6SMatthias Ringwald } 42623deb3ec6SMatthias Ringwald 42633deb3ec6SMatthias Ringwald static inline int sm_calc_actual_encryption_key_size(int other){ 42643deb3ec6SMatthias Ringwald if (other < sm_min_encryption_key_size) return 0; 42653deb3ec6SMatthias Ringwald if (other < sm_max_encryption_key_size) return other; 42663deb3ec6SMatthias Ringwald return sm_max_encryption_key_size; 42673deb3ec6SMatthias Ringwald } 42683deb3ec6SMatthias Ringwald 4269945888f5SMatthias Ringwald 427031c09488SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 42711d80f1e6SMatthias Ringwald static bool sm_just_works_or_numeric_comparison(stk_generation_method_t method){ 4272945888f5SMatthias Ringwald switch (method){ 4273945888f5SMatthias Ringwald case JUST_WORKS: 427447fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 42751d80f1e6SMatthias Ringwald return true; 4276945888f5SMatthias Ringwald default: 42771d80f1e6SMatthias Ringwald return false; 4278945888f5SMatthias Ringwald } 4279945888f5SMatthias Ringwald } 428007036a04SMatthias Ringwald // responder 4281945888f5SMatthias Ringwald 42821d80f1e6SMatthias Ringwald static bool sm_passkey_used(stk_generation_method_t method){ 4283688a08f9SMatthias Ringwald switch (method){ 4284688a08f9SMatthias Ringwald case PK_RESP_INPUT: 42851d80f1e6SMatthias Ringwald return true; 4286688a08f9SMatthias Ringwald default: 4287688a08f9SMatthias Ringwald return 0; 4288688a08f9SMatthias Ringwald } 4289688a08f9SMatthias Ringwald } 429040c5d850SMatthias Ringwald 42916777d8fdSMatthias Ringwald static bool sm_passkey_entry(stk_generation_method_t method){ 429240c5d850SMatthias Ringwald switch (method){ 429340c5d850SMatthias Ringwald case PK_RESP_INPUT: 429440c5d850SMatthias Ringwald case PK_INIT_INPUT: 429547fb4255SMatthias Ringwald case PK_BOTH_INPUT: 42966777d8fdSMatthias Ringwald return true; 429740c5d850SMatthias Ringwald default: 42986777d8fdSMatthias Ringwald return false; 429940c5d850SMatthias Ringwald } 430040c5d850SMatthias Ringwald } 430140c5d850SMatthias Ringwald 430231c09488SMatthias Ringwald #endif 4303688a08f9SMatthias Ringwald 43043deb3ec6SMatthias Ringwald /** 43053deb3ec6SMatthias Ringwald * @return ok 43063deb3ec6SMatthias Ringwald */ 43073deb3ec6SMatthias Ringwald static int sm_validate_stk_generation_method(void){ 43083deb3ec6SMatthias Ringwald // check if STK generation method is acceptable by client 43093deb3ec6SMatthias Ringwald switch (setup->sm_stk_generation_method){ 43103deb3ec6SMatthias Ringwald case JUST_WORKS: 43114ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_JUST_WORKS) != 0u; 43123deb3ec6SMatthias Ringwald case PK_RESP_INPUT: 43133deb3ec6SMatthias Ringwald case PK_INIT_INPUT: 431447fb4255SMatthias Ringwald case PK_BOTH_INPUT: 43154ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_PASSKEY) != 0u; 43163deb3ec6SMatthias Ringwald case OOB: 43174ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_OOB) != 0u; 431847fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 43194ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_NUMERIC_COMPARISON) != 0u; 43203deb3ec6SMatthias Ringwald default: 43213deb3ec6SMatthias Ringwald return 0; 43223deb3ec6SMatthias Ringwald } 43233deb3ec6SMatthias Ringwald } 43243deb3ec6SMatthias Ringwald 432536f0defaSMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 432636f0defaSMatthias Ringwald static void sm_initiator_connected_handle_security_request(sm_connection_t * sm_conn, const uint8_t *packet){ 432736f0defaSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 432836f0defaSMatthias Ringwald if (sm_sc_only_mode){ 432936f0defaSMatthias Ringwald uint8_t auth_req = packet[1]; 433036f0defaSMatthias Ringwald if ((auth_req & SM_AUTHREQ_SECURE_CONNECTION) == 0){ 433136f0defaSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_AUTHENTHICATION_REQUIREMENTS); 433236f0defaSMatthias Ringwald return; 433336f0defaSMatthias Ringwald } 433436f0defaSMatthias Ringwald } 433536f0defaSMatthias Ringwald #else 433636f0defaSMatthias Ringwald UNUSED(packet); 433736f0defaSMatthias Ringwald #endif 433836f0defaSMatthias Ringwald 433936f0defaSMatthias Ringwald int have_ltk; 434036f0defaSMatthias Ringwald uint8_t ltk[16]; 434136f0defaSMatthias Ringwald 434236f0defaSMatthias Ringwald // IRK complete? 434336f0defaSMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 434436f0defaSMatthias Ringwald case IRK_LOOKUP_FAILED: 434536f0defaSMatthias Ringwald // start pairing 434636f0defaSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 434736f0defaSMatthias Ringwald break; 434836f0defaSMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 434936f0defaSMatthias Ringwald le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); 435036f0defaSMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 435136f0defaSMatthias Ringwald log_info("central: security request - have_ltk %u, encryption %u", have_ltk, sm_conn->sm_connection_encrypted); 435236f0defaSMatthias Ringwald if (have_ltk && (sm_conn->sm_connection_encrypted == 0)){ 435336f0defaSMatthias Ringwald // start re-encrypt if we have LTK and the connection is not already encrypted 435436f0defaSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH4_HAS_LTK; 435536f0defaSMatthias Ringwald } else { 435636f0defaSMatthias Ringwald // start pairing 435736f0defaSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 435836f0defaSMatthias Ringwald } 435936f0defaSMatthias Ringwald break; 436036f0defaSMatthias Ringwald default: 436136f0defaSMatthias Ringwald // otherwise, store security request 43620dcaa15fSMatthias Ringwald sm_conn->sm_security_request_received = true; 436336f0defaSMatthias Ringwald break; 436436f0defaSMatthias Ringwald } 436536f0defaSMatthias Ringwald } 436636f0defaSMatthias Ringwald #endif 436736f0defaSMatthias Ringwald 4368f9bda154SMatthias Ringwald static uint8_t sm_pdu_validate_and_get_opcode(uint8_t packet_type, const uint8_t *packet, uint16_t size){ 43698334d3d8SMatthias Ringwald 43704c1d1092SMatthias Ringwald // size of complete sm_pdu used to validate input 43714c1d1092SMatthias Ringwald static const uint8_t sm_pdu_size[] = { 43724c1d1092SMatthias Ringwald 0, // 0x00 invalid opcode 43734c1d1092SMatthias Ringwald 7, // 0x01 pairing request 43744c1d1092SMatthias Ringwald 7, // 0x02 pairing response 43754c1d1092SMatthias Ringwald 17, // 0x03 pairing confirm 43764c1d1092SMatthias Ringwald 17, // 0x04 pairing random 43774c1d1092SMatthias Ringwald 2, // 0x05 pairing failed 43784c1d1092SMatthias Ringwald 17, // 0x06 encryption information 43797a2e6387SMatthias Ringwald 11, // 0x07 master identification 43804c1d1092SMatthias Ringwald 17, // 0x08 identification information 43814c1d1092SMatthias Ringwald 8, // 0x09 identify address information 43824c1d1092SMatthias Ringwald 17, // 0x0a signing information 43834c1d1092SMatthias Ringwald 2, // 0x0b security request 43844c1d1092SMatthias Ringwald 65, // 0x0c pairing public key 43854c1d1092SMatthias Ringwald 17, // 0x0d pairing dhk check 43864c1d1092SMatthias Ringwald 2, // 0x0e keypress notification 43874c1d1092SMatthias Ringwald }; 43883deb3ec6SMatthias Ringwald 4389f9bda154SMatthias Ringwald if (packet_type != SM_DATA_PACKET) return 0; 4390f9bda154SMatthias Ringwald if (size == 0u) return 0; 43914c1d1092SMatthias Ringwald 43924c1d1092SMatthias Ringwald uint8_t sm_pdu_code = packet[0]; 43934c1d1092SMatthias Ringwald 43944c1d1092SMatthias Ringwald // validate pdu size 4395f9bda154SMatthias Ringwald if (sm_pdu_code >= sizeof(sm_pdu_size)) return 0; 4396f9bda154SMatthias Ringwald if (sm_pdu_size[sm_pdu_code] != size) return 0; 4397f9bda154SMatthias Ringwald 4398f9bda154SMatthias Ringwald return sm_pdu_code; 4399f9bda154SMatthias Ringwald } 4400f9bda154SMatthias Ringwald 4401f94048d1SMatthias Ringwald 4402f94048d1SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4403f94048d1SMatthias Ringwald static void sm_pdu_handler_pairing_public_key(sm_connection_t * sm_conn, const uint8_t * packet) { 4404f94048d1SMatthias Ringwald // store public key for DH Key calculation 4405f94048d1SMatthias Ringwald reverse_256(&packet[01], &setup->sm_peer_q[0]); 4406f94048d1SMatthias Ringwald reverse_256(&packet[33], &setup->sm_peer_q[32]); 4407f94048d1SMatthias Ringwald 4408f94048d1SMatthias Ringwald // CVE-2020-26558: abort pairing if remote uses the same public key 4409f94048d1SMatthias Ringwald if (memcmp(&setup->sm_peer_q, ec_q, 64) == 0){ 4410f94048d1SMatthias Ringwald log_info("Remote PK matches ours"); 4411f94048d1SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 4412f94048d1SMatthias Ringwald return; 4413f94048d1SMatthias Ringwald } 4414f94048d1SMatthias Ringwald 4415f94048d1SMatthias Ringwald // validate public key 4416f94048d1SMatthias Ringwald int err = btstack_crypto_ecc_p256_validate_public_key(setup->sm_peer_q); 4417f94048d1SMatthias Ringwald if (err != 0){ 4418f94048d1SMatthias Ringwald log_info("sm: peer public key invalid %x", err); 4419f94048d1SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 4420f94048d1SMatthias Ringwald return; 4421f94048d1SMatthias Ringwald } 4422f94048d1SMatthias Ringwald 4423f94048d1SMatthias Ringwald // start calculating dhkey 4424f94048d1SMatthias 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); 4425f94048d1SMatthias Ringwald 4426f94048d1SMatthias Ringwald log_info("public key received, generation method %u", setup->sm_stk_generation_method); 4427f94048d1SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 4428f94048d1SMatthias Ringwald // responder 4429f94048d1SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 4430f94048d1SMatthias Ringwald } else { 4431f94048d1SMatthias Ringwald // initiator 4432f94048d1SMatthias Ringwald // stk generation method 4433f94048d1SMatthias Ringwald // passkey entry: notify app to show passkey or to request passkey 4434f94048d1SMatthias Ringwald switch (setup->sm_stk_generation_method){ 4435f94048d1SMatthias Ringwald case JUST_WORKS: 4436f94048d1SMatthias Ringwald case NUMERIC_COMPARISON: 4437f94048d1SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_CONFIRMATION; 4438f94048d1SMatthias Ringwald break; 4439f94048d1SMatthias Ringwald case PK_RESP_INPUT: 4440f94048d1SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 4441f94048d1SMatthias Ringwald break; 4442f94048d1SMatthias Ringwald case PK_INIT_INPUT: 4443f94048d1SMatthias Ringwald case PK_BOTH_INPUT: 4444f94048d1SMatthias Ringwald if (setup->sm_user_response != SM_USER_RESPONSE_PASSKEY){ 4445f94048d1SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_USER_RESPONSE; 4446f94048d1SMatthias Ringwald break; 4447f94048d1SMatthias Ringwald } 4448f94048d1SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 4449f94048d1SMatthias Ringwald break; 4450f94048d1SMatthias Ringwald case OOB: 4451f94048d1SMatthias Ringwald if (setup->sm_have_oob_data){ 4452f94048d1SMatthias Ringwald // if we have received rb & cb, verify Cb = f4(PKb, PKb, rb, 0) 4453f94048d1SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION; 4454f94048d1SMatthias Ringwald } else { 4455f94048d1SMatthias Ringwald // otherwise, generate our nonce 4456f94048d1SMatthias Ringwald sm_sc_generate_nx_for_send_random(sm_conn); 4457f94048d1SMatthias Ringwald } 4458f94048d1SMatthias Ringwald break; 4459f94048d1SMatthias Ringwald default: 4460f94048d1SMatthias Ringwald btstack_assert(false); 4461f94048d1SMatthias Ringwald break; 4462f94048d1SMatthias Ringwald } 4463f94048d1SMatthias Ringwald } 4464f94048d1SMatthias Ringwald } 4465f94048d1SMatthias Ringwald #endif 4466f94048d1SMatthias Ringwald 4467f94048d1SMatthias Ringwald 446873970ae5SMatthias Ringwald static void sm_pdu_handler(sm_connection_t *sm_conn, uint8_t sm_pdu_code, const uint8_t *packet) { 44696e46ecceSMatthias Ringwald log_debug("sm_pdu_handler: state %u, pdu 0x%02x", sm_conn->sm_engine_state, sm_pdu_code); 44706e46ecceSMatthias Ringwald 4471*035b1b64SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 44726e46ecceSMatthias Ringwald int err; 4473*035b1b64SMatthias Ringwald #endif 44746e46ecceSMatthias Ringwald uint8_t max_encryption_key_size; 44756e46ecceSMatthias Ringwald 44763deb3ec6SMatthias Ringwald switch (sm_conn->sm_engine_state){ 44773deb3ec6SMatthias Ringwald 4478c8d0ff33SMatthias Ringwald // a sm timeout requires a new physical connection 44793deb3ec6SMatthias Ringwald case SM_GENERAL_TIMEOUT: 44803deb3ec6SMatthias Ringwald return; 44813deb3ec6SMatthias Ringwald 448242134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 448342134bc6SMatthias Ringwald 44843deb3ec6SMatthias Ringwald // Initiator 44853deb3ec6SMatthias Ringwald case SM_INITIATOR_CONNECTED: 44864c1d1092SMatthias Ringwald if ((sm_pdu_code != SM_CODE_SECURITY_REQUEST) || (sm_conn->sm_role)){ 44873deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 44883deb3ec6SMatthias Ringwald break; 44893deb3ec6SMatthias Ringwald } 449036f0defaSMatthias Ringwald sm_initiator_connected_handle_security_request(sm_conn, packet); 4491dc8ca372SMatthias Ringwald break; 44923deb3ec6SMatthias Ringwald 44933deb3ec6SMatthias Ringwald case SM_INITIATOR_PH1_W4_PAIRING_RESPONSE: 4494aacfafc3SMatthias Ringwald // Core 5, Vol 3, Part H, 2.4.6: 4495aacfafc3SMatthias Ringwald // "The master shall ignore the slave’s Security Request if the master has sent a Pairing Request 4496aacfafc3SMatthias Ringwald // without receiving a Pairing Response from the slave or if the master has initiated encryption mode setup." 4497aacfafc3SMatthias Ringwald if (sm_pdu_code == SM_CODE_SECURITY_REQUEST){ 4498aacfafc3SMatthias Ringwald log_info("Ignoring Security Request"); 4499aacfafc3SMatthias Ringwald break; 4500aacfafc3SMatthias Ringwald } 4501aacfafc3SMatthias Ringwald 4502aacfafc3SMatthias Ringwald // all other pdus are incorrect 45034c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RESPONSE){ 45043deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 45053deb3ec6SMatthias Ringwald break; 45063deb3ec6SMatthias Ringwald } 45070af429c6SMatthias Ringwald 45083deb3ec6SMatthias Ringwald // store pairing request 45096535961aSMatthias Ringwald (void)memcpy(&setup->sm_s_pres, packet, 45106535961aSMatthias Ringwald sizeof(sm_pairing_packet_t)); 4511afbd946dSMatthias Ringwald 4512afbd946dSMatthias Ringwald // validate encryption key size 4513afbd946dSMatthias Ringwald max_encryption_key_size = sm_pairing_packet_get_max_encryption_key_size(setup->sm_s_pres); 4514afbd946dSMatthias Ringwald if ((max_encryption_key_size < 7) || (max_encryption_key_size > 16)){ 4515afbd946dSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_INVALID_PARAMETERS); 4516afbd946dSMatthias Ringwald break; 4517afbd946dSMatthias Ringwald } 4518afbd946dSMatthias Ringwald 45193deb3ec6SMatthias Ringwald err = sm_stk_generation_init(sm_conn); 45200af429c6SMatthias Ringwald 45210af429c6SMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 45220af429c6SMatthias Ringwald if (0 < test_pairing_failure && test_pairing_failure < SM_REASON_DHKEY_CHECK_FAILED){ 45230af429c6SMatthias Ringwald log_info("testing_support: abort with pairing failure %u", test_pairing_failure); 45240af429c6SMatthias Ringwald err = test_pairing_failure; 45250af429c6SMatthias Ringwald } 45260af429c6SMatthias Ringwald #endif 45270af429c6SMatthias Ringwald 45289305033eSMatthias Ringwald if (err != 0){ 4529f4935286SMatthias Ringwald sm_pairing_error(sm_conn, err); 45303deb3ec6SMatthias Ringwald break; 45313deb3ec6SMatthias Ringwald } 4532b41539d5SMatthias Ringwald 4533b41539d5SMatthias Ringwald // generate random number first, if we need to show passkey 4534b41539d5SMatthias Ringwald if (setup->sm_stk_generation_method == PK_RESP_INPUT){ 4535f3582630SMatthias 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); 4536b41539d5SMatthias Ringwald break; 4537b41539d5SMatthias Ringwald } 4538b41539d5SMatthias Ringwald 4539136d331aSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4540136d331aSMatthias Ringwald if (setup->sm_use_secure_connections){ 45418cba5ca3SMatthias Ringwald // SC Numeric Comparison will trigger user response after public keys & nonces have been exchanged 45428cba5ca3SMatthias Ringwald if (setup->sm_stk_generation_method == JUST_WORKS){ 4543136d331aSMatthias Ringwald sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 4544136d331aSMatthias Ringwald sm_trigger_user_response(sm_conn); 4545136d331aSMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ 4546c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 4547136d331aSMatthias Ringwald } 45488cba5ca3SMatthias Ringwald } else { 4549c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 45508cba5ca3SMatthias Ringwald } 4551136d331aSMatthias Ringwald break; 4552136d331aSMatthias Ringwald } 4553136d331aSMatthias Ringwald #endif 45543deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 45553deb3ec6SMatthias Ringwald sm_trigger_user_response(sm_conn); 45563deb3ec6SMatthias Ringwald // response_idle == nothing <--> sm_trigger_user_response() did not require response 45573deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ 4558f3582630SMatthias 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); 45593deb3ec6SMatthias Ringwald } 45603deb3ec6SMatthias Ringwald break; 45613deb3ec6SMatthias Ringwald 45623deb3ec6SMatthias Ringwald case SM_INITIATOR_PH2_W4_PAIRING_CONFIRM: 45634c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_CONFIRM){ 45643deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 45653deb3ec6SMatthias Ringwald break; 45663deb3ec6SMatthias Ringwald } 45673deb3ec6SMatthias Ringwald 45683deb3ec6SMatthias Ringwald // store s_confirm 45699c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_confirm); 4570192365feSMatthias Ringwald 4571aa9b34e5SMatthias Ringwald // abort if s_confirm matches m_confirm 4572aa9b34e5SMatthias Ringwald if (memcmp(setup->sm_local_confirm, setup->sm_peer_confirm, 16) == 0){ 4573aa9b34e5SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4574aa9b34e5SMatthias Ringwald break; 4575aa9b34e5SMatthias Ringwald } 4576aa9b34e5SMatthias Ringwald 4577192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 4578192365feSMatthias Ringwald if (test_pairing_failure == SM_REASON_CONFIRM_VALUE_FAILED){ 4579192365feSMatthias Ringwald log_info("testing_support: reset confirm value"); 4580192365feSMatthias Ringwald memset(setup->sm_peer_confirm, 0, 16); 4581192365feSMatthias Ringwald } 4582192365feSMatthias Ringwald #endif 45833deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_SEND_PAIRING_RANDOM; 45843deb3ec6SMatthias Ringwald break; 45853deb3ec6SMatthias Ringwald 45863deb3ec6SMatthias Ringwald case SM_INITIATOR_PH2_W4_PAIRING_RANDOM: 45874c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RANDOM){ 45883deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 45893deb3ec6SMatthias Ringwald break;; 45903deb3ec6SMatthias Ringwald } 45913deb3ec6SMatthias Ringwald 45923deb3ec6SMatthias Ringwald // received random value 45939c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_random); 45943deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_C1_GET_ENC_C; 45953deb3ec6SMatthias Ringwald break; 4596dc542de1SMatthias Ringwald 4597e2a5eb63SMatthias Ringwald case SM_INITIATOR_PH4_HAS_LTK: 4598dc542de1SMatthias Ringwald case SM_PH4_W4_CONNECTION_ENCRYPTED: 4599dc542de1SMatthias Ringwald // ignore Security Request, see SM_INITIATOR_PH1_W4_PAIRING_RESPONSE above 4600dc542de1SMatthias Ringwald if (sm_pdu_code != SM_CODE_SECURITY_REQUEST){ 4601dc542de1SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4602dc542de1SMatthias Ringwald } 4603dc542de1SMatthias Ringwald break; 460442134bc6SMatthias Ringwald #endif 46053deb3ec6SMatthias Ringwald 460642134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 46073deb3ec6SMatthias Ringwald // Responder 46083deb3ec6SMatthias Ringwald case SM_RESPONDER_IDLE: 46093deb3ec6SMatthias Ringwald case SM_RESPONDER_SEND_SECURITY_REQUEST: 46103deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_W4_PAIRING_REQUEST: 46114c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_REQUEST){ 46123deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 46133deb3ec6SMatthias Ringwald break;; 46143deb3ec6SMatthias Ringwald } 46153deb3ec6SMatthias Ringwald 46163deb3ec6SMatthias Ringwald // store pairing request 4617212d735eSMatthias Ringwald (void)memcpy(&sm_conn->sm_m_preq, packet, sizeof(sm_pairing_packet_t)); 4618212d735eSMatthias Ringwald 4619afbd946dSMatthias Ringwald // validation encryption key size 4620afbd946dSMatthias Ringwald max_encryption_key_size = sm_pairing_packet_get_max_encryption_key_size(sm_conn->sm_m_preq); 4621afbd946dSMatthias Ringwald if ((max_encryption_key_size < 7) || (max_encryption_key_size > 16)){ 4622afbd946dSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_INVALID_PARAMETERS); 4623afbd946dSMatthias Ringwald break; 4624afbd946dSMatthias Ringwald } 4625afbd946dSMatthias Ringwald 4626212d735eSMatthias Ringwald // check if IRK completed 4627212d735eSMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 4628212d735eSMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 4629212d735eSMatthias Ringwald case IRK_LOOKUP_FAILED: 46303deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED; 46313deb3ec6SMatthias Ringwald break; 4632212d735eSMatthias Ringwald default: 4633212d735eSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED_W4_IRK; 4634212d735eSMatthias Ringwald break; 4635212d735eSMatthias Ringwald } 4636212d735eSMatthias Ringwald break; 463742134bc6SMatthias Ringwald #endif 46383deb3ec6SMatthias Ringwald 463927c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4640c6b7cbd9SMatthias Ringwald case SM_SC_W4_PUBLIC_KEY_COMMAND: 46414c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_PUBLIC_KEY){ 464227c32905SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 464327c32905SMatthias Ringwald break; 464427c32905SMatthias Ringwald } 4645f94048d1SMatthias Ringwald sm_pdu_handler_pairing_public_key(sm_conn, packet); 464627c32905SMatthias Ringwald break; 4647e53be891SMatthias Ringwald 4648c6b7cbd9SMatthias Ringwald case SM_SC_W4_CONFIRMATION: 46494c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_CONFIRM){ 465045a61d50SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 465145a61d50SMatthias Ringwald break; 465245a61d50SMatthias Ringwald } 465345a61d50SMatthias Ringwald // received confirm value 465445a61d50SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_confirm); 465545a61d50SMatthias Ringwald 4656192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 4657192365feSMatthias Ringwald if (test_pairing_failure == SM_REASON_CONFIRM_VALUE_FAILED){ 4658192365feSMatthias Ringwald log_info("testing_support: reset confirm value"); 4659192365feSMatthias Ringwald memset(setup->sm_peer_confirm, 0, 16); 4660192365feSMatthias Ringwald } 4661192365feSMatthias Ringwald #endif 466242134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 466345a61d50SMatthias Ringwald // responder 466407036a04SMatthias Ringwald if (sm_passkey_used(setup->sm_stk_generation_method)){ 466507036a04SMatthias Ringwald if (setup->sm_user_response != SM_USER_RESPONSE_PASSKEY){ 466607036a04SMatthias Ringwald // still waiting for passkey 466707036a04SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_USER_RESPONSE; 466807036a04SMatthias Ringwald break; 466907036a04SMatthias Ringwald } 467007036a04SMatthias Ringwald } 4671b35a3de2SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 467245a61d50SMatthias Ringwald } else { 467345a61d50SMatthias Ringwald // initiator 4674945888f5SMatthias Ringwald if (sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method)){ 46756ca80073SMatthias 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); 4676f1c1783eSMatthias Ringwald } else { 4677c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM; 467845a61d50SMatthias Ringwald } 4679f1c1783eSMatthias Ringwald } 468045a61d50SMatthias Ringwald break; 468145a61d50SMatthias Ringwald 4682c6b7cbd9SMatthias Ringwald case SM_SC_W4_PAIRING_RANDOM: 46834c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RANDOM){ 4684e53be891SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4685136d331aSMatthias Ringwald break; 4686e53be891SMatthias Ringwald } 4687e53be891SMatthias Ringwald 4688e53be891SMatthias Ringwald // received random value 4689e53be891SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_nonce); 4690e53be891SMatthias Ringwald 46915a293e6eSMatthias Ringwald // validate confirm value if Cb = f4(Pkb, Pka, Nb, z) 4692ae451ec5SMatthias Ringwald // only check for JUST WORK/NC in initiator role OR passkey entry 4693d686b2d0SMatthias Ringwald log_info("SM_SC_W4_PAIRING_RANDOM, responder: %u, just works: %u, passkey used %u, passkey entry %u", 4694d686b2d0SMatthias Ringwald IS_RESPONDER(sm_conn->sm_role), sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method), 4695d686b2d0SMatthias Ringwald sm_passkey_used(setup->sm_stk_generation_method), sm_passkey_entry(setup->sm_stk_generation_method)); 469665a9a04eSMatthias Ringwald if ( (!IS_RESPONDER(sm_conn->sm_role) && sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method)) 4697d686b2d0SMatthias Ringwald || (sm_passkey_entry(setup->sm_stk_generation_method)) ) { 4698688a08f9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION; 4699ae451ec5SMatthias Ringwald break; 47005a293e6eSMatthias Ringwald } 47016f52a196SMatthias Ringwald 47024acf7b7bSMatthias Ringwald // OOB 47034acf7b7bSMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 47044acf7b7bSMatthias Ringwald 47054acf7b7bSMatthias Ringwald // setup local random, set to zero if remote did not receive our data 47064acf7b7bSMatthias Ringwald log_info("Received nonce, setup local random ra/rb for dhkey check"); 47074acf7b7bSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)) { 47084ea43905SMatthias Ringwald if (sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq) == 0u) { 47094acf7b7bSMatthias Ringwald log_info("Reset rb as A does not have OOB data"); 47104acf7b7bSMatthias Ringwald memset(setup->sm_rb, 0, 16); 47114acf7b7bSMatthias Ringwald } else { 47126535961aSMatthias Ringwald (void) memcpy(setup->sm_rb, sm_sc_oob_random, 16); 47134acf7b7bSMatthias Ringwald log_info("Use stored rb"); 47144acf7b7bSMatthias Ringwald log_info_hexdump(setup->sm_rb, 16); 47154acf7b7bSMatthias Ringwald } 47164acf7b7bSMatthias Ringwald } else { 47174ea43905SMatthias Ringwald if (sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres) == 0u){ 47184acf7b7bSMatthias Ringwald log_info("Reset ra as B does not have OOB data"); 47194acf7b7bSMatthias Ringwald memset(setup->sm_ra, 0, 16); 47204acf7b7bSMatthias Ringwald } else { 47216535961aSMatthias Ringwald (void)memcpy(setup->sm_ra, sm_sc_oob_random, 16); 47224acf7b7bSMatthias Ringwald log_info("Use stored ra"); 47234acf7b7bSMatthias Ringwald log_info_hexdump(setup->sm_ra, 16); 47244acf7b7bSMatthias Ringwald } 47254acf7b7bSMatthias Ringwald } 47264acf7b7bSMatthias Ringwald 47272419120aSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 47284acf7b7bSMatthias Ringwald if (setup->sm_have_oob_data){ 47292419120aSMatthias Ringwald // if we have received ra & ca, verify Ca = f4(PKa, PKa, ra, 0) 4730a680ba6bSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION; 47312419120aSMatthias Ringwald } else { 47322419120aSMatthias Ringwald // otherwise, generate our nonce 47332419120aSMatthias Ringwald sm_sc_generate_nx_for_send_random(sm_conn); 4734a680ba6bSMatthias Ringwald } 47352419120aSMatthias Ringwald } else { 47362419120aSMatthias Ringwald // Confirm value already validated if received before, 47372419120aSMatthias Ringwald // move on to DHKey check 47382419120aSMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 47392419120aSMatthias Ringwald } 47402419120aSMatthias Ringwald break; 47414acf7b7bSMatthias Ringwald } 4742a680ba6bSMatthias Ringwald 4743a680ba6bSMatthias Ringwald // TODO: we only get here for Responder role with JW/NC 4744688a08f9SMatthias Ringwald sm_sc_state_after_receiving_random(sm_conn); 4745e53be891SMatthias Ringwald break; 4746e53be891SMatthias Ringwald 4747901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_G2: 4748901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_G2: 47493cf37b8cSMatthias Ringwald case SM_SC_W4_CALCULATE_DHKEY: 4750901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_SALT: 4751901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_SALT: 4752901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_MACKEY: 4753901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_MACKEY: 4754901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_LTK: 4755901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_LTK: 4756901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F6_FOR_DHKEY_CHECK: 4757c6b7cbd9SMatthias Ringwald case SM_SC_W4_DHKEY_CHECK_COMMAND: 4758901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F6_FOR_DHKEY_CHECK: 4759d08147dfSMatthias Ringwald case SM_SC_W4_USER_RESPONSE: 47604c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_DHKEY_CHECK){ 4761e53be891SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4762e53be891SMatthias Ringwald break; 4763e53be891SMatthias Ringwald } 4764e53be891SMatthias Ringwald // store DHKey Check 4765901c000fSMatthias Ringwald setup->sm_state_vars |= SM_STATE_VAR_DHKEY_COMMAND_RECEIVED; 4766e53be891SMatthias Ringwald reverse_128(&packet[01], setup->sm_peer_dhkey_check); 4767446a8c36SMatthias Ringwald 4768901c000fSMatthias Ringwald // have we been only waiting for dhkey check command? 4769901c000fSMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_DHKEY_CHECK_COMMAND){ 4770019005a0SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK; 4771bd57ffebSMatthias Ringwald } 4772bd57ffebSMatthias Ringwald break; 477327c32905SMatthias Ringwald #endif 477427c32905SMatthias Ringwald 477542134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 47763deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_W4_PAIRING_CONFIRM: 47774c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_CONFIRM){ 47783deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 477927c32905SMatthias Ringwald break; 47803deb3ec6SMatthias Ringwald } 47813deb3ec6SMatthias Ringwald 47823deb3ec6SMatthias Ringwald // received confirm value 47839c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_confirm); 47843deb3ec6SMatthias Ringwald 4785192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 4786192365feSMatthias Ringwald if (test_pairing_failure == SM_REASON_CONFIRM_VALUE_FAILED){ 4787192365feSMatthias Ringwald log_info("testing_support: reset confirm value"); 4788192365feSMatthias Ringwald memset(setup->sm_peer_confirm, 0, 16); 4789192365feSMatthias Ringwald } 4790192365feSMatthias Ringwald #endif 47913deb3ec6SMatthias Ringwald // notify client to hide shown passkey 47923deb3ec6SMatthias Ringwald if (setup->sm_stk_generation_method == PK_INIT_INPUT){ 47935611a760SMatthias 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); 47943deb3ec6SMatthias Ringwald } 47953deb3ec6SMatthias Ringwald 47963deb3ec6SMatthias Ringwald // handle user cancel pairing? 47973deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_DECLINE){ 4798f4935286SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_PASSKEY_ENTRY_FAILED); 47993deb3ec6SMatthias Ringwald break; 48003deb3ec6SMatthias Ringwald } 48013deb3ec6SMatthias Ringwald 48023deb3ec6SMatthias Ringwald // wait for user action? 48033deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_PENDING){ 48043deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 48053deb3ec6SMatthias Ringwald break; 48063deb3ec6SMatthias Ringwald } 48073deb3ec6SMatthias Ringwald 48083deb3ec6SMatthias Ringwald // calculate and send local_confirm 4809f3582630SMatthias 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); 48103deb3ec6SMatthias Ringwald break; 48113deb3ec6SMatthias Ringwald 48123deb3ec6SMatthias Ringwald case SM_RESPONDER_PH2_W4_PAIRING_RANDOM: 48134c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RANDOM){ 48143deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 48153deb3ec6SMatthias Ringwald break;; 48163deb3ec6SMatthias Ringwald } 48173deb3ec6SMatthias Ringwald 48183deb3ec6SMatthias Ringwald // received random value 48199c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_random); 48203deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_C1_GET_ENC_C; 48213deb3ec6SMatthias Ringwald break; 482242134bc6SMatthias Ringwald #endif 48233deb3ec6SMatthias Ringwald 4824672dc582SMatthias Ringwald case SM_PH2_W4_CONNECTION_ENCRYPTED: 48253deb3ec6SMatthias Ringwald case SM_PH3_RECEIVE_KEYS: 48264c1d1092SMatthias Ringwald switch(sm_pdu_code){ 48273deb3ec6SMatthias Ringwald case SM_CODE_ENCRYPTION_INFORMATION: 48283deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 48299c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_ltk); 48303deb3ec6SMatthias Ringwald break; 48313deb3ec6SMatthias Ringwald 48323deb3ec6SMatthias Ringwald case SM_CODE_MASTER_IDENTIFICATION: 48333deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 4834f8fbdce0SMatthias Ringwald setup->sm_peer_ediv = little_endian_read_16(packet, 1); 48359c80e4ccSMatthias Ringwald reverse_64(&packet[3], setup->sm_peer_rand); 48363deb3ec6SMatthias Ringwald break; 48373deb3ec6SMatthias Ringwald 48383deb3ec6SMatthias Ringwald case SM_CODE_IDENTITY_INFORMATION: 48393deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 48409c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_irk); 48413deb3ec6SMatthias Ringwald break; 48423deb3ec6SMatthias Ringwald 48433deb3ec6SMatthias Ringwald case SM_CODE_IDENTITY_ADDRESS_INFORMATION: 48443deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 48453deb3ec6SMatthias Ringwald setup->sm_peer_addr_type = packet[1]; 4846724d70a2SMatthias Ringwald reverse_bd_addr(&packet[2], setup->sm_peer_address); 48473deb3ec6SMatthias Ringwald break; 48483deb3ec6SMatthias Ringwald 48493deb3ec6SMatthias Ringwald case SM_CODE_SIGNING_INFORMATION: 48503deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 48519c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_csrk); 48523deb3ec6SMatthias Ringwald break; 48533deb3ec6SMatthias Ringwald default: 48543deb3ec6SMatthias Ringwald // Unexpected PDU 48553deb3ec6SMatthias Ringwald log_info("Unexpected PDU %u in SM_PH3_RECEIVE_KEYS", packet[0]); 48563deb3ec6SMatthias Ringwald break; 48573deb3ec6SMatthias Ringwald } 48583deb3ec6SMatthias Ringwald // done with key distribution? 485961d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 48603deb3ec6SMatthias Ringwald 48613deb3ec6SMatthias Ringwald sm_key_distribution_handle_all_received(sm_conn); 48623deb3ec6SMatthias Ringwald 486342134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 48646f7422f1SMatthias Ringwald sm_key_distribution_complete_responder(sm_conn); 48653deb3ec6SMatthias Ringwald } else { 4866625f00b2SMatthias Ringwald if (setup->sm_use_secure_connections){ 4867625f00b2SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 4868bbf8db22SMatthias Ringwald } else { 4869f3582630SMatthias 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); 4870625f00b2SMatthias Ringwald } 48713deb3ec6SMatthias Ringwald } 48723deb3ec6SMatthias Ringwald } 48733deb3ec6SMatthias Ringwald break; 4874c18be159SMatthias Ringwald 4875c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 4876b322498eSMatthias Ringwald 4877b322498eSMatthias Ringwald case SM_BR_EDR_W4_ENCRYPTION_COMPLETE: 4878b322498eSMatthias Ringwald // GAP/DM/LEP/BI-02-C - reject CTKD if P-192 encryption is used 4879b322498eSMatthias Ringwald if (sm_pdu_code == SM_CODE_PAIRING_REQUEST){ 4880b322498eSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_CROSS_TRANSPORT_KEY_DERIVATION_NOT_ALLOWED); 4881b322498eSMatthias Ringwald } 4882b322498eSMatthias Ringwald break; 4883b322498eSMatthias Ringwald 4884c18be159SMatthias Ringwald case SM_BR_EDR_INITIATOR_W4_PAIRING_RESPONSE: 4885553c9408SMatthias Ringwald 4886553c9408SMatthias Ringwald // dedicated bonding complete 4887f82b8f4bSMatthias Ringwald hci_dedicated_bonding_defer_disconnect(sm_conn->sm_handle, false); 4888553c9408SMatthias Ringwald 4889c18be159SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RESPONSE){ 4890c18be159SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4891c18be159SMatthias Ringwald break; 4892c18be159SMatthias Ringwald } 4893c18be159SMatthias Ringwald // store pairing response 4894c18be159SMatthias Ringwald (void)memcpy(&setup->sm_s_pres, packet, sizeof(sm_pairing_packet_t)); 4895c18be159SMatthias Ringwald 4896c18be159SMatthias Ringwald // validate encryption key size 4897afbd946dSMatthias Ringwald max_encryption_key_size = sm_pairing_packet_get_max_encryption_key_size(setup->sm_s_pres); 4898afbd946dSMatthias Ringwald if ((max_encryption_key_size < 7) || (max_encryption_key_size > 16)){ 4899afbd946dSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_INVALID_PARAMETERS); 4900afbd946dSMatthias Ringwald break; 4901afbd946dSMatthias Ringwald } 4902afbd946dSMatthias Ringwald sm_conn->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(max_encryption_key_size); 4903c18be159SMatthias Ringwald // SC Only mandates 128 bit key size 4904c18be159SMatthias Ringwald if (sm_sc_only_mode && (sm_conn->sm_actual_encryption_key_size < 16)) { 4905c18be159SMatthias Ringwald sm_conn->sm_actual_encryption_key_size = 0; 4906c18be159SMatthias Ringwald } 4907c18be159SMatthias Ringwald if (sm_conn->sm_actual_encryption_key_size == 0){ 4908c18be159SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_ENCRYPTION_KEY_SIZE); 4909c18be159SMatthias Ringwald break; 4910c18be159SMatthias Ringwald } 4911c18be159SMatthias Ringwald 4912c18be159SMatthias Ringwald // prepare key exchange, LTK is derived locally 4913c18be159SMatthias Ringwald sm_setup_key_distribution(sm_pairing_packet_get_initiator_key_distribution(setup->sm_s_pres) & ~SM_KEYDIST_ENC_KEY, 4914c18be159SMatthias Ringwald sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres) & ~SM_KEYDIST_ENC_KEY); 4915c18be159SMatthias Ringwald 4916c18be159SMatthias Ringwald // skip receive if there are none 491761d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 4918c18be159SMatthias Ringwald // distribute keys in run handles 'no keys to send' 4919c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_DISTRIBUTE_KEYS; 4920c18be159SMatthias Ringwald } else { 4921c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_RECEIVE_KEYS; 4922c18be159SMatthias Ringwald } 4923c18be159SMatthias Ringwald break; 4924c18be159SMatthias Ringwald 4925c18be159SMatthias Ringwald case SM_BR_EDR_RESPONDER_W4_PAIRING_REQUEST: 4926c18be159SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_REQUEST){ 4927c18be159SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4928c18be159SMatthias Ringwald break; 4929c18be159SMatthias Ringwald } 4930afbd946dSMatthias Ringwald 4931c18be159SMatthias Ringwald // store pairing request 4932c18be159SMatthias Ringwald (void)memcpy(&sm_conn->sm_m_preq, packet, sizeof(sm_pairing_packet_t)); 4933afbd946dSMatthias Ringwald 4934c18be159SMatthias Ringwald // validate encryption key size 4935f5217d52SMatthias Ringwald max_encryption_key_size = sm_pairing_packet_get_max_encryption_key_size(sm_conn->sm_m_preq); 4936afbd946dSMatthias Ringwald if ((max_encryption_key_size < 7) || (max_encryption_key_size > 16)){ 4937afbd946dSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_INVALID_PARAMETERS); 4938afbd946dSMatthias Ringwald break; 4939afbd946dSMatthias Ringwald } 4940afbd946dSMatthias Ringwald sm_conn->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(max_encryption_key_size); 4941c18be159SMatthias Ringwald // SC Only mandates 128 bit key size 4942c18be159SMatthias Ringwald if (sm_sc_only_mode && (sm_conn->sm_actual_encryption_key_size < 16)) { 4943c18be159SMatthias Ringwald sm_conn->sm_actual_encryption_key_size = 0; 4944c18be159SMatthias Ringwald } 4945c18be159SMatthias Ringwald if (sm_conn->sm_actual_encryption_key_size == 0){ 4946c18be159SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_ENCRYPTION_KEY_SIZE); 4947c18be159SMatthias Ringwald break; 4948c18be159SMatthias Ringwald } 4949c18be159SMatthias Ringwald // trigger response 49506a718a5eSMatthias Ringwald if (sm_ctkd_from_classic(sm_conn)){ 4951c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_RESPONDER_PAIRING_REQUEST_RECEIVED; 49526a718a5eSMatthias Ringwald } else { 49536a718a5eSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_CROSS_TRANSPORT_KEY_DERIVATION_NOT_ALLOWED); 49546a718a5eSMatthias Ringwald } 4955c18be159SMatthias Ringwald break; 4956c18be159SMatthias Ringwald 4957c18be159SMatthias Ringwald case SM_BR_EDR_RECEIVE_KEYS: 4958c18be159SMatthias Ringwald switch(sm_pdu_code){ 4959c18be159SMatthias Ringwald case SM_CODE_IDENTITY_INFORMATION: 4960c18be159SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 4961c18be159SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_irk); 4962c18be159SMatthias Ringwald break; 4963c18be159SMatthias Ringwald case SM_CODE_IDENTITY_ADDRESS_INFORMATION: 4964c18be159SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 4965c18be159SMatthias Ringwald setup->sm_peer_addr_type = packet[1]; 4966c18be159SMatthias Ringwald reverse_bd_addr(&packet[2], setup->sm_peer_address); 4967c18be159SMatthias Ringwald break; 4968c18be159SMatthias Ringwald case SM_CODE_SIGNING_INFORMATION: 4969c18be159SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 4970c18be159SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_csrk); 4971c18be159SMatthias Ringwald break; 4972c18be159SMatthias Ringwald default: 4973c18be159SMatthias Ringwald // Unexpected PDU 4974c18be159SMatthias Ringwald log_info("Unexpected PDU %u in SM_PH3_RECEIVE_KEYS", packet[0]); 4975c18be159SMatthias Ringwald break; 4976c18be159SMatthias Ringwald } 4977c18be159SMatthias Ringwald 4978c18be159SMatthias Ringwald // all keys received 497961d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 4980c18be159SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 4981c18be159SMatthias Ringwald // responder -> keys exchanged, derive LE LTK 4982c18be159SMatthias Ringwald sm_ctkd_start_from_br_edr(sm_conn); 4983c18be159SMatthias Ringwald } else { 4984c18be159SMatthias Ringwald // initiator -> send our keys if any 4985c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_DISTRIBUTE_KEYS; 4986c18be159SMatthias Ringwald } 4987c18be159SMatthias Ringwald } 4988c18be159SMatthias Ringwald break; 4989c18be159SMatthias Ringwald #endif 4990c18be159SMatthias Ringwald 49913deb3ec6SMatthias Ringwald default: 49923deb3ec6SMatthias Ringwald // Unexpected PDU 49933deb3ec6SMatthias Ringwald log_info("Unexpected PDU %u in state %u", packet[0], sm_conn->sm_engine_state); 49942d095694SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 49953deb3ec6SMatthias Ringwald break; 49963deb3ec6SMatthias Ringwald } 49973deb3ec6SMatthias Ringwald 499870b44dd4SMatthias Ringwald // try to send next pdu 499970b44dd4SMatthias Ringwald sm_trigger_run(); 50003deb3ec6SMatthias Ringwald } 50013deb3ec6SMatthias Ringwald 500273970ae5SMatthias Ringwald static void sm_channel_handler(uint8_t packet_type, hci_con_handle_t con_handle, uint8_t *packet, uint16_t size){ 500373970ae5SMatthias Ringwald 500473970ae5SMatthias Ringwald if ((packet_type == HCI_EVENT_PACKET) && (packet[0] == L2CAP_EVENT_CAN_SEND_NOW)){ 500573970ae5SMatthias Ringwald sm_run(); 500673970ae5SMatthias Ringwald } 500773970ae5SMatthias Ringwald 500873970ae5SMatthias Ringwald uint8_t sm_pdu_code = sm_pdu_validate_and_get_opcode(packet_type, packet, size); 500973970ae5SMatthias Ringwald if (sm_pdu_code == 0) return; 501073970ae5SMatthias Ringwald 501173970ae5SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 501273970ae5SMatthias Ringwald if (!sm_conn) return; 501373970ae5SMatthias Ringwald 501473970ae5SMatthias Ringwald if (sm_pdu_code == SM_CODE_PAIRING_FAILED){ 501573970ae5SMatthias Ringwald sm_reencryption_complete(sm_conn, ERROR_CODE_AUTHENTICATION_FAILURE); 501673970ae5SMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_AUTHENTICATION_FAILURE, packet[1]); 501773970ae5SMatthias Ringwald sm_done_for_handle(con_handle); 501873970ae5SMatthias Ringwald sm_conn->sm_engine_state = sm_conn->sm_role ? SM_RESPONDER_IDLE : SM_INITIATOR_CONNECTED; 501973970ae5SMatthias Ringwald return; 502073970ae5SMatthias Ringwald } 502173970ae5SMatthias Ringwald 502273970ae5SMatthias Ringwald if (sm_pdu_code == SM_CODE_KEYPRESS_NOTIFICATION){ 502373970ae5SMatthias Ringwald uint8_t buffer[5]; 502473970ae5SMatthias Ringwald buffer[0] = SM_EVENT_KEYPRESS_NOTIFICATION; 502573970ae5SMatthias Ringwald buffer[1] = 3; 502673970ae5SMatthias Ringwald little_endian_store_16(buffer, 2, con_handle); 502773970ae5SMatthias Ringwald buffer[4] = packet[1]; 502873970ae5SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, buffer, sizeof(buffer)); 502973970ae5SMatthias Ringwald return; 503073970ae5SMatthias Ringwald } 503173970ae5SMatthias Ringwald 503273970ae5SMatthias Ringwald sm_pdu_handler(sm_conn, sm_pdu_code, packet); 503373970ae5SMatthias Ringwald } 503473970ae5SMatthias Ringwald 50353deb3ec6SMatthias Ringwald // Security Manager Client API 5036a680ba6bSMatthias Ringwald void sm_register_oob_data_callback( int (*get_oob_data_callback)(uint8_t address_type, bd_addr_t addr, uint8_t * oob_data)){ 50373deb3ec6SMatthias Ringwald sm_get_oob_data = get_oob_data_callback; 50383deb3ec6SMatthias Ringwald } 50393deb3ec6SMatthias Ringwald 50404acf7b7bSMatthias 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)){ 5041a680ba6bSMatthias Ringwald sm_get_sc_oob_data = get_sc_oob_data_callback; 5042a680ba6bSMatthias Ringwald } 5043a680ba6bSMatthias Ringwald 5044b96d60a6SMatthias 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)){ 5045b96d60a6SMatthias Ringwald sm_get_ltk_callback = get_ltk_callback; 5046b96d60a6SMatthias Ringwald } 5047b96d60a6SMatthias Ringwald 504889a78d34SMatthias Ringwald void sm_add_event_handler(btstack_packet_callback_registration_t * callback_handler){ 504989a78d34SMatthias Ringwald btstack_linked_list_add_tail(&sm_event_handlers, (btstack_linked_item_t*) callback_handler); 505089a78d34SMatthias Ringwald } 505189a78d34SMatthias Ringwald 505267f708e0SMatthias Ringwald void sm_remove_event_handler(btstack_packet_callback_registration_t * callback_handler){ 505367f708e0SMatthias Ringwald btstack_linked_list_remove(&sm_event_handlers, (btstack_linked_item_t*) callback_handler); 505467f708e0SMatthias Ringwald } 505567f708e0SMatthias Ringwald 50563deb3ec6SMatthias Ringwald void sm_set_accepted_stk_generation_methods(uint8_t accepted_stk_generation_methods){ 50573deb3ec6SMatthias Ringwald sm_accepted_stk_generation_methods = accepted_stk_generation_methods; 50583deb3ec6SMatthias Ringwald } 50593deb3ec6SMatthias Ringwald 50603deb3ec6SMatthias Ringwald void sm_set_encryption_key_size_range(uint8_t min_size, uint8_t max_size){ 50613deb3ec6SMatthias Ringwald sm_min_encryption_key_size = min_size; 50623deb3ec6SMatthias Ringwald sm_max_encryption_key_size = max_size; 50633deb3ec6SMatthias Ringwald } 50643deb3ec6SMatthias Ringwald 50653deb3ec6SMatthias Ringwald void sm_set_authentication_requirements(uint8_t auth_req){ 506698d95509SMatthias Ringwald #ifndef ENABLE_LE_SECURE_CONNECTIONS 506798d95509SMatthias Ringwald if (auth_req & SM_AUTHREQ_SECURE_CONNECTION){ 506898d95509SMatthias Ringwald log_error("ENABLE_LE_SECURE_CONNECTIONS not defined, but requested by app. Dropping SC flag"); 506998d95509SMatthias Ringwald auth_req &= ~SM_AUTHREQ_SECURE_CONNECTION; 507098d95509SMatthias Ringwald } 507198d95509SMatthias Ringwald #endif 50723deb3ec6SMatthias Ringwald sm_auth_req = auth_req; 50733deb3ec6SMatthias Ringwald } 50743deb3ec6SMatthias Ringwald 50753deb3ec6SMatthias Ringwald void sm_set_io_capabilities(io_capability_t io_capability){ 50763deb3ec6SMatthias Ringwald sm_io_capabilities = io_capability; 50773deb3ec6SMatthias Ringwald } 50783deb3ec6SMatthias Ringwald 507942134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 5080728f6757SMatthias Ringwald void sm_set_request_security(bool enable){ 50813deb3ec6SMatthias Ringwald sm_slave_request_security = enable; 50823deb3ec6SMatthias Ringwald } 508342134bc6SMatthias Ringwald #endif 50843deb3ec6SMatthias Ringwald 50853deb3ec6SMatthias Ringwald void sm_set_er(sm_key_t er){ 50866535961aSMatthias Ringwald (void)memcpy(sm_persistent_er, er, 16); 50873deb3ec6SMatthias Ringwald } 50883deb3ec6SMatthias Ringwald 50893deb3ec6SMatthias Ringwald void sm_set_ir(sm_key_t ir){ 50906535961aSMatthias Ringwald (void)memcpy(sm_persistent_ir, ir, 16); 50913deb3ec6SMatthias Ringwald } 50923deb3ec6SMatthias Ringwald 50933deb3ec6SMatthias Ringwald // Testing support only 50943deb3ec6SMatthias Ringwald void sm_test_set_irk(sm_key_t irk){ 50956535961aSMatthias Ringwald (void)memcpy(sm_persistent_irk, irk, 16); 5096103fa6b0SMatthias Ringwald dkg_state = DKG_CALC_DHK; 5097841468bbSMatthias Ringwald test_use_fixed_local_irk = true; 50983deb3ec6SMatthias Ringwald } 50993deb3ec6SMatthias Ringwald 51003deb3ec6SMatthias Ringwald void sm_test_use_fixed_local_csrk(void){ 5101841468bbSMatthias Ringwald test_use_fixed_local_csrk = true; 51023deb3ec6SMatthias Ringwald } 51033deb3ec6SMatthias Ringwald 5104d1a1f6a4SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 5105d1a1f6a4SMatthias Ringwald static void sm_ec_generated(void * arg){ 5106d1a1f6a4SMatthias Ringwald UNUSED(arg); 5107d1a1f6a4SMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_DONE; 510834b6528fSMatthias Ringwald // trigger pairing if pending for ec key 510970b44dd4SMatthias Ringwald sm_trigger_run(); 5110d1a1f6a4SMatthias Ringwald } 5111674e5b4aSMatthias Ringwald static void sm_ec_generate_new_key(void) { 511234b6528fSMatthias Ringwald log_info("sm: generate new ec key"); 5113db88441fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS_DEBUG_KEY 5114db88441fSMatthias Ringwald // LE Secure Connections Debug Key 5115db88441fSMatthias Ringwald const uint8_t debug_key_public[64] = { 5116db88441fSMatthias Ringwald 0x20, 0xb0, 0x03, 0xd2, 0xf2, 0x97, 0xbe, 0x2c, 0x5e, 0x2c, 0x83, 0xa7, 0xe9, 0xf9, 0xa5, 0xb9, 5117db88441fSMatthias Ringwald 0xef, 0xf4, 0x91, 0x11, 0xac, 0xf4, 0xfd, 0xdb, 0xcc, 0x03, 0x01, 0x48, 0x0e, 0x35, 0x9d, 0xe6, 5118db88441fSMatthias Ringwald 0xdc, 0x80, 0x9c, 0x49, 0x65, 0x2a, 0xeb, 0x6d, 0x63, 0x32, 0x9a, 0xbf, 0x5a, 0x52, 0x15, 0x5c, 5119db88441fSMatthias Ringwald 0x76, 0x63, 0x45, 0xc2, 0x8f, 0xed, 0x30, 0x24, 0x74, 0x1c, 0x8e, 0xd0, 0x15, 0x89, 0xd2, 0x8b 5120db88441fSMatthias Ringwald }; 5121db88441fSMatthias Ringwald const uint8_t debug_key_private[32] = { 5122db88441fSMatthias Ringwald 0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, 0x74, 0xc9, 0xb3, 0xe3, 0xd2, 0x10, 0x3f, 0x50, 5123db88441fSMatthias Ringwald 0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd 5124db88441fSMatthias Ringwald }; 5125db88441fSMatthias Ringwald if (sm_sc_debug_keys_enabled) { 5126db88441fSMatthias Ringwald memcpy(ec_q, debug_key_public, 64); 5127db88441fSMatthias Ringwald btstack_crypto_ecc_p256_set_key(debug_key_public, debug_key_private); 5128db88441fSMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_DONE; 5129db88441fSMatthias Ringwald } else 5130db88441fSMatthias Ringwald #endif 5131db88441fSMatthias Ringwald { 5132674e5b4aSMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_ACTIVE; 5133674e5b4aSMatthias Ringwald btstack_crypto_ecc_p256_generate_key(&sm_crypto_ecc_p256_request, ec_q, &sm_ec_generated, NULL); 5134674e5b4aSMatthias Ringwald } 5135db88441fSMatthias Ringwald } 5136d1a1f6a4SMatthias Ringwald #endif 5137d1a1f6a4SMatthias Ringwald 5138192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 5139192365feSMatthias Ringwald void sm_test_set_pairing_failure(int reason){ 5140192365feSMatthias Ringwald test_pairing_failure = reason; 5141192365feSMatthias Ringwald } 5142192365feSMatthias Ringwald #endif 5143192365feSMatthias Ringwald 51447887cd92SMatthias Ringwald static void sm_state_reset(void) { 51457f775357SMatthias Ringwald #ifdef USE_CMAC_ENGINE 51467f775357SMatthias Ringwald sm_cmac_active = 0; 51477f775357SMatthias Ringwald #endif 51487f775357SMatthias Ringwald dkg_state = DKG_W4_WORKING; 51497f775357SMatthias Ringwald rau_state = RAU_IDLE; 51507f775357SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 51517f775357SMatthias Ringwald sm_address_resolution_test = -1; // no private address to resolve yet 51527f775357SMatthias Ringwald sm_address_resolution_mode = ADDRESS_RESOLUTION_IDLE; 51537f775357SMatthias Ringwald sm_address_resolution_general_queue = NULL; 51547f775357SMatthias Ringwald sm_active_connection_handle = HCI_CON_HANDLE_INVALID; 5155cbdd51cfSMatthias Ringwald sm_persistent_keys_random_active = false; 51567f775357SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 515715211b85SMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_IDLE; 51587f775357SMatthias Ringwald #endif 51597f775357SMatthias Ringwald } 51607f775357SMatthias Ringwald 51613deb3ec6SMatthias Ringwald void sm_init(void){ 51622d2d4d3cSMatthias Ringwald 51632d2d4d3cSMatthias Ringwald if (sm_initialized) return; 51642d2d4d3cSMatthias Ringwald 5165899e6e02SMatthias Ringwald // set default ER and IR values (should be unique - set by app or sm later using TLV) 5166899e6e02SMatthias Ringwald sm_er_ir_set_default(); 5167899e6e02SMatthias Ringwald 51683deb3ec6SMatthias Ringwald // defaults 51693deb3ec6SMatthias Ringwald sm_accepted_stk_generation_methods = SM_STK_GENERATION_METHOD_JUST_WORKS 51703deb3ec6SMatthias Ringwald | SM_STK_GENERATION_METHOD_OOB 5171b4343428SMatthias Ringwald | SM_STK_GENERATION_METHOD_PASSKEY 5172b4343428SMatthias Ringwald | SM_STK_GENERATION_METHOD_NUMERIC_COMPARISON; 5173b4343428SMatthias Ringwald 51743deb3ec6SMatthias Ringwald sm_max_encryption_key_size = 16; 51753deb3ec6SMatthias Ringwald sm_min_encryption_key_size = 7; 51763deb3ec6SMatthias Ringwald 51775ce1359eSMatthias Ringwald sm_fixed_passkey_in_display_role = 0xffffffffU; 51781979f09cSMatthias Ringwald sm_reconstruct_ltk_without_le_device_db_entry = true; 5179caf15bf3SMatthias Ringwald 51803deb3ec6SMatthias Ringwald gap_random_adress_update_period = 15 * 60 * 1000L; 51813deb3ec6SMatthias Ringwald 5182841468bbSMatthias Ringwald test_use_fixed_local_csrk = false; 51833deb3ec6SMatthias Ringwald 51847f775357SMatthias Ringwald // other 518584c0c5c7SMatthias Ringwald btstack_run_loop_set_timer_handler(&sm_run_timer, &sm_run_timer_handler); 518684c0c5c7SMatthias Ringwald 5187a036ae12SMatthias Ringwald // register for HCI Events 5188e03e489aSMatthias Ringwald hci_event_callback_registration.callback = &sm_event_packet_handler; 5189e03e489aSMatthias Ringwald hci_add_event_handler(&hci_event_callback_registration); 5190e03e489aSMatthias Ringwald 5191bad51150SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 5192a036ae12SMatthias Ringwald // register for L2CAP events 5193a036ae12SMatthias Ringwald l2cap_event_callback_registration.callback = &sm_event_packet_handler; 5194a036ae12SMatthias Ringwald l2cap_add_event_handler(&l2cap_event_callback_registration); 5195bad51150SMatthias Ringwald #endif 5196a036ae12SMatthias Ringwald 5197d1a1f6a4SMatthias Ringwald // 5198d1a1f6a4SMatthias Ringwald btstack_crypto_init(); 5199d1a1f6a4SMatthias Ringwald 520051bd74d1SMatthias Ringwald // init le_device_db 520151bd74d1SMatthias Ringwald le_device_db_init(); 520251bd74d1SMatthias Ringwald 5203b170b20fSMatthias Ringwald // and L2CAP PDUs + L2CAP_EVENT_CAN_SEND_NOW 520473970ae5SMatthias Ringwald l2cap_register_fixed_channel(sm_channel_handler, L2CAP_CID_SECURITY_MANAGER_PROTOCOL); 5205384eabd3SMatthias Ringwald #ifdef ENABLE_CLASSIC 520673970ae5SMatthias Ringwald l2cap_register_fixed_channel(sm_channel_handler, L2CAP_CID_BR_EDR_SECURITY_MANAGER); 5207384eabd3SMatthias Ringwald #endif 520827c32905SMatthias Ringwald 52097f775357SMatthias Ringwald // state 52107f775357SMatthias Ringwald sm_state_reset(); 52112d2d4d3cSMatthias Ringwald 52122d2d4d3cSMatthias Ringwald sm_initialized = true; 52133deb3ec6SMatthias Ringwald } 52143deb3ec6SMatthias Ringwald 521515537ea4SMatthias Ringwald void sm_deinit(void){ 521615537ea4SMatthias Ringwald sm_initialized = false; 521715537ea4SMatthias Ringwald btstack_run_loop_remove_timer(&sm_run_timer); 521892f8d6b6SMatthias Ringwald #if defined(ENABLE_LE_SECURE_CONNECTIONS) && defined (ENABLE_LE_SECURE_CONNECTION_DEBUG_KEY) 5219db88441fSMatthias Ringwald sm_sc_debug_keys_enabled = false; 5220db88441fSMatthias Ringwald #endif 522115537ea4SMatthias Ringwald } 522215537ea4SMatthias Ringwald 52234b8c611fSMatthias Ringwald void sm_use_fixed_passkey_in_display_role(uint32_t passkey){ 52244b8c611fSMatthias Ringwald sm_fixed_passkey_in_display_role = passkey; 5225caf15bf3SMatthias Ringwald } 5226caf15bf3SMatthias Ringwald 52276c39055aSMatthias Ringwald void sm_allow_ltk_reconstruction_without_le_device_db_entry(int allow){ 52281979f09cSMatthias Ringwald sm_reconstruct_ltk_without_le_device_db_entry = allow != 0; 52296c39055aSMatthias Ringwald } 52306c39055aSMatthias Ringwald 5231711e6c80SMatthias Ringwald static sm_connection_t * sm_get_connection_for_handle(hci_con_handle_t con_handle){ 5232711e6c80SMatthias Ringwald hci_connection_t * hci_con = hci_connection_for_handle(con_handle); 52333deb3ec6SMatthias Ringwald if (!hci_con) return NULL; 52343deb3ec6SMatthias Ringwald return &hci_con->sm_connection; 52353deb3ec6SMatthias Ringwald } 52363deb3ec6SMatthias Ringwald 5237916ea5b2SMatthias Ringwald static void sm_cache_ltk(sm_connection_t * connection, const sm_key_t ltk){ 5238916ea5b2SMatthias Ringwald hci_connection_t * hci_con = hci_connection_for_handle(connection->sm_handle); 5239916ea5b2SMatthias Ringwald btstack_assert(hci_con != NULL); 5240916ea5b2SMatthias Ringwald memcpy(hci_con->link_key, ltk, 16); 5241f728bb7bSMatthias Ringwald hci_con->link_key_type = COMBINATION_KEY; 5242916ea5b2SMatthias Ringwald } 5243916ea5b2SMatthias Ringwald 524477e2e5edSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 524577e2e5edSMatthias Ringwald static sm_connection_t * sm_get_connection_for_bd_addr_and_type(bd_addr_t address, bd_addr_type_t addr_type){ 524677e2e5edSMatthias Ringwald hci_connection_t * hci_con = hci_connection_for_bd_addr_and_type(address, addr_type); 524777e2e5edSMatthias Ringwald if (!hci_con) return NULL; 524877e2e5edSMatthias Ringwald return &hci_con->sm_connection; 524977e2e5edSMatthias Ringwald } 525077e2e5edSMatthias Ringwald #endif 525177e2e5edSMatthias Ringwald 52526bc3aba4SMatthias Ringwald // @deprecated: map onto sm_request_pairing 5253711e6c80SMatthias Ringwald void sm_send_security_request(hci_con_handle_t con_handle){ 5254711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 52553deb3ec6SMatthias Ringwald if (!sm_conn) return; 52566bc3aba4SMatthias Ringwald if (!IS_RESPONDER(sm_conn->sm_role)) return; 52576bc3aba4SMatthias Ringwald sm_request_pairing(con_handle); 52583deb3ec6SMatthias Ringwald } 52593deb3ec6SMatthias Ringwald 52603deb3ec6SMatthias Ringwald // request pairing 5261711e6c80SMatthias Ringwald void sm_request_pairing(hci_con_handle_t con_handle){ 5262711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 52633deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 52643deb3ec6SMatthias Ringwald 52657af5dcd5SMatthias Ringwald bool have_ltk; 52667af5dcd5SMatthias Ringwald uint8_t ltk[16]; 52672d68601cSMatthias Ringwald bool auth_required; 52682d68601cSMatthias Ringwald int authenticated; 52692d68601cSMatthias Ringwald bool trigger_reencryption; 52703deb3ec6SMatthias Ringwald log_info("sm_request_pairing in role %u, state %u", sm_conn->sm_role, sm_conn->sm_engine_state); 527142134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 527224c20dc4SMatthias Ringwald switch (sm_conn->sm_engine_state){ 527324c20dc4SMatthias Ringwald case SM_GENERAL_IDLE: 527424c20dc4SMatthias Ringwald case SM_RESPONDER_IDLE: 52757af5dcd5SMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 52767af5dcd5SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 52777af5dcd5SMatthias Ringwald le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); 52787af5dcd5SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 52797af5dcd5SMatthias Ringwald log_info("have ltk %u", have_ltk); 52807af5dcd5SMatthias Ringwald if (have_ltk){ 52815f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 528224c20dc4SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 52837af5dcd5SMatthias Ringwald sm_reencryption_started(sm_conn); 52847af5dcd5SMatthias Ringwald break; 52857af5dcd5SMatthias Ringwald } 52867af5dcd5SMatthias Ringwald /* fall through */ 52877af5dcd5SMatthias Ringwald 52887af5dcd5SMatthias Ringwald case IRK_LOOKUP_FAILED: 52895f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 52907af5dcd5SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 52917af5dcd5SMatthias Ringwald sm_pairing_started(sm_conn); 52927af5dcd5SMatthias Ringwald break; 52937af5dcd5SMatthias Ringwald default: 52947af5dcd5SMatthias Ringwald log_info("irk lookup pending"); 52955f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 52967af5dcd5SMatthias Ringwald break; 52977af5dcd5SMatthias Ringwald } 529824c20dc4SMatthias Ringwald break; 529924c20dc4SMatthias Ringwald default: 530024c20dc4SMatthias Ringwald break; 530124c20dc4SMatthias Ringwald } 53023deb3ec6SMatthias Ringwald } else { 53033deb3ec6SMatthias Ringwald // used as a trigger to start central/master/initiator security procedures 5304175b7faaSMatthias Ringwald switch (sm_conn->sm_engine_state){ 5305175b7faaSMatthias Ringwald case SM_INITIATOR_CONNECTED: 53063deb3ec6SMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 53073deb3ec6SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 53082d68601cSMatthias Ringwald le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, &authenticated, NULL, NULL); 5309f53ec649SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 53102d68601cSMatthias Ringwald auth_required = sm_auth_req & SM_AUTHREQ_MITM_PROTECTION; 53112d68601cSMatthias Ringwald // re-encrypt is sufficient if we have ltk and that is either already authenticated or we don't require authentication 53122d68601cSMatthias Ringwald trigger_reencryption = have_ltk && ((authenticated != 0) || (auth_required == false)); 53132d68601cSMatthias Ringwald log_info("have ltk %u, authenticated %u, auth required %u => reencrypt %u", have_ltk, authenticated, auth_required, trigger_reencryption); 53142d68601cSMatthias Ringwald if (trigger_reencryption){ 53155f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 53165567aa60SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH4_HAS_LTK; 5317c245ca32SMatthias Ringwald break; 5318f53ec649SMatthias Ringwald } 5319cf373d3aSMatthias Ringwald /* fall through */ 5320c245ca32SMatthias Ringwald 532134c39fbdSMatthias Ringwald case IRK_LOOKUP_FAILED: 53223deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 53233deb3ec6SMatthias Ringwald break; 53243deb3ec6SMatthias Ringwald default: 5325d1a1f6a4SMatthias Ringwald log_info("irk lookup pending"); 53265f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 53273deb3ec6SMatthias Ringwald break; 53283deb3ec6SMatthias Ringwald } 5329175b7faaSMatthias Ringwald break; 5330cb6d7eb0SMatthias Ringwald case SM_GENERAL_REENCRYPTION_FAILED: 5331cb6d7eb0SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 5332cb6d7eb0SMatthias Ringwald break; 5333175b7faaSMatthias Ringwald case SM_GENERAL_IDLE: 53345f3874afSMatthias Ringwald sm_conn->sm_pairing_requested = true; 5335175b7faaSMatthias Ringwald break; 5336175b7faaSMatthias Ringwald default: 5337175b7faaSMatthias Ringwald break; 53383deb3ec6SMatthias Ringwald } 53393deb3ec6SMatthias Ringwald } 534070b44dd4SMatthias Ringwald sm_trigger_run(); 53413deb3ec6SMatthias Ringwald } 53423deb3ec6SMatthias Ringwald 53433deb3ec6SMatthias Ringwald // called by client app on authorization request 5344711e6c80SMatthias Ringwald void sm_authorization_decline(hci_con_handle_t con_handle){ 5345711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 53463deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 53473deb3ec6SMatthias Ringwald sm_conn->sm_connection_authorization_state = AUTHORIZATION_DECLINED; 5348589f5a99SMatthias 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); 53493deb3ec6SMatthias Ringwald } 53503deb3ec6SMatthias Ringwald 5351711e6c80SMatthias Ringwald void sm_authorization_grant(hci_con_handle_t con_handle){ 5352711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 53533deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 53543deb3ec6SMatthias Ringwald sm_conn->sm_connection_authorization_state = AUTHORIZATION_GRANTED; 5355589f5a99SMatthias 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); 53563deb3ec6SMatthias Ringwald } 53573deb3ec6SMatthias Ringwald 53583deb3ec6SMatthias Ringwald // GAP Bonding API 53593deb3ec6SMatthias Ringwald 5360711e6c80SMatthias Ringwald void sm_bonding_decline(hci_con_handle_t con_handle){ 5361711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 53623deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 53633deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_DECLINE; 53640af429c6SMatthias Ringwald log_info("decline, state %u", sm_conn->sm_engine_state); 53650af429c6SMatthias Ringwald switch(sm_conn->sm_engine_state){ 53660af429c6SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 53670af429c6SMatthias Ringwald case SM_SC_W4_USER_RESPONSE: 53680af429c6SMatthias Ringwald case SM_SC_W4_CONFIRMATION: 53690af429c6SMatthias Ringwald case SM_SC_W4_PUBLIC_KEY_COMMAND: 53700af429c6SMatthias Ringwald #endif 53710af429c6SMatthias Ringwald case SM_PH1_W4_USER_RESPONSE: 5372de2fd182SMatthias Ringwald switch (setup->sm_stk_generation_method){ 5373de2fd182SMatthias Ringwald case PK_RESP_INPUT: 5374de2fd182SMatthias Ringwald case PK_INIT_INPUT: 537547fb4255SMatthias Ringwald case PK_BOTH_INPUT: 53760af429c6SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_PASSKEY_ENTRY_FAILED); 5377de2fd182SMatthias Ringwald break; 537847fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 5379de2fd182SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_NUMERIC_COMPARISON_FAILED); 5380de2fd182SMatthias Ringwald break; 5381de2fd182SMatthias Ringwald case JUST_WORKS: 5382de2fd182SMatthias Ringwald case OOB: 5383de2fd182SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_UNSPECIFIED_REASON); 5384de2fd182SMatthias Ringwald break; 53857bbeb3adSMilanka Ringwald default: 53867bbeb3adSMilanka Ringwald btstack_assert(false); 53877bbeb3adSMilanka Ringwald break; 5388de2fd182SMatthias Ringwald } 53890af429c6SMatthias Ringwald break; 53900af429c6SMatthias Ringwald default: 53910af429c6SMatthias Ringwald break; 53923deb3ec6SMatthias Ringwald } 539370b44dd4SMatthias Ringwald sm_trigger_run(); 53943deb3ec6SMatthias Ringwald } 53953deb3ec6SMatthias Ringwald 5396711e6c80SMatthias Ringwald void sm_just_works_confirm(hci_con_handle_t con_handle){ 5397711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 53983deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 53993deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_CONFIRM; 54003deb3ec6SMatthias Ringwald if (sm_conn->sm_engine_state == SM_PH1_W4_USER_RESPONSE){ 5401136d331aSMatthias Ringwald if (setup->sm_use_secure_connections){ 5402c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 5403bbf8db22SMatthias Ringwald } else { 5404f3582630SMatthias 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); 5405136d331aSMatthias Ringwald } 54063deb3ec6SMatthias Ringwald } 54070346c37cSMatthias Ringwald 54080346c37cSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 5409c6b7cbd9SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_USER_RESPONSE){ 5410dc300847SMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 5411446a8c36SMatthias Ringwald } 54120346c37cSMatthias Ringwald #endif 54130346c37cSMatthias Ringwald 541470b44dd4SMatthias Ringwald sm_trigger_run(); 54153deb3ec6SMatthias Ringwald } 54163deb3ec6SMatthias Ringwald 5417c8c46d51SMatthias Ringwald void sm_numeric_comparison_confirm(hci_con_handle_t con_handle){ 5418c8c46d51SMatthias Ringwald // for now, it's the same 5419c8c46d51SMatthias Ringwald sm_just_works_confirm(con_handle); 5420c8c46d51SMatthias Ringwald } 5421c8c46d51SMatthias Ringwald 5422711e6c80SMatthias Ringwald void sm_passkey_input(hci_con_handle_t con_handle, uint32_t passkey){ 5423711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 54243deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 54253deb3ec6SMatthias Ringwald sm_reset_tk(); 5426f8fbdce0SMatthias Ringwald big_endian_store_32(setup->sm_tk, 12, passkey); 54273deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_PASSKEY; 54283deb3ec6SMatthias Ringwald if (sm_conn->sm_engine_state == SM_PH1_W4_USER_RESPONSE){ 5429f3582630SMatthias 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); 54303deb3ec6SMatthias Ringwald } 54311c516d8fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 54326535961aSMatthias Ringwald (void)memcpy(setup->sm_ra, setup->sm_tk, 16); 54336535961aSMatthias Ringwald (void)memcpy(setup->sm_rb, setup->sm_tk, 16); 543407036a04SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_USER_RESPONSE){ 543507036a04SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 543607036a04SMatthias Ringwald } 54371c516d8fSMatthias Ringwald #endif 543870b44dd4SMatthias Ringwald sm_trigger_run(); 54393deb3ec6SMatthias Ringwald } 54403deb3ec6SMatthias Ringwald 54413d7fe1e9SMatthias Ringwald void sm_keypress_notification(hci_con_handle_t con_handle, uint8_t action){ 54423d7fe1e9SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 54433d7fe1e9SMatthias Ringwald if (!sm_conn) return; // wrong connection 54443d7fe1e9SMatthias Ringwald if (action > SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED) return; 5445dd4a08fbSMatthias Ringwald uint8_t num_actions = setup->sm_keypress_notification >> 5; 54464ea43905SMatthias Ringwald uint8_t flags = setup->sm_keypress_notification & 0x1fu; 5447dd4a08fbSMatthias Ringwald switch (action){ 5448dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_STARTED: 5449dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED: 54504ea43905SMatthias Ringwald flags |= (1u << action); 5451dd4a08fbSMatthias Ringwald break; 5452dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_CLEARED: 5453dd4a08fbSMatthias Ringwald // clear counter, keypress & erased flags + set passkey cleared 54544ea43905SMatthias Ringwald flags = (flags & 0x19u) | (1u << SM_KEYPRESS_PASSKEY_CLEARED); 5455dd4a08fbSMatthias Ringwald break; 5456dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ENTERED: 54571d80f1e6SMatthias Ringwald if ((flags & (1u << SM_KEYPRESS_PASSKEY_DIGIT_ERASED)) != 0u){ 5458dd4a08fbSMatthias Ringwald // erase actions queued 5459dd4a08fbSMatthias Ringwald num_actions--; 54604ea43905SMatthias Ringwald if (num_actions == 0u){ 5461dd4a08fbSMatthias Ringwald // clear counter, keypress & erased flags 54624ea43905SMatthias Ringwald flags &= 0x19u; 5463dd4a08fbSMatthias Ringwald } 5464dd4a08fbSMatthias Ringwald break; 5465dd4a08fbSMatthias Ringwald } 5466dd4a08fbSMatthias Ringwald num_actions++; 54674ea43905SMatthias Ringwald flags |= (1u << SM_KEYPRESS_PASSKEY_DIGIT_ENTERED); 5468dd4a08fbSMatthias Ringwald break; 5469dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ERASED: 54701d80f1e6SMatthias Ringwald if ((flags & (1u << SM_KEYPRESS_PASSKEY_DIGIT_ENTERED)) != 0u){ 5471dd4a08fbSMatthias Ringwald // enter actions queued 5472dd4a08fbSMatthias Ringwald num_actions--; 54734ea43905SMatthias Ringwald if (num_actions == 0u){ 5474dd4a08fbSMatthias Ringwald // clear counter, keypress & erased flags 54754ea43905SMatthias Ringwald flags &= 0x19u; 5476dd4a08fbSMatthias Ringwald } 5477dd4a08fbSMatthias Ringwald break; 5478dd4a08fbSMatthias Ringwald } 5479dd4a08fbSMatthias Ringwald num_actions++; 54804ea43905SMatthias Ringwald flags |= (1u << SM_KEYPRESS_PASSKEY_DIGIT_ERASED); 5481dd4a08fbSMatthias Ringwald break; 5482dd4a08fbSMatthias Ringwald default: 5483dd4a08fbSMatthias Ringwald break; 5484dd4a08fbSMatthias Ringwald } 5485dd4a08fbSMatthias Ringwald setup->sm_keypress_notification = (num_actions << 5) | flags; 548670b44dd4SMatthias Ringwald sm_trigger_run(); 54873d7fe1e9SMatthias Ringwald } 54883d7fe1e9SMatthias Ringwald 5489c59d0c92SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 5490d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_oob(void * arg){ 5491d1a1f6a4SMatthias Ringwald UNUSED(arg); 5492d1a1f6a4SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_W2_CALC_CONFIRM; 549370b44dd4SMatthias Ringwald sm_trigger_run(); 5494d1a1f6a4SMatthias Ringwald } 5495c59d0c92SMatthias Ringwald uint8_t sm_generate_sc_oob_data(void (*callback)(const uint8_t * confirm_value, const uint8_t * random_value)){ 54968334d3d8SMatthias Ringwald 54978334d3d8SMatthias Ringwald static btstack_crypto_random_t sm_crypto_random_oob_request; 54988334d3d8SMatthias Ringwald 5499c59d0c92SMatthias Ringwald if (sm_sc_oob_state != SM_SC_OOB_IDLE) return ERROR_CODE_COMMAND_DISALLOWED; 5500c59d0c92SMatthias Ringwald sm_sc_oob_callback = callback; 5501d1a1f6a4SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_W4_RANDOM; 5502d1a1f6a4SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_oob_request, sm_sc_oob_random, 16, &sm_handle_random_result_oob, NULL); 5503c59d0c92SMatthias Ringwald return 0; 5504c59d0c92SMatthias Ringwald } 5505c59d0c92SMatthias Ringwald #endif 5506c59d0c92SMatthias Ringwald 55073deb3ec6SMatthias Ringwald /** 5508ba394633SMatthias Ringwald * @brief Get Identity Resolving state 5509ba394633SMatthias Ringwald * @param con_handle 5510ba394633SMatthias Ringwald * @return irk_lookup_state_t 5511ba394633SMatthias Ringwald */ 5512ba394633SMatthias Ringwald irk_lookup_state_t sm_identity_resolving_state(hci_con_handle_t con_handle){ 5513ba394633SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 5514ba394633SMatthias Ringwald if (!sm_conn) return IRK_LOOKUP_IDLE; 5515ba394633SMatthias Ringwald return sm_conn->sm_irk_lookup_state; 5516ba394633SMatthias Ringwald } 5517ba394633SMatthias Ringwald 5518ba394633SMatthias Ringwald /** 55193deb3ec6SMatthias Ringwald * @brief Identify device in LE Device DB 55203deb3ec6SMatthias Ringwald * @param handle 55216b65794dSMilanka Ringwald * @return index from le_device_db or -1 if not found/identified 55223deb3ec6SMatthias Ringwald */ 5523711e6c80SMatthias Ringwald int sm_le_device_index(hci_con_handle_t con_handle ){ 5524711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 55253deb3ec6SMatthias Ringwald if (!sm_conn) return -1; 55263deb3ec6SMatthias Ringwald return sm_conn->sm_le_db_index; 55273deb3ec6SMatthias Ringwald } 55283deb3ec6SMatthias Ringwald 5529916ea5b2SMatthias Ringwald uint8_t sm_get_ltk(hci_con_handle_t con_handle, sm_key_t ltk){ 5530916ea5b2SMatthias Ringwald hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); 5531916ea5b2SMatthias Ringwald if (hci_connection == NULL){ 5532916ea5b2SMatthias Ringwald return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 5533916ea5b2SMatthias Ringwald } 5534f728bb7bSMatthias Ringwald if (hci_connection->link_key_type == INVALID_LINK_KEY){ 5535916ea5b2SMatthias Ringwald return ERROR_CODE_PIN_OR_KEY_MISSING; 5536916ea5b2SMatthias Ringwald } 5537916ea5b2SMatthias Ringwald memcpy(ltk, hci_connection->link_key, 16); 5538916ea5b2SMatthias Ringwald return ERROR_CODE_SUCCESS; 5539916ea5b2SMatthias Ringwald } 5540916ea5b2SMatthias Ringwald 55418f57b085SMatthias Ringwald static int gap_random_address_type_requires_updates(void){ 554247ba4de1SMatthias Ringwald switch (gap_random_adress_type){ 554347ba4de1SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_OFF: 554447ba4de1SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_STATIC: 554547ba4de1SMatthias Ringwald return 0; 554647ba4de1SMatthias Ringwald default: 55478f57b085SMatthias Ringwald return 1; 55488f57b085SMatthias Ringwald } 554947ba4de1SMatthias Ringwald } 5550d70217a2SMatthias Ringwald 555133373e40SMatthias Ringwald static uint8_t own_address_type(void){ 5552b95a5a35SMatthias Ringwald switch (gap_random_adress_type){ 5553b95a5a35SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_OFF: 5554b95a5a35SMatthias Ringwald return BD_ADDR_TYPE_LE_PUBLIC; 5555b95a5a35SMatthias Ringwald default: 5556b95a5a35SMatthias Ringwald return BD_ADDR_TYPE_LE_RANDOM; 5557b95a5a35SMatthias Ringwald } 555833373e40SMatthias Ringwald } 55598f57b085SMatthias Ringwald 55603deb3ec6SMatthias Ringwald // GAP LE API 55613deb3ec6SMatthias Ringwald void gap_random_address_set_mode(gap_random_address_type_t random_address_type){ 55623deb3ec6SMatthias Ringwald gap_random_address_update_stop(); 55633deb3ec6SMatthias Ringwald gap_random_adress_type = random_address_type; 5564b95a5a35SMatthias Ringwald hci_le_set_own_address_type(own_address_type()); 55658f57b085SMatthias Ringwald if (!gap_random_address_type_requires_updates()) return; 55663deb3ec6SMatthias Ringwald gap_random_address_update_start(); 55673deb3ec6SMatthias Ringwald gap_random_address_trigger(); 55683deb3ec6SMatthias Ringwald } 55693deb3ec6SMatthias Ringwald 55703deb3ec6SMatthias Ringwald gap_random_address_type_t gap_random_address_get_mode(void){ 55713deb3ec6SMatthias Ringwald return gap_random_adress_type; 55723deb3ec6SMatthias Ringwald } 55733deb3ec6SMatthias Ringwald 55743deb3ec6SMatthias Ringwald void gap_random_address_set_update_period(int period_ms){ 55753deb3ec6SMatthias Ringwald gap_random_adress_update_period = period_ms; 55768f57b085SMatthias Ringwald if (!gap_random_address_type_requires_updates()) return; 55773deb3ec6SMatthias Ringwald gap_random_address_update_stop(); 55783deb3ec6SMatthias Ringwald gap_random_address_update_start(); 55793deb3ec6SMatthias Ringwald } 55803deb3ec6SMatthias Ringwald 5581667ba9d1SMatthias Ringwald void gap_random_address_set(const bd_addr_t addr){ 55828f57b085SMatthias Ringwald gap_random_address_set_mode(GAP_RANDOM_ADDRESS_TYPE_STATIC); 55836535961aSMatthias Ringwald (void)memcpy(sm_random_address, addr, 6); 558463d302e8SMatthias Ringwald // assert msb bits are set to '11' 558563d302e8SMatthias Ringwald sm_random_address[0] |= 0xc0; 558663d302e8SMatthias Ringwald hci_le_random_address_set(sm_random_address); 55877e252622SMatthias Ringwald } 55887e252622SMatthias Ringwald 5589d70217a2SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 55903deb3ec6SMatthias Ringwald /* 55913deb3ec6SMatthias Ringwald * @brief Set Advertisement Paramters 55923deb3ec6SMatthias Ringwald * @param adv_int_min 55933deb3ec6SMatthias Ringwald * @param adv_int_max 55943deb3ec6SMatthias Ringwald * @param adv_type 55953deb3ec6SMatthias Ringwald * @param direct_address_type 55963deb3ec6SMatthias Ringwald * @param direct_address 55973deb3ec6SMatthias Ringwald * @param channel_map 55983deb3ec6SMatthias Ringwald * @param filter_policy 55993deb3ec6SMatthias Ringwald * 56003deb3ec6SMatthias Ringwald * @note own_address_type is used from gap_random_address_set_mode 56013deb3ec6SMatthias Ringwald */ 56023deb3ec6SMatthias Ringwald void gap_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, 56033deb3ec6SMatthias Ringwald uint8_t direct_address_typ, bd_addr_t direct_address, uint8_t channel_map, uint8_t filter_policy){ 5604b95a5a35SMatthias Ringwald hci_le_advertisements_set_params(adv_int_min, adv_int_max, adv_type, 56053deb3ec6SMatthias Ringwald direct_address_typ, direct_address, channel_map, filter_policy); 56063deb3ec6SMatthias Ringwald } 5607d70217a2SMatthias Ringwald #endif 5608dcd6c9b5SMatthias Ringwald 5609c7ceba59SMatthias Ringwald bool gap_reconnect_security_setup_active(hci_con_handle_t con_handle){ 5610dcd6c9b5SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 5611dcd6c9b5SMatthias Ringwald // wrong connection 5612c7ceba59SMatthias Ringwald if (!sm_conn) return false; 5613dcd6c9b5SMatthias Ringwald // already encrypted 5614c7ceba59SMatthias Ringwald if (sm_conn->sm_connection_encrypted) return false; 5615dcd6c9b5SMatthias Ringwald // irk status? 5616dcd6c9b5SMatthias Ringwald switch(sm_conn->sm_irk_lookup_state){ 5617dcd6c9b5SMatthias Ringwald case IRK_LOOKUP_FAILED: 5618dcd6c9b5SMatthias Ringwald // done, cannot setup encryption 5619c7ceba59SMatthias Ringwald return false; 5620dcd6c9b5SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 5621dcd6c9b5SMatthias Ringwald break; 5622dcd6c9b5SMatthias Ringwald default: 5623dcd6c9b5SMatthias Ringwald // IR Lookup pending 5624c7ceba59SMatthias Ringwald return true; 5625dcd6c9b5SMatthias Ringwald } 5626f0674e22SMatthias Ringwald // IRK Lookup Succeeded, re-encryption should be initiated. When done, state gets reset or indicates failure 5627c7ceba59SMatthias Ringwald if (sm_conn->sm_engine_state == SM_GENERAL_REENCRYPTION_FAILED) return false; 5628c7ceba59SMatthias Ringwald if (sm_conn->sm_role != 0){ 5629b15d5ceaSMatthias Ringwald return sm_conn->sm_engine_state != SM_RESPONDER_IDLE; 5630b15d5ceaSMatthias Ringwald } else { 5631dcd6c9b5SMatthias Ringwald return sm_conn->sm_engine_state != SM_INITIATOR_CONNECTED; 5632dcd6c9b5SMatthias Ringwald } 5633b15d5ceaSMatthias Ringwald } 56343cdbe9dbSMatthias Ringwald 56353cdbe9dbSMatthias Ringwald void sm_set_secure_connections_only_mode(bool enable){ 56363cdbe9dbSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 56373cdbe9dbSMatthias Ringwald sm_sc_only_mode = enable; 56383cdbe9dbSMatthias Ringwald #else 56393cdbe9dbSMatthias Ringwald // SC Only mode not possible without support for SC 56403cdbe9dbSMatthias Ringwald btstack_assert(enable == false); 56413cdbe9dbSMatthias Ringwald #endif 56423cdbe9dbSMatthias Ringwald } 5643052bbdc5SMatthias Ringwald 564492f8d6b6SMatthias Ringwald #if defined(ENABLE_LE_SECURE_CONNECTIONS) && defined (ENABLE_LE_SECURE_CONNECTION_DEBUG_KEY) 5645db88441fSMatthias Ringwald void sm_test_enable_secure_connections_debug_keys(void) { 5646db88441fSMatthias Ringwald log_info("Enable LE Secure Connection Debug Keys for testing"); 5647db88441fSMatthias Ringwald sm_sc_debug_keys_enabled = true; 5648db88441fSMatthias Ringwald // set debug key 5649db88441fSMatthias Ringwald sm_ec_generate_new_key(); 5650db88441fSMatthias Ringwald } 5651db88441fSMatthias Ringwald #endif 5652db88441fSMatthias Ringwald 5653052bbdc5SMatthias Ringwald const uint8_t * gap_get_persistent_irk(void){ 5654052bbdc5SMatthias Ringwald return sm_persistent_irk; 5655052bbdc5SMatthias Ringwald } 56564f384501SMatthias Ringwald 56574f384501SMatthias Ringwald void gap_delete_bonding(bd_addr_type_t address_type, bd_addr_t address){ 565822cb578bSMatthias Ringwald int index = sm_le_device_db_index_lookup(address_type, address); 565922cb578bSMatthias Ringwald if (index >= 0){ 566022cb578bSMatthias Ringwald sm_remove_le_device_db_entry(index); 56614f384501SMatthias Ringwald } 56624f384501SMatthias Ringwald } 5663