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) 7542134bc6SMatthias Ringwald #define IS_RESPONDER(role) (role) 7642134bc6SMatthias Ringwald #else 7742134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 7842134bc6SMatthias Ringwald // only central - never responder (avoid 'unused variable' warnings) 7942134bc6SMatthias Ringwald #define IS_RESPONDER(role) (0 && role) 8042134bc6SMatthias Ringwald #else 8142134bc6SMatthias Ringwald // only peripheral - always responder (avoid 'unused variable' warnings) 8242134bc6SMatthias Ringwald #define IS_RESPONDER(role) (1 || role) 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 201b6f39a74SMatthias Ringwald static uint8_t 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; 209*db88441fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS_DEBUG_KEY 210*db88441fSMatthias Ringwald static bool sm_sc_debug_keys_enabled; 211*db88441fSMatthias 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; 32527c32905SMatthias Ringwald uint8_t 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); 4322a526f21SMatthias Ringwald static int sm_passkey_entry(stk_generation_method_t method); 433d1a1f6a4SMatthias Ringwald #endif 4340ccf6c9cSMatthias Ringwald static void sm_pairing_complete(sm_connection_t * sm_conn, uint8_t status, uint8_t reason); 4353deb3ec6SMatthias Ringwald 4363deb3ec6SMatthias Ringwald static void log_info_hex16(const char * name, uint16_t value){ 4373deb3ec6SMatthias Ringwald log_info("%-6s 0x%04x", name, value); 4383deb3ec6SMatthias Ringwald } 4393deb3ec6SMatthias Ringwald 4401fbd72c5SMatthias Ringwald // static inline uint8_t sm_pairing_packet_get_code(sm_pairing_packet_t packet){ 4411fbd72c5SMatthias Ringwald // return packet[0]; 4421fbd72c5SMatthias Ringwald // } 4431fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_io_capability(sm_pairing_packet_t packet){ 4441fbd72c5SMatthias Ringwald return packet[1]; 4451fbd72c5SMatthias Ringwald } 4461fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_oob_data_flag(sm_pairing_packet_t packet){ 4471fbd72c5SMatthias Ringwald return packet[2]; 4481fbd72c5SMatthias Ringwald } 4491fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_auth_req(sm_pairing_packet_t packet){ 4501fbd72c5SMatthias Ringwald return packet[3]; 4511fbd72c5SMatthias Ringwald } 4521fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_max_encryption_key_size(sm_pairing_packet_t packet){ 4531fbd72c5SMatthias Ringwald return packet[4]; 4541fbd72c5SMatthias Ringwald } 4551fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_initiator_key_distribution(sm_pairing_packet_t packet){ 4561fbd72c5SMatthias Ringwald return packet[5]; 4571fbd72c5SMatthias Ringwald } 4581fbd72c5SMatthias Ringwald static inline uint8_t sm_pairing_packet_get_responder_key_distribution(sm_pairing_packet_t packet){ 4591fbd72c5SMatthias Ringwald return packet[6]; 4601fbd72c5SMatthias Ringwald } 4611fbd72c5SMatthias Ringwald 4621fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_code(sm_pairing_packet_t packet, uint8_t code){ 4631fbd72c5SMatthias Ringwald packet[0] = code; 4641fbd72c5SMatthias Ringwald } 4651fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_io_capability(sm_pairing_packet_t packet, uint8_t io_capability){ 4661fbd72c5SMatthias Ringwald packet[1] = io_capability; 4671fbd72c5SMatthias Ringwald } 4681fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_oob_data_flag(sm_pairing_packet_t packet, uint8_t oob_data_flag){ 4691fbd72c5SMatthias Ringwald packet[2] = oob_data_flag; 4701fbd72c5SMatthias Ringwald } 4711fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_auth_req(sm_pairing_packet_t packet, uint8_t auth_req){ 4721fbd72c5SMatthias Ringwald packet[3] = auth_req; 4731fbd72c5SMatthias Ringwald } 4741fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_max_encryption_key_size(sm_pairing_packet_t packet, uint8_t max_encryption_key_size){ 4751fbd72c5SMatthias Ringwald packet[4] = max_encryption_key_size; 4761fbd72c5SMatthias Ringwald } 4771fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_initiator_key_distribution(sm_pairing_packet_t packet, uint8_t initiator_key_distribution){ 4781fbd72c5SMatthias Ringwald packet[5] = initiator_key_distribution; 4791fbd72c5SMatthias Ringwald } 4801fbd72c5SMatthias Ringwald static inline void sm_pairing_packet_set_responder_key_distribution(sm_pairing_packet_t packet, uint8_t responder_key_distribution){ 4811fbd72c5SMatthias Ringwald packet[6] = responder_key_distribution; 4821fbd72c5SMatthias Ringwald } 4831fbd72c5SMatthias Ringwald 4841979f09cSMatthias Ringwald static bool sm_is_null_random(uint8_t random[8]){ 48524c4191dSMatthias Ringwald return btstack_is_null(random, 8); 4863764b551SMatthias Ringwald } 4873764b551SMatthias Ringwald 4881979f09cSMatthias Ringwald static bool sm_is_null_key(uint8_t * key){ 48924c4191dSMatthias Ringwald return btstack_is_null(key, 16); 4903764b551SMatthias Ringwald } 4913764b551SMatthias Ringwald 4921c34405fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4931c34405fSMatthias Ringwald static bool sm_is_ff(const uint8_t * buffer, uint16_t size){ 4941c34405fSMatthias Ringwald uint16_t i; 4951c34405fSMatthias Ringwald for (i=0; i < size ; i++){ 4961c34405fSMatthias Ringwald if (buffer[i] != 0xff) { 4971c34405fSMatthias Ringwald return false; 4981c34405fSMatthias Ringwald } 4991c34405fSMatthias Ringwald } 5001c34405fSMatthias Ringwald return true; 5011c34405fSMatthias Ringwald } 5021c34405fSMatthias Ringwald #endif 5031c34405fSMatthias Ringwald 50470b44dd4SMatthias Ringwald // sm_trigger_run allows to schedule callback from main run loop // reduces stack depth 50570b44dd4SMatthias Ringwald static void sm_run_timer_handler(btstack_timer_source_t * ts){ 50670b44dd4SMatthias Ringwald UNUSED(ts); 50770b44dd4SMatthias Ringwald sm_run(); 50870b44dd4SMatthias Ringwald } 50970b44dd4SMatthias Ringwald static void sm_trigger_run(void){ 5102d2d4d3cSMatthias Ringwald if (!sm_initialized) return; 51184c0c5c7SMatthias Ringwald (void)btstack_run_loop_remove_timer(&sm_run_timer); 51270b44dd4SMatthias Ringwald btstack_run_loop_set_timer(&sm_run_timer, 0); 51370b44dd4SMatthias Ringwald btstack_run_loop_add_timer(&sm_run_timer); 51470b44dd4SMatthias Ringwald } 51570b44dd4SMatthias Ringwald 5163deb3ec6SMatthias Ringwald // Key utils 5173deb3ec6SMatthias Ringwald static void sm_reset_tk(void){ 5183deb3ec6SMatthias Ringwald int i; 5193deb3ec6SMatthias Ringwald for (i=0;i<16;i++){ 5203deb3ec6SMatthias Ringwald setup->sm_tk[i] = 0; 5213deb3ec6SMatthias Ringwald } 5223deb3ec6SMatthias Ringwald } 5233deb3ec6SMatthias Ringwald 5243deb3ec6SMatthias Ringwald // "For example, if a 128-bit encryption key is 0x123456789ABCDEF0123456789ABCDEF0 5253deb3ec6SMatthias Ringwald // and it is reduced to 7 octets (56 bits), then the resulting key is 0x0000000000000000003456789ABCDEF0."" 5263deb3ec6SMatthias Ringwald static void sm_truncate_key(sm_key_t key, int max_encryption_size){ 5273deb3ec6SMatthias Ringwald int i; 5283deb3ec6SMatthias Ringwald for (i = max_encryption_size ; i < 16 ; i++){ 5293deb3ec6SMatthias Ringwald key[15-i] = 0; 5303deb3ec6SMatthias Ringwald } 5313deb3ec6SMatthias Ringwald } 5323deb3ec6SMatthias Ringwald 533899e6e02SMatthias Ringwald // ER / IR checks 53421045273SMatthias Ringwald static void sm_er_ir_set_default(void){ 535899e6e02SMatthias Ringwald int i; 536899e6e02SMatthias Ringwald for (i=0;i<16;i++){ 537899e6e02SMatthias Ringwald sm_persistent_er[i] = 0x30 + i; 538899e6e02SMatthias Ringwald sm_persistent_ir[i] = 0x90 + i; 539899e6e02SMatthias Ringwald } 540899e6e02SMatthias Ringwald } 541899e6e02SMatthias Ringwald 542899e6e02SMatthias Ringwald static int sm_er_is_default(void){ 543899e6e02SMatthias Ringwald int i; 544899e6e02SMatthias Ringwald for (i=0;i<16;i++){ 545899e6e02SMatthias Ringwald if (sm_persistent_er[i] != (0x30+i)) return 0; 546899e6e02SMatthias Ringwald } 547899e6e02SMatthias Ringwald return 1; 548899e6e02SMatthias Ringwald } 549899e6e02SMatthias Ringwald 550899e6e02SMatthias Ringwald static int sm_ir_is_default(void){ 551899e6e02SMatthias Ringwald int i; 552899e6e02SMatthias Ringwald for (i=0;i<16;i++){ 553899e6e02SMatthias Ringwald if (sm_persistent_ir[i] != (0x90+i)) return 0; 554899e6e02SMatthias Ringwald } 555899e6e02SMatthias Ringwald return 1; 556899e6e02SMatthias Ringwald } 557899e6e02SMatthias Ringwald 55873102768SMatthias Ringwald static void sm_dispatch_event(uint8_t packet_type, uint16_t channel, uint8_t * packet, uint16_t size){ 55973102768SMatthias Ringwald UNUSED(channel); 56073102768SMatthias Ringwald 56173102768SMatthias Ringwald // log event 56273102768SMatthias Ringwald hci_dump_packet(packet_type, 1, packet, size); 56373102768SMatthias Ringwald // dispatch to all event handlers 56473102768SMatthias Ringwald btstack_linked_list_iterator_t it; 56573102768SMatthias Ringwald btstack_linked_list_iterator_init(&it, &sm_event_handlers); 56673102768SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&it)){ 56773102768SMatthias Ringwald btstack_packet_callback_registration_t * entry = (btstack_packet_callback_registration_t*) btstack_linked_list_iterator_next(&it); 56873102768SMatthias Ringwald entry->callback(packet_type, 0, packet, size); 56973102768SMatthias Ringwald } 57073102768SMatthias Ringwald } 57173102768SMatthias Ringwald 57273102768SMatthias Ringwald static void sm_setup_event_base(uint8_t * event, int event_size, uint8_t type, hci_con_handle_t con_handle, uint8_t addr_type, bd_addr_t address){ 57373102768SMatthias Ringwald event[0] = type; 57473102768SMatthias Ringwald event[1] = event_size - 2; 57573102768SMatthias Ringwald little_endian_store_16(event, 2, con_handle); 57673102768SMatthias Ringwald event[4] = addr_type; 57773102768SMatthias Ringwald reverse_bd_addr(address, &event[5]); 57873102768SMatthias Ringwald } 57973102768SMatthias Ringwald 58073102768SMatthias Ringwald static void sm_notify_client_base(uint8_t type, hci_con_handle_t con_handle, uint8_t addr_type, bd_addr_t address){ 58173102768SMatthias Ringwald uint8_t event[11]; 58273102768SMatthias Ringwald sm_setup_event_base(event, sizeof(event), type, con_handle, addr_type, address); 58373102768SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, event, sizeof(event)); 58473102768SMatthias Ringwald } 58573102768SMatthias Ringwald 58673102768SMatthias Ringwald static void sm_notify_client_index(uint8_t type, hci_con_handle_t con_handle, uint8_t addr_type, bd_addr_t address, uint16_t index){ 58773102768SMatthias Ringwald // fetch addr and addr type from db, only called for valid entries 58873102768SMatthias Ringwald bd_addr_t identity_address; 58973102768SMatthias Ringwald int identity_address_type; 59073102768SMatthias Ringwald le_device_db_info(index, &identity_address_type, identity_address, NULL); 59173102768SMatthias Ringwald 59273102768SMatthias Ringwald uint8_t event[20]; 59373102768SMatthias Ringwald sm_setup_event_base(event, sizeof(event), type, con_handle, addr_type, address); 59473102768SMatthias Ringwald event[11] = identity_address_type; 59573102768SMatthias Ringwald reverse_bd_addr(identity_address, &event[12]); 59673102768SMatthias Ringwald little_endian_store_16(event, 18, index); 59773102768SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, event, sizeof(event)); 59873102768SMatthias Ringwald } 59973102768SMatthias Ringwald 60073102768SMatthias Ringwald static void sm_notify_client_status(uint8_t type, hci_con_handle_t con_handle, uint8_t addr_type, bd_addr_t address, uint8_t status){ 60173102768SMatthias Ringwald uint8_t event[12]; 60273102768SMatthias Ringwald sm_setup_event_base(event, sizeof(event), type, con_handle, addr_type, address); 60373102768SMatthias Ringwald event[11] = status; 60473102768SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, (uint8_t*) &event, sizeof(event)); 60573102768SMatthias Ringwald } 60673102768SMatthias Ringwald 60773102768SMatthias Ringwald 60873102768SMatthias Ringwald static void sm_reencryption_started(sm_connection_t * sm_conn){ 60973102768SMatthias Ringwald 6103ab61f77SMatthias Ringwald if (sm_conn->sm_reencryption_active) return; 6113ab61f77SMatthias Ringwald 6127b001f4eSMatthias Ringwald sm_conn->sm_reencryption_active = true; 61373102768SMatthias Ringwald 61473102768SMatthias Ringwald int identity_addr_type; 61573102768SMatthias Ringwald bd_addr_t identity_addr; 6163c0e26deSMatthias Ringwald if (sm_conn->sm_le_db_index >= 0){ 6173c0e26deSMatthias Ringwald // fetch addr and addr type from db, only called for valid entries 61873102768SMatthias Ringwald le_device_db_info(sm_conn->sm_le_db_index, &identity_addr_type, identity_addr, NULL); 6193c0e26deSMatthias Ringwald } else { 6203c0e26deSMatthias Ringwald // for legacy pairing with LTK re-construction, use current peer addr 6213c0e26deSMatthias Ringwald identity_addr_type = sm_conn->sm_peer_addr_type; 622d5529700SMatthias Ringwald // cppcheck-suppress uninitvar ; identity_addr is reported as uninitialized although it's the destination of the memcpy 6233c0e26deSMatthias Ringwald memcpy(identity_addr, sm_conn->sm_peer_address, 6); 6243c0e26deSMatthias Ringwald } 62573102768SMatthias Ringwald 62673102768SMatthias Ringwald sm_notify_client_base(SM_EVENT_REENCRYPTION_STARTED, sm_conn->sm_handle, identity_addr_type, identity_addr); 62773102768SMatthias Ringwald } 62873102768SMatthias Ringwald 62973102768SMatthias Ringwald static void sm_reencryption_complete(sm_connection_t * sm_conn, uint8_t status){ 63073102768SMatthias Ringwald 63160be5b21SMatthias Ringwald if (!sm_conn->sm_reencryption_active) return; 63260be5b21SMatthias Ringwald 6337b001f4eSMatthias Ringwald sm_conn->sm_reencryption_active = false; 63473102768SMatthias Ringwald 63573102768SMatthias Ringwald int identity_addr_type; 63673102768SMatthias Ringwald bd_addr_t identity_addr; 6373c0e26deSMatthias Ringwald if (sm_conn->sm_le_db_index >= 0){ 6383c0e26deSMatthias Ringwald // fetch addr and addr type from db, only called for valid entries 63973102768SMatthias Ringwald le_device_db_info(sm_conn->sm_le_db_index, &identity_addr_type, identity_addr, NULL); 6403c0e26deSMatthias Ringwald } else { 6413c0e26deSMatthias Ringwald // for legacy pairing with LTK re-construction, use current peer addr 6423c0e26deSMatthias Ringwald identity_addr_type = sm_conn->sm_peer_addr_type; 643d5529700SMatthias Ringwald // cppcheck-suppress uninitvar ; identity_addr is reported as uninitialized although it's the destination of the memcpy 6443c0e26deSMatthias Ringwald memcpy(identity_addr, sm_conn->sm_peer_address, 6); 6453c0e26deSMatthias Ringwald } 64673102768SMatthias Ringwald 64773102768SMatthias Ringwald sm_notify_client_status(SM_EVENT_REENCRYPTION_COMPLETE, sm_conn->sm_handle, identity_addr_type, identity_addr, status); 64873102768SMatthias Ringwald } 64973102768SMatthias Ringwald 650d3c12277SMatthias Ringwald static void sm_pairing_started(sm_connection_t * sm_conn){ 651d3c12277SMatthias Ringwald 652d3c12277SMatthias Ringwald if (sm_conn->sm_pairing_active) return; 653d3c12277SMatthias Ringwald 654d3c12277SMatthias Ringwald sm_conn->sm_pairing_active = true; 655d3c12277SMatthias Ringwald 656d3c12277SMatthias Ringwald uint8_t event[11]; 657d3c12277SMatthias Ringwald sm_setup_event_base(event, sizeof(event), SM_EVENT_PAIRING_STARTED, sm_conn->sm_handle, setup->sm_peer_addr_type, setup->sm_peer_address); 658d3c12277SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, (uint8_t*) &event, sizeof(event)); 659d3c12277SMatthias Ringwald } 660d3c12277SMatthias Ringwald 6610ccf6c9cSMatthias Ringwald static void sm_pairing_complete(sm_connection_t * sm_conn, uint8_t status, uint8_t reason){ 662f61072f5SMatthias Ringwald 663d77906ffSMatthias Ringwald if (!sm_conn->sm_pairing_active) return; 664d77906ffSMatthias Ringwald 66569f82ad8SMatthias Ringwald sm_conn->sm_pairing_active = false; 66669f82ad8SMatthias Ringwald 6670ccf6c9cSMatthias Ringwald uint8_t event[13]; 6680ccf6c9cSMatthias Ringwald sm_setup_event_base(event, sizeof(event), SM_EVENT_PAIRING_COMPLETE, sm_conn->sm_handle, setup->sm_peer_addr_type, setup->sm_peer_address); 6690ccf6c9cSMatthias Ringwald event[11] = status; 6700ccf6c9cSMatthias Ringwald event[12] = reason; 6710ccf6c9cSMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, (uint8_t*) &event, sizeof(event)); 6720ccf6c9cSMatthias Ringwald } 6730ccf6c9cSMatthias Ringwald 6743deb3ec6SMatthias Ringwald // SMP Timeout implementation 6753deb3ec6SMatthias Ringwald 6763deb3ec6SMatthias Ringwald // Upon transmission of the Pairing Request command or reception of the Pairing Request command, 6773deb3ec6SMatthias Ringwald // the Security Manager Timer shall be reset and started. 6783deb3ec6SMatthias Ringwald // 6793deb3ec6SMatthias Ringwald // The Security Manager Timer shall be reset when an L2CAP SMP command is queued for transmission. 6803deb3ec6SMatthias Ringwald // 6813deb3ec6SMatthias Ringwald // If the Security Manager Timer reaches 30 seconds, the procedure shall be considered to have failed, 6823deb3ec6SMatthias Ringwald // and the local higher layer shall be notified. No further SMP commands shall be sent over the L2CAP 6833deb3ec6SMatthias Ringwald // Security Manager Channel. A new SM procedure shall only be performed when a new physical link has been 6843deb3ec6SMatthias Ringwald // established. 6853deb3ec6SMatthias Ringwald 686ec820d77SMatthias Ringwald static void sm_timeout_handler(btstack_timer_source_t * timer){ 6873deb3ec6SMatthias Ringwald log_info("SM timeout"); 688c5b64319SMatthias Ringwald sm_connection_t * sm_conn = (sm_connection_t*) btstack_run_loop_get_timer_context(timer); 6893deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_TIMEOUT; 69068a18fb9SMatthias Ringwald sm_reencryption_complete(sm_conn, ERROR_CODE_CONNECTION_TIMEOUT); 6910ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_CONNECTION_TIMEOUT, 0); 6923deb3ec6SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 6933deb3ec6SMatthias Ringwald 6943deb3ec6SMatthias Ringwald // trigger handling of next ready connection 6953deb3ec6SMatthias Ringwald sm_run(); 6963deb3ec6SMatthias Ringwald } 6973deb3ec6SMatthias Ringwald static void sm_timeout_start(sm_connection_t * sm_conn){ 698528a4a3bSMatthias Ringwald btstack_run_loop_remove_timer(&setup->sm_timeout); 69991a977e8SMatthias Ringwald btstack_run_loop_set_timer_context(&setup->sm_timeout, sm_conn); 700528a4a3bSMatthias Ringwald btstack_run_loop_set_timer_handler(&setup->sm_timeout, sm_timeout_handler); 701528a4a3bSMatthias Ringwald btstack_run_loop_set_timer(&setup->sm_timeout, 30000); // 30 seconds sm timeout 702528a4a3bSMatthias Ringwald btstack_run_loop_add_timer(&setup->sm_timeout); 7033deb3ec6SMatthias Ringwald } 7043deb3ec6SMatthias Ringwald static void sm_timeout_stop(void){ 705528a4a3bSMatthias Ringwald btstack_run_loop_remove_timer(&setup->sm_timeout); 7063deb3ec6SMatthias Ringwald } 7073deb3ec6SMatthias Ringwald static void sm_timeout_reset(sm_connection_t * sm_conn){ 7083deb3ec6SMatthias Ringwald sm_timeout_stop(); 7093deb3ec6SMatthias Ringwald sm_timeout_start(sm_conn); 7103deb3ec6SMatthias Ringwald } 7113deb3ec6SMatthias Ringwald 7123deb3ec6SMatthias Ringwald // end of sm timeout 7133deb3ec6SMatthias Ringwald 7143deb3ec6SMatthias Ringwald // GAP Random Address updates 7153deb3ec6SMatthias Ringwald static gap_random_address_type_t gap_random_adress_type; 716ec820d77SMatthias Ringwald static btstack_timer_source_t gap_random_address_update_timer; 7173deb3ec6SMatthias Ringwald static uint32_t gap_random_adress_update_period; 7183deb3ec6SMatthias Ringwald 7193deb3ec6SMatthias Ringwald static void gap_random_address_trigger(void){ 720899e6e02SMatthias Ringwald log_info("gap_random_address_trigger, state %u", rau_state); 721d1a1f6a4SMatthias Ringwald if (rau_state != RAU_IDLE) return; 722fbd4e238SMatthias Ringwald rau_state = RAU_GET_RANDOM; 72370b44dd4SMatthias Ringwald sm_trigger_run(); 7243deb3ec6SMatthias Ringwald } 7253deb3ec6SMatthias Ringwald 726ec820d77SMatthias Ringwald static void gap_random_address_update_handler(btstack_timer_source_t * timer){ 7279ec2630cSMatthias Ringwald UNUSED(timer); 7289ec2630cSMatthias Ringwald 7293deb3ec6SMatthias Ringwald log_info("GAP Random Address Update due"); 730528a4a3bSMatthias Ringwald btstack_run_loop_set_timer(&gap_random_address_update_timer, gap_random_adress_update_period); 731528a4a3bSMatthias Ringwald btstack_run_loop_add_timer(&gap_random_address_update_timer); 7323deb3ec6SMatthias Ringwald gap_random_address_trigger(); 7333deb3ec6SMatthias Ringwald } 7343deb3ec6SMatthias Ringwald 7353deb3ec6SMatthias Ringwald static void gap_random_address_update_start(void){ 736528a4a3bSMatthias Ringwald btstack_run_loop_set_timer_handler(&gap_random_address_update_timer, gap_random_address_update_handler); 737528a4a3bSMatthias Ringwald btstack_run_loop_set_timer(&gap_random_address_update_timer, gap_random_adress_update_period); 738528a4a3bSMatthias Ringwald btstack_run_loop_add_timer(&gap_random_address_update_timer); 7393deb3ec6SMatthias Ringwald } 7403deb3ec6SMatthias Ringwald 7413deb3ec6SMatthias Ringwald static void gap_random_address_update_stop(void){ 742528a4a3bSMatthias Ringwald btstack_run_loop_remove_timer(&gap_random_address_update_timer); 7433deb3ec6SMatthias Ringwald } 7443deb3ec6SMatthias Ringwald 7453deb3ec6SMatthias Ringwald // ah(k,r) helper 7463deb3ec6SMatthias Ringwald // r = padding || r 7473deb3ec6SMatthias Ringwald // r - 24 bit value 7484a6806f3SMatthias Ringwald static void sm_ah_r_prime(uint8_t r[3], uint8_t * r_prime){ 7493deb3ec6SMatthias Ringwald // r'= padding || r 7503deb3ec6SMatthias Ringwald memset(r_prime, 0, 16); 7516535961aSMatthias Ringwald (void)memcpy(&r_prime[13], r, 3); 7523deb3ec6SMatthias Ringwald } 7533deb3ec6SMatthias Ringwald 7543deb3ec6SMatthias Ringwald // d1 helper 7553deb3ec6SMatthias Ringwald // d' = padding || r || d 7563deb3ec6SMatthias Ringwald // d,r - 16 bit values 7574a6806f3SMatthias Ringwald static void sm_d1_d_prime(uint16_t d, uint16_t r, uint8_t * d1_prime){ 7583deb3ec6SMatthias Ringwald // d'= padding || r || d 7593deb3ec6SMatthias Ringwald memset(d1_prime, 0, 16); 760f8fbdce0SMatthias Ringwald big_endian_store_16(d1_prime, 12, r); 761f8fbdce0SMatthias Ringwald big_endian_store_16(d1_prime, 14, d); 7623deb3ec6SMatthias Ringwald } 7633deb3ec6SMatthias Ringwald 7643deb3ec6SMatthias Ringwald // calculate arguments for first AES128 operation in C1 function 7654a6806f3SMatthias Ringwald static void sm_c1_t1(sm_key_t r, uint8_t preq[7], uint8_t pres[7], uint8_t iat, uint8_t rat, uint8_t * t1){ 7663deb3ec6SMatthias Ringwald 7673deb3ec6SMatthias Ringwald // p1 = pres || preq || rat’ || iat’ 7683deb3ec6SMatthias Ringwald // "The octet of iat’ becomes the least significant octet of p1 and the most signifi- 7693deb3ec6SMatthias Ringwald // cant octet of pres becomes the most significant octet of p1. 7703deb3ec6SMatthias Ringwald // For example, if the 8-bit iat’ is 0x01, the 8-bit rat’ is 0x00, the 56-bit preq 7713deb3ec6SMatthias Ringwald // is 0x07071000000101 and the 56 bit pres is 0x05000800000302 then 7723deb3ec6SMatthias Ringwald // p1 is 0x05000800000302070710000001010001." 7733deb3ec6SMatthias Ringwald 7743deb3ec6SMatthias Ringwald sm_key_t p1; 7759c80e4ccSMatthias Ringwald reverse_56(pres, &p1[0]); 7769c80e4ccSMatthias Ringwald reverse_56(preq, &p1[7]); 7773deb3ec6SMatthias Ringwald p1[14] = rat; 7783deb3ec6SMatthias Ringwald p1[15] = iat; 7798314c363SMatthias Ringwald log_info_key("p1", p1); 7808314c363SMatthias Ringwald log_info_key("r", r); 7813deb3ec6SMatthias Ringwald 7823deb3ec6SMatthias Ringwald // t1 = r xor p1 7833deb3ec6SMatthias Ringwald int i; 7843deb3ec6SMatthias Ringwald for (i=0;i<16;i++){ 7853deb3ec6SMatthias Ringwald t1[i] = r[i] ^ p1[i]; 7863deb3ec6SMatthias Ringwald } 7878314c363SMatthias Ringwald log_info_key("t1", t1); 7883deb3ec6SMatthias Ringwald } 7893deb3ec6SMatthias Ringwald 7903deb3ec6SMatthias Ringwald // calculate arguments for second AES128 operation in C1 function 7914a6806f3SMatthias Ringwald static void sm_c1_t3(sm_key_t t2, bd_addr_t ia, bd_addr_t ra, uint8_t * t3){ 7923deb3ec6SMatthias Ringwald // p2 = padding || ia || ra 7933deb3ec6SMatthias Ringwald // "The least significant octet of ra becomes the least significant octet of p2 and 7943deb3ec6SMatthias Ringwald // the most significant octet of padding becomes the most significant octet of p2. 7953deb3ec6SMatthias Ringwald // For example, if 48-bit ia is 0xA1A2A3A4A5A6 and the 48-bit ra is 7963deb3ec6SMatthias Ringwald // 0xB1B2B3B4B5B6 then p2 is 0x00000000A1A2A3A4A5A6B1B2B3B4B5B6. 7973deb3ec6SMatthias Ringwald 7983deb3ec6SMatthias Ringwald sm_key_t p2; 799d5529700SMatthias Ringwald // cppcheck-suppress uninitvar ; p2 is reported as uninitialized 8003deb3ec6SMatthias Ringwald memset(p2, 0, 16); 8016535961aSMatthias Ringwald (void)memcpy(&p2[4], ia, 6); 8026535961aSMatthias Ringwald (void)memcpy(&p2[10], ra, 6); 8038314c363SMatthias Ringwald log_info_key("p2", p2); 8043deb3ec6SMatthias Ringwald 8053deb3ec6SMatthias Ringwald // c1 = e(k, t2_xor_p2) 8063deb3ec6SMatthias Ringwald int i; 8073deb3ec6SMatthias Ringwald for (i=0;i<16;i++){ 8083deb3ec6SMatthias Ringwald t3[i] = t2[i] ^ p2[i]; 8093deb3ec6SMatthias Ringwald } 8108314c363SMatthias Ringwald log_info_key("t3", t3); 8113deb3ec6SMatthias Ringwald } 8123deb3ec6SMatthias Ringwald 8134a6806f3SMatthias Ringwald static void sm_s1_r_prime(sm_key_t r1, sm_key_t r2, uint8_t * r_prime){ 8148314c363SMatthias Ringwald log_info_key("r1", r1); 8158314c363SMatthias Ringwald log_info_key("r2", r2); 8166535961aSMatthias Ringwald (void)memcpy(&r_prime[8], &r2[8], 8); 8176535961aSMatthias Ringwald (void)memcpy(&r_prime[0], &r1[8], 8); 8183deb3ec6SMatthias Ringwald } 8193deb3ec6SMatthias Ringwald 820fbe050beSMatthias Ringwald 8213deb3ec6SMatthias Ringwald // decide on stk generation based on 8223deb3ec6SMatthias Ringwald // - pairing request 8233deb3ec6SMatthias Ringwald // - io capabilities 8243deb3ec6SMatthias Ringwald // - OOB data availability 8253deb3ec6SMatthias Ringwald static void sm_setup_tk(void){ 8263deb3ec6SMatthias Ringwald 8278334d3d8SMatthias Ringwald // horizontal: initiator capabilities 8288334d3d8SMatthias Ringwald // vertial: responder capabilities 8298334d3d8SMatthias Ringwald static const stk_generation_method_t stk_generation_method [5] [5] = { 8308334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, PK_INIT_INPUT, JUST_WORKS, PK_INIT_INPUT }, 8318334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, PK_INIT_INPUT, JUST_WORKS, PK_INIT_INPUT }, 8328334d3d8SMatthias Ringwald { PK_RESP_INPUT, PK_RESP_INPUT, PK_BOTH_INPUT, JUST_WORKS, PK_RESP_INPUT }, 8338334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS }, 8348334d3d8SMatthias Ringwald { PK_RESP_INPUT, PK_RESP_INPUT, PK_INIT_INPUT, JUST_WORKS, PK_RESP_INPUT }, 8358334d3d8SMatthias Ringwald }; 8368334d3d8SMatthias Ringwald 8378334d3d8SMatthias Ringwald // uses numeric comparison if one side has DisplayYesNo and KeyboardDisplay combinations 8388334d3d8SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 8398334d3d8SMatthias Ringwald static const stk_generation_method_t stk_generation_method_with_secure_connection[5][5] = { 8408334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, PK_INIT_INPUT, JUST_WORKS, PK_INIT_INPUT }, 8418334d3d8SMatthias Ringwald { JUST_WORKS, NUMERIC_COMPARISON, PK_INIT_INPUT, JUST_WORKS, NUMERIC_COMPARISON }, 8428334d3d8SMatthias Ringwald { PK_RESP_INPUT, PK_RESP_INPUT, PK_BOTH_INPUT, JUST_WORKS, PK_RESP_INPUT }, 8438334d3d8SMatthias Ringwald { JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS }, 8448334d3d8SMatthias Ringwald { PK_RESP_INPUT, NUMERIC_COMPARISON, PK_INIT_INPUT, JUST_WORKS, NUMERIC_COMPARISON }, 8458334d3d8SMatthias Ringwald }; 8468334d3d8SMatthias Ringwald #endif 8478334d3d8SMatthias Ringwald 8483deb3ec6SMatthias Ringwald // default: just works 8493deb3ec6SMatthias Ringwald setup->sm_stk_generation_method = JUST_WORKS; 8503deb3ec6SMatthias Ringwald 85127c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 85227c32905SMatthias Ringwald setup->sm_use_secure_connections = ( sm_pairing_packet_get_auth_req(setup->sm_m_preq) 85327c32905SMatthias Ringwald & sm_pairing_packet_get_auth_req(setup->sm_s_pres) 8544ea43905SMatthias Ringwald & SM_AUTHREQ_SECURE_CONNECTION ) != 0u; 85527c32905SMatthias Ringwald #else 85627c32905SMatthias Ringwald setup->sm_use_secure_connections = 0; 85727c32905SMatthias Ringwald #endif 85898d95509SMatthias Ringwald log_info("Secure pairing: %u", setup->sm_use_secure_connections); 85927c32905SMatthias Ringwald 86065a9a04eSMatthias Ringwald 86165a9a04eSMatthias Ringwald // decide if OOB will be used based on SC vs. Legacy and oob flags 8621979f09cSMatthias Ringwald bool use_oob; 86365a9a04eSMatthias Ringwald if (setup->sm_use_secure_connections){ 86465a9a04eSMatthias Ringwald // In LE Secure Connections pairing, the out of band method is used if at least 86565a9a04eSMatthias Ringwald // one device has the peer device's out of band authentication data available. 8661979f09cSMatthias Ringwald use_oob = (sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq) | sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres)) != 0; 86765a9a04eSMatthias Ringwald } else { 86865a9a04eSMatthias Ringwald // In LE legacy pairing, the out of band method is used if both the devices have 86965a9a04eSMatthias Ringwald // the other device's out of band authentication data available. 8701979f09cSMatthias Ringwald use_oob = (sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq) & sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres)) != 0; 87165a9a04eSMatthias Ringwald } 87265a9a04eSMatthias Ringwald if (use_oob){ 87365a9a04eSMatthias Ringwald log_info("SM: have OOB data"); 87465a9a04eSMatthias Ringwald log_info_key("OOB", setup->sm_tk); 87565a9a04eSMatthias Ringwald setup->sm_stk_generation_method = OOB; 87665a9a04eSMatthias Ringwald return; 87765a9a04eSMatthias Ringwald } 87865a9a04eSMatthias Ringwald 87927c32905SMatthias Ringwald // If both devices have not set the MITM option in the Authentication Requirements 88027c32905SMatthias Ringwald // Flags, then the IO capabilities shall be ignored and the Just Works association 88127c32905SMatthias Ringwald // model shall be used. 8824ea43905SMatthias Ringwald if (((sm_pairing_packet_get_auth_req(setup->sm_m_preq) & SM_AUTHREQ_MITM_PROTECTION) == 0u) 8834ea43905SMatthias Ringwald && ((sm_pairing_packet_get_auth_req(setup->sm_s_pres) & SM_AUTHREQ_MITM_PROTECTION) == 0u)){ 88427c32905SMatthias Ringwald log_info("SM: MITM not required by both -> JUST WORKS"); 88527c32905SMatthias Ringwald return; 88627c32905SMatthias Ringwald } 88727c32905SMatthias Ringwald 8883deb3ec6SMatthias Ringwald // Reset TK as it has been setup in sm_init_setup 8893deb3ec6SMatthias Ringwald sm_reset_tk(); 8903deb3ec6SMatthias Ringwald 8913deb3ec6SMatthias Ringwald // Also use just works if unknown io capabilites 8928da2e96dSMatthias Ringwald if ((sm_pairing_packet_get_io_capability(setup->sm_m_preq) > IO_CAPABILITY_KEYBOARD_DISPLAY) || (sm_pairing_packet_get_io_capability(setup->sm_s_pres) > IO_CAPABILITY_KEYBOARD_DISPLAY)){ 8933deb3ec6SMatthias Ringwald return; 8943deb3ec6SMatthias Ringwald } 8953deb3ec6SMatthias Ringwald 8963deb3ec6SMatthias Ringwald // Otherwise the IO capabilities of the devices shall be used to determine the 8973deb3ec6SMatthias Ringwald // pairing method as defined in Table 2.4. 89827c32905SMatthias Ringwald // see http://stackoverflow.com/a/1052837/393697 for how to specify pointer to 2-dimensional array 89927c32905SMatthias Ringwald const stk_generation_method_t (*generation_method)[5] = stk_generation_method; 90027c32905SMatthias Ringwald 90127c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 902c6b7cbd9SMatthias Ringwald // table not define by default 90327c32905SMatthias Ringwald if (setup->sm_use_secure_connections){ 90427c32905SMatthias Ringwald generation_method = stk_generation_method_with_secure_connection; 90527c32905SMatthias Ringwald } 90627c32905SMatthias Ringwald #endif 90727c32905SMatthias Ringwald setup->sm_stk_generation_method = generation_method[sm_pairing_packet_get_io_capability(setup->sm_s_pres)][sm_pairing_packet_get_io_capability(setup->sm_m_preq)]; 90827c32905SMatthias Ringwald 9093deb3ec6SMatthias Ringwald log_info("sm_setup_tk: master io cap: %u, slave io cap: %u -> method %u", 9101ad129beSMatthias Ringwald sm_pairing_packet_get_io_capability(setup->sm_m_preq), sm_pairing_packet_get_io_capability(setup->sm_s_pres), setup->sm_stk_generation_method); 9113deb3ec6SMatthias Ringwald } 9123deb3ec6SMatthias Ringwald 9133deb3ec6SMatthias Ringwald static int sm_key_distribution_flags_for_set(uint8_t key_set){ 9143deb3ec6SMatthias Ringwald int flags = 0; 9153deb3ec6SMatthias Ringwald if (key_set & SM_KEYDIST_ENC_KEY){ 9163deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 9173deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 9183deb3ec6SMatthias Ringwald } 9193deb3ec6SMatthias Ringwald if (key_set & SM_KEYDIST_ID_KEY){ 9203deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 9213deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 9223deb3ec6SMatthias Ringwald } 9233deb3ec6SMatthias Ringwald if (key_set & SM_KEYDIST_SIGN){ 9243deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 9253deb3ec6SMatthias Ringwald } 9263deb3ec6SMatthias Ringwald return flags; 9273deb3ec6SMatthias Ringwald } 9283deb3ec6SMatthias Ringwald 9299a90d41aSMatthias Ringwald static void sm_setup_key_distribution(uint8_t keys_to_send, uint8_t keys_to_receive){ 9303deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set = 0; 9319a90d41aSMatthias Ringwald setup->sm_key_distribution_expected_set = sm_key_distribution_flags_for_set(keys_to_receive); 9329a90d41aSMatthias Ringwald setup->sm_key_distribution_send_set = sm_key_distribution_flags_for_set(keys_to_send); 933715a43d1SMatthias Ringwald setup->sm_key_distribution_sent_set = 0; 9349790be5fSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 935715a43d1SMatthias Ringwald setup->sm_le_device_index = -1; 9369790be5fSMatthias Ringwald #endif 9373deb3ec6SMatthias Ringwald } 9383deb3ec6SMatthias Ringwald 9393deb3ec6SMatthias Ringwald // CSRK Key Lookup 9403deb3ec6SMatthias Ringwald 9413deb3ec6SMatthias Ringwald 9423deb3ec6SMatthias Ringwald static int sm_address_resolution_idle(void){ 9433deb3ec6SMatthias Ringwald return sm_address_resolution_mode == ADDRESS_RESOLUTION_IDLE; 9443deb3ec6SMatthias Ringwald } 9453deb3ec6SMatthias Ringwald 946711e6c80SMatthias Ringwald static void sm_address_resolution_start_lookup(uint8_t addr_type, hci_con_handle_t con_handle, bd_addr_t addr, address_resolution_mode_t mode, void * context){ 9476535961aSMatthias Ringwald (void)memcpy(sm_address_resolution_address, addr, 6); 9483deb3ec6SMatthias Ringwald sm_address_resolution_addr_type = addr_type; 9493deb3ec6SMatthias Ringwald sm_address_resolution_test = 0; 9503deb3ec6SMatthias Ringwald sm_address_resolution_mode = mode; 9513deb3ec6SMatthias Ringwald sm_address_resolution_context = context; 952711e6c80SMatthias Ringwald sm_notify_client_base(SM_EVENT_IDENTITY_RESOLVING_STARTED, con_handle, addr_type, addr); 9533deb3ec6SMatthias Ringwald } 9543deb3ec6SMatthias Ringwald 9553deb3ec6SMatthias Ringwald int sm_address_resolution_lookup(uint8_t address_type, bd_addr_t address){ 9563deb3ec6SMatthias Ringwald // check if already in list 957665d90f2SMatthias Ringwald btstack_linked_list_iterator_t it; 9583deb3ec6SMatthias Ringwald sm_lookup_entry_t * entry; 959665d90f2SMatthias Ringwald btstack_linked_list_iterator_init(&it, &sm_address_resolution_general_queue); 960665d90f2SMatthias Ringwald while(btstack_linked_list_iterator_has_next(&it)){ 961665d90f2SMatthias Ringwald entry = (sm_lookup_entry_t *) btstack_linked_list_iterator_next(&it); 9623deb3ec6SMatthias Ringwald if (entry->address_type != address_type) continue; 9633deb3ec6SMatthias Ringwald if (memcmp(entry->address, address, 6)) continue; 9643deb3ec6SMatthias Ringwald // already in list 9653deb3ec6SMatthias Ringwald return BTSTACK_BUSY; 9663deb3ec6SMatthias Ringwald } 9673deb3ec6SMatthias Ringwald entry = btstack_memory_sm_lookup_entry_get(); 9683deb3ec6SMatthias Ringwald if (!entry) return BTSTACK_MEMORY_ALLOC_FAILED; 9693deb3ec6SMatthias Ringwald entry->address_type = (bd_addr_type_t) address_type; 9706535961aSMatthias Ringwald (void)memcpy(entry->address, address, 6); 971665d90f2SMatthias Ringwald btstack_linked_list_add(&sm_address_resolution_general_queue, (btstack_linked_item_t *) entry); 97270b44dd4SMatthias Ringwald sm_trigger_run(); 9733deb3ec6SMatthias Ringwald return 0; 9743deb3ec6SMatthias Ringwald } 9753deb3ec6SMatthias Ringwald 976d1a1f6a4SMatthias Ringwald // CMAC calculation using AES Engineq 977d1a1f6a4SMatthias Ringwald #ifdef USE_CMAC_ENGINE 978514d35fcSMatthias Ringwald 979d1a1f6a4SMatthias Ringwald static void sm_cmac_done_trampoline(void * arg){ 980d1a1f6a4SMatthias Ringwald UNUSED(arg); 981d1a1f6a4SMatthias Ringwald sm_cmac_active = 0; 982d1a1f6a4SMatthias Ringwald (*sm_cmac_done_callback)(sm_cmac_hash); 98370b44dd4SMatthias Ringwald sm_trigger_run(); 9843deb3ec6SMatthias Ringwald } 985514d35fcSMatthias Ringwald 9864dfd504aSMatthias Ringwald int sm_cmac_ready(void){ 9874ea43905SMatthias Ringwald return sm_cmac_active == 0u; 9883deb3ec6SMatthias Ringwald } 9896d80b495SMatthias Ringwald #endif 9903deb3ec6SMatthias Ringwald 9916d80b495SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 992514d35fcSMatthias Ringwald // generic cmac calculation 993d1a1f6a4SMatthias Ringwald static void sm_cmac_message_start(const sm_key_t key, uint16_t message_len, const uint8_t * message, void (*done_callback)(uint8_t * hash)){ 994d1a1f6a4SMatthias Ringwald sm_cmac_active = 1; 995d1a1f6a4SMatthias Ringwald sm_cmac_done_callback = done_callback; 996d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_cmac_message(&sm_cmac_request, key, message_len, message, sm_cmac_hash, sm_cmac_done_trampoline, NULL); 9973deb3ec6SMatthias Ringwald } 9987a766ebfSMatthias Ringwald #endif 9993deb3ec6SMatthias Ringwald 1000514d35fcSMatthias Ringwald // cmac for ATT Message signing 10017a766ebfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 1002d1a1f6a4SMatthias Ringwald 1003d1a1f6a4SMatthias Ringwald static void sm_cmac_generator_start(const sm_key_t key, uint16_t message_len, uint8_t (*get_byte_callback)(uint16_t offset), void (*done_callback)(uint8_t * hash)){ 1004d1a1f6a4SMatthias Ringwald sm_cmac_active = 1; 1005d1a1f6a4SMatthias Ringwald sm_cmac_done_callback = done_callback; 1006d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_cmac_generator(&sm_cmac_request, key, message_len, get_byte_callback, sm_cmac_hash, sm_cmac_done_trampoline, NULL); 1007d1a1f6a4SMatthias Ringwald } 1008d1a1f6a4SMatthias Ringwald 10094dfd504aSMatthias Ringwald static uint8_t sm_cmac_signed_write_message_get_byte(uint16_t offset){ 1010d1a1f6a4SMatthias Ringwald if (offset >= sm_cmac_signed_write_message_len) { 1011d1a1f6a4SMatthias Ringwald log_error("sm_cmac_signed_write_message_get_byte. out of bounds, access %u, len %u", offset, sm_cmac_signed_write_message_len); 10124dfd504aSMatthias Ringwald return 0; 10134dfd504aSMatthias Ringwald } 10144dfd504aSMatthias Ringwald 1015d1a1f6a4SMatthias Ringwald offset = sm_cmac_signed_write_message_len - 1 - offset; 10164dfd504aSMatthias Ringwald 1017d1a1f6a4SMatthias Ringwald // sm_cmac_signed_write_header[3] | message[] | sm_cmac_signed_write_sign_counter[4] 10184dfd504aSMatthias Ringwald if (offset < 3){ 1019d1a1f6a4SMatthias Ringwald return sm_cmac_signed_write_header[offset]; 10204dfd504aSMatthias Ringwald } 1021d1a1f6a4SMatthias Ringwald int actual_message_len_incl_header = sm_cmac_signed_write_message_len - 4; 10224dfd504aSMatthias Ringwald if (offset < actual_message_len_incl_header){ 1023d1a1f6a4SMatthias Ringwald return sm_cmac_signed_write_message[offset - 3]; 10244dfd504aSMatthias Ringwald } 1025d1a1f6a4SMatthias Ringwald return sm_cmac_signed_write_sign_counter[offset - actual_message_len_incl_header]; 10264dfd504aSMatthias Ringwald } 10274dfd504aSMatthias Ringwald 10284dfd504aSMatthias Ringwald void sm_cmac_signed_write_start(const sm_key_t k, uint8_t opcode, hci_con_handle_t con_handle, uint16_t message_len, const uint8_t * message, uint32_t sign_counter, void (*done_handler)(uint8_t * hash)){ 1029514d35fcSMatthias Ringwald // ATT Message Signing 1030d1a1f6a4SMatthias Ringwald sm_cmac_signed_write_header[0] = opcode; 1031d1a1f6a4SMatthias Ringwald little_endian_store_16(sm_cmac_signed_write_header, 1, con_handle); 1032d1a1f6a4SMatthias Ringwald little_endian_store_32(sm_cmac_signed_write_sign_counter, 0, sign_counter); 1033514d35fcSMatthias Ringwald uint16_t total_message_len = 3 + message_len + 4; // incl. virtually prepended att opcode, handle and appended sign_counter in LE 1034d1a1f6a4SMatthias Ringwald sm_cmac_signed_write_message = message; 1035d1a1f6a4SMatthias Ringwald sm_cmac_signed_write_message_len = total_message_len; 1036d1a1f6a4SMatthias Ringwald sm_cmac_generator_start(k, total_message_len, &sm_cmac_signed_write_message_get_byte, done_handler); 10373deb3ec6SMatthias Ringwald } 10387a766ebfSMatthias Ringwald #endif 10393deb3ec6SMatthias Ringwald 1040ea9b6796SMatthias Ringwald static void sm_trigger_user_response_basic(sm_connection_t * sm_conn, uint8_t event_type){ 1041ea9b6796SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_PENDING; 10425baa755bSMatthias Ringwald uint8_t event[12]; 1043f6a153d5SMatthias Ringwald sm_setup_event_base(event, sizeof(event), event_type, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address); 10445baa755bSMatthias Ringwald event[11] = setup->sm_use_secure_connections ? 1 : 0; 1045f6a153d5SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, event, sizeof(event)); 1046ea9b6796SMatthias Ringwald } 1047ea9b6796SMatthias Ringwald 104874b4d42aSMatthias Ringwald static void sm_trigger_user_response_passkey(sm_connection_t * sm_conn, uint8_t event_type){ 10495baa755bSMatthias Ringwald uint8_t event[16]; 1050f6a153d5SMatthias Ringwald uint32_t passkey = big_endian_read_32(setup->sm_tk, 12); 105174b4d42aSMatthias Ringwald sm_setup_event_base(event, sizeof(event), event_type, sm_conn->sm_handle, 1052f6a153d5SMatthias Ringwald sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address); 10535baa755bSMatthias Ringwald event[11] = setup->sm_use_secure_connections ? 1 : 0; 10545baa755bSMatthias Ringwald little_endian_store_32(event, 12, passkey); 1055f6a153d5SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, event, sizeof(event)); 1056ea9b6796SMatthias Ringwald } 1057ea9b6796SMatthias Ringwald 10583deb3ec6SMatthias Ringwald static void sm_trigger_user_response(sm_connection_t * sm_conn){ 1059446a8c36SMatthias Ringwald // notify client for: JUST WORKS confirm, Numeric comparison confirm, PASSKEY display or input 10603deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_IDLE; 1061d77906ffSMatthias Ringwald sm_conn->sm_pairing_active = true; 10623deb3ec6SMatthias Ringwald switch (setup->sm_stk_generation_method){ 10633deb3ec6SMatthias Ringwald case PK_RESP_INPUT: 106442134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1065ea9b6796SMatthias Ringwald sm_trigger_user_response_basic(sm_conn, SM_EVENT_PASSKEY_INPUT_NUMBER); 10663deb3ec6SMatthias Ringwald } else { 106774b4d42aSMatthias Ringwald sm_trigger_user_response_passkey(sm_conn, SM_EVENT_PASSKEY_DISPLAY_NUMBER); 10683deb3ec6SMatthias Ringwald } 10693deb3ec6SMatthias Ringwald break; 10703deb3ec6SMatthias Ringwald case PK_INIT_INPUT: 107142134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 107274b4d42aSMatthias Ringwald sm_trigger_user_response_passkey(sm_conn, SM_EVENT_PASSKEY_DISPLAY_NUMBER); 10733deb3ec6SMatthias Ringwald } else { 1074ea9b6796SMatthias Ringwald sm_trigger_user_response_basic(sm_conn, SM_EVENT_PASSKEY_INPUT_NUMBER); 10753deb3ec6SMatthias Ringwald } 10763deb3ec6SMatthias Ringwald break; 107747fb4255SMatthias Ringwald case PK_BOTH_INPUT: 1078ea9b6796SMatthias Ringwald sm_trigger_user_response_basic(sm_conn, SM_EVENT_PASSKEY_INPUT_NUMBER); 10793deb3ec6SMatthias Ringwald break; 108047fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 108174b4d42aSMatthias Ringwald sm_trigger_user_response_passkey(sm_conn, SM_EVENT_NUMERIC_COMPARISON_REQUEST); 108227c32905SMatthias Ringwald break; 10833deb3ec6SMatthias Ringwald case JUST_WORKS: 1084ea9b6796SMatthias Ringwald sm_trigger_user_response_basic(sm_conn, SM_EVENT_JUST_WORKS_REQUEST); 10853deb3ec6SMatthias Ringwald break; 10863deb3ec6SMatthias Ringwald case OOB: 10873deb3ec6SMatthias Ringwald // client already provided OOB data, let's skip notification. 10883deb3ec6SMatthias Ringwald break; 10897bbeb3adSMilanka Ringwald default: 10907bbeb3adSMilanka Ringwald btstack_assert(false); 10917bbeb3adSMilanka Ringwald break; 10923deb3ec6SMatthias Ringwald } 10933deb3ec6SMatthias Ringwald } 10943deb3ec6SMatthias Ringwald 109561d1a45eSMatthias Ringwald static bool sm_key_distribution_all_received(void) { 10965fa700b1SMatthias Ringwald log_debug("sm_key_distribution_all_received: received 0x%02x, expecting 0x%02x", setup->sm_key_distribution_received_set, setup->sm_key_distribution_expected_set); 1097b2296177SMatthias Ringwald return (setup->sm_key_distribution_expected_set & setup->sm_key_distribution_received_set) == setup->sm_key_distribution_expected_set; 10983deb3ec6SMatthias Ringwald } 10993deb3ec6SMatthias Ringwald 1100711e6c80SMatthias Ringwald static void sm_done_for_handle(hci_con_handle_t con_handle){ 11017149bde5SMatthias Ringwald if (sm_active_connection_handle == con_handle){ 11023deb3ec6SMatthias Ringwald sm_timeout_stop(); 11037149bde5SMatthias Ringwald sm_active_connection_handle = HCI_CON_HANDLE_INVALID; 1104711e6c80SMatthias Ringwald log_info("sm: connection 0x%x released setup context", con_handle); 1105c085d9ffSMatthias Ringwald 1106c085d9ffSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 1107c085d9ffSMatthias Ringwald // generate new ec key after each pairing (that used it) 1108c085d9ffSMatthias Ringwald if (setup->sm_use_secure_connections){ 1109c085d9ffSMatthias Ringwald sm_ec_generate_new_key(); 1110c085d9ffSMatthias Ringwald } 1111c085d9ffSMatthias Ringwald #endif 11123deb3ec6SMatthias Ringwald } 11133deb3ec6SMatthias Ringwald } 11143deb3ec6SMatthias Ringwald 11157d1c0c3aSMatthias Ringwald static void sm_master_pairing_success(sm_connection_t *connection) {// master -> all done 11161dca9d8aSMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_CONNECTED; 11170ccf6c9cSMatthias Ringwald sm_pairing_complete(connection, ERROR_CODE_SUCCESS, 0); 11181dca9d8aSMatthias Ringwald sm_done_for_handle(connection->sm_handle); 11191dca9d8aSMatthias Ringwald } 11201dca9d8aSMatthias Ringwald 11213deb3ec6SMatthias Ringwald static int sm_key_distribution_flags_for_auth_req(void){ 1122bb09604fSMatthias Ringwald 1123bb09604fSMatthias Ringwald int flags = SM_KEYDIST_ID_KEY; 11243deb3ec6SMatthias Ringwald if (sm_auth_req & SM_AUTHREQ_BONDING){ 1125bb09604fSMatthias Ringwald // encryption and signing information only if bonding requested 11263deb3ec6SMatthias Ringwald flags |= SM_KEYDIST_ENC_KEY; 1127bb09604fSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 1128bb09604fSMatthias Ringwald flags |= SM_KEYDIST_SIGN; 1129bb09604fSMatthias Ringwald #endif 11307ece0eaaSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 11317ece0eaaSMatthias Ringwald // LinkKey for CTKD requires SC 11327ece0eaaSMatthias Ringwald if (sm_auth_req & SM_AUTHREQ_SECURE_CONNECTION){ 11337ece0eaaSMatthias Ringwald flags |= SM_KEYDIST_LINK_KEY; 11347ece0eaaSMatthias Ringwald } 11357ece0eaaSMatthias Ringwald #endif 11363deb3ec6SMatthias Ringwald } 11373deb3ec6SMatthias Ringwald return flags; 11383deb3ec6SMatthias Ringwald } 11393deb3ec6SMatthias Ringwald 1140d7471931SMatthias Ringwald static void sm_reset_setup(void){ 11413deb3ec6SMatthias Ringwald // fill in sm setup 1142901c000fSMatthias Ringwald setup->sm_state_vars = 0; 1143dd4a08fbSMatthias Ringwald setup->sm_keypress_notification = 0; 1144d0ea782aSMatthias Ringwald setup->sm_have_oob_data = 0; 11453deb3ec6SMatthias Ringwald sm_reset_tk(); 1146d7471931SMatthias Ringwald } 1147d7471931SMatthias Ringwald 1148d7471931SMatthias Ringwald static void sm_init_setup(sm_connection_t * sm_conn){ 1149d7471931SMatthias Ringwald // fill in sm setup 11503deb3ec6SMatthias Ringwald setup->sm_peer_addr_type = sm_conn->sm_peer_addr_type; 11516535961aSMatthias Ringwald (void)memcpy(setup->sm_peer_address, sm_conn->sm_peer_address, 6); 11523deb3ec6SMatthias Ringwald 1153a680ba6bSMatthias Ringwald // query client for Legacy Pairing OOB data 11549305033eSMatthias Ringwald if (sm_get_oob_data != NULL) { 1155a680ba6bSMatthias Ringwald setup->sm_have_oob_data = (*sm_get_oob_data)(sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address, setup->sm_tk); 11563deb3ec6SMatthias Ringwald } 11573deb3ec6SMatthias Ringwald 1158a680ba6bSMatthias Ringwald // if available and SC supported, also ask for SC OOB Data 1159a680ba6bSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 11604acf7b7bSMatthias Ringwald memset(setup->sm_ra, 0, 16); 11614acf7b7bSMatthias Ringwald memset(setup->sm_rb, 0, 16); 1162a680ba6bSMatthias Ringwald if (setup->sm_have_oob_data && (sm_auth_req & SM_AUTHREQ_SECURE_CONNECTION)){ 11639305033eSMatthias Ringwald if (sm_get_sc_oob_data != NULL){ 11644acf7b7bSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1165a680ba6bSMatthias Ringwald setup->sm_have_oob_data = (*sm_get_sc_oob_data)( 1166a680ba6bSMatthias Ringwald sm_conn->sm_peer_addr_type, 1167a680ba6bSMatthias Ringwald sm_conn->sm_peer_address, 1168a680ba6bSMatthias Ringwald setup->sm_peer_confirm, 11694acf7b7bSMatthias Ringwald setup->sm_ra); 11704acf7b7bSMatthias Ringwald } else { 11714acf7b7bSMatthias Ringwald setup->sm_have_oob_data = (*sm_get_sc_oob_data)( 11724acf7b7bSMatthias Ringwald sm_conn->sm_peer_addr_type, 11734acf7b7bSMatthias Ringwald sm_conn->sm_peer_address, 11744acf7b7bSMatthias Ringwald setup->sm_peer_confirm, 11754acf7b7bSMatthias Ringwald setup->sm_rb); 11764acf7b7bSMatthias Ringwald } 1177a680ba6bSMatthias Ringwald } else { 1178a680ba6bSMatthias Ringwald setup->sm_have_oob_data = 0; 1179a680ba6bSMatthias Ringwald } 1180a680ba6bSMatthias Ringwald } 1181a680ba6bSMatthias Ringwald #endif 1182a680ba6bSMatthias Ringwald 11833deb3ec6SMatthias Ringwald sm_pairing_packet_t * local_packet; 118442134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 11853deb3ec6SMatthias Ringwald // slave 11863deb3ec6SMatthias Ringwald local_packet = &setup->sm_s_pres; 11873deb3ec6SMatthias Ringwald setup->sm_m_addr_type = sm_conn->sm_peer_addr_type; 1188d5314cbeSMatthias Ringwald setup->sm_s_addr_type = sm_conn->sm_own_addr_type; 11896535961aSMatthias Ringwald (void)memcpy(setup->sm_m_address, sm_conn->sm_peer_address, 6); 1190d5314cbeSMatthias Ringwald (void)memcpy(setup->sm_s_address, sm_conn->sm_own_address, 6); 11913deb3ec6SMatthias Ringwald } else { 11923deb3ec6SMatthias Ringwald // master 11933deb3ec6SMatthias Ringwald local_packet = &setup->sm_m_preq; 11943deb3ec6SMatthias Ringwald setup->sm_s_addr_type = sm_conn->sm_peer_addr_type; 1195d5314cbeSMatthias Ringwald setup->sm_m_addr_type = sm_conn->sm_own_addr_type; 11966535961aSMatthias Ringwald (void)memcpy(setup->sm_s_address, sm_conn->sm_peer_address, 6); 1197d5314cbeSMatthias Ringwald (void)memcpy(setup->sm_m_address, sm_conn->sm_own_address, 6); 11983deb3ec6SMatthias Ringwald 1199d0ea782aSMatthias Ringwald uint8_t key_distribution_flags = sm_key_distribution_flags_for_auth_req(); 12001ad129beSMatthias Ringwald sm_pairing_packet_set_initiator_key_distribution(setup->sm_m_preq, key_distribution_flags); 12011ad129beSMatthias Ringwald sm_pairing_packet_set_responder_key_distribution(setup->sm_m_preq, key_distribution_flags); 12023deb3ec6SMatthias Ringwald } 12033deb3ec6SMatthias Ringwald 120457132f12SMatthias Ringwald uint8_t auth_req = sm_auth_req & ~SM_AUTHREQ_CT2; 1205d0ea782aSMatthias Ringwald uint8_t max_encryption_key_size = sm_max_encryption_key_size; 12062c041b42SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 12072c041b42SMatthias Ringwald // enable SC for SC only mode 12082c041b42SMatthias Ringwald if (sm_sc_only_mode){ 12092c041b42SMatthias Ringwald auth_req |= SM_AUTHREQ_SECURE_CONNECTION; 1210d0ea782aSMatthias Ringwald max_encryption_key_size = 16; 12112c041b42SMatthias Ringwald } 12122c041b42SMatthias Ringwald #endif 121357132f12SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 121457132f12SMatthias Ringwald // set CT2 if SC + Bonding + CTKD 121557132f12SMatthias Ringwald const uint8_t auth_req_for_ct2 = SM_AUTHREQ_SECURE_CONNECTION | SM_AUTHREQ_BONDING; 121657132f12SMatthias Ringwald if ((auth_req & auth_req_for_ct2) == auth_req_for_ct2){ 121757132f12SMatthias Ringwald auth_req |= SM_AUTHREQ_CT2; 121857132f12SMatthias Ringwald } 121957132f12SMatthias Ringwald #endif 12201ad129beSMatthias Ringwald sm_pairing_packet_set_io_capability(*local_packet, sm_io_capabilities); 1221a680ba6bSMatthias Ringwald sm_pairing_packet_set_oob_data_flag(*local_packet, setup->sm_have_oob_data); 1222df86eb96SMatthias Ringwald sm_pairing_packet_set_auth_req(*local_packet, auth_req); 1223d0ea782aSMatthias Ringwald sm_pairing_packet_set_max_encryption_key_size(*local_packet, max_encryption_key_size); 12243deb3ec6SMatthias Ringwald } 12253deb3ec6SMatthias Ringwald 12263deb3ec6SMatthias Ringwald static int sm_stk_generation_init(sm_connection_t * sm_conn){ 12273deb3ec6SMatthias Ringwald 12283deb3ec6SMatthias Ringwald sm_pairing_packet_t * remote_packet; 12299a90d41aSMatthias Ringwald uint8_t keys_to_send; 12309a90d41aSMatthias Ringwald uint8_t keys_to_receive; 123142134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 123252f9cf63SMatthias Ringwald // slave / responder 12333deb3ec6SMatthias Ringwald remote_packet = &setup->sm_m_preq; 12349a90d41aSMatthias Ringwald keys_to_send = sm_pairing_packet_get_responder_key_distribution(setup->sm_m_preq); 12359a90d41aSMatthias Ringwald keys_to_receive = sm_pairing_packet_get_initiator_key_distribution(setup->sm_m_preq); 12363deb3ec6SMatthias Ringwald } else { 12373deb3ec6SMatthias Ringwald // master / initiator 12383deb3ec6SMatthias Ringwald remote_packet = &setup->sm_s_pres; 12399a90d41aSMatthias Ringwald keys_to_send = sm_pairing_packet_get_initiator_key_distribution(setup->sm_s_pres); 12409a90d41aSMatthias Ringwald keys_to_receive = sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres); 12413deb3ec6SMatthias Ringwald } 12423deb3ec6SMatthias Ringwald 12433deb3ec6SMatthias Ringwald // check key size 12442c041b42SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 12452c041b42SMatthias Ringwald // SC Only mandates 128 bit key size 12462c041b42SMatthias Ringwald if (sm_sc_only_mode && (sm_pairing_packet_get_max_encryption_key_size(*remote_packet) < 16)) { 12472c041b42SMatthias Ringwald return SM_REASON_ENCRYPTION_KEY_SIZE; 12482c041b42SMatthias Ringwald } 12492c041b42SMatthias Ringwald #endif 12501ad129beSMatthias Ringwald sm_conn->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(sm_pairing_packet_get_max_encryption_key_size(*remote_packet)); 12514ea43905SMatthias Ringwald if (sm_conn->sm_actual_encryption_key_size == 0u) return SM_REASON_ENCRYPTION_KEY_SIZE; 12523deb3ec6SMatthias Ringwald 1253eddc894fSMatthias Ringwald // decide on STK generation method / SC 12543deb3ec6SMatthias Ringwald sm_setup_tk(); 12553deb3ec6SMatthias Ringwald log_info("SMP: generation method %u", setup->sm_stk_generation_method); 12563deb3ec6SMatthias Ringwald 12573deb3ec6SMatthias Ringwald // check if STK generation method is acceptable by client 12583deb3ec6SMatthias Ringwald if (!sm_validate_stk_generation_method()) return SM_REASON_AUTHENTHICATION_REQUIREMENTS; 12593deb3ec6SMatthias Ringwald 1260eddc894fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 12612c041b42SMatthias Ringwald // Check LE SC Only mode 12623cdbe9dbSMatthias Ringwald if (sm_sc_only_mode && (setup->sm_use_secure_connections == false)){ 12633cdbe9dbSMatthias Ringwald log_info("SC Only mode active but SC not possible"); 12643cdbe9dbSMatthias Ringwald return SM_REASON_AUTHENTHICATION_REQUIREMENTS; 12653cdbe9dbSMatthias Ringwald } 12663cdbe9dbSMatthias Ringwald 12679a90d41aSMatthias Ringwald // LTK (= encryption information & master identification) only used exchanged for LE Legacy Connection 1268eddc894fSMatthias Ringwald if (setup->sm_use_secure_connections){ 12699a90d41aSMatthias Ringwald keys_to_send &= ~SM_KEYDIST_ENC_KEY; 12709a90d41aSMatthias Ringwald keys_to_receive &= ~SM_KEYDIST_ENC_KEY; 1271eddc894fSMatthias Ringwald } 1272eddc894fSMatthias Ringwald #endif 1273eddc894fSMatthias Ringwald 127452f9cf63SMatthias Ringwald // identical to responder 12759a90d41aSMatthias Ringwald sm_setup_key_distribution(keys_to_send, keys_to_receive); 127652f9cf63SMatthias Ringwald 12773deb3ec6SMatthias Ringwald // JUST WORKS doens't provide authentication 1278c1ab6cc1SMatthias Ringwald sm_conn->sm_connection_authenticated = (setup->sm_stk_generation_method == JUST_WORKS) ? 0 : 1; 12793deb3ec6SMatthias Ringwald 12803deb3ec6SMatthias Ringwald return 0; 12813deb3ec6SMatthias Ringwald } 12823deb3ec6SMatthias Ringwald 12833deb3ec6SMatthias Ringwald static void sm_address_resolution_handle_event(address_resolution_event_t event){ 12843deb3ec6SMatthias Ringwald 12853deb3ec6SMatthias Ringwald // cache and reset context 12863deb3ec6SMatthias Ringwald int matched_device_id = sm_address_resolution_test; 12873deb3ec6SMatthias Ringwald address_resolution_mode_t mode = sm_address_resolution_mode; 12883deb3ec6SMatthias Ringwald void * context = sm_address_resolution_context; 12893deb3ec6SMatthias Ringwald 12903deb3ec6SMatthias Ringwald // reset context 12913deb3ec6SMatthias Ringwald sm_address_resolution_mode = ADDRESS_RESOLUTION_IDLE; 12923deb3ec6SMatthias Ringwald sm_address_resolution_context = NULL; 12933deb3ec6SMatthias Ringwald sm_address_resolution_test = -1; 1294711e6c80SMatthias Ringwald hci_con_handle_t con_handle = 0; 12953deb3ec6SMatthias Ringwald 12963deb3ec6SMatthias Ringwald sm_connection_t * sm_connection; 1297d2e90122SMatthias Ringwald sm_key_t ltk; 12981979f09cSMatthias Ringwald bool have_ltk; 12996c44b759SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 13001979f09cSMatthias Ringwald bool trigger_pairing; 13012d68601cSMatthias Ringwald int authenticated; 130242134bc6SMatthias Ringwald #endif 13033deb3ec6SMatthias Ringwald switch (mode){ 13043deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_GENERAL: 13053deb3ec6SMatthias Ringwald break; 13063deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_FOR_CONNECTION: 13073deb3ec6SMatthias Ringwald sm_connection = (sm_connection_t *) context; 1308711e6c80SMatthias Ringwald con_handle = sm_connection->sm_handle; 13096c44b759SMatthias Ringwald 13106c44b759SMatthias Ringwald // have ltk -> start encryption / send security request 13116c44b759SMatthias Ringwald // Core 5, Vol 3, Part C, 10.3.2 Initiating a Service Request 13126c44b759SMatthias Ringwald // "When a bond has been created between two devices, any reconnection should result in the local device 13136c44b759SMatthias Ringwald // enabling or requesting encryption with the remote device before initiating any service request." 13146c44b759SMatthias Ringwald 13153deb3ec6SMatthias Ringwald switch (event){ 1316a66b030fSMatthias Ringwald case ADDRESS_RESOLUTION_SUCCEEDED: 13173deb3ec6SMatthias Ringwald sm_connection->sm_irk_lookup_state = IRK_LOOKUP_SUCCEEDED; 13183deb3ec6SMatthias Ringwald sm_connection->sm_le_db_index = matched_device_id; 1319a66b030fSMatthias Ringwald log_info("ADDRESS_RESOLUTION_SUCCEEDED, index %d", sm_connection->sm_le_db_index); 13206c44b759SMatthias Ringwald 13212d68601cSMatthias Ringwald le_device_db_encryption_get(sm_connection->sm_le_db_index, NULL, NULL, ltk, NULL, &authenticated, NULL, NULL); 13226c44b759SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 13236c44b759SMatthias Ringwald 13246c39055aSMatthias Ringwald if (sm_connection->sm_role) { 13256c44b759SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 1326212d735eSMatthias Ringwald // IRK required before, continue 13276c39055aSMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK){ 13286c39055aSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST; 13296c39055aSMatthias Ringwald break; 13306c39055aSMatthias Ringwald } 1331212d735eSMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED_W4_IRK){ 1332212d735eSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED; 1333212d735eSMatthias Ringwald break; 1334212d735eSMatthias Ringwald } 13357af5dcd5SMatthias Ringwald bool trigger_security_request = (sm_connection->sm_pairing_requested != 0) || (sm_slave_request_security != 0); 13367af5dcd5SMatthias Ringwald sm_connection->sm_pairing_requested = 0; 13376c44b759SMatthias Ringwald #ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 13387af5dcd5SMatthias Ringwald // trigger security request for Proactive Authentication if LTK available 13397af5dcd5SMatthias Ringwald trigger_security_request = trigger_security_request || have_ltk; 13406c44b759SMatthias Ringwald #endif 13417af5dcd5SMatthias Ringwald 13427af5dcd5SMatthias Ringwald log_info("peripheral: pairing request local %u, have_ltk %u => trigger_security_request %u", 13431979f09cSMatthias Ringwald sm_connection->sm_pairing_requested, (int) have_ltk, trigger_security_request); 13447af5dcd5SMatthias Ringwald 13457af5dcd5SMatthias Ringwald if (trigger_security_request){ 13467af5dcd5SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 13477af5dcd5SMatthias Ringwald if (have_ltk){ 13487af5dcd5SMatthias Ringwald sm_reencryption_started(sm_connection); 13497af5dcd5SMatthias Ringwald } else { 13507af5dcd5SMatthias Ringwald sm_pairing_started(sm_connection); 13517af5dcd5SMatthias Ringwald } 13527af5dcd5SMatthias Ringwald sm_trigger_run(); 13536c44b759SMatthias Ringwald } 13546c44b759SMatthias Ringwald #endif 13556c44b759SMatthias Ringwald } else { 13566c44b759SMatthias Ringwald 135742134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 13586c44b759SMatthias Ringwald // check if pairing already requested and reset requests 13596c44b759SMatthias Ringwald trigger_pairing = sm_connection->sm_pairing_requested || sm_connection->sm_security_request_received; 13602d68601cSMatthias Ringwald bool auth_required = sm_auth_req & SM_AUTHREQ_MITM_PROTECTION; 13612d68601cSMatthias Ringwald 13626c44b759SMatthias Ringwald log_info("central: pairing request local %u, remote %u => trigger_pairing %u. have_ltk %u", 13631979f09cSMatthias Ringwald sm_connection->sm_pairing_requested, sm_connection->sm_security_request_received, (int) trigger_pairing, (int) have_ltk); 13643deb3ec6SMatthias Ringwald sm_connection->sm_security_request_received = 0; 136509ea1b62SMatthias Ringwald sm_connection->sm_pairing_requested = 0; 136632bc5d65SMatthias Ringwald bool trigger_reencryption = false; 1367c245ca32SMatthias Ringwald 1368d4af1595SMatthias Ringwald if (have_ltk){ 13692d68601cSMatthias Ringwald if (trigger_pairing){ 13702d68601cSMatthias Ringwald // if pairing is requested, re-encryption is sufficient, if ltk is already authenticated or we don't require authentication 13712d68601cSMatthias Ringwald trigger_reencryption = (authenticated != 0) || (auth_required == false); 13722d68601cSMatthias Ringwald } else { 13736a43f611SMatthias Ringwald #ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 1374b187cc61SMatthias Ringwald trigger_reencryption = true; 137532bc5d65SMatthias Ringwald #else 137632bc5d65SMatthias Ringwald log_info("central: defer enabling encryption for bonded device"); 137732bc5d65SMatthias Ringwald #endif 137832bc5d65SMatthias Ringwald } 13792d68601cSMatthias Ringwald } 138032bc5d65SMatthias Ringwald 138132bc5d65SMatthias Ringwald if (trigger_reencryption){ 13826c44b759SMatthias Ringwald log_info("central: enable encryption for bonded device"); 13835567aa60SMatthias Ringwald sm_connection->sm_engine_state = SM_INITIATOR_PH4_HAS_LTK; 1384d4af1595SMatthias Ringwald break; 1385d4af1595SMatthias Ringwald } 13866c44b759SMatthias Ringwald 13876c44b759SMatthias Ringwald // pairing_request -> send pairing request 13886c44b759SMatthias Ringwald if (trigger_pairing){ 13893deb3ec6SMatthias Ringwald sm_connection->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 1390d4af1595SMatthias Ringwald break; 13913deb3ec6SMatthias Ringwald } 139242134bc6SMatthias Ringwald #endif 1393298ab52bSMatthias Ringwald } 13943deb3ec6SMatthias Ringwald break; 13953deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_FAILED: 13963deb3ec6SMatthias Ringwald sm_connection->sm_irk_lookup_state = IRK_LOOKUP_FAILED; 13976c39055aSMatthias Ringwald if (sm_connection->sm_role) { 13987af5dcd5SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 13996c39055aSMatthias Ringwald // LTK request received before, IRK required -> negative LTK reply 14006c39055aSMatthias Ringwald if (sm_connection->sm_engine_state == SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK){ 14016c39055aSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY; 14026c39055aSMatthias Ringwald } 14037af5dcd5SMatthias Ringwald // send security request if requested 14047af5dcd5SMatthias Ringwald bool trigger_security_request = (sm_connection->sm_pairing_requested != 0) || (sm_slave_request_security != 0); 14057af5dcd5SMatthias Ringwald sm_connection->sm_pairing_requested = 0; 14067af5dcd5SMatthias Ringwald if (trigger_security_request){ 14077af5dcd5SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 14087af5dcd5SMatthias Ringwald sm_pairing_started(sm_connection); 14097af5dcd5SMatthias Ringwald } 14106c39055aSMatthias Ringwald break; 14117af5dcd5SMatthias Ringwald #endif 14126c39055aSMatthias Ringwald } 141342134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 141409ea1b62SMatthias Ringwald if (!sm_connection->sm_pairing_requested && !sm_connection->sm_security_request_received) break; 14153deb3ec6SMatthias Ringwald sm_connection->sm_security_request_received = 0; 141609ea1b62SMatthias Ringwald sm_connection->sm_pairing_requested = 0; 14173deb3ec6SMatthias Ringwald sm_connection->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 141842134bc6SMatthias Ringwald #endif 14193deb3ec6SMatthias Ringwald break; 14207bbeb3adSMilanka Ringwald 14217bbeb3adSMilanka Ringwald default: 14227bbeb3adSMilanka Ringwald btstack_assert(false); 14237bbeb3adSMilanka Ringwald break; 14243deb3ec6SMatthias Ringwald } 14253deb3ec6SMatthias Ringwald break; 14263deb3ec6SMatthias Ringwald default: 14273deb3ec6SMatthias Ringwald break; 14283deb3ec6SMatthias Ringwald } 14293deb3ec6SMatthias Ringwald 14303deb3ec6SMatthias Ringwald switch (event){ 1431a66b030fSMatthias Ringwald case ADDRESS_RESOLUTION_SUCCEEDED: 1432711e6c80SMatthias Ringwald sm_notify_client_index(SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED, con_handle, sm_address_resolution_addr_type, sm_address_resolution_address, matched_device_id); 14333deb3ec6SMatthias Ringwald break; 14343deb3ec6SMatthias Ringwald case ADDRESS_RESOLUTION_FAILED: 1435711e6c80SMatthias Ringwald sm_notify_client_base(SM_EVENT_IDENTITY_RESOLVING_FAILED, con_handle, sm_address_resolution_addr_type, sm_address_resolution_address); 14363deb3ec6SMatthias Ringwald break; 14377bbeb3adSMilanka Ringwald default: 14387bbeb3adSMilanka Ringwald btstack_assert(false); 14397bbeb3adSMilanka Ringwald break; 14403deb3ec6SMatthias Ringwald } 14413deb3ec6SMatthias Ringwald } 14423deb3ec6SMatthias Ringwald 144355f09f49SMatthias Ringwald static void sm_store_bonding_information(sm_connection_t * sm_conn){ 14443deb3ec6SMatthias Ringwald int le_db_index = -1; 14453deb3ec6SMatthias Ringwald 14463deb3ec6SMatthias Ringwald // lookup device based on IRK 14473deb3ec6SMatthias Ringwald if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION){ 14483deb3ec6SMatthias Ringwald int i; 1449092ec58eSMatthias Ringwald for (i=0; i < le_device_db_max_count(); i++){ 14503deb3ec6SMatthias Ringwald sm_key_t irk; 14513deb3ec6SMatthias Ringwald bd_addr_t address; 1452c7e2c1a5SMatthias Ringwald int address_type = BD_ADDR_TYPE_UNKNOWN; 14533deb3ec6SMatthias Ringwald le_device_db_info(i, &address_type, address, irk); 1454adf5eaa9SMatthias Ringwald // skip unused entries 1455c7e2c1a5SMatthias Ringwald if (address_type == BD_ADDR_TYPE_UNKNOWN) continue; 145611d10bdaSMatthias Ringwald // compare Identity Address 145711d10bdaSMatthias Ringwald if (memcmp(address, setup->sm_peer_address, 6) != 0) continue; 145811d10bdaSMatthias Ringwald // compare Identity Resolving Key 1459c7e2c1a5SMatthias Ringwald if (memcmp(irk, setup->sm_peer_irk, 16) != 0) continue; 1460c7e2c1a5SMatthias Ringwald 14613deb3ec6SMatthias Ringwald log_info("sm: device found for IRK, updating"); 14623deb3ec6SMatthias Ringwald le_db_index = i; 14633deb3ec6SMatthias Ringwald break; 14643deb3ec6SMatthias Ringwald } 1465c7e2c1a5SMatthias Ringwald } else { 1466c7e2c1a5SMatthias Ringwald // assert IRK is set to zero 1467c7e2c1a5SMatthias Ringwald memset(setup->sm_peer_irk, 0, 16); 14683deb3ec6SMatthias Ringwald } 14693deb3ec6SMatthias Ringwald 14703deb3ec6SMatthias Ringwald // if not found, lookup via public address if possible 14713deb3ec6SMatthias Ringwald log_info("sm peer addr type %u, peer addres %s", setup->sm_peer_addr_type, bd_addr_to_str(setup->sm_peer_address)); 1472c1ab6cc1SMatthias Ringwald if ((le_db_index < 0) && (setup->sm_peer_addr_type == BD_ADDR_TYPE_LE_PUBLIC)){ 14733deb3ec6SMatthias Ringwald int i; 1474092ec58eSMatthias Ringwald for (i=0; i < le_device_db_max_count(); i++){ 14753deb3ec6SMatthias Ringwald bd_addr_t address; 1476adf5eaa9SMatthias Ringwald int address_type = BD_ADDR_TYPE_UNKNOWN; 14773deb3ec6SMatthias Ringwald le_device_db_info(i, &address_type, address, NULL); 1478adf5eaa9SMatthias Ringwald // skip unused entries 1479adf5eaa9SMatthias Ringwald if (address_type == BD_ADDR_TYPE_UNKNOWN) continue; 14803deb3ec6SMatthias Ringwald log_info("device %u, sm peer addr type %u, peer addres %s", i, address_type, bd_addr_to_str(address)); 14815df9dc78SMatthias Ringwald if ((address_type == BD_ADDR_TYPE_LE_PUBLIC) && (memcmp(address, setup->sm_peer_address, 6) == 0)){ 14823deb3ec6SMatthias Ringwald log_info("sm: device found for public address, updating"); 14833deb3ec6SMatthias Ringwald le_db_index = i; 14843deb3ec6SMatthias Ringwald break; 14853deb3ec6SMatthias Ringwald } 14863deb3ec6SMatthias Ringwald } 14873deb3ec6SMatthias Ringwald } 14883deb3ec6SMatthias Ringwald 14893deb3ec6SMatthias Ringwald // if not found, add to db 149002b02cffSMatthias Ringwald bool new_to_le_device_db = false; 14913deb3ec6SMatthias Ringwald if (le_db_index < 0) { 14923deb3ec6SMatthias Ringwald le_db_index = le_device_db_add(setup->sm_peer_addr_type, setup->sm_peer_address, setup->sm_peer_irk); 149302b02cffSMatthias Ringwald new_to_le_device_db = true; 14943deb3ec6SMatthias Ringwald } 14953deb3ec6SMatthias Ringwald 14963deb3ec6SMatthias Ringwald if (le_db_index >= 0){ 14973deb3ec6SMatthias Ringwald 149802b02cffSMatthias Ringwald #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION 149902b02cffSMatthias Ringwald if (!new_to_le_device_db){ 150002b02cffSMatthias Ringwald hci_remove_le_device_db_entry_from_resolving_list(le_db_index); 150102b02cffSMatthias Ringwald } 150202b02cffSMatthias Ringwald hci_load_le_device_db_entry_into_resolving_list(le_db_index); 150302b02cffSMatthias Ringwald #else 150402b02cffSMatthias Ringwald UNUSED(new_to_le_device_db); 150502b02cffSMatthias Ringwald #endif 150602b02cffSMatthias Ringwald 150748163929SMatthias 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); 1508e1086030SMatthias Ringwald sm_conn->sm_irk_lookup_state = IRK_LOOKUP_SUCCEEDED; 15097710ebd2SMatthias Ringwald sm_conn->sm_le_db_index = le_db_index; 151048163929SMatthias Ringwald 1511eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 15123deb3ec6SMatthias Ringwald // store local CSRK 1513715a43d1SMatthias Ringwald setup->sm_le_device_index = le_db_index; 1514715a43d1SMatthias Ringwald if ((setup->sm_key_distribution_sent_set) & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION){ 15153deb3ec6SMatthias Ringwald log_info("sm: store local CSRK"); 15163deb3ec6SMatthias Ringwald le_device_db_local_csrk_set(le_db_index, setup->sm_local_csrk); 15173deb3ec6SMatthias Ringwald le_device_db_local_counter_set(le_db_index, 0); 15183deb3ec6SMatthias Ringwald } 15193deb3ec6SMatthias Ringwald 15203deb3ec6SMatthias Ringwald // store remote CSRK 15213deb3ec6SMatthias Ringwald if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION){ 15223deb3ec6SMatthias Ringwald log_info("sm: store remote CSRK"); 15233deb3ec6SMatthias Ringwald le_device_db_remote_csrk_set(le_db_index, setup->sm_peer_csrk); 15243deb3ec6SMatthias Ringwald le_device_db_remote_counter_set(le_db_index, 0); 15253deb3ec6SMatthias Ringwald } 1526eda85fbfSMatthias Ringwald #endif 152778f44163SMatthias Ringwald // store encryption information for secure connections: LTK generated by ECDH 152878f44163SMatthias Ringwald if (setup->sm_use_secure_connections){ 1529e6343eb6SMatthias Ringwald log_info("sm: store SC LTK (key size %u, authenticated %u)", sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated); 153078f44163SMatthias Ringwald uint8_t zero_rand[8]; 153178f44163SMatthias Ringwald memset(zero_rand, 0, 8); 153278f44163SMatthias Ringwald le_device_db_encryption_set(le_db_index, 0, zero_rand, setup->sm_ltk, sm_conn->sm_actual_encryption_key_size, 15333dc3a67dSMatthias Ringwald sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED, 1); 153478f44163SMatthias Ringwald } 153578f44163SMatthias Ringwald 1536e6343eb6SMatthias Ringwald // store encryption information for legacy pairing: peer LTK, EDIV, RAND 153778f44163SMatthias Ringwald else if ( (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION) 153878f44163SMatthias Ringwald && (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_MASTER_IDENTIFICATION )){ 1539e6343eb6SMatthias Ringwald log_info("sm: set encryption information (key size %u, authenticated %u)", sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated); 15403deb3ec6SMatthias Ringwald le_device_db_encryption_set(le_db_index, setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk, 15413dc3a67dSMatthias Ringwald sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED, 0); 154278f44163SMatthias Ringwald 15433deb3ec6SMatthias Ringwald } 15443deb3ec6SMatthias Ringwald } 154555f09f49SMatthias Ringwald } 154655f09f49SMatthias Ringwald 15478980298aSMatthias Ringwald static void sm_pairing_error(sm_connection_t * sm_conn, uint8_t reason){ 15488980298aSMatthias Ringwald sm_conn->sm_pairing_failed_reason = reason; 15498980298aSMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_SEND_PAIRING_FAILED; 15508980298aSMatthias Ringwald } 15518980298aSMatthias Ringwald 155222cb578bSMatthias Ringwald static int sm_le_device_db_index_lookup(bd_addr_type_t address_type, bd_addr_t address){ 15531a55487aSMatthias Ringwald int i; 15541a55487aSMatthias Ringwald for (i=0; i < le_device_db_max_count(); i++){ 155522cb578bSMatthias Ringwald bd_addr_t db_address; 155622cb578bSMatthias Ringwald int db_address_type = BD_ADDR_TYPE_UNKNOWN; 155722cb578bSMatthias Ringwald le_device_db_info(i, &db_address_type, db_address, NULL); 15581a55487aSMatthias Ringwald // skip unused entries 15591a55487aSMatthias Ringwald if (address_type == BD_ADDR_TYPE_UNKNOWN) continue; 156022cb578bSMatthias Ringwald if ((address_type == db_address_type) && (memcmp(address, db_address, 6) == 0)){ 15611a55487aSMatthias Ringwald return i; 15621a55487aSMatthias Ringwald } 15631a55487aSMatthias Ringwald } 15641a55487aSMatthias Ringwald return -1; 15651a55487aSMatthias Ringwald } 15661a55487aSMatthias Ringwald 15672e08b70bSMatthias Ringwald static void sm_remove_le_device_db_entry(uint16_t i) { 15682e08b70bSMatthias Ringwald le_device_db_remove(i); 1569672dc582SMatthias Ringwald #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION 1570672dc582SMatthias Ringwald // to remove an entry from the resolving list requires its identity address, which was already deleted 1571672dc582SMatthias Ringwald // fully reload resolving list instead 1572672dc582SMatthias Ringwald gap_load_resolving_list_from_le_device_db(); 1573672dc582SMatthias Ringwald #endif 15742e08b70bSMatthias Ringwald } 15752e08b70bSMatthias Ringwald 15768980298aSMatthias Ringwald static uint8_t sm_key_distribution_validate_received(sm_connection_t * sm_conn){ 15771a55487aSMatthias Ringwald // if identity is provided, abort if we have bonding with same address but different irk 15781a55487aSMatthias Ringwald if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION){ 157922cb578bSMatthias Ringwald int index = sm_le_device_db_index_lookup(BD_ADDR_TYPE_LE_PUBLIC, setup->sm_peer_address); 15801a55487aSMatthias Ringwald if (index >= 0){ 15811a55487aSMatthias Ringwald sm_key_t irk; 15821a55487aSMatthias Ringwald le_device_db_info(index, NULL, NULL, irk); 15831a55487aSMatthias Ringwald if (memcmp(irk, setup->sm_peer_irk, 16) != 0){ 15841a55487aSMatthias Ringwald // IRK doesn't match, delete bonding information 15851a55487aSMatthias 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); 15869202d845SMatthias Ringwald sm_remove_le_device_db_entry(index); 15871a55487aSMatthias Ringwald } 15881a55487aSMatthias Ringwald } 15891a55487aSMatthias Ringwald } 15908980298aSMatthias Ringwald return 0; 15918980298aSMatthias Ringwald } 15928980298aSMatthias Ringwald 159355f09f49SMatthias Ringwald static void sm_key_distribution_handle_all_received(sm_connection_t * sm_conn){ 159455f09f49SMatthias Ringwald 15958980298aSMatthias Ringwald // abort pairing if received keys are not valid 15968980298aSMatthias Ringwald uint8_t reason = sm_key_distribution_validate_received(sm_conn); 15978980298aSMatthias Ringwald if (reason != 0){ 15988980298aSMatthias Ringwald sm_pairing_error(sm_conn, reason); 15998980298aSMatthias Ringwald return; 16008980298aSMatthias Ringwald } 16018980298aSMatthias Ringwald 160255f09f49SMatthias Ringwald // only store pairing information if both sides are bondable, i.e., the bonadble flag is set 160355f09f49SMatthias Ringwald bool bonding_enabled = (sm_pairing_packet_get_auth_req(setup->sm_m_preq) 160455f09f49SMatthias Ringwald & sm_pairing_packet_get_auth_req(setup->sm_s_pres) 160555f09f49SMatthias Ringwald & SM_AUTHREQ_BONDING ) != 0u; 160655f09f49SMatthias Ringwald 160755f09f49SMatthias Ringwald if (bonding_enabled){ 160855f09f49SMatthias Ringwald sm_store_bonding_information(sm_conn); 160927ef8bc8SMatthias Ringwald } else { 161027ef8bc8SMatthias Ringwald log_info("Ignoring received keys, bonding not enabled"); 161127ef8bc8SMatthias Ringwald } 16123deb3ec6SMatthias Ringwald } 16133deb3ec6SMatthias Ringwald 1614688a08f9SMatthias Ringwald static inline void sm_pdu_received_in_wrong_state(sm_connection_t * sm_conn){ 1615688a08f9SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_UNSPECIFIED_REASON); 1616688a08f9SMatthias Ringwald } 1617688a08f9SMatthias Ringwald 16189af0f475SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 1619688a08f9SMatthias Ringwald 1620dc300847SMatthias Ringwald static void sm_sc_prepare_dhkey_check(sm_connection_t * sm_conn); 1621945888f5SMatthias Ringwald static int sm_passkey_used(stk_generation_method_t method); 1622f1c1783eSMatthias Ringwald static int sm_just_works_or_numeric_comparison(stk_generation_method_t method); 1623dc300847SMatthias Ringwald 1624b35a3de2SMatthias Ringwald static void sm_sc_start_calculating_local_confirm(sm_connection_t * sm_conn){ 1625b90c4e75SMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 16261f9d84e9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CONFIRMATION; 1627b90c4e75SMatthias Ringwald } else { 1628b90c4e75SMatthias 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); 1629b35a3de2SMatthias Ringwald } 1630b35a3de2SMatthias Ringwald } 1631b35a3de2SMatthias Ringwald 1632688a08f9SMatthias Ringwald static void sm_sc_state_after_receiving_random(sm_connection_t * sm_conn){ 163342134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1634688a08f9SMatthias Ringwald // Responder 16354acf7b7bSMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 16364acf7b7bSMatthias Ringwald // generate Nb 16374acf7b7bSMatthias Ringwald log_info("Generate Nb"); 16386ca80073SMatthias 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); 16394acf7b7bSMatthias Ringwald } else { 1640688a08f9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM; 16414acf7b7bSMatthias Ringwald } 1642688a08f9SMatthias Ringwald } else { 1643688a08f9SMatthias Ringwald // Initiator role 1644688a08f9SMatthias Ringwald switch (setup->sm_stk_generation_method){ 1645688a08f9SMatthias Ringwald case JUST_WORKS: 1646dc300847SMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 1647688a08f9SMatthias Ringwald break; 1648688a08f9SMatthias Ringwald 164947fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 1650bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_G2; 1651688a08f9SMatthias Ringwald break; 1652688a08f9SMatthias Ringwald case PK_INIT_INPUT: 1653688a08f9SMatthias Ringwald case PK_RESP_INPUT: 165447fb4255SMatthias Ringwald case PK_BOTH_INPUT: 16554ea43905SMatthias Ringwald if (setup->sm_passkey_bit < 20u) { 1656b35a3de2SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 1657688a08f9SMatthias Ringwald } else { 1658dc300847SMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 1659688a08f9SMatthias Ringwald } 1660688a08f9SMatthias Ringwald break; 1661688a08f9SMatthias Ringwald case OOB: 166265a9a04eSMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 1663688a08f9SMatthias Ringwald break; 16647bbeb3adSMilanka Ringwald default: 16657bbeb3adSMilanka Ringwald btstack_assert(false); 16667bbeb3adSMilanka Ringwald break; 1667688a08f9SMatthias Ringwald } 1668688a08f9SMatthias Ringwald } 1669688a08f9SMatthias Ringwald } 1670688a08f9SMatthias Ringwald 1671aec94140SMatthias Ringwald static void sm_sc_cmac_done(uint8_t * hash){ 1672688a08f9SMatthias Ringwald log_info("sm_sc_cmac_done: "); 1673688a08f9SMatthias Ringwald log_info_hexdump(hash, 16); 1674688a08f9SMatthias Ringwald 1675c59d0c92SMatthias Ringwald if (sm_sc_oob_state == SM_SC_OOB_W4_CONFIRM){ 1676c59d0c92SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_IDLE; 1677a680ba6bSMatthias Ringwald (*sm_sc_oob_callback)(hash, sm_sc_oob_random); 1678c59d0c92SMatthias Ringwald return; 1679c59d0c92SMatthias Ringwald } 1680c59d0c92SMatthias Ringwald 1681bd57ffebSMatthias Ringwald sm_connection_t * sm_conn = sm_cmac_connection; 1682bd57ffebSMatthias Ringwald sm_cmac_connection = NULL; 16836857ad8fSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 16842bacf595SMatthias Ringwald link_key_type_t link_key_type; 1685b4f65634SMatthias Ringwald #endif 1686bd57ffebSMatthias Ringwald 1687bd57ffebSMatthias Ringwald switch (sm_conn->sm_engine_state){ 1688aec94140SMatthias Ringwald case SM_SC_W4_CMAC_FOR_CONFIRMATION: 16896535961aSMatthias Ringwald (void)memcpy(setup->sm_local_confirm, hash, 16); 1690bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_CONFIRMATION; 1691aec94140SMatthias Ringwald break; 1692688a08f9SMatthias Ringwald case SM_SC_W4_CMAC_FOR_CHECK_CONFIRMATION: 1693688a08f9SMatthias Ringwald // check 1694688a08f9SMatthias Ringwald if (0 != memcmp(hash, setup->sm_peer_confirm, 16)){ 1695bd57ffebSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_CONFIRM_VALUE_FAILED); 1696688a08f9SMatthias Ringwald break; 1697688a08f9SMatthias Ringwald } 1698bd57ffebSMatthias Ringwald sm_sc_state_after_receiving_random(sm_conn); 1699688a08f9SMatthias Ringwald break; 1700901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_G2: { 1701901c000fSMatthias Ringwald uint32_t vab = big_endian_read_32(hash, 12) % 1000000; 1702901c000fSMatthias Ringwald big_endian_store_32(setup->sm_tk, 12, vab); 1703901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_USER_RESPONSE; 1704901c000fSMatthias Ringwald sm_trigger_user_response(sm_conn); 1705019005a0SMatthias Ringwald break; 1706019005a0SMatthias Ringwald } 17070346c37cSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_SALT: 17086535961aSMatthias Ringwald (void)memcpy(setup->sm_t, hash, 16); 1709bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_MACKEY; 17100346c37cSMatthias Ringwald break; 17110346c37cSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_MACKEY: 17126535961aSMatthias Ringwald (void)memcpy(setup->sm_mackey, hash, 16); 1713bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_LTK; 17140346c37cSMatthias Ringwald break; 17150346c37cSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_LTK: 1716b18300a6SMatthias Ringwald // truncate sm_ltk, but keep full LTK for cross-transport key derivation in sm_local_ltk 1717b18300a6SMatthias Ringwald // Errata Service Release to the Bluetooth Specification: ESR09 1718b18300a6SMatthias Ringwald // E6405 – Cross transport key derivation from a key of size less than 128 bits 1719b18300a6SMatthias Ringwald // Note: When the BR/EDR link key is being derived from the LTK, the derivation is done before the LTK gets masked." 17206535961aSMatthias Ringwald (void)memcpy(setup->sm_ltk, hash, 16); 17216535961aSMatthias Ringwald (void)memcpy(setup->sm_local_ltk, hash, 16); 1722893e9333SMatthias Ringwald sm_truncate_key(setup->sm_ltk, sm_conn->sm_actual_encryption_key_size); 1723bd57ffebSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F6_FOR_DHKEY_CHECK; 1724019005a0SMatthias Ringwald break; 1725901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F6_FOR_DHKEY_CHECK: 17266535961aSMatthias Ringwald (void)memcpy(setup->sm_local_dhkey_check, hash, 16); 172742134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1728901c000fSMatthias Ringwald // responder 1729901c000fSMatthias Ringwald if (setup->sm_state_vars & SM_STATE_VAR_DHKEY_COMMAND_RECEIVED){ 1730901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK; 1731901c000fSMatthias Ringwald } else { 1732901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_DHKEY_CHECK_COMMAND; 1733901c000fSMatthias Ringwald } 1734901c000fSMatthias Ringwald } else { 1735901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_DHKEY_CHECK_COMMAND; 1736901c000fSMatthias Ringwald } 1737901c000fSMatthias Ringwald break; 1738901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK: 1739901c000fSMatthias Ringwald if (0 != memcmp(hash, setup->sm_peer_dhkey_check, 16) ){ 1740901c000fSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 1741aec94140SMatthias Ringwald break; 1742aec94140SMatthias Ringwald } 174342134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1744901c000fSMatthias Ringwald // responder 1745901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_DHKEY_CHECK_COMMAND; 1746901c000fSMatthias Ringwald } else { 1747901c000fSMatthias Ringwald // initiator 1748901c000fSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH3_SEND_START_ENCRYPTION; 1749bd57ffebSMatthias Ringwald } 1750901c000fSMatthias Ringwald break; 17516857ad8fSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 175257132f12SMatthias Ringwald case SM_SC_W4_CALCULATE_ILK: 17536535961aSMatthias Ringwald (void)memcpy(setup->sm_t, hash, 16); 175457132f12SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_BR_EDR_LINK_KEY; 17552bacf595SMatthias Ringwald break; 175657132f12SMatthias Ringwald case SM_SC_W4_CALCULATE_BR_EDR_LINK_KEY: 17572bacf595SMatthias Ringwald reverse_128(hash, setup->sm_t); 17582bacf595SMatthias Ringwald link_key_type = sm_conn->sm_connection_authenticated ? 17592bacf595SMatthias Ringwald AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256 : UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256; 17608974e43fSMatthias Ringwald log_info("Derived classic link key from LE using h6, type %u", (int) link_key_type); 176155160b1cSMatthias Ringwald gap_store_link_key_for_bd_addr(setup->sm_peer_address, setup->sm_t, link_key_type); 17628974e43fSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 17632bacf595SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 17642bacf595SMatthias Ringwald } else { 17652bacf595SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 17662bacf595SMatthias Ringwald } 17670ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_SUCCESS, 0); 17682bacf595SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 17692bacf595SMatthias Ringwald break; 1770e0a03c85SMatthias Ringwald case SM_BR_EDR_W4_CALCULATE_ILK: 1771e0a03c85SMatthias Ringwald (void)memcpy(setup->sm_t, hash, 16); 1772e0a03c85SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_W2_CALCULATE_LE_LTK; 1773e0a03c85SMatthias Ringwald break; 1774e0a03c85SMatthias Ringwald case SM_BR_EDR_W4_CALCULATE_LE_LTK: 1775e0a03c85SMatthias Ringwald log_info("Derived LE LTK from BR/EDR Link Key"); 1776e0a03c85SMatthias Ringwald log_info_key("Link Key", hash); 1777e0a03c85SMatthias Ringwald (void)memcpy(setup->sm_ltk, hash, 16); 1778e0a03c85SMatthias Ringwald sm_truncate_key(setup->sm_ltk, sm_conn->sm_actual_encryption_key_size); 1779e0a03c85SMatthias Ringwald sm_conn->sm_connection_authenticated = setup->sm_link_key_type == AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256; 1780e0a03c85SMatthias Ringwald sm_store_bonding_information(sm_conn); 1781c18be159SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 1782e0a03c85SMatthias Ringwald break; 1783bdb14b0eSMatthias Ringwald #endif 1784bd57ffebSMatthias Ringwald default: 1785bd57ffebSMatthias Ringwald log_error("sm_sc_cmac_done in state %u", sm_conn->sm_engine_state); 1786bd57ffebSMatthias Ringwald break; 1787bd57ffebSMatthias Ringwald } 178870b44dd4SMatthias Ringwald sm_trigger_run(); 1789aec94140SMatthias Ringwald } 1790aec94140SMatthias Ringwald 1791688a08f9SMatthias 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){ 1792dc300847SMatthias Ringwald const uint16_t message_len = 65; 1793aec94140SMatthias Ringwald sm_cmac_connection = sm_conn; 17946535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, u, 32); 17956535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 32, v, 32); 1796aec94140SMatthias Ringwald sm_cmac_sc_buffer[64] = z; 1797aec94140SMatthias Ringwald log_info("f4 key"); 1798aec94140SMatthias Ringwald log_info_hexdump(x, 16); 1799aec94140SMatthias Ringwald log_info("f4 message"); 1800dc300847SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1801d1a1f6a4SMatthias Ringwald sm_cmac_message_start(x, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 1802aec94140SMatthias Ringwald } 1803aec94140SMatthias Ringwald 18040346c37cSMatthias Ringwald static const uint8_t f5_key_id[] = { 0x62, 0x74, 0x6c, 0x65 }; 18050346c37cSMatthias Ringwald static const uint8_t f5_length[] = { 0x01, 0x00}; 18060346c37cSMatthias Ringwald 18070346c37cSMatthias Ringwald static void f5_calculate_salt(sm_connection_t * sm_conn){ 18088334d3d8SMatthias Ringwald 18098334d3d8SMatthias Ringwald static const sm_key_t f5_salt = { 0x6C ,0x88, 0x83, 0x91, 0xAA, 0xF5, 0xA5, 0x38, 0x60, 0x37, 0x0B, 0xDB, 0x5A, 0x60, 0x83, 0xBE}; 18108334d3d8SMatthias Ringwald 181140c5d850SMatthias Ringwald log_info("f5_calculate_salt"); 18120346c37cSMatthias Ringwald // calculate salt for f5 18130346c37cSMatthias Ringwald const uint16_t message_len = 32; 18140346c37cSMatthias Ringwald sm_cmac_connection = sm_conn; 18156535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, setup->sm_dhkey, message_len); 1816d1a1f6a4SMatthias Ringwald sm_cmac_message_start(f5_salt, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 18170346c37cSMatthias Ringwald } 18180346c37cSMatthias Ringwald 18190346c37cSMatthias 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){ 18200346c37cSMatthias Ringwald const uint16_t message_len = 53; 18210346c37cSMatthias Ringwald sm_cmac_connection = sm_conn; 18220346c37cSMatthias Ringwald 18230346c37cSMatthias Ringwald // f5(W, N1, N2, A1, A2) = AES-CMACT (Counter = 0 || keyID || N1 || N2|| A1|| A2 || Length = 256) -- this is the MacKey 18240346c37cSMatthias Ringwald sm_cmac_sc_buffer[0] = 0; 18256535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 01, f5_key_id, 4); 18266535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 05, n1, 16); 18276535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 21, n2, 16); 18286535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 37, a1, 7); 18296535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 44, a2, 7); 18306535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 51, f5_length, 2); 18310346c37cSMatthias Ringwald log_info("f5 key"); 18320346c37cSMatthias Ringwald log_info_hexdump(t, 16); 18330346c37cSMatthias Ringwald log_info("f5 message for MacKey"); 18340346c37cSMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1835d1a1f6a4SMatthias Ringwald sm_cmac_message_start(t, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 18360346c37cSMatthias Ringwald } 18370346c37cSMatthias Ringwald 18380346c37cSMatthias Ringwald static void f5_calculate_mackey(sm_connection_t * sm_conn){ 18390346c37cSMatthias Ringwald sm_key56_t bd_addr_master, bd_addr_slave; 18400346c37cSMatthias Ringwald bd_addr_master[0] = setup->sm_m_addr_type; 18410346c37cSMatthias Ringwald bd_addr_slave[0] = setup->sm_s_addr_type; 18426535961aSMatthias Ringwald (void)memcpy(&bd_addr_master[1], setup->sm_m_address, 6); 18436535961aSMatthias Ringwald (void)memcpy(&bd_addr_slave[1], setup->sm_s_address, 6); 184442134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 18450346c37cSMatthias Ringwald // responder 18460346c37cSMatthias Ringwald f5_mackkey(sm_conn, setup->sm_t, setup->sm_peer_nonce, setup->sm_local_nonce, bd_addr_master, bd_addr_slave); 18470346c37cSMatthias Ringwald } else { 18480346c37cSMatthias Ringwald // initiator 18490346c37cSMatthias Ringwald f5_mackkey(sm_conn, setup->sm_t, setup->sm_local_nonce, setup->sm_peer_nonce, bd_addr_master, bd_addr_slave); 18500346c37cSMatthias Ringwald } 18510346c37cSMatthias Ringwald } 18520346c37cSMatthias Ringwald 18530346c37cSMatthias Ringwald // note: must be called right after f5_mackey, as sm_cmac_buffer[1..52] will be reused 18540346c37cSMatthias Ringwald static inline void f5_ltk(sm_connection_t * sm_conn, sm_key_t t){ 18550346c37cSMatthias Ringwald const uint16_t message_len = 53; 18560346c37cSMatthias Ringwald sm_cmac_connection = sm_conn; 18570346c37cSMatthias Ringwald sm_cmac_sc_buffer[0] = 1; 18580346c37cSMatthias Ringwald // 1..52 setup before 18590346c37cSMatthias Ringwald log_info("f5 key"); 18600346c37cSMatthias Ringwald log_info_hexdump(t, 16); 18610346c37cSMatthias Ringwald log_info("f5 message for LTK"); 18620346c37cSMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1863d1a1f6a4SMatthias Ringwald sm_cmac_message_start(t, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 18640346c37cSMatthias Ringwald } 1865f92edc8eSMatthias Ringwald 18660346c37cSMatthias Ringwald static void f5_calculate_ltk(sm_connection_t * sm_conn){ 18670346c37cSMatthias Ringwald f5_ltk(sm_conn, setup->sm_t); 18680346c37cSMatthias Ringwald } 18690346c37cSMatthias Ringwald 187031f061fbSMatthias 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){ 18716535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, n1, 16); 18726535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 16, n2, 16); 18736535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 32, r, 16); 18746535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 48, io_cap, 3); 18756535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 51, a1, 7); 18766535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 58, a2, 7); 187731f061fbSMatthias Ringwald } 187831f061fbSMatthias Ringwald 187931f061fbSMatthias Ringwald static void f6_engine(sm_connection_t * sm_conn, const sm_key_t w){ 188031f061fbSMatthias Ringwald const uint16_t message_len = 65; 188131f061fbSMatthias Ringwald sm_cmac_connection = sm_conn; 1882dc300847SMatthias Ringwald log_info("f6 key"); 1883dc300847SMatthias Ringwald log_info_hexdump(w, 16); 1884dc300847SMatthias Ringwald log_info("f6 message"); 1885dc300847SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1886d1a1f6a4SMatthias Ringwald sm_cmac_message_start(w, 65, sm_cmac_sc_buffer, &sm_sc_cmac_done); 1887dc300847SMatthias Ringwald } 1888dc300847SMatthias Ringwald 1889f92edc8eSMatthias Ringwald // g2(U, V, X, Y) = AES-CMACX(U || V || Y) mod 2^32 1890f92edc8eSMatthias Ringwald // - U is 256 bits 1891f92edc8eSMatthias Ringwald // - V is 256 bits 1892f92edc8eSMatthias Ringwald // - X is 128 bits 1893f92edc8eSMatthias Ringwald // - Y is 128 bits 1894bd57ffebSMatthias 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){ 1895bd57ffebSMatthias Ringwald const uint16_t message_len = 80; 1896bd57ffebSMatthias Ringwald sm_cmac_connection = sm_conn; 18976535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer, u, 32); 18986535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 32, v, 32); 18996535961aSMatthias Ringwald (void)memcpy(sm_cmac_sc_buffer + 64, y, 16); 1900f92edc8eSMatthias Ringwald log_info("g2 key"); 1901f92edc8eSMatthias Ringwald log_info_hexdump(x, 16); 1902f92edc8eSMatthias Ringwald log_info("g2 message"); 19032bacf595SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 1904d1a1f6a4SMatthias Ringwald sm_cmac_message_start(x, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 1905f92edc8eSMatthias Ringwald } 1906f92edc8eSMatthias Ringwald 1907b35a3de2SMatthias Ringwald static void g2_calculate(sm_connection_t * sm_conn) { 1908f92edc8eSMatthias Ringwald // calc Va if numeric comparison 190942134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1910f92edc8eSMatthias Ringwald // responder 1911fc5bff5fSMatthias Ringwald g2_engine(sm_conn, setup->sm_peer_q, ec_q, setup->sm_peer_nonce, setup->sm_local_nonce);; 1912f92edc8eSMatthias Ringwald } else { 1913f92edc8eSMatthias Ringwald // initiator 1914fc5bff5fSMatthias Ringwald g2_engine(sm_conn, ec_q, setup->sm_peer_q, setup->sm_local_nonce, setup->sm_peer_nonce); 1915f92edc8eSMatthias Ringwald } 1916f92edc8eSMatthias Ringwald } 1917f92edc8eSMatthias Ringwald 1918945888f5SMatthias Ringwald static void sm_sc_calculate_local_confirm(sm_connection_t * sm_conn){ 19199af0f475SMatthias Ringwald uint8_t z = 0; 192040c5d850SMatthias Ringwald if (sm_passkey_entry(setup->sm_stk_generation_method)){ 19219af0f475SMatthias Ringwald // some form of passkey 19229af0f475SMatthias Ringwald uint32_t pk = big_endian_read_32(setup->sm_tk, 12); 19234ea43905SMatthias Ringwald z = 0x80u | ((pk >> setup->sm_passkey_bit) & 1u); 19249af0f475SMatthias Ringwald setup->sm_passkey_bit++; 19259af0f475SMatthias Ringwald } 1926fc5bff5fSMatthias Ringwald f4_engine(sm_conn, ec_q, setup->sm_peer_q, setup->sm_local_nonce, z); 19279af0f475SMatthias Ringwald } 1928688a08f9SMatthias Ringwald 1929688a08f9SMatthias Ringwald static void sm_sc_calculate_remote_confirm(sm_connection_t * sm_conn){ 1930a680ba6bSMatthias Ringwald // OOB 1931a680ba6bSMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 19324acf7b7bSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 19334acf7b7bSMatthias Ringwald f4_engine(sm_conn, setup->sm_peer_q, setup->sm_peer_q, setup->sm_ra, 0); 19344acf7b7bSMatthias Ringwald } else { 19354acf7b7bSMatthias Ringwald f4_engine(sm_conn, setup->sm_peer_q, setup->sm_peer_q, setup->sm_rb, 0); 19364acf7b7bSMatthias Ringwald } 1937a680ba6bSMatthias Ringwald return; 1938a680ba6bSMatthias Ringwald } 1939a680ba6bSMatthias Ringwald 1940688a08f9SMatthias Ringwald uint8_t z = 0; 194140c5d850SMatthias Ringwald if (sm_passkey_entry(setup->sm_stk_generation_method)){ 1942688a08f9SMatthias Ringwald // some form of passkey 1943688a08f9SMatthias Ringwald uint32_t pk = big_endian_read_32(setup->sm_tk, 12); 1944688a08f9SMatthias Ringwald // sm_passkey_bit was increased before sending confirm value 19454ea43905SMatthias Ringwald z = 0x80u | ((pk >> (setup->sm_passkey_bit-1u)) & 1u); 1946688a08f9SMatthias Ringwald } 1947fc5bff5fSMatthias Ringwald f4_engine(sm_conn, setup->sm_peer_q, ec_q, setup->sm_peer_nonce, z); 1948688a08f9SMatthias Ringwald } 1949688a08f9SMatthias Ringwald 19500346c37cSMatthias Ringwald static void sm_sc_prepare_dhkey_check(sm_connection_t * sm_conn){ 1951505f1c30SMatthias Ringwald log_info("sm_sc_prepare_dhkey_check, DHKEY calculated %u", (setup->sm_state_vars & SM_STATE_VAR_DHKEY_CALCULATED) ? 1 : 0); 19523cf37b8cSMatthias Ringwald 19533cf37b8cSMatthias Ringwald if (setup->sm_state_vars & SM_STATE_VAR_DHKEY_CALCULATED){ 19543cf37b8cSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_SALT; 19553cf37b8cSMatthias Ringwald return; 19563cf37b8cSMatthias Ringwald } else { 19573cf37b8cSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_CALCULATE_DHKEY; 19583cf37b8cSMatthias Ringwald } 1959d1a1f6a4SMatthias Ringwald } 19603cf37b8cSMatthias Ringwald 1961d1a1f6a4SMatthias Ringwald static void sm_sc_dhkey_calculated(void * arg){ 1962f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 1963f3582630SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 1964f3582630SMatthias Ringwald if (sm_conn == NULL) return; 1965f3582630SMatthias Ringwald 19661c34405fSMatthias Ringwald // check for invalid public key detected by Controller 19671c34405fSMatthias Ringwald if (sm_is_ff(setup->sm_dhkey, 32)){ 19681c34405fSMatthias Ringwald log_info("sm: peer public key invalid"); 19691c34405fSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 19701c34405fSMatthias Ringwald return; 19711c34405fSMatthias Ringwald } 19721c34405fSMatthias Ringwald 1973d1a1f6a4SMatthias Ringwald log_info("dhkey"); 1974d1a1f6a4SMatthias Ringwald log_info_hexdump(&setup->sm_dhkey[0], 32); 1975d1a1f6a4SMatthias Ringwald setup->sm_state_vars |= SM_STATE_VAR_DHKEY_CALCULATED; 1976d1a1f6a4SMatthias Ringwald // trigger next step 1977d1a1f6a4SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_CALCULATE_DHKEY){ 1978d1a1f6a4SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_SALT; 1979d1a1f6a4SMatthias Ringwald } 198070b44dd4SMatthias Ringwald sm_trigger_run(); 1981dc300847SMatthias Ringwald } 1982dc300847SMatthias Ringwald 1983dc300847SMatthias Ringwald static void sm_sc_calculate_f6_for_dhkey_check(sm_connection_t * sm_conn){ 1984dc300847SMatthias Ringwald // calculate DHKCheck 1985dc300847SMatthias Ringwald sm_key56_t bd_addr_master, bd_addr_slave; 1986dc300847SMatthias Ringwald bd_addr_master[0] = setup->sm_m_addr_type; 1987dc300847SMatthias Ringwald bd_addr_slave[0] = setup->sm_s_addr_type; 19886535961aSMatthias Ringwald (void)memcpy(&bd_addr_master[1], setup->sm_m_address, 6); 19896535961aSMatthias Ringwald (void)memcpy(&bd_addr_slave[1], setup->sm_s_address, 6); 1990dc300847SMatthias Ringwald uint8_t iocap_a[3]; 1991dc300847SMatthias Ringwald iocap_a[0] = sm_pairing_packet_get_auth_req(setup->sm_m_preq); 1992dc300847SMatthias Ringwald iocap_a[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq); 1993dc300847SMatthias Ringwald iocap_a[2] = sm_pairing_packet_get_io_capability(setup->sm_m_preq); 1994dc300847SMatthias Ringwald uint8_t iocap_b[3]; 1995dc300847SMatthias Ringwald iocap_b[0] = sm_pairing_packet_get_auth_req(setup->sm_s_pres); 1996dc300847SMatthias Ringwald iocap_b[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres); 1997dc300847SMatthias Ringwald iocap_b[2] = sm_pairing_packet_get_io_capability(setup->sm_s_pres); 199842134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 1999dc300847SMatthias Ringwald // responder 200031f061fbSMatthias Ringwald f6_setup(setup->sm_local_nonce, setup->sm_peer_nonce, setup->sm_ra, iocap_b, bd_addr_slave, bd_addr_master); 200131f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2002dc300847SMatthias Ringwald } else { 2003dc300847SMatthias Ringwald // initiator 200431f061fbSMatthias Ringwald f6_setup( setup->sm_local_nonce, setup->sm_peer_nonce, setup->sm_rb, iocap_a, bd_addr_master, bd_addr_slave); 200531f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2006dc300847SMatthias Ringwald } 2007dc300847SMatthias Ringwald } 2008dc300847SMatthias Ringwald 2009019005a0SMatthias Ringwald static void sm_sc_calculate_f6_to_verify_dhkey_check(sm_connection_t * sm_conn){ 2010019005a0SMatthias Ringwald // validate E = f6() 2011019005a0SMatthias Ringwald sm_key56_t bd_addr_master, bd_addr_slave; 2012019005a0SMatthias Ringwald bd_addr_master[0] = setup->sm_m_addr_type; 2013019005a0SMatthias Ringwald bd_addr_slave[0] = setup->sm_s_addr_type; 20146535961aSMatthias Ringwald (void)memcpy(&bd_addr_master[1], setup->sm_m_address, 6); 20156535961aSMatthias Ringwald (void)memcpy(&bd_addr_slave[1], setup->sm_s_address, 6); 2016019005a0SMatthias Ringwald 2017019005a0SMatthias Ringwald uint8_t iocap_a[3]; 2018019005a0SMatthias Ringwald iocap_a[0] = sm_pairing_packet_get_auth_req(setup->sm_m_preq); 2019019005a0SMatthias Ringwald iocap_a[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq); 2020019005a0SMatthias Ringwald iocap_a[2] = sm_pairing_packet_get_io_capability(setup->sm_m_preq); 2021019005a0SMatthias Ringwald uint8_t iocap_b[3]; 2022019005a0SMatthias Ringwald iocap_b[0] = sm_pairing_packet_get_auth_req(setup->sm_s_pres); 2023019005a0SMatthias Ringwald iocap_b[1] = sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres); 2024019005a0SMatthias Ringwald iocap_b[2] = sm_pairing_packet_get_io_capability(setup->sm_s_pres); 202542134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 2026019005a0SMatthias Ringwald // responder 202731f061fbSMatthias Ringwald f6_setup(setup->sm_peer_nonce, setup->sm_local_nonce, setup->sm_rb, iocap_a, bd_addr_master, bd_addr_slave); 202831f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2029019005a0SMatthias Ringwald } else { 2030019005a0SMatthias Ringwald // initiator 203131f061fbSMatthias Ringwald f6_setup(setup->sm_peer_nonce, setup->sm_local_nonce, setup->sm_ra, iocap_b, bd_addr_slave, bd_addr_master); 203231f061fbSMatthias Ringwald f6_engine(sm_conn, setup->sm_mackey); 2033019005a0SMatthias Ringwald } 2034019005a0SMatthias Ringwald } 20352bacf595SMatthias Ringwald 203655c62cf5SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 20372bacf595SMatthias Ringwald 20382bacf595SMatthias Ringwald // 20392bacf595SMatthias Ringwald // Link Key Conversion Function h6 20402bacf595SMatthias Ringwald // 204157132f12SMatthias Ringwald // h6(W, keyID) = AES-CMAC_W(keyID) 20422bacf595SMatthias Ringwald // - W is 128 bits 20432bacf595SMatthias Ringwald // - keyID is 32 bits 20442bacf595SMatthias Ringwald static void h6_engine(sm_connection_t * sm_conn, const sm_key_t w, const uint32_t key_id){ 20452bacf595SMatthias Ringwald const uint16_t message_len = 4; 20462bacf595SMatthias Ringwald sm_cmac_connection = sm_conn; 20472bacf595SMatthias Ringwald big_endian_store_32(sm_cmac_sc_buffer, 0, key_id); 20482bacf595SMatthias Ringwald log_info("h6 key"); 20492bacf595SMatthias Ringwald log_info_hexdump(w, 16); 20502bacf595SMatthias Ringwald log_info("h6 message"); 20512bacf595SMatthias Ringwald log_info_hexdump(sm_cmac_sc_buffer, message_len); 2052d1a1f6a4SMatthias Ringwald sm_cmac_message_start(w, message_len, sm_cmac_sc_buffer, &sm_sc_cmac_done); 20532bacf595SMatthias Ringwald } 205457132f12SMatthias Ringwald // 205557132f12SMatthias Ringwald // Link Key Conversion Function h7 205657132f12SMatthias Ringwald // 205757132f12SMatthias Ringwald // h7(SALT, W) = AES-CMAC_SALT(W) 205857132f12SMatthias Ringwald // - SALT is 128 bits 205957132f12SMatthias Ringwald // - W is 128 bits 206057132f12SMatthias Ringwald static void h7_engine(sm_connection_t * sm_conn, const sm_key_t salt, const sm_key_t w) { 206157132f12SMatthias Ringwald const uint16_t message_len = 16; 206257132f12SMatthias Ringwald sm_cmac_connection = sm_conn; 206357132f12SMatthias Ringwald log_info("h7 key"); 206457132f12SMatthias Ringwald log_info_hexdump(salt, 16); 206557132f12SMatthias Ringwald log_info("h7 message"); 206657132f12SMatthias Ringwald log_info_hexdump(w, 16); 206757132f12SMatthias Ringwald sm_cmac_message_start(salt, message_len, w, &sm_sc_cmac_done); 206857132f12SMatthias Ringwald } 20692bacf595SMatthias Ringwald 2070b18300a6SMatthias Ringwald // For SC, setup->sm_local_ltk holds full LTK (sm_ltk is already truncated) 2071b18300a6SMatthias Ringwald // Errata Service Release to the Bluetooth Specification: ESR09 2072b18300a6SMatthias Ringwald // E6405 – Cross transport key derivation from a key of size less than 128 bits 2073b18300a6SMatthias Ringwald // "Note: When the BR/EDR link key is being derived from the LTK, the derivation is done before the LTK gets masked." 207457132f12SMatthias Ringwald 2075c82679c3SMatthias Ringwald static void h6_calculate_ilk_from_le_ltk(sm_connection_t * sm_conn){ 2076b18300a6SMatthias Ringwald h6_engine(sm_conn, setup->sm_local_ltk, 0x746D7031); // "tmp1" 20772bacf595SMatthias Ringwald } 20782bacf595SMatthias Ringwald 2079e0a03c85SMatthias Ringwald static void h6_calculate_ilk_from_br_edr(sm_connection_t * sm_conn){ 2080e0a03c85SMatthias Ringwald h6_engine(sm_conn, setup->sm_link_key, 0x746D7032); // "tmp2" 2081e0a03c85SMatthias Ringwald } 2082e0a03c85SMatthias Ringwald 20832bacf595SMatthias Ringwald static void h6_calculate_br_edr_link_key(sm_connection_t * sm_conn){ 20842bacf595SMatthias Ringwald h6_engine(sm_conn, setup->sm_t, 0x6c656272); // "lebr" 20852bacf595SMatthias Ringwald } 20862bacf595SMatthias Ringwald 2087e0a03c85SMatthias Ringwald static void h6_calculate_le_ltk(sm_connection_t * sm_conn){ 2088e0a03c85SMatthias Ringwald h6_engine(sm_conn, setup->sm_t, 0x62726C65); // "brle" 2089e0a03c85SMatthias Ringwald } 2090e0a03c85SMatthias Ringwald 2091c82679c3SMatthias Ringwald static void h7_calculate_ilk_from_le_ltk(sm_connection_t * sm_conn){ 209257132f12SMatthias Ringwald const uint8_t salt[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x6D, 0x70, 0x31}; // "tmp1" 209357132f12SMatthias Ringwald h7_engine(sm_conn, salt, setup->sm_local_ltk); 209457132f12SMatthias Ringwald } 2095e0a03c85SMatthias Ringwald 2096e0a03c85SMatthias Ringwald static void h7_calculate_ilk_from_br_edr(sm_connection_t * sm_conn){ 2097e0a03c85SMatthias Ringwald const uint8_t salt[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x6D, 0x70, 0x32}; // "tmp2" 2098e0a03c85SMatthias Ringwald h7_engine(sm_conn, salt, setup->sm_link_key); 2099e0a03c85SMatthias Ringwald } 2100e0a03c85SMatthias Ringwald 2101c18be159SMatthias Ringwald static void sm_ctkd_fetch_br_edr_link_key(sm_connection_t * sm_conn){ 2102e0a03c85SMatthias Ringwald hci_connection_t * hci_connection = hci_connection_for_handle(sm_conn->sm_handle); 2103e0a03c85SMatthias Ringwald btstack_assert(hci_connection != NULL); 2104e0a03c85SMatthias Ringwald reverse_128(hci_connection->link_key, setup->sm_link_key); 2105e0a03c85SMatthias Ringwald setup->sm_link_key_type = hci_connection->link_key_type; 2106e0a03c85SMatthias Ringwald } 2107e0a03c85SMatthias Ringwald 210813aed524SMatthias Ringwald static void sm_ctkd_start_from_br_edr(sm_connection_t * sm_conn){ 210913aed524SMatthias Ringwald // only derive LTK if EncKey is set by both 211013aed524SMatthias Ringwald bool derive_ltk = (sm_pairing_packet_get_initiator_key_distribution(setup->sm_s_pres) & 211113aed524SMatthias Ringwald sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres) & SM_KEYDIST_ENC_KEY) != 0; 211213aed524SMatthias Ringwald if (derive_ltk){ 2113c18be159SMatthias Ringwald bool use_h7 = (sm_pairing_packet_get_auth_req(setup->sm_m_preq) & sm_pairing_packet_get_auth_req(setup->sm_s_pres) & SM_AUTHREQ_CT2) != 0; 211413aed524SMatthias Ringwald sm_conn->sm_engine_state = use_h7 ? SM_BR_EDR_W2_CALCULATE_ILK_USING_H7 : SM_BR_EDR_W2_CALCULATE_ILK_USING_H6; 211513aed524SMatthias Ringwald } else { 211613aed524SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 211713aed524SMatthias Ringwald } 2118c18be159SMatthias Ringwald } 2119c18be159SMatthias Ringwald 21209af0f475SMatthias Ringwald #endif 21219af0f475SMatthias Ringwald 212255c62cf5SMatthias Ringwald #endif 212355c62cf5SMatthias Ringwald 2124613da3deSMatthias Ringwald // key management legacy connections: 2125613da3deSMatthias Ringwald // - potentially two different LTKs based on direction. each device stores LTK provided by peer 2126613da3deSMatthias Ringwald // - master stores LTK, EDIV, RAND. responder optionally stored master LTK (only if it needs to reconnect) 2127613da3deSMatthias Ringwald // - initiators reconnects: initiator uses stored LTK, EDIV, RAND generated by responder 2128613da3deSMatthias Ringwald // - responder reconnects: responder uses LTK receveived from master 2129613da3deSMatthias Ringwald 2130613da3deSMatthias Ringwald // key management secure connections: 2131613da3deSMatthias Ringwald // - both devices store same LTK from ECDH key exchange. 2132613da3deSMatthias Ringwald 213342134bc6SMatthias Ringwald #if defined(ENABLE_LE_SECURE_CONNECTIONS) || defined(ENABLE_LE_CENTRAL) 21345829ebe2SMatthias Ringwald static void sm_load_security_info(sm_connection_t * sm_connection){ 21355829ebe2SMatthias Ringwald int encryption_key_size; 21365829ebe2SMatthias Ringwald int authenticated; 21375829ebe2SMatthias Ringwald int authorized; 21383dc3a67dSMatthias Ringwald int secure_connection; 21395829ebe2SMatthias Ringwald 21405829ebe2SMatthias Ringwald // fetch data from device db - incl. authenticated/authorized/key size. Note all sm_connection_X require encryption enabled 21415829ebe2SMatthias Ringwald le_device_db_encryption_get(sm_connection->sm_le_db_index, &setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk, 21423dc3a67dSMatthias Ringwald &encryption_key_size, &authenticated, &authorized, &secure_connection); 21433dc3a67dSMatthias Ringwald log_info("db index %u, key size %u, authenticated %u, authorized %u, secure connetion %u", sm_connection->sm_le_db_index, encryption_key_size, authenticated, authorized, secure_connection); 21445829ebe2SMatthias Ringwald sm_connection->sm_actual_encryption_key_size = encryption_key_size; 21455829ebe2SMatthias Ringwald sm_connection->sm_connection_authenticated = authenticated; 21465829ebe2SMatthias Ringwald sm_connection->sm_connection_authorization_state = authorized ? AUTHORIZATION_GRANTED : AUTHORIZATION_UNKNOWN; 21473dc3a67dSMatthias Ringwald sm_connection->sm_connection_sc = secure_connection; 21485829ebe2SMatthias Ringwald } 214942134bc6SMatthias Ringwald #endif 2150bd57ffebSMatthias Ringwald 215142134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 215259066796SMatthias Ringwald static void sm_start_calculating_ltk_from_ediv_and_rand(sm_connection_t * sm_connection){ 21536535961aSMatthias Ringwald (void)memcpy(setup->sm_local_rand, sm_connection->sm_local_rand, 8); 215459066796SMatthias Ringwald setup->sm_local_ediv = sm_connection->sm_local_ediv; 215559066796SMatthias Ringwald // re-establish used key encryption size 215659066796SMatthias Ringwald // no db for encryption size hack: encryption size is stored in lowest nibble of setup->sm_local_rand 21574ea43905SMatthias Ringwald sm_connection->sm_actual_encryption_key_size = (setup->sm_local_rand[7u] & 0x0fu) + 1u; 215859066796SMatthias Ringwald // no db for authenticated flag hack: flag is stored in bit 4 of LSB 21594ea43905SMatthias Ringwald sm_connection->sm_connection_authenticated = (setup->sm_local_rand[7u] & 0x10u) >> 4u; 21603dc3a67dSMatthias Ringwald // Legacy paring -> not SC 21613dc3a67dSMatthias Ringwald sm_connection->sm_connection_sc = 0; 216259066796SMatthias Ringwald log_info("sm: received ltk request with key size %u, authenticated %u", 216359066796SMatthias Ringwald sm_connection->sm_actual_encryption_key_size, sm_connection->sm_connection_authenticated); 216459066796SMatthias Ringwald } 216542134bc6SMatthias Ringwald #endif 216659066796SMatthias Ringwald 21673deb3ec6SMatthias Ringwald // distributed key generation 2168d7f1c72eSMatthias Ringwald static bool sm_run_dpkg(void){ 21693deb3ec6SMatthias Ringwald switch (dkg_state){ 21703deb3ec6SMatthias Ringwald case DKG_CALC_IRK: 21713deb3ec6SMatthias Ringwald // already busy? 21723deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_IDLE) { 2173d1a1f6a4SMatthias Ringwald log_info("DKG_CALC_IRK started"); 21743deb3ec6SMatthias Ringwald // IRK = d1(IR, 1, 0) 2175d1a1f6a4SMatthias Ringwald sm_d1_d_prime(1, 0, sm_aes128_plaintext); // plaintext = d1 prime 2176d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2177d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_ir, sm_aes128_plaintext, sm_persistent_irk, sm_handle_encryption_result_dkg_irk, NULL); 2178d7f1c72eSMatthias Ringwald return true; 21793deb3ec6SMatthias Ringwald } 21803deb3ec6SMatthias Ringwald break; 21813deb3ec6SMatthias Ringwald case DKG_CALC_DHK: 21823deb3ec6SMatthias Ringwald // already busy? 21833deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_IDLE) { 2184d1a1f6a4SMatthias Ringwald log_info("DKG_CALC_DHK started"); 21853deb3ec6SMatthias Ringwald // DHK = d1(IR, 3, 0) 2186d1a1f6a4SMatthias Ringwald sm_d1_d_prime(3, 0, sm_aes128_plaintext); // plaintext = d1 prime 2187d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2188d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_ir, sm_aes128_plaintext, sm_persistent_dhk, sm_handle_encryption_result_dkg_dhk, NULL); 2189d7f1c72eSMatthias Ringwald return true; 21903deb3ec6SMatthias Ringwald } 21913deb3ec6SMatthias Ringwald break; 21923deb3ec6SMatthias Ringwald default: 21933deb3ec6SMatthias Ringwald break; 21943deb3ec6SMatthias Ringwald } 2195d7f1c72eSMatthias Ringwald return false; 2196d7f1c72eSMatthias Ringwald } 21973deb3ec6SMatthias Ringwald 21983deb3ec6SMatthias Ringwald // random address updates 2199d7f1c72eSMatthias Ringwald static bool sm_run_rau(void){ 22003deb3ec6SMatthias Ringwald switch (rau_state){ 2201fbd4e238SMatthias Ringwald case RAU_GET_RANDOM: 2202fbd4e238SMatthias Ringwald rau_state = RAU_W4_RANDOM; 22035b4dd597SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_address, 6, &sm_handle_random_result_rau, NULL); 2204d7f1c72eSMatthias Ringwald return true; 22053deb3ec6SMatthias Ringwald case RAU_GET_ENC: 22063deb3ec6SMatthias Ringwald // already busy? 22073deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_IDLE) { 2208d1a1f6a4SMatthias Ringwald sm_ah_r_prime(sm_random_address, sm_aes128_plaintext); 2209d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2210d1a1f6a4SMatthias Ringwald btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_irk, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_rau, NULL); 2211d7f1c72eSMatthias Ringwald return true; 22123deb3ec6SMatthias Ringwald } 22133deb3ec6SMatthias Ringwald break; 22143deb3ec6SMatthias Ringwald default: 22153deb3ec6SMatthias Ringwald break; 22163deb3ec6SMatthias Ringwald } 2217d7f1c72eSMatthias Ringwald return false; 2218d7f1c72eSMatthias Ringwald } 22193deb3ec6SMatthias Ringwald 22203deb3ec6SMatthias Ringwald // CSRK Lookup 2221d7f1c72eSMatthias Ringwald static bool sm_run_csrk(void){ 2222d7f1c72eSMatthias Ringwald btstack_linked_list_iterator_t it; 2223d7f1c72eSMatthias Ringwald 22243deb3ec6SMatthias Ringwald // -- if csrk lookup ready, find connection that require csrk lookup 22253deb3ec6SMatthias Ringwald if (sm_address_resolution_idle()){ 22263deb3ec6SMatthias Ringwald hci_connections_get_iterator(&it); 2227665d90f2SMatthias Ringwald while(btstack_linked_list_iterator_has_next(&it)){ 2228665d90f2SMatthias Ringwald hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 22293deb3ec6SMatthias Ringwald sm_connection_t * sm_connection = &hci_connection->sm_connection; 22303deb3ec6SMatthias Ringwald if (sm_connection->sm_irk_lookup_state == IRK_LOOKUP_W4_READY){ 22313deb3ec6SMatthias Ringwald // and start lookup 22323deb3ec6SMatthias Ringwald sm_address_resolution_start_lookup(sm_connection->sm_peer_addr_type, sm_connection->sm_handle, sm_connection->sm_peer_address, ADDRESS_RESOLUTION_FOR_CONNECTION, sm_connection); 22333deb3ec6SMatthias Ringwald sm_connection->sm_irk_lookup_state = IRK_LOOKUP_STARTED; 22343deb3ec6SMatthias Ringwald break; 22353deb3ec6SMatthias Ringwald } 22363deb3ec6SMatthias Ringwald } 22373deb3ec6SMatthias Ringwald } 22383deb3ec6SMatthias Ringwald 22393deb3ec6SMatthias Ringwald // -- if csrk lookup ready, resolved addresses for received addresses 22403deb3ec6SMatthias Ringwald if (sm_address_resolution_idle()) { 2241665d90f2SMatthias Ringwald if (!btstack_linked_list_empty(&sm_address_resolution_general_queue)){ 22423deb3ec6SMatthias Ringwald sm_lookup_entry_t * entry = (sm_lookup_entry_t *) sm_address_resolution_general_queue; 2243665d90f2SMatthias Ringwald btstack_linked_list_remove(&sm_address_resolution_general_queue, (btstack_linked_item_t *) entry); 22443deb3ec6SMatthias Ringwald sm_address_resolution_start_lookup(entry->address_type, 0, entry->address, ADDRESS_RESOLUTION_GENERAL, NULL); 22453deb3ec6SMatthias Ringwald btstack_memory_sm_lookup_entry_free(entry); 22463deb3ec6SMatthias Ringwald } 22473deb3ec6SMatthias Ringwald } 22483deb3ec6SMatthias Ringwald 2249ca685291SMatthias Ringwald // -- Continue with device lookup by public or resolvable private address 22503deb3ec6SMatthias Ringwald if (!sm_address_resolution_idle()){ 2251092ec58eSMatthias Ringwald while (sm_address_resolution_test < le_device_db_max_count()){ 2252adf5eaa9SMatthias Ringwald int addr_type = BD_ADDR_TYPE_UNKNOWN; 22533deb3ec6SMatthias Ringwald bd_addr_t addr; 22543deb3ec6SMatthias Ringwald sm_key_t irk; 22553deb3ec6SMatthias Ringwald le_device_db_info(sm_address_resolution_test, &addr_type, addr, irk); 22563deb3ec6SMatthias Ringwald 2257adf5eaa9SMatthias Ringwald // skip unused entries 2258adf5eaa9SMatthias Ringwald if (addr_type == BD_ADDR_TYPE_UNKNOWN){ 2259adf5eaa9SMatthias Ringwald sm_address_resolution_test++; 2260adf5eaa9SMatthias Ringwald continue; 2261adf5eaa9SMatthias Ringwald } 2262adf5eaa9SMatthias Ringwald 2263ca685291SMatthias Ringwald log_info("LE Device Lookup: device %u of %u", sm_address_resolution_test, le_device_db_max_count()); 2264ca685291SMatthias Ringwald 22655df9dc78SMatthias Ringwald if ((sm_address_resolution_addr_type == addr_type) && (memcmp(addr, sm_address_resolution_address, 6) == 0)){ 2266ca685291SMatthias Ringwald log_info("LE Device Lookup: found by { addr_type, address} "); 2267a66b030fSMatthias Ringwald sm_address_resolution_handle_event(ADDRESS_RESOLUTION_SUCCEEDED); 22683deb3ec6SMatthias Ringwald break; 22693deb3ec6SMatthias Ringwald } 22703deb3ec6SMatthias Ringwald 2271a9987c8eSMatthias Ringwald // if connection type is public, it must be a different one 2272a9987c8eSMatthias Ringwald if (sm_address_resolution_addr_type == BD_ADDR_TYPE_LE_PUBLIC){ 22733deb3ec6SMatthias Ringwald sm_address_resolution_test++; 22743deb3ec6SMatthias Ringwald continue; 22753deb3ec6SMatthias Ringwald } 22763deb3ec6SMatthias Ringwald 22778cc81b50SMatthias Ringwald // skip AH if no IRK 22788cc81b50SMatthias Ringwald if (sm_is_null_key(irk)){ 22798cc81b50SMatthias Ringwald sm_address_resolution_test++; 22808cc81b50SMatthias Ringwald continue; 22818cc81b50SMatthias Ringwald } 22828cc81b50SMatthias Ringwald 22833deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 22843deb3ec6SMatthias Ringwald 22853deb3ec6SMatthias Ringwald log_info("LE Device Lookup: calculate AH"); 22868314c363SMatthias Ringwald log_info_key("IRK", irk); 22873deb3ec6SMatthias Ringwald 22886535961aSMatthias Ringwald (void)memcpy(sm_aes128_key, irk, 16); 2289d1a1f6a4SMatthias Ringwald sm_ah_r_prime(sm_address_resolution_address, sm_aes128_plaintext); 2290d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 2291d1a1f6a4SMatthias 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); 2292d7f1c72eSMatthias Ringwald return true; 22933deb3ec6SMatthias Ringwald } 22943deb3ec6SMatthias Ringwald 2295092ec58eSMatthias Ringwald if (sm_address_resolution_test >= le_device_db_max_count()){ 22963deb3ec6SMatthias Ringwald log_info("LE Device Lookup: not found"); 22973deb3ec6SMatthias Ringwald sm_address_resolution_handle_event(ADDRESS_RESOLUTION_FAILED); 22983deb3ec6SMatthias Ringwald } 22993deb3ec6SMatthias Ringwald } 2300d7f1c72eSMatthias Ringwald return false; 2301d7f1c72eSMatthias Ringwald } 23023deb3ec6SMatthias Ringwald 2303d7f1c72eSMatthias Ringwald // SC OOB 2304d7f1c72eSMatthias Ringwald static bool sm_run_oob(void){ 2305c59d0c92SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2306c59d0c92SMatthias Ringwald switch (sm_sc_oob_state){ 2307c59d0c92SMatthias Ringwald case SM_SC_OOB_W2_CALC_CONFIRM: 2308c59d0c92SMatthias Ringwald if (!sm_cmac_ready()) break; 2309c59d0c92SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_W4_CONFIRM; 2310c59d0c92SMatthias Ringwald f4_engine(NULL, ec_q, ec_q, sm_sc_oob_random, 0); 2311d7f1c72eSMatthias Ringwald return true; 2312c59d0c92SMatthias Ringwald default: 2313c59d0c92SMatthias Ringwald break; 2314c59d0c92SMatthias Ringwald } 2315c59d0c92SMatthias Ringwald #endif 2316d7f1c72eSMatthias Ringwald return false; 2317d7f1c72eSMatthias Ringwald } 2318275aafe8SMatthias Ringwald 2319687a03c8SMatthias Ringwald static void sm_send_connectionless(sm_connection_t * sm_connection, const uint8_t * buffer, uint16_t size){ 2320687a03c8SMatthias Ringwald l2cap_send_connectionless(sm_connection->sm_handle, sm_connection->sm_cid, (uint8_t*) buffer, size); 2321687a03c8SMatthias Ringwald } 2322687a03c8SMatthias Ringwald 232341d32297SMatthias Ringwald // handle basic actions that don't requires the full context 2324d7f1c72eSMatthias Ringwald static bool sm_run_basic(void){ 2325d7f1c72eSMatthias Ringwald btstack_linked_list_iterator_t it; 232641d32297SMatthias Ringwald hci_connections_get_iterator(&it); 2327e9af1bf6SMatthias Ringwald while(btstack_linked_list_iterator_has_next(&it)){ 232841d32297SMatthias Ringwald hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 232941d32297SMatthias Ringwald sm_connection_t * sm_connection = &hci_connection->sm_connection; 233041d32297SMatthias Ringwald switch(sm_connection->sm_engine_state){ 2331f4935286SMatthias Ringwald 2332f4935286SMatthias Ringwald // general 2333f4935286SMatthias Ringwald case SM_GENERAL_SEND_PAIRING_FAILED: { 2334f4935286SMatthias Ringwald uint8_t buffer[2]; 2335f4935286SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_FAILED; 2336f4935286SMatthias Ringwald buffer[1] = sm_connection->sm_pairing_failed_reason; 2337f4935286SMatthias Ringwald sm_connection->sm_engine_state = sm_connection->sm_role ? SM_RESPONDER_IDLE : SM_INITIATOR_CONNECTED; 2338687a03c8SMatthias Ringwald sm_send_connectionless(sm_connection, (uint8_t*) buffer, sizeof(buffer)); 2339f4935286SMatthias Ringwald sm_pairing_complete(sm_connection, ERROR_CODE_AUTHENTICATION_FAILURE, sm_connection->sm_pairing_failed_reason); 2340f4935286SMatthias Ringwald sm_done_for_handle(sm_connection->sm_handle); 2341f4935286SMatthias Ringwald break; 2342f4935286SMatthias Ringwald } 2343f4935286SMatthias Ringwald 234441d32297SMatthias Ringwald // responder side 234541d32297SMatthias Ringwald case SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY: 234641d32297SMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_IDLE; 234741d32297SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_negative_reply, sm_connection->sm_handle); 2348d7f1c72eSMatthias Ringwald return true; 23494b8b5afeSMatthias Ringwald 23504b8b5afeSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 23514b8b5afeSMatthias Ringwald case SM_SC_RECEIVED_LTK_REQUEST: 23524b8b5afeSMatthias Ringwald switch (sm_connection->sm_irk_lookup_state){ 23534b8b5afeSMatthias Ringwald case IRK_LOOKUP_FAILED: 2354e9af1bf6SMatthias Ringwald log_info("LTK Request: IRK Lookup Failed)"); 23554b8b5afeSMatthias Ringwald sm_connection->sm_engine_state = SM_RESPONDER_IDLE; 23564b8b5afeSMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_negative_reply, sm_connection->sm_handle); 2357d7f1c72eSMatthias Ringwald return true; 23584b8b5afeSMatthias Ringwald default: 23594b8b5afeSMatthias Ringwald break; 23604b8b5afeSMatthias Ringwald } 23614b8b5afeSMatthias Ringwald break; 23624b8b5afeSMatthias Ringwald #endif 236341d32297SMatthias Ringwald default: 236441d32297SMatthias Ringwald break; 236541d32297SMatthias Ringwald } 236641d32297SMatthias Ringwald } 2367d7f1c72eSMatthias Ringwald return false; 2368d7f1c72eSMatthias Ringwald } 23693deb3ec6SMatthias Ringwald 2370d7f1c72eSMatthias Ringwald static void sm_run_activate_connection(void){ 23713deb3ec6SMatthias Ringwald // Find connections that requires setup context and make active if no other is locked 2372d7f1c72eSMatthias Ringwald btstack_linked_list_iterator_t it; 23733deb3ec6SMatthias Ringwald hci_connections_get_iterator(&it); 23747149bde5SMatthias Ringwald while((sm_active_connection_handle == HCI_CON_HANDLE_INVALID) && btstack_linked_list_iterator_has_next(&it)){ 2375665d90f2SMatthias Ringwald hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 23763deb3ec6SMatthias Ringwald sm_connection_t * sm_connection = &hci_connection->sm_connection; 23773deb3ec6SMatthias Ringwald // - if no connection locked and we're ready/waiting for setup context, fetch it and start 23781979f09cSMatthias Ringwald bool done = true; 23793deb3ec6SMatthias Ringwald int err; 238042134bc6SMatthias Ringwald UNUSED(err); 238134b6528fSMatthias Ringwald 238234b6528fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 238334b6528fSMatthias Ringwald // assert ec key is ready 2384505f1c30SMatthias Ringwald if ( (sm_connection->sm_engine_state == SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED) 2385178e8c1bSMatthias Ringwald || (sm_connection->sm_engine_state == SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST) 2386178e8c1bSMatthias Ringwald || (sm_connection->sm_engine_state == SM_RESPONDER_SEND_SECURITY_REQUEST)){ 238734b6528fSMatthias Ringwald if (ec_key_generation_state == EC_KEY_GENERATION_IDLE){ 238834b6528fSMatthias Ringwald sm_ec_generate_new_key(); 238934b6528fSMatthias Ringwald } 239034b6528fSMatthias Ringwald if (ec_key_generation_state != EC_KEY_GENERATION_DONE){ 239134b6528fSMatthias Ringwald continue; 239234b6528fSMatthias Ringwald } 239334b6528fSMatthias Ringwald } 239434b6528fSMatthias Ringwald #endif 239534b6528fSMatthias Ringwald 23963deb3ec6SMatthias Ringwald switch (sm_connection->sm_engine_state) { 239742134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 23983deb3ec6SMatthias Ringwald case SM_RESPONDER_SEND_SECURITY_REQUEST: 23993deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED: 240042134bc6SMatthias Ringwald case SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST: 2401549ad5d2SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 240206cd539fSMatthias Ringwald case SM_SC_RECEIVED_LTK_REQUEST: 240387014f74SMatthias Ringwald #endif 240487014f74SMatthias Ringwald #endif 240534c39fbdSMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 24065567aa60SMatthias Ringwald case SM_INITIATOR_PH4_HAS_LTK: 240734c39fbdSMatthias Ringwald case SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST: 2408549ad5d2SMatthias Ringwald #endif 2409c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 2410c18be159SMatthias Ringwald case SM_BR_EDR_RESPONDER_PAIRING_REQUEST_RECEIVED: 2411c18be159SMatthias Ringwald case SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST: 2412c18be159SMatthias Ringwald #endif 241387014f74SMatthias Ringwald // just lock context 241487014f74SMatthias Ringwald break; 24153deb3ec6SMatthias Ringwald default: 24161979f09cSMatthias Ringwald done = false; 24173deb3ec6SMatthias Ringwald break; 24183deb3ec6SMatthias Ringwald } 24193deb3ec6SMatthias Ringwald if (done){ 24207149bde5SMatthias Ringwald sm_active_connection_handle = sm_connection->sm_handle; 24217149bde5SMatthias 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); 24223deb3ec6SMatthias Ringwald } 24233deb3ec6SMatthias Ringwald } 2424d7f1c72eSMatthias Ringwald } 2425d7f1c72eSMatthias Ringwald 2426403280b9SMatthias Ringwald static void sm_run_send_keypress_notification(sm_connection_t * connection){ 2427403280b9SMatthias Ringwald int i; 2428403280b9SMatthias Ringwald uint8_t flags = setup->sm_keypress_notification & 0x1fu; 2429403280b9SMatthias Ringwald uint8_t num_actions = setup->sm_keypress_notification >> 5; 2430403280b9SMatthias Ringwald uint8_t action = 0; 2431403280b9SMatthias Ringwald for (i=SM_KEYPRESS_PASSKEY_ENTRY_STARTED;i<=SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED;i++){ 2432403280b9SMatthias Ringwald if (flags & (1u<<i)){ 2433403280b9SMatthias Ringwald bool clear_flag = true; 2434403280b9SMatthias Ringwald switch (i){ 2435403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_STARTED: 2436403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_CLEARED: 2437403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED: 2438403280b9SMatthias Ringwald default: 2439403280b9SMatthias Ringwald break; 2440403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ENTERED: 2441403280b9SMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ERASED: 2442403280b9SMatthias Ringwald num_actions--; 2443403280b9SMatthias Ringwald clear_flag = num_actions == 0u; 2444403280b9SMatthias Ringwald break; 2445403280b9SMatthias Ringwald } 2446403280b9SMatthias Ringwald if (clear_flag){ 2447403280b9SMatthias Ringwald flags &= ~(1<<i); 2448403280b9SMatthias Ringwald } 2449403280b9SMatthias Ringwald action = i; 2450403280b9SMatthias Ringwald break; 2451403280b9SMatthias Ringwald } 2452403280b9SMatthias Ringwald } 2453403280b9SMatthias Ringwald setup->sm_keypress_notification = (num_actions << 5) | flags; 2454403280b9SMatthias Ringwald 2455403280b9SMatthias Ringwald // send keypress notification 2456403280b9SMatthias Ringwald uint8_t buffer[2]; 2457403280b9SMatthias Ringwald buffer[0] = SM_CODE_KEYPRESS_NOTIFICATION; 2458403280b9SMatthias Ringwald buffer[1] = action; 2459687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2460403280b9SMatthias Ringwald 2461403280b9SMatthias Ringwald // try 2462384eabd3SMatthias Ringwald l2cap_request_can_send_fix_channel_now_event(sm_active_connection_handle, connection->sm_cid); 2463403280b9SMatthias Ringwald } 2464403280b9SMatthias Ringwald 2465403280b9SMatthias Ringwald static void sm_run_distribute_keys(sm_connection_t * connection){ 2466403280b9SMatthias Ringwald if (setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION){ 2467403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 2468403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 2469403280b9SMatthias Ringwald uint8_t buffer[17]; 2470403280b9SMatthias Ringwald buffer[0] = SM_CODE_ENCRYPTION_INFORMATION; 2471403280b9SMatthias Ringwald reverse_128(setup->sm_ltk, &buffer[1]); 2472687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2473403280b9SMatthias Ringwald sm_timeout_reset(connection); 2474403280b9SMatthias Ringwald return; 2475403280b9SMatthias Ringwald } 2476403280b9SMatthias Ringwald if (setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_MASTER_IDENTIFICATION){ 2477403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 2478403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 2479403280b9SMatthias Ringwald uint8_t buffer[11]; 2480403280b9SMatthias Ringwald buffer[0] = SM_CODE_MASTER_IDENTIFICATION; 2481403280b9SMatthias Ringwald little_endian_store_16(buffer, 1, setup->sm_local_ediv); 2482403280b9SMatthias Ringwald reverse_64(setup->sm_local_rand, &buffer[3]); 2483687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2484403280b9SMatthias Ringwald sm_timeout_reset(connection); 2485403280b9SMatthias Ringwald return; 2486403280b9SMatthias Ringwald } 2487403280b9SMatthias Ringwald if (setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION){ 2488403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 2489403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 2490403280b9SMatthias Ringwald uint8_t buffer[17]; 2491403280b9SMatthias Ringwald buffer[0] = SM_CODE_IDENTITY_INFORMATION; 2492403280b9SMatthias Ringwald reverse_128(sm_persistent_irk, &buffer[1]); 2493687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2494403280b9SMatthias Ringwald sm_timeout_reset(connection); 2495403280b9SMatthias Ringwald return; 2496403280b9SMatthias Ringwald } 2497403280b9SMatthias Ringwald if (setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION){ 2498403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 2499403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 2500403280b9SMatthias Ringwald bd_addr_t local_address; 2501403280b9SMatthias Ringwald uint8_t buffer[8]; 2502403280b9SMatthias Ringwald buffer[0] = SM_CODE_IDENTITY_ADDRESS_INFORMATION; 2503403280b9SMatthias Ringwald switch (gap_random_address_get_mode()){ 2504403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_OFF: 2505403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_STATIC: 2506403280b9SMatthias Ringwald // public or static random 2507403280b9SMatthias Ringwald gap_le_get_own_address(&buffer[1], local_address); 2508403280b9SMatthias Ringwald break; 2509403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_NON_RESOLVABLE: 2510403280b9SMatthias Ringwald case GAP_RANDOM_ADDRESS_RESOLVABLE: 2511403280b9SMatthias Ringwald // fallback to public 2512403280b9SMatthias Ringwald gap_local_bd_addr(local_address); 2513403280b9SMatthias Ringwald buffer[1] = 0; 2514403280b9SMatthias Ringwald break; 2515403280b9SMatthias Ringwald default: 2516403280b9SMatthias Ringwald btstack_assert(false); 2517403280b9SMatthias Ringwald break; 2518403280b9SMatthias Ringwald } 2519403280b9SMatthias Ringwald reverse_bd_addr(local_address, &buffer[2]); 2520687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2521403280b9SMatthias Ringwald sm_timeout_reset(connection); 2522403280b9SMatthias Ringwald return; 2523403280b9SMatthias Ringwald } 2524403280b9SMatthias Ringwald if (setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION){ 2525403280b9SMatthias Ringwald setup->sm_key_distribution_send_set &= ~SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 2526403280b9SMatthias Ringwald setup->sm_key_distribution_sent_set |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 2527403280b9SMatthias Ringwald 2528403280b9SMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 2529403280b9SMatthias Ringwald // hack to reproduce test runs 2530403280b9SMatthias Ringwald if (test_use_fixed_local_csrk){ 2531403280b9SMatthias Ringwald memset(setup->sm_local_csrk, 0xcc, 16); 2532403280b9SMatthias Ringwald } 2533403280b9SMatthias Ringwald 2534403280b9SMatthias Ringwald // store local CSRK 2535403280b9SMatthias Ringwald if (setup->sm_le_device_index >= 0){ 2536403280b9SMatthias Ringwald log_info("sm: store local CSRK"); 2537403280b9SMatthias Ringwald le_device_db_local_csrk_set(setup->sm_le_device_index, setup->sm_local_csrk); 2538403280b9SMatthias Ringwald le_device_db_local_counter_set(setup->sm_le_device_index, 0); 2539403280b9SMatthias Ringwald } 2540403280b9SMatthias Ringwald #endif 2541403280b9SMatthias Ringwald 2542403280b9SMatthias Ringwald uint8_t buffer[17]; 2543403280b9SMatthias Ringwald buffer[0] = SM_CODE_SIGNING_INFORMATION; 2544403280b9SMatthias Ringwald reverse_128(setup->sm_local_csrk, &buffer[1]); 2545687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2546403280b9SMatthias Ringwald sm_timeout_reset(connection); 2547403280b9SMatthias Ringwald return; 2548403280b9SMatthias Ringwald } 2549403280b9SMatthias Ringwald btstack_assert(false); 2550403280b9SMatthias Ringwald } 2551403280b9SMatthias Ringwald 2552bbd73538SMatthias Ringwald static bool sm_ctkd_from_le(sm_connection_t *sm_connection) { 2553bbd73538SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 2554bbd73538SMatthias Ringwald // requirements to derive link key from LE: 2555bbd73538SMatthias Ringwald // - use secure connections 2556bbd73538SMatthias Ringwald if (setup->sm_use_secure_connections == 0) return false; 2557bbd73538SMatthias Ringwald // - bonding needs to be enabled: 2558bbd73538SMatthias 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; 2559bbd73538SMatthias Ringwald if (!bonding_enabled) return false; 2560bbd73538SMatthias Ringwald // - need identity address / public addr 2561bbd73538SMatthias 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); 2562bbd73538SMatthias Ringwald if (!have_identity_address_info) return false; 2563bbd73538SMatthias 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) 2564bbd73538SMatthias Ringwald // this requirement is motivated by BLURtooth paper. The paper recommends to not overwrite keys at all. 2565bbd73538SMatthias Ringwald // If SC is authenticated, we consider it safe to overwrite a stored key. 2566bbd73538SMatthias 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. 2567bbd73538SMatthias Ringwald uint8_t link_key[16]; 2568bbd73538SMatthias Ringwald link_key_type_t link_key_type; 2569bbd73538SMatthias Ringwald bool have_link_key = gap_get_link_key_for_bd_addr(setup->sm_peer_address, link_key, &link_key_type); 25707040ba26SMatthias Ringwald bool link_key_authenticated = gap_authenticated_for_link_key_type(link_key_type); 2571bbd73538SMatthias Ringwald bool derived_key_authenticated = sm_connection->sm_connection_authenticated != 0; 2572bbd73538SMatthias Ringwald if (have_link_key && link_key_authenticated && !derived_key_authenticated) { 2573bbd73538SMatthias Ringwald return false; 2574bbd73538SMatthias Ringwald } 2575bbd73538SMatthias Ringwald // get started (all of the above are true) 2576bbd73538SMatthias Ringwald return true; 2577bbd73538SMatthias Ringwald #else 2578bbd73538SMatthias Ringwald UNUSED(sm_connection); 2579bbd73538SMatthias Ringwald return false; 2580bbd73538SMatthias Ringwald #endif 2581bbd73538SMatthias Ringwald } 2582bbd73538SMatthias Ringwald 25836a718a5eSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 25846a718a5eSMatthias Ringwald static bool sm_ctkd_from_classic(sm_connection_t * sm_connection){ 25856a718a5eSMatthias Ringwald hci_connection_t * hci_connection = hci_connection_for_handle(sm_connection->sm_handle); 25866a718a5eSMatthias Ringwald btstack_assert(hci_connection != NULL); 25876a718a5eSMatthias Ringwald // requirements to derive ltk from BR/EDR: 25886a718a5eSMatthias Ringwald // - BR/EDR uses secure connections 25896a718a5eSMatthias Ringwald if (gap_secure_connection_for_link_key_type(hci_connection->link_key_type) == false) return false; 25906a718a5eSMatthias Ringwald // - bonding needs to be enabled: 25916a718a5eSMatthias 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; 25926a718a5eSMatthias Ringwald if (!bonding_enabled) return false; 25936a718a5eSMatthias 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) 25946a718a5eSMatthias Ringwald bool link_key_authenticated = gap_authenticated_for_link_key_type(hci_connection->link_key_type); 25956a718a5eSMatthias Ringwald if (link_key_authenticated) return true; 25966a718a5eSMatthias Ringwald int index = sm_le_device_db_index_lookup(BD_ADDR_TYPE_LE_PUBLIC, hci_connection->address); 25976a718a5eSMatthias Ringwald if (index >= 0){ 25986a718a5eSMatthias Ringwald int ltk_authenticated; 25996a718a5eSMatthias Ringwald sm_key_t ltk; 26006a718a5eSMatthias Ringwald le_device_db_encryption_get(sm_connection->sm_le_db_index, NULL, NULL, ltk, NULL, <k_authenticated, NULL, NULL); 26016a718a5eSMatthias Ringwald bool have_ltk = !sm_is_null_key(ltk); 26026a718a5eSMatthias Ringwald if (have_ltk && ltk_authenticated) return false; 26036a718a5eSMatthias Ringwald } 26046a718a5eSMatthias Ringwald return true; 26056a718a5eSMatthias Ringwald } 26066a718a5eSMatthias Ringwald #endif 26076a718a5eSMatthias Ringwald 26086f7422f1SMatthias Ringwald static void sm_key_distribution_complete_responder(sm_connection_t * connection){ 26096f7422f1SMatthias Ringwald if (sm_ctkd_from_le(connection)){ 26106f7422f1SMatthias 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; 26116f7422f1SMatthias Ringwald connection->sm_engine_state = use_h7 ? SM_SC_W2_CALCULATE_ILK_USING_H7 : SM_SC_W2_CALCULATE_ILK_USING_H6; 26126f7422f1SMatthias Ringwald } else { 26136f7422f1SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_IDLE; 26146f7422f1SMatthias Ringwald sm_pairing_complete(connection, ERROR_CODE_SUCCESS, 0); 26156f7422f1SMatthias Ringwald sm_done_for_handle(connection->sm_handle); 26166f7422f1SMatthias Ringwald } 26176f7422f1SMatthias Ringwald } 26186f7422f1SMatthias Ringwald 2619af7ef9d1SMatthias Ringwald static void sm_key_distribution_complete_initiator(sm_connection_t * connection){ 2620af7ef9d1SMatthias Ringwald if (sm_ctkd_from_le(connection)){ 2621af7ef9d1SMatthias 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; 2622af7ef9d1SMatthias Ringwald connection->sm_engine_state = use_h7 ? SM_SC_W2_CALCULATE_ILK_USING_H7 : SM_SC_W2_CALCULATE_ILK_USING_H6; 2623af7ef9d1SMatthias Ringwald } else { 2624af7ef9d1SMatthias Ringwald sm_master_pairing_success(connection); 2625af7ef9d1SMatthias Ringwald } 2626af7ef9d1SMatthias Ringwald } 2627af7ef9d1SMatthias Ringwald 2628b919f264SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2629b919f264SMatthias Ringwald static void sm_run_state_sc_send_confirmation(sm_connection_t *connection) { 2630b919f264SMatthias Ringwald uint8_t buffer[17]; 2631b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_CONFIRM; 2632b919f264SMatthias Ringwald reverse_128(setup->sm_local_confirm, &buffer[1]); 2633b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2634b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2635b919f264SMatthias Ringwald } else { 2636b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2637b919f264SMatthias Ringwald } 2638b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2639b919f264SMatthias Ringwald sm_timeout_reset(connection); 2640b919f264SMatthias Ringwald } 2641b919f264SMatthias Ringwald 2642b919f264SMatthias Ringwald static void sm_run_state_sc_send_pairing_random(sm_connection_t *connection) { 2643b919f264SMatthias Ringwald uint8_t buffer[17]; 2644b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_RANDOM; 2645b919f264SMatthias Ringwald reverse_128(setup->sm_local_nonce, &buffer[1]); 2646b919f264SMatthias Ringwald log_info("stk method %u, bit num: %u", setup->sm_stk_generation_method, setup->sm_passkey_bit); 2647b919f264SMatthias Ringwald if (sm_passkey_entry(setup->sm_stk_generation_method) && (setup->sm_passkey_bit < 20u)){ 2648b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM A"); 2649b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2650b919f264SMatthias Ringwald // responder 2651b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2652b919f264SMatthias Ringwald } else { 2653b919f264SMatthias Ringwald // initiator 2654b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2655b919f264SMatthias Ringwald } 2656b919f264SMatthias Ringwald } else { 2657b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM B"); 2658b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2659b919f264SMatthias Ringwald // responder 2660b919f264SMatthias Ringwald if (setup->sm_stk_generation_method == NUMERIC_COMPARISON){ 2661b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM B1"); 2662b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W2_CALCULATE_G2; 2663b919f264SMatthias Ringwald } else { 2664b919f264SMatthias Ringwald log_info("SM_SC_SEND_PAIRING_RANDOM B2"); 2665b919f264SMatthias Ringwald sm_sc_prepare_dhkey_check(connection); 2666b919f264SMatthias Ringwald } 2667b919f264SMatthias Ringwald } else { 2668b919f264SMatthias Ringwald // initiator 2669b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2670b919f264SMatthias Ringwald } 2671b919f264SMatthias Ringwald } 2672b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2673b919f264SMatthias Ringwald sm_timeout_reset(connection); 2674b919f264SMatthias Ringwald } 2675b919f264SMatthias Ringwald 2676b919f264SMatthias Ringwald static void sm_run_state_sc_send_dhkey_check_command(sm_connection_t *connection) { 2677b919f264SMatthias Ringwald uint8_t buffer[17]; 2678b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_DHKEY_CHECK; 2679b919f264SMatthias Ringwald reverse_128(setup->sm_local_dhkey_check, &buffer[1]); 2680b919f264SMatthias Ringwald 2681b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2682b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_LTK_REQUEST_SC; 2683b919f264SMatthias Ringwald } else { 2684b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_DHKEY_CHECK_COMMAND; 2685b919f264SMatthias Ringwald } 2686b919f264SMatthias Ringwald 2687b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2688b919f264SMatthias Ringwald sm_timeout_reset(connection); 2689b919f264SMatthias Ringwald } 2690b919f264SMatthias Ringwald 2691b919f264SMatthias Ringwald static void sm_run_state_sc_send_public_key_command(sm_connection_t *connection) { 2692b919f264SMatthias Ringwald bool trigger_user_response = false; 2693b919f264SMatthias Ringwald bool trigger_start_calculating_local_confirm = false; 2694b919f264SMatthias Ringwald uint8_t buffer[65]; 2695b919f264SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_PUBLIC_KEY; 2696b919f264SMatthias Ringwald // 2697b919f264SMatthias Ringwald reverse_256(&ec_q[0], &buffer[1]); 2698b919f264SMatthias Ringwald reverse_256(&ec_q[32], &buffer[33]); 2699b919f264SMatthias Ringwald 2700b919f264SMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 2701b919f264SMatthias Ringwald if (test_pairing_failure == SM_REASON_DHKEY_CHECK_FAILED){ 2702b919f264SMatthias Ringwald log_info("testing_support: invalidating public key"); 2703b919f264SMatthias Ringwald // flip single bit of public key coordinate 2704b919f264SMatthias Ringwald buffer[1] ^= 1; 2705b919f264SMatthias Ringwald } 2706b919f264SMatthias Ringwald #endif 2707b919f264SMatthias Ringwald 2708b919f264SMatthias Ringwald // stk generation method 2709b919f264SMatthias Ringwald // passkey entry: notify app to show passkey or to request passkey 2710b919f264SMatthias Ringwald switch (setup->sm_stk_generation_method){ 2711b919f264SMatthias Ringwald case JUST_WORKS: 2712b919f264SMatthias Ringwald case NUMERIC_COMPARISON: 2713b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2714b919f264SMatthias Ringwald // responder 2715b919f264SMatthias Ringwald trigger_start_calculating_local_confirm = true; 2716b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_LOCAL_NONCE; 2717b919f264SMatthias Ringwald } else { 2718b919f264SMatthias Ringwald // initiator 2719b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2720b919f264SMatthias Ringwald } 2721b919f264SMatthias Ringwald break; 2722b919f264SMatthias Ringwald case PK_INIT_INPUT: 2723b919f264SMatthias Ringwald case PK_RESP_INPUT: 2724b919f264SMatthias Ringwald case PK_BOTH_INPUT: 2725b919f264SMatthias Ringwald // use random TK for display 2726b919f264SMatthias Ringwald (void)memcpy(setup->sm_ra, setup->sm_tk, 16); 2727b919f264SMatthias Ringwald (void)memcpy(setup->sm_rb, setup->sm_tk, 16); 2728b919f264SMatthias Ringwald setup->sm_passkey_bit = 0; 2729b919f264SMatthias Ringwald 2730b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2731b919f264SMatthias Ringwald // responder 2732b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2733b919f264SMatthias Ringwald } else { 2734b919f264SMatthias Ringwald // initiator 2735b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2736b919f264SMatthias Ringwald } 2737b919f264SMatthias Ringwald trigger_user_response = true; 2738b919f264SMatthias Ringwald break; 2739b919f264SMatthias Ringwald case OOB: 2740b919f264SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 2741b919f264SMatthias Ringwald // responder 2742b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2743b919f264SMatthias Ringwald } else { 2744b919f264SMatthias Ringwald // initiator 2745b919f264SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2746b919f264SMatthias Ringwald } 2747b919f264SMatthias Ringwald break; 2748b919f264SMatthias Ringwald default: 2749b919f264SMatthias Ringwald btstack_assert(false); 2750b919f264SMatthias Ringwald break; 2751b919f264SMatthias Ringwald } 2752b919f264SMatthias Ringwald 2753b919f264SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 2754b919f264SMatthias Ringwald sm_timeout_reset(connection); 2755b919f264SMatthias Ringwald 2756b919f264SMatthias Ringwald // trigger user response and calc confirm after sending pdu 2757b919f264SMatthias Ringwald if (trigger_user_response){ 2758b919f264SMatthias Ringwald sm_trigger_user_response(connection); 2759b919f264SMatthias Ringwald } 2760b919f264SMatthias Ringwald if (trigger_start_calculating_local_confirm){ 2761b919f264SMatthias Ringwald sm_sc_start_calculating_local_confirm(connection); 2762b919f264SMatthias Ringwald } 2763b919f264SMatthias Ringwald } 2764b919f264SMatthias Ringwald #endif 2765b919f264SMatthias Ringwald 2766de42cac5SMatthias Ringwald static bool sm_run_non_connection_logic(void){ 2767de42cac5SMatthias Ringwald bool done;; 2768de42cac5SMatthias Ringwald 2769de42cac5SMatthias Ringwald done = sm_run_dpkg(); 2770de42cac5SMatthias Ringwald if (done) return true; 2771de42cac5SMatthias Ringwald 2772de42cac5SMatthias Ringwald done = sm_run_rau(); 2773de42cac5SMatthias Ringwald if (done) return true; 2774de42cac5SMatthias Ringwald 2775de42cac5SMatthias Ringwald done = sm_run_csrk(); 2776de42cac5SMatthias Ringwald if (done) return true; 2777de42cac5SMatthias Ringwald 2778de42cac5SMatthias Ringwald done = sm_run_oob(); 2779de42cac5SMatthias Ringwald return done; 2780de42cac5SMatthias Ringwald } 2781b919f264SMatthias Ringwald 2782d7f1c72eSMatthias Ringwald static void sm_run(void){ 2783d7f1c72eSMatthias Ringwald 2784d7f1c72eSMatthias Ringwald // assert that stack has already bootet 2785d7f1c72eSMatthias Ringwald if (hci_get_state() != HCI_STATE_WORKING) return; 2786d7f1c72eSMatthias Ringwald 2787d7f1c72eSMatthias Ringwald // assert that we can send at least commands 2788d7f1c72eSMatthias Ringwald if (!hci_can_send_command_packet_now()) return; 2789d7f1c72eSMatthias Ringwald 2790d7f1c72eSMatthias Ringwald // pause until IR/ER are ready 2791d7f1c72eSMatthias Ringwald if (sm_persistent_keys_random_active) return; 2792d7f1c72eSMatthias Ringwald 2793d7f1c72eSMatthias Ringwald // non-connection related behaviour 2794de42cac5SMatthias Ringwald bool done = sm_run_non_connection_logic(); 2795d7f1c72eSMatthias Ringwald if (done) return; 2796d7f1c72eSMatthias Ringwald 2797d7f1c72eSMatthias Ringwald // assert that we can send at least commands - cmd might have been sent by crypto engine 2798d7f1c72eSMatthias Ringwald if (!hci_can_send_command_packet_now()) return; 2799d7f1c72eSMatthias Ringwald 2800d7f1c72eSMatthias Ringwald // handle basic actions that don't requires the full context 2801d7f1c72eSMatthias Ringwald done = sm_run_basic(); 2802d7f1c72eSMatthias Ringwald if (done) return; 2803d7f1c72eSMatthias Ringwald 2804d7f1c72eSMatthias Ringwald // 2805d7f1c72eSMatthias Ringwald // active connection handling 2806d7f1c72eSMatthias Ringwald // -- use loop to handle next connection if lock on setup context is released 2807d7f1c72eSMatthias Ringwald 2808d7f1c72eSMatthias Ringwald while (true) { 2809d7f1c72eSMatthias Ringwald 2810d7f1c72eSMatthias Ringwald sm_run_activate_connection(); 2811d7f1c72eSMatthias Ringwald 2812d7f1c72eSMatthias Ringwald if (sm_active_connection_handle == HCI_CON_HANDLE_INVALID) return; 28133deb3ec6SMatthias Ringwald 28143deb3ec6SMatthias Ringwald // 28153deb3ec6SMatthias Ringwald // active connection handling 28163deb3ec6SMatthias Ringwald // 28173deb3ec6SMatthias Ringwald 28183cf37b8cSMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(sm_active_connection_handle); 28193cf37b8cSMatthias Ringwald if (!connection) { 28203cf37b8cSMatthias Ringwald log_info("no connection for handle 0x%04x", sm_active_connection_handle); 28213cf37b8cSMatthias Ringwald return; 28223cf37b8cSMatthias Ringwald } 28233cf37b8cSMatthias Ringwald 28243deb3ec6SMatthias Ringwald // assert that we could send a SM PDU - not needed for all of the following 2825384eabd3SMatthias Ringwald if (!l2cap_can_send_fixed_channel_packet_now(sm_active_connection_handle, connection->sm_cid)) { 28267149bde5SMatthias Ringwald log_info("cannot send now, requesting can send now event"); 2827384eabd3SMatthias Ringwald l2cap_request_can_send_fix_channel_now_event(sm_active_connection_handle, connection->sm_cid); 2828b170b20fSMatthias Ringwald return; 2829b170b20fSMatthias Ringwald } 28303deb3ec6SMatthias Ringwald 28313d7fe1e9SMatthias Ringwald // send keypress notifications 2832dd4a08fbSMatthias Ringwald if (setup->sm_keypress_notification){ 2833403280b9SMatthias Ringwald sm_run_send_keypress_notification(connection); 2834d7471931SMatthias Ringwald return; 28353d7fe1e9SMatthias Ringwald } 28363d7fe1e9SMatthias Ringwald 2837f7ea4423SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2838234022e5SMatthias Ringwald // assert that sm cmac engine is ready 2839234022e5SMatthias Ringwald if (sm_cmac_ready() == false){ 2840234022e5SMatthias Ringwald break; 2841234022e5SMatthias Ringwald } 2842f7ea4423SMatthias Ringwald #endif 2843234022e5SMatthias Ringwald 28443deb3ec6SMatthias Ringwald int key_distribution_flags; 284542134bc6SMatthias Ringwald UNUSED(key_distribution_flags); 2846b6f39a74SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 2847b6afa23eSMatthias Ringwald int err; 28489b75de03SMatthias Ringwald bool have_ltk; 28499b75de03SMatthias Ringwald uint8_t ltk[16]; 2850b6f39a74SMatthias Ringwald #endif 28513deb3ec6SMatthias Ringwald 28523deb3ec6SMatthias Ringwald log_info("sm_run: state %u", connection->sm_engine_state); 28533deb3ec6SMatthias Ringwald switch (connection->sm_engine_state){ 28543deb3ec6SMatthias Ringwald 2855f32b7a88SMatthias Ringwald // secure connections, initiator + responding states 2856aec94140SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2857aec94140SMatthias Ringwald case SM_SC_W2_CMAC_FOR_CONFIRMATION: 2858aec94140SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CMAC_FOR_CONFIRMATION; 2859aec94140SMatthias Ringwald sm_sc_calculate_local_confirm(connection); 2860aec94140SMatthias Ringwald break; 2861688a08f9SMatthias Ringwald case SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION: 2862688a08f9SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CMAC_FOR_CHECK_CONFIRMATION; 2863688a08f9SMatthias Ringwald sm_sc_calculate_remote_confirm(connection); 2864688a08f9SMatthias Ringwald break; 2865dc300847SMatthias Ringwald case SM_SC_W2_CALCULATE_F6_FOR_DHKEY_CHECK: 2866dc300847SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F6_FOR_DHKEY_CHECK; 2867dc300847SMatthias Ringwald sm_sc_calculate_f6_for_dhkey_check(connection); 2868dc300847SMatthias Ringwald break; 2869019005a0SMatthias Ringwald case SM_SC_W2_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK: 2870019005a0SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK; 28710346c37cSMatthias Ringwald sm_sc_calculate_f6_to_verify_dhkey_check(connection); 28720346c37cSMatthias Ringwald break; 28730346c37cSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_SALT: 28740346c37cSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F5_SALT; 28750346c37cSMatthias Ringwald f5_calculate_salt(connection); 28760346c37cSMatthias Ringwald break; 28770346c37cSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_MACKEY: 28780346c37cSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F5_MACKEY; 28790346c37cSMatthias Ringwald f5_calculate_mackey(connection); 28800346c37cSMatthias Ringwald break; 28810346c37cSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_LTK: 28820346c37cSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_F5_LTK; 28830346c37cSMatthias Ringwald f5_calculate_ltk(connection); 2884019005a0SMatthias Ringwald break; 2885bd57ffebSMatthias Ringwald case SM_SC_W2_CALCULATE_G2: 2886bd57ffebSMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_G2; 2887b35a3de2SMatthias Ringwald g2_calculate(connection); 2888bd57ffebSMatthias Ringwald break; 2889e0a03c85SMatthias Ringwald #endif 2890e0a03c85SMatthias Ringwald 289142134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 28923deb3ec6SMatthias Ringwald // initiator side 2893f32b7a88SMatthias Ringwald 28945567aa60SMatthias Ringwald case SM_INITIATOR_PH4_HAS_LTK: { 2895f32b7a88SMatthias Ringwald sm_reset_setup(); 2896f32b7a88SMatthias Ringwald sm_load_security_info(connection); 2897f32b7a88SMatthias Ringwald 28983deb3ec6SMatthias Ringwald sm_key_t peer_ltk_flipped; 28999c80e4ccSMatthias Ringwald reverse_128(setup->sm_peer_ltk, peer_ltk_flipped); 29005567aa60SMatthias Ringwald connection->sm_engine_state = SM_PH4_W4_CONNECTION_ENCRYPTED; 29013deb3ec6SMatthias Ringwald log_info("sm: hci_le_start_encryption ediv 0x%04x", setup->sm_peer_ediv); 2902c9b8fdd9SMatthias Ringwald uint32_t rand_high = big_endian_read_32(setup->sm_peer_rand, 0); 2903c9b8fdd9SMatthias Ringwald uint32_t rand_low = big_endian_read_32(setup->sm_peer_rand, 4); 29043deb3ec6SMatthias Ringwald hci_send_cmd(&hci_le_start_encryption, connection->sm_handle,rand_low, rand_high, setup->sm_peer_ediv, peer_ltk_flipped); 290549c9e430SMatthias Ringwald 290649c9e430SMatthias Ringwald // notify after sending 290749c9e430SMatthias Ringwald sm_reencryption_started(connection); 29083deb3ec6SMatthias Ringwald return; 29093deb3ec6SMatthias Ringwald } 29103deb3ec6SMatthias Ringwald 2911b26f445fSMatthias Ringwald case SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST: 2912b26f445fSMatthias Ringwald sm_reset_setup(); 2913b26f445fSMatthias Ringwald sm_init_setup(connection); 2914b26f445fSMatthias Ringwald 29151ad129beSMatthias Ringwald sm_pairing_packet_set_code(setup->sm_m_preq, SM_CODE_PAIRING_REQUEST); 29163deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH1_W4_PAIRING_RESPONSE; 2917687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) &setup->sm_m_preq, sizeof(sm_pairing_packet_t)); 29183deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 291949c9e430SMatthias Ringwald 292049c9e430SMatthias Ringwald // notify after sending 292149c9e430SMatthias Ringwald sm_pairing_started(connection); 29223deb3ec6SMatthias Ringwald break; 292342134bc6SMatthias Ringwald #endif 29243deb3ec6SMatthias Ringwald 292527c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 2926b919f264SMatthias Ringwald case SM_SC_SEND_PUBLIC_KEY_COMMAND: 2927b919f264SMatthias Ringwald sm_run_state_sc_send_public_key_command(connection); 292845a61d50SMatthias Ringwald break; 2929b919f264SMatthias Ringwald case SM_SC_SEND_CONFIRMATION: 2930b919f264SMatthias Ringwald sm_run_state_sc_send_confirmation(connection); 293145a61d50SMatthias Ringwald break; 2932b919f264SMatthias Ringwald case SM_SC_SEND_PAIRING_RANDOM: 2933b919f264SMatthias Ringwald sm_run_state_sc_send_pairing_random(connection); 293445a61d50SMatthias Ringwald break; 2935b919f264SMatthias Ringwald case SM_SC_SEND_DHKEY_CHECK_COMMAND: 2936b919f264SMatthias Ringwald sm_run_state_sc_send_dhkey_check_command(connection); 29377bbeb3adSMilanka Ringwald break; 2938e53be891SMatthias Ringwald #endif 293942134bc6SMatthias Ringwald 294042134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 2941dd12a62bSMatthias Ringwald 294287014f74SMatthias Ringwald case SM_RESPONDER_SEND_SECURITY_REQUEST: { 294387014f74SMatthias Ringwald const uint8_t buffer[2] = {SM_CODE_SECURITY_REQUEST, sm_auth_req}; 294487014f74SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH1_W4_PAIRING_REQUEST; 2945687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t *) buffer, sizeof(buffer)); 2946c8d0ff33SMatthias Ringwald sm_timeout_start(connection); 294787014f74SMatthias Ringwald break; 294887014f74SMatthias Ringwald } 294987014f74SMatthias Ringwald 295038196718SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 295138196718SMatthias Ringwald case SM_SC_RECEIVED_LTK_REQUEST: 295238196718SMatthias Ringwald switch (connection->sm_irk_lookup_state){ 295338196718SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 295438196718SMatthias Ringwald // assuming Secure Connection, we have a stored LTK and the EDIV/RAND are null 295538196718SMatthias Ringwald // start using context by loading security info 295638196718SMatthias Ringwald sm_reset_setup(); 295738196718SMatthias Ringwald sm_load_security_info(connection); 295838196718SMatthias Ringwald if ((setup->sm_peer_ediv == 0u) && sm_is_null_random(setup->sm_peer_rand) && !sm_is_null_key(setup->sm_peer_ltk)){ 295938196718SMatthias Ringwald (void)memcpy(setup->sm_ltk, setup->sm_peer_ltk, 16); 296038196718SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH4_SEND_LTK_REPLY; 296142646f38SMatthias Ringwald sm_reencryption_started(connection); 296238196718SMatthias Ringwald sm_trigger_run(); 296338196718SMatthias Ringwald break; 296438196718SMatthias Ringwald } 296538196718SMatthias Ringwald log_info("LTK Request: ediv & random are empty, but no stored LTK (IRK Lookup Succeeded)"); 296638196718SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_IDLE; 296738196718SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_negative_reply, connection->sm_handle); 296838196718SMatthias Ringwald return; 296938196718SMatthias Ringwald default: 297038196718SMatthias Ringwald // just wait until IRK lookup is completed 297138196718SMatthias Ringwald break; 297238196718SMatthias Ringwald } 297338196718SMatthias Ringwald break; 297438196718SMatthias Ringwald #endif /* ENABLE_LE_SECURE_CONNECTIONS */ 297538196718SMatthias Ringwald 2976b6afa23eSMatthias Ringwald case SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED: 2977b6afa23eSMatthias Ringwald sm_reset_setup(); 29789b75de03SMatthias Ringwald 29799b75de03SMatthias Ringwald // handle Pairing Request with LTK available 29809b75de03SMatthias Ringwald switch (connection->sm_irk_lookup_state) { 29819b75de03SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 29829b75de03SMatthias Ringwald le_device_db_encryption_get(connection->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); 29839b75de03SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 29849b75de03SMatthias Ringwald if (have_ltk){ 29859b75de03SMatthias Ringwald log_info("pairing request but LTK available"); 298619a40772SMatthias Ringwald // emit re-encryption start/fail sequence 29879b75de03SMatthias Ringwald sm_reencryption_started(connection); 29889b75de03SMatthias Ringwald sm_reencryption_complete(connection, ERROR_CODE_PIN_OR_KEY_MISSING); 29899b75de03SMatthias Ringwald } 29909b75de03SMatthias Ringwald break; 29919b75de03SMatthias Ringwald default: 29929b75de03SMatthias Ringwald break; 29939b75de03SMatthias Ringwald } 29949b75de03SMatthias Ringwald 2995b6afa23eSMatthias Ringwald sm_init_setup(connection); 299639543d07SMatthias Ringwald 2997b6afa23eSMatthias Ringwald // recover pairing request 2998b6afa23eSMatthias Ringwald (void)memcpy(&setup->sm_m_preq, &connection->sm_m_preq, sizeof(sm_pairing_packet_t)); 2999b6afa23eSMatthias Ringwald err = sm_stk_generation_init(connection); 3000b6afa23eSMatthias Ringwald 3001b6afa23eSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 3002b6afa23eSMatthias Ringwald if ((0 < test_pairing_failure) && (test_pairing_failure < SM_REASON_DHKEY_CHECK_FAILED)){ 3003b6afa23eSMatthias Ringwald log_info("testing_support: respond with pairing failure %u", test_pairing_failure); 3004b6afa23eSMatthias Ringwald err = test_pairing_failure; 3005b6afa23eSMatthias Ringwald } 3006b6afa23eSMatthias Ringwald #endif 30079305033eSMatthias Ringwald if (err != 0){ 300849c9e430SMatthias Ringwald // emit pairing started/failed sequence 300949c9e430SMatthias Ringwald sm_pairing_started(connection); 3010f4935286SMatthias Ringwald sm_pairing_error(connection, err); 3011b6afa23eSMatthias Ringwald sm_trigger_run(); 3012b6afa23eSMatthias Ringwald break; 3013b6afa23eSMatthias Ringwald } 3014b6afa23eSMatthias Ringwald 3015b6afa23eSMatthias Ringwald sm_timeout_start(connection); 3016b6afa23eSMatthias Ringwald 3017b6afa23eSMatthias Ringwald // generate random number first, if we need to show passkey, otherwise send response 3018b6afa23eSMatthias Ringwald if (setup->sm_stk_generation_method == PK_INIT_INPUT){ 3019b6afa23eSMatthias 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); 3020b6afa23eSMatthias Ringwald break; 3021b6afa23eSMatthias Ringwald } 3022b6afa23eSMatthias Ringwald 3023b6afa23eSMatthias Ringwald /* fall through */ 3024b6afa23eSMatthias Ringwald 30253deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE: 30261ad129beSMatthias Ringwald sm_pairing_packet_set_code(setup->sm_s_pres,SM_CODE_PAIRING_RESPONSE); 3027f55bd529SMatthias Ringwald 3028f55bd529SMatthias Ringwald // start with initiator key dist flags 30293deb3ec6SMatthias Ringwald key_distribution_flags = sm_key_distribution_flags_for_auth_req(); 30301ad129beSMatthias Ringwald 3031f55bd529SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 3032f55bd529SMatthias Ringwald // LTK (= encyrption information & master identification) only exchanged for LE Legacy Connection 3033f55bd529SMatthias Ringwald if (setup->sm_use_secure_connections){ 3034f55bd529SMatthias Ringwald key_distribution_flags &= ~SM_KEYDIST_ENC_KEY; 3035f55bd529SMatthias Ringwald } 3036f55bd529SMatthias Ringwald #endif 3037f55bd529SMatthias Ringwald // setup in response 3038f55bd529SMatthias 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); 3039f55bd529SMatthias 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); 3040f55bd529SMatthias Ringwald 3041f55bd529SMatthias Ringwald // update key distribution after ENC was dropped 30429a90d41aSMatthias 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)); 3043f55bd529SMatthias Ringwald 304427c32905SMatthias Ringwald if (setup->sm_use_secure_connections){ 3045c6b7cbd9SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 30460b8af2a5SMatthias Ringwald } else { 30470b8af2a5SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH1_W4_PAIRING_CONFIRM; 304827c32905SMatthias Ringwald } 30490b8af2a5SMatthias Ringwald 3050687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) &setup->sm_s_pres, sizeof(sm_pairing_packet_t)); 30513deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 305249c9e430SMatthias Ringwald 305349c9e430SMatthias Ringwald // notify after sending 305449c9e430SMatthias Ringwald sm_pairing_started(connection); 305549c9e430SMatthias Ringwald 3056446a8c36SMatthias Ringwald // SC Numeric Comparison will trigger user response after public keys & nonces have been exchanged 3057c1ab6cc1SMatthias Ringwald if (!setup->sm_use_secure_connections || (setup->sm_stk_generation_method == JUST_WORKS)){ 30583deb3ec6SMatthias Ringwald sm_trigger_user_response(connection); 3059446a8c36SMatthias Ringwald } 30603deb3ec6SMatthias Ringwald return; 306142134bc6SMatthias Ringwald #endif 30623deb3ec6SMatthias Ringwald 30633deb3ec6SMatthias Ringwald case SM_PH2_SEND_PAIRING_RANDOM: { 30643deb3ec6SMatthias Ringwald uint8_t buffer[17]; 30653deb3ec6SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_RANDOM; 30669c80e4ccSMatthias Ringwald reverse_128(setup->sm_local_random, &buffer[1]); 306742134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 30683deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH2_W4_LTK_REQUEST; 30693deb3ec6SMatthias Ringwald } else { 30703deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH2_W4_PAIRING_RANDOM; 30713deb3ec6SMatthias Ringwald } 3072687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 30733deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 30743deb3ec6SMatthias Ringwald break; 30753deb3ec6SMatthias Ringwald } 30763deb3ec6SMatthias Ringwald 3077d1a1f6a4SMatthias Ringwald case SM_PH2_C1_GET_ENC_A: 30783deb3ec6SMatthias Ringwald // already busy? 30793deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 3080d1a1f6a4SMatthias Ringwald // calculate confirm using aes128 engine - step 1 3081d1a1f6a4SMatthias 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); 3082d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_W4_ENC_A; 3083d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3084f3582630SMatthias 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); 30853deb3ec6SMatthias Ringwald break; 30863deb3ec6SMatthias Ringwald 30873deb3ec6SMatthias Ringwald case SM_PH2_C1_GET_ENC_C: 30883deb3ec6SMatthias Ringwald // already busy? 30893deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 30903deb3ec6SMatthias Ringwald // calculate m_confirm using aes128 engine - step 1 3091d1a1f6a4SMatthias 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); 3092d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_W4_ENC_C; 3093d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3094f3582630SMatthias 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); 30953deb3ec6SMatthias Ringwald break; 3096d1a1f6a4SMatthias Ringwald 30973deb3ec6SMatthias Ringwald case SM_PH2_CALC_STK: 30983deb3ec6SMatthias Ringwald // already busy? 30993deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31003deb3ec6SMatthias Ringwald // calculate STK 310142134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 3102d1a1f6a4SMatthias Ringwald sm_s1_r_prime(setup->sm_local_random, setup->sm_peer_random, sm_aes128_plaintext); 31033deb3ec6SMatthias Ringwald } else { 3104d1a1f6a4SMatthias Ringwald sm_s1_r_prime(setup->sm_peer_random, setup->sm_local_random, sm_aes128_plaintext); 31053deb3ec6SMatthias Ringwald } 3106d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_W4_STK; 3107d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3108f3582630SMatthias 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); 31093deb3ec6SMatthias Ringwald break; 3110d1a1f6a4SMatthias Ringwald 31113deb3ec6SMatthias Ringwald case SM_PH3_Y_GET_ENC: 31123deb3ec6SMatthias Ringwald // already busy? 31133deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31143deb3ec6SMatthias Ringwald // PH3B2 - calculate Y from - enc 31159ad0dd7cSMatthias Ringwald 31169ad0dd7cSMatthias Ringwald // dm helper (was sm_dm_r_prime) 31179ad0dd7cSMatthias Ringwald // r' = padding || r 31189ad0dd7cSMatthias Ringwald // r - 64 bit value 31199ad0dd7cSMatthias Ringwald memset(&sm_aes128_plaintext[0], 0, 8); 31206535961aSMatthias Ringwald (void)memcpy(&sm_aes128_plaintext[8], setup->sm_local_rand, 8); 31219ad0dd7cSMatthias Ringwald 31223deb3ec6SMatthias Ringwald // Y = dm(DHK, Rand) 3123d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH3_Y_W4_ENC; 3124d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3125f3582630SMatthias 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); 3126d1a1f6a4SMatthias Ringwald break; 3127d1a1f6a4SMatthias Ringwald 31283deb3ec6SMatthias Ringwald case SM_PH2_C1_SEND_PAIRING_CONFIRM: { 31293deb3ec6SMatthias Ringwald uint8_t buffer[17]; 31303deb3ec6SMatthias Ringwald buffer[0] = SM_CODE_PAIRING_CONFIRM; 31319c80e4ccSMatthias Ringwald reverse_128(setup->sm_local_confirm, &buffer[1]); 313242134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 31333deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH2_W4_PAIRING_RANDOM; 31343deb3ec6SMatthias Ringwald } else { 31353deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH2_W4_PAIRING_CONFIRM; 31363deb3ec6SMatthias Ringwald } 3137687a03c8SMatthias Ringwald sm_send_connectionless(connection, (uint8_t*) buffer, sizeof(buffer)); 31383deb3ec6SMatthias Ringwald sm_timeout_reset(connection); 31393deb3ec6SMatthias Ringwald return; 31403deb3ec6SMatthias Ringwald } 314142134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 31423deb3ec6SMatthias Ringwald case SM_RESPONDER_PH2_SEND_LTK_REPLY: { 3143916ea5b2SMatthias Ringwald // cache key before using 3144916ea5b2SMatthias Ringwald sm_cache_ltk(connection, setup->sm_ltk); 31453deb3ec6SMatthias Ringwald sm_key_t stk_flipped; 31469c80e4ccSMatthias Ringwald reverse_128(setup->sm_ltk, stk_flipped); 31473deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH2_W4_CONNECTION_ENCRYPTED; 31483deb3ec6SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_request_reply, connection->sm_handle, stk_flipped); 31493deb3ec6SMatthias Ringwald return; 31503deb3ec6SMatthias Ringwald } 3151d7471931SMatthias Ringwald case SM_RESPONDER_PH4_SEND_LTK_REPLY: { 3152b96d60a6SMatthias Ringwald // allow to override LTK 3153b96d60a6SMatthias Ringwald if (sm_get_ltk_callback != NULL){ 3154b96d60a6SMatthias Ringwald (void)(*sm_get_ltk_callback)(connection->sm_handle, connection->sm_peer_addr_type, connection->sm_peer_address, setup->sm_ltk); 3155b96d60a6SMatthias Ringwald } 3156916ea5b2SMatthias Ringwald // cache key before using 3157916ea5b2SMatthias Ringwald sm_cache_ltk(connection, setup->sm_ltk); 31583deb3ec6SMatthias Ringwald sm_key_t ltk_flipped; 31599c80e4ccSMatthias Ringwald reverse_128(setup->sm_ltk, ltk_flipped); 31605567aa60SMatthias Ringwald connection->sm_engine_state = SM_PH4_W4_CONNECTION_ENCRYPTED; 31613deb3ec6SMatthias Ringwald hci_send_cmd(&hci_le_long_term_key_request_reply, connection->sm_handle, ltk_flipped); 31623deb3ec6SMatthias Ringwald return; 31633deb3ec6SMatthias Ringwald } 3164dd12a62bSMatthias Ringwald 3165dd12a62bSMatthias Ringwald case SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST: 31663deb3ec6SMatthias Ringwald // already busy? 31673deb3ec6SMatthias Ringwald if (sm_aes128_state == SM_AES128_ACTIVE) break; 31683deb3ec6SMatthias Ringwald log_info("LTK Request: recalculating with ediv 0x%04x", setup->sm_local_ediv); 3169c61cfe5aSMatthias Ringwald 3170dd12a62bSMatthias Ringwald sm_reset_setup(); 3171dd12a62bSMatthias Ringwald sm_start_calculating_ltk_from_ediv_and_rand(connection); 3172dd12a62bSMatthias Ringwald 317342646f38SMatthias Ringwald sm_reencryption_started(connection); 317442646f38SMatthias Ringwald 3175c61cfe5aSMatthias Ringwald // dm helper (was sm_dm_r_prime) 3176c61cfe5aSMatthias Ringwald // r' = padding || r 3177c61cfe5aSMatthias Ringwald // r - 64 bit value 3178c61cfe5aSMatthias Ringwald memset(&sm_aes128_plaintext[0], 0, 8); 31796535961aSMatthias Ringwald (void)memcpy(&sm_aes128_plaintext[8], setup->sm_local_rand, 8); 3180c61cfe5aSMatthias Ringwald 31813deb3ec6SMatthias Ringwald // Y = dm(DHK, Rand) 3182d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH4_Y_W4_ENC; 3183d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3184f3582630SMatthias 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); 31853deb3ec6SMatthias Ringwald return; 318642134bc6SMatthias Ringwald #endif 318742134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 318842134bc6SMatthias Ringwald case SM_INITIATOR_PH3_SEND_START_ENCRYPTION: { 318942134bc6SMatthias Ringwald sm_key_t stk_flipped; 319042134bc6SMatthias Ringwald reverse_128(setup->sm_ltk, stk_flipped); 319142134bc6SMatthias Ringwald connection->sm_engine_state = SM_PH2_W4_CONNECTION_ENCRYPTED; 319242134bc6SMatthias Ringwald hci_send_cmd(&hci_le_start_encryption, connection->sm_handle, 0, 0, 0, stk_flipped); 319342134bc6SMatthias Ringwald return; 319442134bc6SMatthias Ringwald } 319542134bc6SMatthias Ringwald #endif 31963deb3ec6SMatthias Ringwald 31973deb3ec6SMatthias Ringwald case SM_PH3_DISTRIBUTE_KEYS: 3198e94757aeSMatthias Ringwald // send next key 3199403280b9SMatthias Ringwald if (setup->sm_key_distribution_send_set != 0){ 3200403280b9SMatthias Ringwald sm_run_distribute_keys(connection); 3201e94757aeSMatthias Ringwald } 3202e94757aeSMatthias Ringwald 3203e94757aeSMatthias Ringwald // more to send? 3204e94757aeSMatthias Ringwald if (setup->sm_key_distribution_send_set != 0){ 32053deb3ec6SMatthias Ringwald return; 32063deb3ec6SMatthias Ringwald } 32073deb3ec6SMatthias Ringwald 32083deb3ec6SMatthias Ringwald // keys are sent 320942134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 32103deb3ec6SMatthias Ringwald // slave -> receive master keys if any 321161d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 32123deb3ec6SMatthias Ringwald sm_key_distribution_handle_all_received(connection); 3213f5020412SMatthias Ringwald sm_key_distribution_complete_responder(connection); 3214f5020412SMatthias Ringwald // start CTKD right away 3215f5020412SMatthias Ringwald continue; 32163deb3ec6SMatthias Ringwald } else { 32173deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH3_RECEIVE_KEYS; 32183deb3ec6SMatthias Ringwald } 32193deb3ec6SMatthias Ringwald } else { 32201dca9d8aSMatthias Ringwald sm_master_pairing_success(connection); 32213deb3ec6SMatthias Ringwald } 32223deb3ec6SMatthias Ringwald break; 32233deb3ec6SMatthias Ringwald 3224c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 3225c18be159SMatthias Ringwald case SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST: 3226c18be159SMatthias Ringwald // fill in sm setup (lite version of sm_init_setup) 3227c18be159SMatthias Ringwald sm_reset_setup(); 3228c18be159SMatthias Ringwald setup->sm_peer_addr_type = connection->sm_peer_addr_type; 3229c18be159SMatthias Ringwald setup->sm_m_addr_type = connection->sm_peer_addr_type; 3230c18be159SMatthias Ringwald setup->sm_s_addr_type = connection->sm_own_addr_type; 3231c18be159SMatthias Ringwald (void) memcpy(setup->sm_peer_address, connection->sm_peer_address, 6); 3232c18be159SMatthias Ringwald (void) memcpy(setup->sm_m_address, connection->sm_peer_address, 6); 3233c18be159SMatthias Ringwald (void) memcpy(setup->sm_s_address, connection->sm_own_address, 6); 3234c18be159SMatthias Ringwald setup->sm_use_secure_connections = true; 3235c18be159SMatthias Ringwald sm_ctkd_fetch_br_edr_link_key(connection); 3236c18be159SMatthias Ringwald 3237c18be159SMatthias Ringwald // Enc Key and IRK if requested 3238c18be159SMatthias Ringwald key_distribution_flags = SM_KEYDIST_ID_KEY | SM_KEYDIST_ENC_KEY; 3239c18be159SMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 3240c18be159SMatthias Ringwald // Plus signing key if supported 3241c18be159SMatthias Ringwald key_distribution_flags |= SM_KEYDIST_ID_KEY; 3242c18be159SMatthias Ringwald #endif 3243c18be159SMatthias Ringwald sm_pairing_packet_set_code(setup->sm_m_preq, SM_CODE_PAIRING_REQUEST); 3244c18be159SMatthias Ringwald sm_pairing_packet_set_io_capability(setup->sm_m_preq, 0); 3245c18be159SMatthias Ringwald sm_pairing_packet_set_oob_data_flag(setup->sm_m_preq, 0); 3246c18be159SMatthias Ringwald sm_pairing_packet_set_auth_req(setup->sm_m_preq, SM_AUTHREQ_CT2); 3247c18be159SMatthias Ringwald sm_pairing_packet_set_max_encryption_key_size(setup->sm_m_preq, sm_max_encryption_key_size); 3248c18be159SMatthias Ringwald sm_pairing_packet_set_initiator_key_distribution(setup->sm_m_preq, key_distribution_flags); 3249c18be159SMatthias Ringwald sm_pairing_packet_set_responder_key_distribution(setup->sm_m_preq, key_distribution_flags); 3250c18be159SMatthias Ringwald 3251c18be159SMatthias Ringwald // set state and send pairing response 3252c18be159SMatthias Ringwald sm_timeout_start(connection); 3253c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_INITIATOR_W4_PAIRING_RESPONSE; 3254c18be159SMatthias Ringwald sm_send_connectionless(connection, (uint8_t *) &setup->sm_m_preq, sizeof(sm_pairing_packet_t)); 3255c18be159SMatthias Ringwald break; 3256c18be159SMatthias Ringwald 3257c18be159SMatthias Ringwald case SM_BR_EDR_RESPONDER_PAIRING_REQUEST_RECEIVED: 3258c18be159SMatthias Ringwald // fill in sm setup (lite version of sm_init_setup) 3259c18be159SMatthias Ringwald sm_reset_setup(); 3260c18be159SMatthias Ringwald setup->sm_peer_addr_type = connection->sm_peer_addr_type; 3261c18be159SMatthias Ringwald setup->sm_m_addr_type = connection->sm_peer_addr_type; 3262c18be159SMatthias Ringwald setup->sm_s_addr_type = connection->sm_own_addr_type; 3263c18be159SMatthias Ringwald (void) memcpy(setup->sm_peer_address, connection->sm_peer_address, 6); 3264c18be159SMatthias Ringwald (void) memcpy(setup->sm_m_address, connection->sm_peer_address, 6); 3265c18be159SMatthias Ringwald (void) memcpy(setup->sm_s_address, connection->sm_own_address, 6); 3266c18be159SMatthias Ringwald setup->sm_use_secure_connections = true; 3267c18be159SMatthias Ringwald sm_ctkd_fetch_br_edr_link_key(connection); 3268c18be159SMatthias Ringwald (void) memcpy(&setup->sm_m_preq, &connection->sm_m_preq, sizeof(sm_pairing_packet_t)); 3269c18be159SMatthias Ringwald 3270c18be159SMatthias Ringwald // Enc Key and IRK if requested 3271c18be159SMatthias Ringwald key_distribution_flags = SM_KEYDIST_ID_KEY | SM_KEYDIST_ENC_KEY; 3272c18be159SMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE 3273c18be159SMatthias Ringwald // Plus signing key if supported 3274c18be159SMatthias Ringwald key_distribution_flags |= SM_KEYDIST_ID_KEY; 3275c18be159SMatthias Ringwald #endif 3276c18be159SMatthias Ringwald // drop flags not requested by initiator 3277c18be159SMatthias Ringwald key_distribution_flags &= sm_pairing_packet_get_initiator_key_distribution(connection->sm_m_preq); 3278c18be159SMatthias Ringwald 3279c18be159SMatthias 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: 3280c18be159SMatthias Ringwald // - the IO Capability field, 3281c18be159SMatthias Ringwald // - the OOB data flag field, and 3282c18be159SMatthias Ringwald // - all bits in the Auth Req field except the CT2 bit. 3283c18be159SMatthias Ringwald sm_pairing_packet_set_code(setup->sm_s_pres, SM_CODE_PAIRING_RESPONSE); 3284c18be159SMatthias Ringwald sm_pairing_packet_set_io_capability(setup->sm_s_pres, 0); 3285c18be159SMatthias Ringwald sm_pairing_packet_set_oob_data_flag(setup->sm_s_pres, 0); 3286c18be159SMatthias Ringwald sm_pairing_packet_set_auth_req(setup->sm_s_pres, SM_AUTHREQ_CT2); 3287c18be159SMatthias Ringwald sm_pairing_packet_set_max_encryption_key_size(setup->sm_s_pres, connection->sm_actual_encryption_key_size); 3288c18be159SMatthias Ringwald sm_pairing_packet_set_initiator_key_distribution(setup->sm_s_pres, key_distribution_flags); 3289c18be159SMatthias Ringwald sm_pairing_packet_set_responder_key_distribution(setup->sm_s_pres, key_distribution_flags); 3290c18be159SMatthias Ringwald 3291c18be159SMatthias Ringwald // configure key distribution, LTK is derived locally 3292c18be159SMatthias Ringwald key_distribution_flags &= ~SM_KEYDIST_ENC_KEY; 3293c18be159SMatthias Ringwald sm_setup_key_distribution(key_distribution_flags, key_distribution_flags); 3294c18be159SMatthias Ringwald 3295c18be159SMatthias Ringwald // set state and send pairing response 3296c18be159SMatthias Ringwald sm_timeout_start(connection); 3297c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_DISTRIBUTE_KEYS; 3298c18be159SMatthias Ringwald sm_send_connectionless(connection, (uint8_t *) &setup->sm_s_pres, sizeof(sm_pairing_packet_t)); 3299c18be159SMatthias Ringwald break; 3300c18be159SMatthias Ringwald case SM_BR_EDR_DISTRIBUTE_KEYS: 3301c18be159SMatthias Ringwald if (setup->sm_key_distribution_send_set != 0) { 3302c18be159SMatthias Ringwald sm_run_distribute_keys(connection); 3303c18be159SMatthias Ringwald return; 3304c18be159SMatthias Ringwald } 3305c18be159SMatthias Ringwald // keys are sent 3306c18be159SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)) { 3307c18be159SMatthias Ringwald // responder -> receive master keys if there are any 330861d1a45eSMatthias Ringwald if (!sm_key_distribution_all_received()){ 3309c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_RECEIVE_KEYS; 3310c18be159SMatthias Ringwald break; 3311c18be159SMatthias Ringwald } 3312c18be159SMatthias Ringwald } 3313c18be159SMatthias Ringwald // otherwise start CTKD right away (responder and no keys to receive / initiator) 3314c18be159SMatthias Ringwald sm_ctkd_start_from_br_edr(connection); 3315c18be159SMatthias Ringwald continue; 3316c18be159SMatthias Ringwald case SM_SC_W2_CALCULATE_ILK_USING_H6: 3317c18be159SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_ILK; 3318c18be159SMatthias Ringwald h6_calculate_ilk_from_le_ltk(connection); 3319c18be159SMatthias Ringwald break; 3320c18be159SMatthias Ringwald case SM_SC_W2_CALCULATE_BR_EDR_LINK_KEY: 3321c18be159SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_BR_EDR_LINK_KEY; 3322c18be159SMatthias Ringwald h6_calculate_br_edr_link_key(connection); 3323c18be159SMatthias Ringwald break; 3324c18be159SMatthias Ringwald case SM_SC_W2_CALCULATE_ILK_USING_H7: 3325c18be159SMatthias Ringwald connection->sm_engine_state = SM_SC_W4_CALCULATE_ILK; 3326c18be159SMatthias Ringwald h7_calculate_ilk_from_le_ltk(connection); 3327c18be159SMatthias Ringwald break; 3328c18be159SMatthias Ringwald case SM_BR_EDR_W2_CALCULATE_ILK_USING_H6: 3329c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_W4_CALCULATE_ILK; 3330c18be159SMatthias Ringwald h6_calculate_ilk_from_br_edr(connection); 3331c18be159SMatthias Ringwald break; 3332c18be159SMatthias Ringwald case SM_BR_EDR_W2_CALCULATE_LE_LTK: 3333c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_W4_CALCULATE_LE_LTK; 3334c18be159SMatthias Ringwald h6_calculate_le_ltk(connection); 3335c18be159SMatthias Ringwald break; 3336c18be159SMatthias Ringwald case SM_BR_EDR_W2_CALCULATE_ILK_USING_H7: 3337c18be159SMatthias Ringwald connection->sm_engine_state = SM_BR_EDR_W4_CALCULATE_ILK; 3338c18be159SMatthias Ringwald h7_calculate_ilk_from_br_edr(connection); 3339c18be159SMatthias Ringwald break; 3340c18be159SMatthias Ringwald #endif 3341c18be159SMatthias Ringwald 33423deb3ec6SMatthias Ringwald default: 33433deb3ec6SMatthias Ringwald break; 33443deb3ec6SMatthias Ringwald } 33453deb3ec6SMatthias Ringwald 33463deb3ec6SMatthias Ringwald // check again if active connection was released 33477149bde5SMatthias Ringwald if (sm_active_connection_handle != HCI_CON_HANDLE_INVALID) break; 33483deb3ec6SMatthias Ringwald } 33493deb3ec6SMatthias Ringwald } 33503deb3ec6SMatthias Ringwald 3351d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3352d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_a(void *arg){ 3353f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 335404678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 335504678764SMatthias Ringwald 3356f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3357f3582630SMatthias Ringwald if (connection == NULL) return; 3358f3582630SMatthias Ringwald 3359d1a1f6a4SMatthias Ringwald sm_c1_t3(sm_aes128_ciphertext, setup->sm_m_address, setup->sm_s_address, setup->sm_c1_t3_value); 336004678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3361f3582630SMatthias 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); 3362d1a1f6a4SMatthias Ringwald } 33633deb3ec6SMatthias Ringwald 3364d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_b(void *arg){ 3365f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 336604678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 336704678764SMatthias Ringwald 3368f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3369f3582630SMatthias Ringwald if (connection == NULL) return; 3370f3582630SMatthias Ringwald 33718314c363SMatthias Ringwald log_info_key("c1!", setup->sm_local_confirm); 33723deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_SEND_PAIRING_CONFIRM; 337370b44dd4SMatthias Ringwald sm_trigger_run(); 3374d1a1f6a4SMatthias Ringwald } 3375d1a1f6a4SMatthias Ringwald 3376d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3377d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_c(void *arg){ 3378f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 337904678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 338004678764SMatthias Ringwald 3381f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3382f3582630SMatthias Ringwald if (connection == NULL) return; 3383f3582630SMatthias Ringwald 3384d1a1f6a4SMatthias Ringwald sm_c1_t3(sm_aes128_ciphertext, setup->sm_m_address, setup->sm_s_address, setup->sm_c1_t3_value); 338504678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3386f3582630SMatthias 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); 3387d1a1f6a4SMatthias Ringwald } 3388d1a1f6a4SMatthias Ringwald 3389d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_d(void * arg){ 3390f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 339104678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 339204678764SMatthias Ringwald 3393f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3394f3582630SMatthias Ringwald if (connection == NULL) return; 3395f3582630SMatthias Ringwald 3396d1a1f6a4SMatthias Ringwald log_info_key("c1!", sm_aes128_ciphertext); 3397d1a1f6a4SMatthias Ringwald if (memcmp(setup->sm_peer_confirm, sm_aes128_ciphertext, 16) != 0){ 3398f4935286SMatthias Ringwald sm_pairing_error(connection, SM_REASON_CONFIRM_VALUE_FAILED); 339970b44dd4SMatthias Ringwald sm_trigger_run(); 34003deb3ec6SMatthias Ringwald return; 34013deb3ec6SMatthias Ringwald } 340242134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 34033deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH2_SEND_PAIRING_RANDOM; 340470b44dd4SMatthias Ringwald sm_trigger_run(); 34053deb3ec6SMatthias Ringwald } else { 3406d1a1f6a4SMatthias Ringwald sm_s1_r_prime(setup->sm_peer_random, setup->sm_local_random, sm_aes128_plaintext); 3407d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3408f3582630SMatthias 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); 34093deb3ec6SMatthias Ringwald } 34103deb3ec6SMatthias Ringwald } 3411d1a1f6a4SMatthias Ringwald 3412d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_stk(void *arg){ 341304678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 3414f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 341504678764SMatthias Ringwald 3416f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3417f3582630SMatthias Ringwald if (connection == NULL) return; 3418f3582630SMatthias Ringwald 34193deb3ec6SMatthias Ringwald sm_truncate_key(setup->sm_ltk, connection->sm_actual_encryption_key_size); 34208314c363SMatthias Ringwald log_info_key("stk", setup->sm_ltk); 342142134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 34223deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH2_SEND_LTK_REPLY; 34233deb3ec6SMatthias Ringwald } else { 34243deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_INITIATOR_PH3_SEND_START_ENCRYPTION; 34253deb3ec6SMatthias Ringwald } 342670b44dd4SMatthias Ringwald sm_trigger_run(); 3427d1a1f6a4SMatthias Ringwald } 3428d1a1f6a4SMatthias Ringwald 3429d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3430d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph3_y(void *arg){ 3431f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 343204678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 343304678764SMatthias Ringwald 3434f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3435f3582630SMatthias Ringwald if (connection == NULL) return; 3436f3582630SMatthias Ringwald 3437d1a1f6a4SMatthias Ringwald setup->sm_local_y = big_endian_read_16(sm_aes128_ciphertext, 14); 34383deb3ec6SMatthias Ringwald log_info_hex16("y", setup->sm_local_y); 34393deb3ec6SMatthias Ringwald // PH3B3 - calculate EDIV 34403deb3ec6SMatthias Ringwald setup->sm_local_ediv = setup->sm_local_y ^ setup->sm_local_div; 34413deb3ec6SMatthias Ringwald log_info_hex16("ediv", setup->sm_local_ediv); 34423deb3ec6SMatthias Ringwald // PH3B4 - calculate LTK - enc 34433deb3ec6SMatthias Ringwald // LTK = d1(ER, DIV, 0)) 3444d1a1f6a4SMatthias Ringwald sm_d1_d_prime(setup->sm_local_div, 0, sm_aes128_plaintext); 344504678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3446f3582630SMatthias 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); 34473deb3ec6SMatthias Ringwald } 3448d1a1f6a4SMatthias Ringwald 34492a526f21SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 3450d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3451d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph4_y(void *arg){ 345204678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 3453f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 345404678764SMatthias Ringwald 3455f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3456f3582630SMatthias Ringwald if (connection == NULL) return; 3457f3582630SMatthias Ringwald 3458d1a1f6a4SMatthias Ringwald setup->sm_local_y = big_endian_read_16(sm_aes128_ciphertext, 14); 34593deb3ec6SMatthias Ringwald log_info_hex16("y", setup->sm_local_y); 34603deb3ec6SMatthias Ringwald 34613deb3ec6SMatthias Ringwald // PH3B3 - calculate DIV 34623deb3ec6SMatthias Ringwald setup->sm_local_div = setup->sm_local_y ^ setup->sm_local_ediv; 34633deb3ec6SMatthias Ringwald log_info_hex16("ediv", setup->sm_local_ediv); 34643deb3ec6SMatthias Ringwald // PH3B4 - calculate LTK - enc 34653deb3ec6SMatthias Ringwald // LTK = d1(ER, DIV, 0)) 3466d1a1f6a4SMatthias Ringwald sm_d1_d_prime(setup->sm_local_div, 0, sm_aes128_plaintext); 346704678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3468f3582630SMatthias 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); 34693deb3ec6SMatthias Ringwald } 34702a526f21SMatthias Ringwald #endif 3471d1a1f6a4SMatthias Ringwald 3472d1a1f6a4SMatthias Ringwald // sm_aes128_state stays active 3473d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph3_ltk(void *arg){ 3474f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 347504678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 347604678764SMatthias Ringwald 3477f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3478f3582630SMatthias Ringwald if (connection == NULL) return; 3479f3582630SMatthias Ringwald 34808314c363SMatthias Ringwald log_info_key("ltk", setup->sm_ltk); 34813deb3ec6SMatthias Ringwald // calc CSRK next 3482d1a1f6a4SMatthias Ringwald sm_d1_d_prime(setup->sm_local_div, 1, sm_aes128_plaintext); 348304678764SMatthias Ringwald sm_aes128_state = SM_AES128_ACTIVE; 3484f3582630SMatthias 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); 3485d1a1f6a4SMatthias Ringwald } 3486d1a1f6a4SMatthias Ringwald 3487d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_csrk(void *arg){ 3488f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 348904678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 349004678764SMatthias Ringwald 3491f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3492f3582630SMatthias Ringwald if (connection == NULL) return; 3493f3582630SMatthias Ringwald 3494d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 34958314c363SMatthias Ringwald log_info_key("csrk", setup->sm_local_csrk); 34963deb3ec6SMatthias Ringwald if (setup->sm_key_distribution_send_set){ 34973deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 34983deb3ec6SMatthias Ringwald } else { 34993deb3ec6SMatthias Ringwald // no keys to send, just continue 350042134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 350161d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 3502c5a72e35SMatthias Ringwald sm_key_distribution_handle_all_received(connection); 3503c5a72e35SMatthias Ringwald sm_key_distribution_complete_responder(connection); 3504c5a72e35SMatthias Ringwald } else { 35053deb3ec6SMatthias Ringwald // slave -> receive master keys 35063deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH3_RECEIVE_KEYS; 3507c5a72e35SMatthias Ringwald } 35083deb3ec6SMatthias Ringwald } else { 3509af7ef9d1SMatthias Ringwald sm_key_distribution_complete_initiator(connection); 35103deb3ec6SMatthias Ringwald } 35112bacf595SMatthias Ringwald } 351270b44dd4SMatthias Ringwald sm_trigger_run(); 3513d1a1f6a4SMatthias Ringwald } 3514d1a1f6a4SMatthias Ringwald 351542134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 3516d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_enc_ph4_ltk(void *arg){ 3517f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 351804678764SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 351904678764SMatthias Ringwald 3520f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3521f3582630SMatthias Ringwald if (connection == NULL) return; 3522f3582630SMatthias Ringwald 35233deb3ec6SMatthias Ringwald sm_truncate_key(setup->sm_ltk, connection->sm_actual_encryption_key_size); 35248314c363SMatthias Ringwald log_info_key("ltk", setup->sm_ltk); 3525d7471931SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH4_SEND_LTK_REPLY; 352670b44dd4SMatthias Ringwald sm_trigger_run(); 3527d1a1f6a4SMatthias Ringwald } 3528d1a1f6a4SMatthias Ringwald #endif 3529d1a1f6a4SMatthias Ringwald 3530d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_address_resolution(void *arg){ 3531d1a1f6a4SMatthias Ringwald UNUSED(arg); 3532d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 353304678764SMatthias Ringwald 3534d1a1f6a4SMatthias Ringwald // compare calulated address against connecting device 3535d1a1f6a4SMatthias Ringwald uint8_t * hash = &sm_aes128_ciphertext[13]; 3536d1a1f6a4SMatthias Ringwald if (memcmp(&sm_address_resolution_address[3], hash, 3) == 0){ 3537d1a1f6a4SMatthias Ringwald log_info("LE Device Lookup: matched resolvable private address"); 3538a66b030fSMatthias Ringwald sm_address_resolution_handle_event(ADDRESS_RESOLUTION_SUCCEEDED); 353970b44dd4SMatthias Ringwald sm_trigger_run(); 35403deb3ec6SMatthias Ringwald return; 35413deb3ec6SMatthias Ringwald } 3542d1a1f6a4SMatthias Ringwald // no match, try next 3543d1a1f6a4SMatthias Ringwald sm_address_resolution_test++; 354470b44dd4SMatthias Ringwald sm_trigger_run(); 35453deb3ec6SMatthias Ringwald } 35463deb3ec6SMatthias Ringwald 3547d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_dkg_irk(void *arg){ 3548d1a1f6a4SMatthias Ringwald UNUSED(arg); 3549d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 355004678764SMatthias Ringwald 3551d1a1f6a4SMatthias Ringwald log_info_key("irk", sm_persistent_irk); 3552d1a1f6a4SMatthias Ringwald dkg_state = DKG_CALC_DHK; 355370b44dd4SMatthias Ringwald sm_trigger_run(); 35547df18c15SMatthias Ringwald } 3555d1a1f6a4SMatthias Ringwald 3556d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_dkg_dhk(void *arg){ 3557d1a1f6a4SMatthias Ringwald UNUSED(arg); 3558d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 355904678764SMatthias Ringwald 3560d1a1f6a4SMatthias Ringwald log_info_key("dhk", sm_persistent_dhk); 3561d1a1f6a4SMatthias Ringwald dkg_state = DKG_READY; 356270b44dd4SMatthias Ringwald sm_trigger_run(); 35637df18c15SMatthias Ringwald } 3564d1a1f6a4SMatthias Ringwald 3565d1a1f6a4SMatthias Ringwald static void sm_handle_encryption_result_rau(void *arg){ 3566d1a1f6a4SMatthias Ringwald UNUSED(arg); 3567d1a1f6a4SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 356804678764SMatthias Ringwald 35696535961aSMatthias Ringwald (void)memcpy(&sm_random_address[3], &sm_aes128_ciphertext[13], 3); 3570e91ddb40SMatthias Ringwald rau_state = RAU_IDLE; 3571e91ddb40SMatthias Ringwald hci_le_random_address_set(sm_random_address); 3572e91ddb40SMatthias Ringwald 357370b44dd4SMatthias Ringwald sm_trigger_run(); 357451fa0b28SMatthias Ringwald } 35757df18c15SMatthias Ringwald 3576d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_rau(void * arg){ 3577d1a1f6a4SMatthias Ringwald UNUSED(arg); 35783deb3ec6SMatthias Ringwald // non-resolvable vs. resolvable 35793deb3ec6SMatthias Ringwald switch (gap_random_adress_type){ 35803deb3ec6SMatthias Ringwald case GAP_RANDOM_ADDRESS_RESOLVABLE: 35813deb3ec6SMatthias Ringwald // resolvable: use random as prand and calc address hash 35823deb3ec6SMatthias Ringwald // "The two most significant bits of prand shall be equal to ‘0’ and ‘1" 35834ea43905SMatthias Ringwald sm_random_address[0u] &= 0x3fu; 35844ea43905SMatthias Ringwald sm_random_address[0u] |= 0x40u; 35853deb3ec6SMatthias Ringwald rau_state = RAU_GET_ENC; 35863deb3ec6SMatthias Ringwald break; 35873deb3ec6SMatthias Ringwald case GAP_RANDOM_ADDRESS_NON_RESOLVABLE: 35883deb3ec6SMatthias Ringwald default: 35893deb3ec6SMatthias Ringwald // "The two most significant bits of the address shall be equal to ‘0’"" 35904ea43905SMatthias Ringwald sm_random_address[0u] &= 0x3fu; 35912954e6c6SMatthias Ringwald rau_state = RAU_IDLE; 3592e91ddb40SMatthias Ringwald hci_le_random_address_set(sm_random_address); 35933deb3ec6SMatthias Ringwald break; 35943deb3ec6SMatthias Ringwald } 359570b44dd4SMatthias Ringwald sm_trigger_run(); 35963deb3ec6SMatthias Ringwald } 35973deb3ec6SMatthias Ringwald 3598c59d0c92SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 35996ca80073SMatthias Ringwald static void sm_handle_random_result_sc_next_send_pairing_random(void * arg){ 3600f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3601f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3602f3582630SMatthias Ringwald if (connection == NULL) return; 3603c59d0c92SMatthias Ringwald 360465a9a04eSMatthias Ringwald connection->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM; 360570b44dd4SMatthias Ringwald sm_trigger_run(); 360665a9a04eSMatthias Ringwald } 3607d1a1f6a4SMatthias Ringwald 36086ca80073SMatthias Ringwald static void sm_handle_random_result_sc_next_w2_cmac_for_confirmation(void * arg){ 36096ca80073SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 36106ca80073SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 36116ca80073SMatthias Ringwald if (connection == NULL) return; 36126ca80073SMatthias Ringwald 3613b35a3de2SMatthias Ringwald connection->sm_engine_state = SM_SC_W2_CMAC_FOR_CONFIRMATION; 361470b44dd4SMatthias Ringwald sm_trigger_run(); 3615d1a1f6a4SMatthias Ringwald } 3616f1c1783eSMatthias Ringwald #endif 3617f1c1783eSMatthias Ringwald 3618d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph2_random(void * arg){ 3619f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3620f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3621f3582630SMatthias Ringwald if (connection == NULL) return; 3622f3582630SMatthias Ringwald 3623d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH2_C1_GET_ENC_A; 362470b44dd4SMatthias Ringwald sm_trigger_run(); 3625d1a1f6a4SMatthias Ringwald } 3626d1a1f6a4SMatthias Ringwald 3627d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph2_tk(void * arg){ 3628f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3629f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3630f3582630SMatthias Ringwald if (connection == NULL) return; 3631f3582630SMatthias Ringwald 3632caf15bf3SMatthias Ringwald sm_reset_tk(); 3633caf15bf3SMatthias Ringwald uint32_t tk; 36345ce1359eSMatthias Ringwald if (sm_fixed_passkey_in_display_role == 0xffffffffU){ 36353deb3ec6SMatthias Ringwald // map random to 0-999999 without speding much cycles on a modulus operation 3636d1a1f6a4SMatthias Ringwald tk = little_endian_read_32(sm_random_data,0); 36373deb3ec6SMatthias Ringwald tk = tk & 0xfffff; // 1048575 36384ea43905SMatthias Ringwald if (tk >= 999999u){ 36394ea43905SMatthias Ringwald tk = tk - 999999u; 36403deb3ec6SMatthias Ringwald } 3641caf15bf3SMatthias Ringwald } else { 3642caf15bf3SMatthias Ringwald // override with pre-defined passkey 36434b8c611fSMatthias Ringwald tk = sm_fixed_passkey_in_display_role; 3644caf15bf3SMatthias Ringwald } 3645f8fbdce0SMatthias Ringwald big_endian_store_32(setup->sm_tk, 12, tk); 364642134bc6SMatthias Ringwald if (IS_RESPONDER(connection->sm_role)){ 36473deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE; 36483deb3ec6SMatthias Ringwald } else { 3649b41539d5SMatthias Ringwald if (setup->sm_use_secure_connections){ 3650b41539d5SMatthias Ringwald connection->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 3651b41539d5SMatthias Ringwald } else { 36523deb3ec6SMatthias Ringwald connection->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 36533deb3ec6SMatthias Ringwald sm_trigger_user_response(connection); 36543deb3ec6SMatthias Ringwald // response_idle == nothing <--> sm_trigger_user_response() did not require response 36553deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ 3656f3582630SMatthias 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); 36573deb3ec6SMatthias Ringwald } 36583deb3ec6SMatthias Ringwald } 3659b41539d5SMatthias Ringwald } 366070b44dd4SMatthias Ringwald sm_trigger_run(); 36613deb3ec6SMatthias Ringwald } 3662d1a1f6a4SMatthias Ringwald 3663d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph3_div(void * arg){ 3664f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3665f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3666f3582630SMatthias Ringwald if (connection == NULL) return; 3667f3582630SMatthias Ringwald 3668d1a1f6a4SMatthias Ringwald // use 16 bit from random value as div 3669d1a1f6a4SMatthias Ringwald setup->sm_local_div = big_endian_read_16(sm_random_data, 0); 3670d1a1f6a4SMatthias Ringwald log_info_hex16("div", setup->sm_local_div); 3671d1a1f6a4SMatthias Ringwald connection->sm_engine_state = SM_PH3_Y_GET_ENC; 367270b44dd4SMatthias Ringwald sm_trigger_run(); 3673d1a1f6a4SMatthias Ringwald } 3674d1a1f6a4SMatthias Ringwald 3675d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_ph3_random(void * arg){ 3676f3582630SMatthias Ringwald hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg; 3677f3582630SMatthias Ringwald sm_connection_t * connection = sm_get_connection_for_handle(con_handle); 3678f3582630SMatthias Ringwald if (connection == NULL) return; 3679f3582630SMatthias Ringwald 3680d1a1f6a4SMatthias Ringwald reverse_64(sm_random_data, setup->sm_local_rand); 36813deb3ec6SMatthias Ringwald // no db for encryption size hack: encryption size is stored in lowest nibble of setup->sm_local_rand 36824ea43905SMatthias Ringwald setup->sm_local_rand[7u] = (setup->sm_local_rand[7u] & 0xf0u) + (connection->sm_actual_encryption_key_size - 1u); 36833deb3ec6SMatthias Ringwald // no db for authenticated flag hack: store flag in bit 4 of LSB 36844ea43905SMatthias Ringwald setup->sm_local_rand[7u] = (setup->sm_local_rand[7u] & 0xefu) + (connection->sm_connection_authenticated << 4u); 36858b3ffec5SMatthias 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); 36863deb3ec6SMatthias Ringwald } 3687899e6e02SMatthias Ringwald static void sm_validate_er_ir(void){ 3688899e6e02SMatthias Ringwald // warn about default ER/IR 36891979f09cSMatthias Ringwald bool warning = false; 3690899e6e02SMatthias Ringwald if (sm_ir_is_default()){ 36911979f09cSMatthias Ringwald warning = true; 3692899e6e02SMatthias Ringwald log_error("Persistent IR not set with sm_set_ir. Use of private addresses will cause pairing issues"); 3693899e6e02SMatthias Ringwald } 3694899e6e02SMatthias Ringwald if (sm_er_is_default()){ 36951979f09cSMatthias Ringwald warning = true; 3696899e6e02SMatthias Ringwald log_error("Persistent ER not set with sm_set_er. Legacy Pairing LTK is not secure"); 3697899e6e02SMatthias Ringwald } 369821045273SMatthias Ringwald if (warning) { 3699899e6e02SMatthias Ringwald log_error("Please configure btstack_tlv to let BTstack setup ER and IR keys"); 3700899e6e02SMatthias Ringwald } 370121045273SMatthias Ringwald } 3702899e6e02SMatthias Ringwald 3703899e6e02SMatthias Ringwald static void sm_handle_random_result_ir(void *arg){ 37041979f09cSMatthias Ringwald sm_persistent_keys_random_active = false; 37059305033eSMatthias Ringwald if (arg != NULL){ 3706899e6e02SMatthias Ringwald // key generated, store in tlv 37074ea43905SMatthias Ringwald int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16u); 3708899e6e02SMatthias Ringwald log_info("Generated IR key. Store in TLV status: %d", status); 3709e0d13a19SMilanka Ringwald UNUSED(status); 3710899e6e02SMatthias Ringwald } 3711899e6e02SMatthias Ringwald log_info_key("IR", sm_persistent_ir); 37128d9b6072SMatthias Ringwald dkg_state = DKG_CALC_IRK; 3713841468bbSMatthias Ringwald 3714841468bbSMatthias Ringwald if (test_use_fixed_local_irk){ 3715841468bbSMatthias Ringwald log_info_key("IRK", sm_persistent_irk); 3716841468bbSMatthias Ringwald dkg_state = DKG_CALC_DHK; 3717841468bbSMatthias Ringwald } 3718841468bbSMatthias Ringwald 371970b44dd4SMatthias Ringwald sm_trigger_run(); 3720899e6e02SMatthias Ringwald } 3721899e6e02SMatthias Ringwald 3722899e6e02SMatthias Ringwald static void sm_handle_random_result_er(void *arg){ 37231979f09cSMatthias Ringwald sm_persistent_keys_random_active = false; 37249305033eSMatthias Ringwald if (arg != 0){ 3725899e6e02SMatthias Ringwald // key generated, store in tlv 37264ea43905SMatthias Ringwald int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16u); 3727899e6e02SMatthias Ringwald log_info("Generated ER key. Store in TLV status: %d", status); 3728e0d13a19SMilanka Ringwald UNUSED(status); 3729899e6e02SMatthias Ringwald } 3730899e6e02SMatthias Ringwald log_info_key("ER", sm_persistent_er); 3731899e6e02SMatthias Ringwald 3732899e6e02SMatthias Ringwald // try load ir 37334ea43905SMatthias Ringwald int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16u); 3734899e6e02SMatthias Ringwald if (key_size == 16){ 3735899e6e02SMatthias Ringwald // ok, let's continue 3736899e6e02SMatthias Ringwald log_info("IR from TLV"); 3737899e6e02SMatthias Ringwald sm_handle_random_result_ir( NULL ); 3738899e6e02SMatthias Ringwald } else { 3739899e6e02SMatthias Ringwald // invalid, generate new random one 37401979f09cSMatthias Ringwald sm_persistent_keys_random_active = true; 3741899e6e02SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_ir, 16, &sm_handle_random_result_ir, &sm_persistent_ir); 3742899e6e02SMatthias Ringwald } 3743899e6e02SMatthias Ringwald } 37443deb3ec6SMatthias Ringwald 3745f664b5e8SMatthias Ringwald static void sm_connection_init(sm_connection_t * sm_conn, hci_con_handle_t con_handle, uint8_t role, uint8_t addr_type, bd_addr_t address){ 3746f664b5e8SMatthias Ringwald 3747f664b5e8SMatthias Ringwald // connection info 3748f664b5e8SMatthias Ringwald sm_conn->sm_handle = con_handle; 3749f664b5e8SMatthias Ringwald sm_conn->sm_role = role; 3750f664b5e8SMatthias Ringwald sm_conn->sm_peer_addr_type = addr_type; 3751f664b5e8SMatthias Ringwald memcpy(sm_conn->sm_peer_address, address, 6); 3752f664b5e8SMatthias Ringwald 3753f664b5e8SMatthias Ringwald // security properties 3754f664b5e8SMatthias Ringwald sm_conn->sm_connection_encrypted = 0; 3755f664b5e8SMatthias Ringwald sm_conn->sm_connection_authenticated = 0; 3756f664b5e8SMatthias Ringwald sm_conn->sm_connection_authorization_state = AUTHORIZATION_UNKNOWN; 3757f664b5e8SMatthias Ringwald sm_conn->sm_le_db_index = -1; 3758f664b5e8SMatthias Ringwald sm_conn->sm_reencryption_active = false; 3759f664b5e8SMatthias Ringwald 3760f664b5e8SMatthias Ringwald // prepare CSRK lookup (does not involve setup) 3761f664b5e8SMatthias Ringwald sm_conn->sm_irk_lookup_state = IRK_LOOKUP_W4_READY; 3762f664b5e8SMatthias Ringwald 3763f664b5e8SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_IDLE; 3764f664b5e8SMatthias Ringwald } 3765f664b5e8SMatthias Ringwald 3766599e89daSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 3767599e89daSMatthias Ringwald static void sm_event_handle_classic_encryption_event(sm_connection_t * sm_conn, hci_con_handle_t con_handle){ 3768599e89daSMatthias Ringwald // CTKD requires BR/EDR Secure Connection 3769599e89daSMatthias Ringwald if (sm_conn->sm_connection_encrypted != 2) return; 3770599e89daSMatthias Ringwald // prepare for pairing request 3771599e89daSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 3772599e89daSMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_RESPONDER_W4_PAIRING_REQUEST; 3773599e89daSMatthias Ringwald } else if (sm_conn->sm_pairing_requested){ 3774599e89daSMatthias Ringwald // check if remote supports fixed channels 3775599e89daSMatthias Ringwald bool defer = true; 3776599e89daSMatthias Ringwald const hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); 3777599e89daSMatthias Ringwald if (hci_connection->l2cap_state.information_state == L2CAP_INFORMATION_STATE_DONE){ 3778599e89daSMatthias Ringwald // check if remote supports SMP over BR/EDR 3779599e89daSMatthias Ringwald if ((hci_connection->l2cap_state.fixed_channels_supported & (1 << L2CAP_CID_BR_EDR_SECURITY_MANAGER)) != 0){ 3780599e89daSMatthias Ringwald log_info("CTKD: SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST"); 3781599e89daSMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST; 3782599e89daSMatthias Ringwald } else { 3783599e89daSMatthias Ringwald defer = false; 3784599e89daSMatthias Ringwald } 3785599e89daSMatthias Ringwald } else { 3786599e89daSMatthias Ringwald // wait for fixed channel info 3787599e89daSMatthias Ringwald log_info("CTKD: SM_BR_EDR_INITIATOR_W4_FIXED_CHANNEL_MASK"); 3788599e89daSMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_INITIATOR_W4_FIXED_CHANNEL_MASK; 3789599e89daSMatthias Ringwald } 3790599e89daSMatthias Ringwald if (defer){ 3791599e89daSMatthias Ringwald hci_dedicated_bonding_defer_disconnect(con_handle, true); 3792599e89daSMatthias Ringwald } 3793599e89daSMatthias Ringwald } 3794599e89daSMatthias Ringwald } 3795599e89daSMatthias Ringwald #endif 3796599e89daSMatthias Ringwald 3797d9a7306aSMatthias Ringwald static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 37983deb3ec6SMatthias Ringwald 3799cbdfe9f7SMatthias Ringwald UNUSED(channel); // ok: there is no channel 3800cbdfe9f7SMatthias Ringwald UNUSED(size); // ok: fixed format HCI events 38019ec2630cSMatthias Ringwald 38023deb3ec6SMatthias Ringwald sm_connection_t * sm_conn; 3803711e6c80SMatthias Ringwald hci_con_handle_t con_handle; 3804fbe050beSMatthias Ringwald uint8_t status; 3805f664b5e8SMatthias Ringwald bd_addr_t addr; 3806f664b5e8SMatthias Ringwald 38073deb3ec6SMatthias Ringwald switch (packet_type) { 38083deb3ec6SMatthias Ringwald 38093deb3ec6SMatthias Ringwald case HCI_EVENT_PACKET: 38100e2df43fSMatthias Ringwald switch (hci_event_packet_get_type(packet)) { 38113deb3ec6SMatthias Ringwald 38123deb3ec6SMatthias Ringwald case BTSTACK_EVENT_STATE: 3813745015f6SMatthias Ringwald switch (btstack_event_state_get_state(packet)){ 3814745015f6SMatthias Ringwald case HCI_STATE_WORKING: 38153deb3ec6SMatthias Ringwald log_info("HCI Working!"); 3816899e6e02SMatthias Ringwald // setup IR/ER with TLV 3817899e6e02SMatthias Ringwald btstack_tlv_get_instance(&sm_tlv_impl, &sm_tlv_context); 38189305033eSMatthias Ringwald if (sm_tlv_impl != NULL){ 38194ea43905SMatthias Ringwald int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16u); 3820899e6e02SMatthias Ringwald if (key_size == 16){ 3821899e6e02SMatthias Ringwald // ok, let's continue 3822899e6e02SMatthias Ringwald log_info("ER from TLV"); 3823899e6e02SMatthias Ringwald sm_handle_random_result_er( NULL ); 3824899e6e02SMatthias Ringwald } else { 3825899e6e02SMatthias Ringwald // invalid, generate random one 38261979f09cSMatthias Ringwald sm_persistent_keys_random_active = true; 3827899e6e02SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_er, 16, &sm_handle_random_result_er, &sm_persistent_er); 3828899e6e02SMatthias Ringwald } 3829899e6e02SMatthias Ringwald } else { 3830899e6e02SMatthias Ringwald sm_validate_er_ir(); 38318d9b6072SMatthias Ringwald dkg_state = DKG_CALC_IRK; 3832841468bbSMatthias Ringwald 3833841468bbSMatthias Ringwald if (test_use_fixed_local_irk){ 3834841468bbSMatthias Ringwald log_info_key("IRK", sm_persistent_irk); 3835841468bbSMatthias Ringwald dkg_state = DKG_CALC_DHK; 3836841468bbSMatthias Ringwald } 3837899e6e02SMatthias Ringwald } 38381bf086daSMatthias Ringwald 383915211b85SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 384015211b85SMatthias Ringwald // trigger ECC key generation 384115211b85SMatthias Ringwald if (ec_key_generation_state == EC_KEY_GENERATION_IDLE){ 384215211b85SMatthias Ringwald sm_ec_generate_new_key(); 384315211b85SMatthias Ringwald } 384415211b85SMatthias Ringwald #endif 384515211b85SMatthias Ringwald 38461bf086daSMatthias Ringwald // restart random address updates after power cycle 38474a688bd1SMatthias Ringwald if (gap_random_adress_type == GAP_RANDOM_ADDRESS_TYPE_STATIC){ 38484a688bd1SMatthias Ringwald gap_random_address_set(sm_random_address); 38494a688bd1SMatthias Ringwald } else { 38501bf086daSMatthias Ringwald gap_random_address_set_mode(gap_random_adress_type); 38514a688bd1SMatthias Ringwald } 3852745015f6SMatthias Ringwald break; 3853745015f6SMatthias Ringwald 3854745015f6SMatthias Ringwald case HCI_STATE_OFF: 38557f775357SMatthias Ringwald case HCI_STATE_HALTING: 3856cbdd51cfSMatthias Ringwald log_info("SM: reset state"); 3857745015f6SMatthias Ringwald // stop random address update 3858745015f6SMatthias Ringwald gap_random_address_update_stop(); 3859cbdd51cfSMatthias Ringwald // reset state 3860cbdd51cfSMatthias Ringwald sm_state_reset(); 3861745015f6SMatthias Ringwald break; 3862745015f6SMatthias Ringwald 3863745015f6SMatthias Ringwald default: 3864745015f6SMatthias Ringwald break; 38653deb3ec6SMatthias Ringwald } 38663deb3ec6SMatthias Ringwald break; 3867c18be159SMatthias Ringwald 38682d095694SMatthias Ringwald #ifdef ENABLE_CLASSIC 38692d095694SMatthias Ringwald case HCI_EVENT_CONNECTION_COMPLETE: 38702d095694SMatthias Ringwald // ignore if connection failed 38712d095694SMatthias Ringwald if (hci_event_connection_complete_get_status(packet)) return; 38723deb3ec6SMatthias Ringwald 38732d095694SMatthias Ringwald con_handle = hci_event_connection_complete_get_connection_handle(packet); 38742d095694SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 38752d095694SMatthias Ringwald if (!sm_conn) break; 38762d095694SMatthias Ringwald 38772d095694SMatthias Ringwald hci_event_connection_complete_get_bd_addr(packet, addr); 38782d095694SMatthias Ringwald sm_connection_init(sm_conn, 38792d095694SMatthias Ringwald con_handle, 38802d095694SMatthias Ringwald (uint8_t) gap_get_role(con_handle), 3881f72f7944SMatthias Ringwald BD_ADDR_TYPE_LE_PUBLIC, 38822d095694SMatthias Ringwald addr); 38832d095694SMatthias Ringwald // classic connection corresponds to public le address 38842d095694SMatthias Ringwald sm_conn->sm_own_addr_type = BD_ADDR_TYPE_LE_PUBLIC; 38852d095694SMatthias Ringwald gap_local_bd_addr(sm_conn->sm_own_address); 38862d095694SMatthias Ringwald sm_conn->sm_cid = L2CAP_CID_BR_EDR_SECURITY_MANAGER; 3887c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_W4_ENCRYPTION_COMPLETE; 38882d095694SMatthias Ringwald break; 38892d095694SMatthias Ringwald #endif 3890c18be159SMatthias Ringwald 3891c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 3892c18be159SMatthias Ringwald case HCI_EVENT_SIMPLE_PAIRING_COMPLETE: 3893c18be159SMatthias Ringwald if (hci_event_simple_pairing_complete_get_status(packet) != ERROR_CODE_SUCCESS) break; 3894c18be159SMatthias Ringwald hci_event_simple_pairing_complete_get_bd_addr(packet, addr); 3895c18be159SMatthias Ringwald sm_conn = sm_get_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL); 3896c18be159SMatthias Ringwald if (sm_conn == NULL) break; 3897c18be159SMatthias Ringwald sm_conn->sm_pairing_requested = 1; 3898c18be159SMatthias Ringwald break; 3899c18be159SMatthias Ringwald #endif 3900c18be159SMatthias Ringwald 39013deb3ec6SMatthias Ringwald case HCI_EVENT_LE_META: 39023deb3ec6SMatthias Ringwald switch (packet[2]) { 39033deb3ec6SMatthias Ringwald case HCI_SUBEVENT_LE_CONNECTION_COMPLETE: 3904f664b5e8SMatthias Ringwald // ignore if connection failed 3905f664b5e8SMatthias Ringwald if (packet[3]) return; 39063deb3ec6SMatthias Ringwald 3907711e6c80SMatthias Ringwald con_handle = little_endian_read_16(packet, 4); 3908711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 39093deb3ec6SMatthias Ringwald if (!sm_conn) break; 39103deb3ec6SMatthias Ringwald 3911f664b5e8SMatthias Ringwald hci_subevent_le_connection_complete_get_peer_address(packet, addr); 3912f664b5e8SMatthias Ringwald sm_connection_init(sm_conn, 3913f664b5e8SMatthias Ringwald con_handle, 3914f664b5e8SMatthias Ringwald hci_subevent_le_connection_complete_get_role(packet), 3915f664b5e8SMatthias Ringwald hci_subevent_le_connection_complete_get_peer_address_type(packet), 3916f664b5e8SMatthias Ringwald addr); 3917687a03c8SMatthias Ringwald sm_conn->sm_cid = L2CAP_CID_SECURITY_MANAGER_PROTOCOL; 3918f664b5e8SMatthias Ringwald 3919f664b5e8SMatthias Ringwald // track our addr used for this connection and set state 3920b6f39a74SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 3921b892db1cSMatthias Ringwald if (hci_subevent_le_connection_complete_get_role(packet) != 0){ 3922ba9fc867SMatthias Ringwald // responder - use own address from advertisements 3923ba9fc867SMatthias Ringwald gap_le_get_own_advertisements_address(&sm_conn->sm_own_addr_type, sm_conn->sm_own_address); 3924f664b5e8SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 3925b892db1cSMatthias Ringwald } 3926b892db1cSMatthias Ringwald #endif 3927b892db1cSMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 3928b892db1cSMatthias Ringwald if (hci_subevent_le_connection_complete_get_role(packet) == 0){ 3929ba9fc867SMatthias Ringwald // initiator - use own address from create connection 3930ba9fc867SMatthias Ringwald gap_le_get_own_connection_address(&sm_conn->sm_own_addr_type, sm_conn->sm_own_address); 39313deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 39323deb3ec6SMatthias Ringwald } 3933b892db1cSMatthias Ringwald #endif 39343deb3ec6SMatthias Ringwald break; 39353deb3ec6SMatthias Ringwald 39363deb3ec6SMatthias Ringwald case HCI_SUBEVENT_LE_LONG_TERM_KEY_REQUEST: 3937711e6c80SMatthias Ringwald con_handle = little_endian_read_16(packet, 3); 3938711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 39393deb3ec6SMatthias Ringwald if (!sm_conn) break; 39403deb3ec6SMatthias Ringwald 39413deb3ec6SMatthias Ringwald log_info("LTK Request: state %u", sm_conn->sm_engine_state); 39423deb3ec6SMatthias Ringwald if (sm_conn->sm_engine_state == SM_RESPONDER_PH2_W4_LTK_REQUEST){ 39433deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_CALC_STK; 39443deb3ec6SMatthias Ringwald break; 39453deb3ec6SMatthias Ringwald } 3946c6b7cbd9SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_LTK_REQUEST_SC){ 3947778b6aadSMatthias Ringwald // PH2 SEND LTK as we need to exchange keys in PH3 3948778b6aadSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH2_SEND_LTK_REPLY; 3949e53be891SMatthias Ringwald break; 3950e53be891SMatthias Ringwald } 39513deb3ec6SMatthias Ringwald 39523deb3ec6SMatthias Ringwald // store rand and ediv 39539c80e4ccSMatthias Ringwald reverse_64(&packet[5], sm_conn->sm_local_rand); 3954f8fbdce0SMatthias Ringwald sm_conn->sm_local_ediv = little_endian_read_16(packet, 13); 3955549ad5d2SMatthias Ringwald 3956549ad5d2SMatthias Ringwald // For Legacy Pairing (<=> EDIV != 0 || RAND != NULL), we need to recalculated our LTK as a 3957549ad5d2SMatthias Ringwald // potentially stored LTK is from the master 39584ea43905SMatthias Ringwald if ((sm_conn->sm_local_ediv != 0u) || !sm_is_null_random(sm_conn->sm_local_rand)){ 39596c39055aSMatthias Ringwald if (sm_reconstruct_ltk_without_le_device_db_entry){ 396006cd539fSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST; 3961549ad5d2SMatthias Ringwald break; 3962549ad5d2SMatthias Ringwald } 39636c39055aSMatthias Ringwald // additionally check if remote is in LE Device DB if requested 39646c39055aSMatthias Ringwald switch(sm_conn->sm_irk_lookup_state){ 39656c39055aSMatthias Ringwald case IRK_LOOKUP_FAILED: 39666c39055aSMatthias Ringwald log_info("LTK Request: device not in device db"); 39676c39055aSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY; 39686c39055aSMatthias Ringwald break; 39696c39055aSMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 39706c39055aSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST; 39716c39055aSMatthias Ringwald break; 39726c39055aSMatthias Ringwald default: 39736c39055aSMatthias Ringwald // wait for irk look doen 39746c39055aSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK; 39756c39055aSMatthias Ringwald break; 39766c39055aSMatthias Ringwald } 39776c39055aSMatthias Ringwald break; 39786c39055aSMatthias Ringwald } 3979549ad5d2SMatthias Ringwald 3980549ad5d2SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 398106cd539fSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_RECEIVED_LTK_REQUEST; 3982549ad5d2SMatthias Ringwald #else 3983549ad5d2SMatthias Ringwald log_info("LTK Request: ediv & random are empty, but LE Secure Connections not supported"); 3984549ad5d2SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY; 3985549ad5d2SMatthias Ringwald #endif 39863deb3ec6SMatthias Ringwald break; 3987804d3e67SMatthias Ringwald 39883deb3ec6SMatthias Ringwald default: 39893deb3ec6SMatthias Ringwald break; 39903deb3ec6SMatthias Ringwald } 39913deb3ec6SMatthias Ringwald break; 39923deb3ec6SMatthias Ringwald 39933deb3ec6SMatthias Ringwald case HCI_EVENT_ENCRYPTION_CHANGE: 39948601e696SMatthias Ringwald case HCI_EVENT_ENCRYPTION_CHANGE_V2: 39953b7fd749SMatthias Ringwald con_handle = hci_event_encryption_change_get_connection_handle(packet); 3996711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 39973deb3ec6SMatthias Ringwald if (!sm_conn) break; 39983deb3ec6SMatthias Ringwald 39993b7fd749SMatthias Ringwald sm_conn->sm_connection_encrypted = hci_event_encryption_change_get_encryption_enabled(packet); 40003deb3ec6SMatthias Ringwald log_info("Encryption state change: %u, key size %u", sm_conn->sm_connection_encrypted, 40013deb3ec6SMatthias Ringwald sm_conn->sm_actual_encryption_key_size); 40023deb3ec6SMatthias Ringwald log_info("event handler, state %u", sm_conn->sm_engine_state); 400303a9359aSMatthias Ringwald 4004fbe050beSMatthias Ringwald switch (sm_conn->sm_engine_state){ 4005fbe050beSMatthias Ringwald 40065567aa60SMatthias Ringwald case SM_PH4_W4_CONNECTION_ENCRYPTED: 400703a9359aSMatthias Ringwald // encryption change event concludes re-encryption for bonded devices (even if it fails) 4008fbe050beSMatthias Ringwald if (sm_conn->sm_connection_encrypted) { 4009fbe050beSMatthias Ringwald status = ERROR_CODE_SUCCESS; 40108d4eef95SMatthias Ringwald if (sm_conn->sm_role){ 40118d4eef95SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 40128d4eef95SMatthias Ringwald } else { 401303a9359aSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 40148d4eef95SMatthias Ringwald } 4015fbe050beSMatthias Ringwald } else { 4016e28291c1SMatthias Ringwald status = hci_event_encryption_change_get_status(packet); 4017cb6d7eb0SMatthias Ringwald // set state to 'RE-ENCRYPTION FAILED' to allow pairing but prevent other interactions 40183b7fd749SMatthias Ringwald // also, gap_reconnect_security_setup_active will return true 4019cb6d7eb0SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_REENCRYPTION_FAILED; 40203b7fd749SMatthias Ringwald } 4021fbe050beSMatthias Ringwald 4022fbe050beSMatthias Ringwald // emit re-encryption complete 402373102768SMatthias Ringwald sm_reencryption_complete(sm_conn, status); 4024fbe050beSMatthias Ringwald 4025c245ca32SMatthias Ringwald // notify client, if pairing was requested before 4026c245ca32SMatthias Ringwald if (sm_conn->sm_pairing_requested){ 4027c245ca32SMatthias Ringwald sm_conn->sm_pairing_requested = 0; 40280ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, status, 0); 402903a9359aSMatthias Ringwald } 403003a9359aSMatthias Ringwald 40313deb3ec6SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 40323deb3ec6SMatthias Ringwald break; 4033fbe050beSMatthias Ringwald 40343deb3ec6SMatthias Ringwald case SM_PH2_W4_CONNECTION_ENCRYPTED: 4035fbe050beSMatthias Ringwald if (!sm_conn->sm_connection_encrypted) break; 403657ff4745SMatthias Ringwald // handler for HCI_EVENT_ENCRYPTION_KEY_REFRESH_COMPLETE 403757ff4745SMatthias Ringwald // contains the same code for this state 4038dd583d9fSMatthias Ringwald sm_conn->sm_connection_sc = setup->sm_use_secure_connections; 403942134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 40403deb3ec6SMatthias Ringwald // slave 404157ff4745SMatthias Ringwald if (sm_conn->sm_connection_sc){ 4042bbf8db22SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 4043bbf8db22SMatthias Ringwald } else { 4044f3582630SMatthias 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); 4045bbf8db22SMatthias Ringwald } 40463deb3ec6SMatthias Ringwald } else { 40473deb3ec6SMatthias Ringwald // master 404861d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 40493deb3ec6SMatthias Ringwald // skip receiving keys as there are none 40503deb3ec6SMatthias Ringwald sm_key_distribution_handle_all_received(sm_conn); 4051f3582630SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph3_random, (void *)(uintptr_t) sm_conn->sm_handle); 40523deb3ec6SMatthias Ringwald } else { 40533deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS; 40543deb3ec6SMatthias Ringwald } 40553deb3ec6SMatthias Ringwald } 40563deb3ec6SMatthias Ringwald break; 4057c18be159SMatthias Ringwald 4058c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 4059c18be159SMatthias Ringwald case SM_BR_EDR_W4_ENCRYPTION_COMPLETE: 4060599e89daSMatthias Ringwald sm_event_handle_classic_encryption_event(sm_conn, con_handle); 4061c18be159SMatthias Ringwald break; 4062c18be159SMatthias Ringwald #endif 40633deb3ec6SMatthias Ringwald default: 40643deb3ec6SMatthias Ringwald break; 40653deb3ec6SMatthias Ringwald } 40663deb3ec6SMatthias Ringwald break; 40673deb3ec6SMatthias Ringwald 40683deb3ec6SMatthias Ringwald case HCI_EVENT_ENCRYPTION_KEY_REFRESH_COMPLETE: 4069711e6c80SMatthias Ringwald con_handle = little_endian_read_16(packet, 3); 4070711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 40713deb3ec6SMatthias Ringwald if (!sm_conn) break; 40723deb3ec6SMatthias Ringwald 40733deb3ec6SMatthias Ringwald log_info("Encryption key refresh complete, key size %u", sm_conn->sm_actual_encryption_key_size); 40743deb3ec6SMatthias Ringwald log_info("event handler, state %u", sm_conn->sm_engine_state); 40753deb3ec6SMatthias Ringwald // continue if part of initial pairing 40763deb3ec6SMatthias Ringwald switch (sm_conn->sm_engine_state){ 40775567aa60SMatthias Ringwald case SM_PH4_W4_CONNECTION_ENCRYPTED: 40785567aa60SMatthias Ringwald if (sm_conn->sm_role){ 40795567aa60SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_IDLE; 40805567aa60SMatthias Ringwald } else { 40813deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 40825567aa60SMatthias Ringwald } 40833deb3ec6SMatthias Ringwald sm_done_for_handle(sm_conn->sm_handle); 40843deb3ec6SMatthias Ringwald break; 40853deb3ec6SMatthias Ringwald case SM_PH2_W4_CONNECTION_ENCRYPTED: 408657ff4745SMatthias Ringwald // handler for HCI_EVENT_ENCRYPTION_CHANGE 408757ff4745SMatthias Ringwald // contains the same code for this state 408857ff4745SMatthias Ringwald sm_conn->sm_connection_sc = setup->sm_use_secure_connections; 408942134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 40903deb3ec6SMatthias Ringwald // slave 409157ff4745SMatthias Ringwald if (sm_conn->sm_connection_sc){ 409257ff4745SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 409357ff4745SMatthias Ringwald } else { 4094f3582630SMatthias 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); 409557ff4745SMatthias Ringwald } 40963deb3ec6SMatthias Ringwald } else { 40973deb3ec6SMatthias Ringwald // master 409857ff4745SMatthias Ringwald if (sm_key_distribution_all_received()){ 409957ff4745SMatthias Ringwald // skip receiving keys as there are none 410057ff4745SMatthias Ringwald sm_key_distribution_handle_all_received(sm_conn); 410157ff4745SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph3_random, (void *)(uintptr_t) sm_conn->sm_handle); 410257ff4745SMatthias Ringwald } else { 41033deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS; 41043deb3ec6SMatthias Ringwald } 410557ff4745SMatthias Ringwald } 41063deb3ec6SMatthias Ringwald break; 410794219034SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 410894219034SMatthias Ringwald case SM_BR_EDR_W4_ENCRYPTION_COMPLETE: 410994219034SMatthias Ringwald sm_event_handle_classic_encryption_event(sm_conn, con_handle); 411094219034SMatthias Ringwald break; 411194219034SMatthias Ringwald #endif 41123deb3ec6SMatthias Ringwald default: 41133deb3ec6SMatthias Ringwald break; 41143deb3ec6SMatthias Ringwald } 41153deb3ec6SMatthias Ringwald break; 41163deb3ec6SMatthias Ringwald 41173deb3ec6SMatthias Ringwald 41183deb3ec6SMatthias Ringwald case HCI_EVENT_DISCONNECTION_COMPLETE: 4119711e6c80SMatthias Ringwald con_handle = little_endian_read_16(packet, 3); 4120711e6c80SMatthias Ringwald sm_done_for_handle(con_handle); 4121711e6c80SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 41223deb3ec6SMatthias Ringwald if (!sm_conn) break; 41233deb3ec6SMatthias Ringwald 412403f736b1SMatthias Ringwald // pairing failed, if it was ongoing 41257f3f442dSMatthias Ringwald switch (sm_conn->sm_engine_state){ 41267f3f442dSMatthias Ringwald case SM_GENERAL_IDLE: 41277f3f442dSMatthias Ringwald case SM_INITIATOR_CONNECTED: 41287f3f442dSMatthias Ringwald case SM_RESPONDER_IDLE: 41297f3f442dSMatthias Ringwald break; 41307f3f442dSMatthias Ringwald default: 413168a18fb9SMatthias Ringwald sm_reencryption_complete(sm_conn, ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION); 41320ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION, 0); 41337f3f442dSMatthias Ringwald break; 413403f736b1SMatthias Ringwald } 4135accbde80SMatthias Ringwald 41363deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_GENERAL_IDLE; 41373deb3ec6SMatthias Ringwald sm_conn->sm_handle = 0; 41383deb3ec6SMatthias Ringwald break; 41393deb3ec6SMatthias Ringwald 41403deb3ec6SMatthias Ringwald case HCI_EVENT_COMMAND_COMPLETE: 4141f7811256SMatthias Ringwald if (hci_event_command_complete_get_command_opcode(packet) == HCI_OPCODE_HCI_READ_BD_ADDR) { 41429091c5f5SMatthias Ringwald // set local addr for le device db 414333373e40SMatthias Ringwald reverse_bd_addr(&packet[OFFSET_OF_DATA_IN_COMMAND_COMPLETE + 1], addr); 41440c130b19SMatthias Ringwald le_device_db_set_local_bd_addr(addr); 414533373e40SMatthias Ringwald } 414665b44ffdSMatthias Ringwald break; 4147a036ae12SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 4148a036ae12SMatthias Ringwald case L2CAP_EVENT_INFORMATION_RESPONSE: 4149a036ae12SMatthias Ringwald con_handle = l2cap_event_information_response_get_con_handle(packet); 4150a036ae12SMatthias Ringwald sm_conn = sm_get_connection_for_handle(con_handle); 4151a036ae12SMatthias Ringwald if (!sm_conn) break; 4152a036ae12SMatthias Ringwald if (sm_conn->sm_engine_state == SM_BR_EDR_INITIATOR_W4_FIXED_CHANNEL_MASK){ 4153a036ae12SMatthias Ringwald // check if remote supports SMP over BR/EDR 4154a036ae12SMatthias Ringwald const hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); 4155a036ae12SMatthias Ringwald if ((hci_connection->l2cap_state.fixed_channels_supported & (1 << L2CAP_CID_BR_EDR_SECURITY_MANAGER)) != 0){ 4156a036ae12SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_INITIATOR_SEND_PAIRING_REQUEST; 4157a036ae12SMatthias Ringwald } else { 4158a036ae12SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; 4159f82b8f4bSMatthias Ringwald hci_dedicated_bonding_defer_disconnect(con_handle, false); 4160a036ae12SMatthias Ringwald } 4161a036ae12SMatthias Ringwald } 4162a036ae12SMatthias Ringwald break; 4163a036ae12SMatthias Ringwald #endif 416465b44ffdSMatthias Ringwald default: 416565b44ffdSMatthias Ringwald break; 41663deb3ec6SMatthias Ringwald } 416765b44ffdSMatthias Ringwald break; 416865b44ffdSMatthias Ringwald default: 416965b44ffdSMatthias Ringwald break; 41703deb3ec6SMatthias Ringwald } 41713deb3ec6SMatthias Ringwald 41723deb3ec6SMatthias Ringwald sm_run(); 41733deb3ec6SMatthias Ringwald } 41743deb3ec6SMatthias Ringwald 41753deb3ec6SMatthias Ringwald static inline int sm_calc_actual_encryption_key_size(int other){ 41763deb3ec6SMatthias Ringwald if (other < sm_min_encryption_key_size) return 0; 41773deb3ec6SMatthias Ringwald if (other < sm_max_encryption_key_size) return other; 41783deb3ec6SMatthias Ringwald return sm_max_encryption_key_size; 41793deb3ec6SMatthias Ringwald } 41803deb3ec6SMatthias Ringwald 4181945888f5SMatthias Ringwald 418231c09488SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4183945888f5SMatthias Ringwald static int sm_just_works_or_numeric_comparison(stk_generation_method_t method){ 4184945888f5SMatthias Ringwald switch (method){ 4185945888f5SMatthias Ringwald case JUST_WORKS: 418647fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 4187945888f5SMatthias Ringwald return 1; 4188945888f5SMatthias Ringwald default: 4189945888f5SMatthias Ringwald return 0; 4190945888f5SMatthias Ringwald } 4191945888f5SMatthias Ringwald } 419207036a04SMatthias Ringwald // responder 4193945888f5SMatthias Ringwald 4194688a08f9SMatthias Ringwald static int sm_passkey_used(stk_generation_method_t method){ 4195688a08f9SMatthias Ringwald switch (method){ 4196688a08f9SMatthias Ringwald case PK_RESP_INPUT: 4197688a08f9SMatthias Ringwald return 1; 4198688a08f9SMatthias Ringwald default: 4199688a08f9SMatthias Ringwald return 0; 4200688a08f9SMatthias Ringwald } 4201688a08f9SMatthias Ringwald } 420240c5d850SMatthias Ringwald 420340c5d850SMatthias Ringwald static int sm_passkey_entry(stk_generation_method_t method){ 420440c5d850SMatthias Ringwald switch (method){ 420540c5d850SMatthias Ringwald case PK_RESP_INPUT: 420640c5d850SMatthias Ringwald case PK_INIT_INPUT: 420747fb4255SMatthias Ringwald case PK_BOTH_INPUT: 420840c5d850SMatthias Ringwald return 1; 420940c5d850SMatthias Ringwald default: 421040c5d850SMatthias Ringwald return 0; 421140c5d850SMatthias Ringwald } 421240c5d850SMatthias Ringwald } 421340c5d850SMatthias Ringwald 421431c09488SMatthias Ringwald #endif 4215688a08f9SMatthias Ringwald 42163deb3ec6SMatthias Ringwald /** 42173deb3ec6SMatthias Ringwald * @return ok 42183deb3ec6SMatthias Ringwald */ 42193deb3ec6SMatthias Ringwald static int sm_validate_stk_generation_method(void){ 42203deb3ec6SMatthias Ringwald // check if STK generation method is acceptable by client 42213deb3ec6SMatthias Ringwald switch (setup->sm_stk_generation_method){ 42223deb3ec6SMatthias Ringwald case JUST_WORKS: 42234ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_JUST_WORKS) != 0u; 42243deb3ec6SMatthias Ringwald case PK_RESP_INPUT: 42253deb3ec6SMatthias Ringwald case PK_INIT_INPUT: 422647fb4255SMatthias Ringwald case PK_BOTH_INPUT: 42274ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_PASSKEY) != 0u; 42283deb3ec6SMatthias Ringwald case OOB: 42294ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_OOB) != 0u; 423047fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 42314ea43905SMatthias Ringwald return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_NUMERIC_COMPARISON) != 0u; 42323deb3ec6SMatthias Ringwald default: 42333deb3ec6SMatthias Ringwald return 0; 42343deb3ec6SMatthias Ringwald } 42353deb3ec6SMatthias Ringwald } 42363deb3ec6SMatthias Ringwald 423736f0defaSMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 423836f0defaSMatthias Ringwald static void sm_initiator_connected_handle_security_request(sm_connection_t * sm_conn, const uint8_t *packet){ 423936f0defaSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 424036f0defaSMatthias Ringwald if (sm_sc_only_mode){ 424136f0defaSMatthias Ringwald uint8_t auth_req = packet[1]; 424236f0defaSMatthias Ringwald if ((auth_req & SM_AUTHREQ_SECURE_CONNECTION) == 0){ 424336f0defaSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_AUTHENTHICATION_REQUIREMENTS); 424436f0defaSMatthias Ringwald return; 424536f0defaSMatthias Ringwald } 424636f0defaSMatthias Ringwald } 424736f0defaSMatthias Ringwald #else 424836f0defaSMatthias Ringwald UNUSED(packet); 424936f0defaSMatthias Ringwald #endif 425036f0defaSMatthias Ringwald 425136f0defaSMatthias Ringwald int have_ltk; 425236f0defaSMatthias Ringwald uint8_t ltk[16]; 425336f0defaSMatthias Ringwald 425436f0defaSMatthias Ringwald // IRK complete? 425536f0defaSMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 425636f0defaSMatthias Ringwald case IRK_LOOKUP_FAILED: 425736f0defaSMatthias Ringwald // start pairing 425836f0defaSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 425936f0defaSMatthias Ringwald break; 426036f0defaSMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 426136f0defaSMatthias Ringwald le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); 426236f0defaSMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 426336f0defaSMatthias Ringwald log_info("central: security request - have_ltk %u, encryption %u", have_ltk, sm_conn->sm_connection_encrypted); 426436f0defaSMatthias Ringwald if (have_ltk && (sm_conn->sm_connection_encrypted == 0)){ 426536f0defaSMatthias Ringwald // start re-encrypt if we have LTK and the connection is not already encrypted 426636f0defaSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH4_HAS_LTK; 426736f0defaSMatthias Ringwald } else { 426836f0defaSMatthias Ringwald // start pairing 426936f0defaSMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 427036f0defaSMatthias Ringwald } 427136f0defaSMatthias Ringwald break; 427236f0defaSMatthias Ringwald default: 427336f0defaSMatthias Ringwald // otherwise, store security request 427436f0defaSMatthias Ringwald sm_conn->sm_security_request_received = 1; 427536f0defaSMatthias Ringwald break; 427636f0defaSMatthias Ringwald } 427736f0defaSMatthias Ringwald } 427836f0defaSMatthias Ringwald #endif 427936f0defaSMatthias Ringwald 4280f9bda154SMatthias Ringwald static uint8_t sm_pdu_validate_and_get_opcode(uint8_t packet_type, const uint8_t *packet, uint16_t size){ 42818334d3d8SMatthias Ringwald 42824c1d1092SMatthias Ringwald // size of complete sm_pdu used to validate input 42834c1d1092SMatthias Ringwald static const uint8_t sm_pdu_size[] = { 42844c1d1092SMatthias Ringwald 0, // 0x00 invalid opcode 42854c1d1092SMatthias Ringwald 7, // 0x01 pairing request 42864c1d1092SMatthias Ringwald 7, // 0x02 pairing response 42874c1d1092SMatthias Ringwald 17, // 0x03 pairing confirm 42884c1d1092SMatthias Ringwald 17, // 0x04 pairing random 42894c1d1092SMatthias Ringwald 2, // 0x05 pairing failed 42904c1d1092SMatthias Ringwald 17, // 0x06 encryption information 42917a2e6387SMatthias Ringwald 11, // 0x07 master identification 42924c1d1092SMatthias Ringwald 17, // 0x08 identification information 42934c1d1092SMatthias Ringwald 8, // 0x09 identify address information 42944c1d1092SMatthias Ringwald 17, // 0x0a signing information 42954c1d1092SMatthias Ringwald 2, // 0x0b security request 42964c1d1092SMatthias Ringwald 65, // 0x0c pairing public key 42974c1d1092SMatthias Ringwald 17, // 0x0d pairing dhk check 42984c1d1092SMatthias Ringwald 2, // 0x0e keypress notification 42994c1d1092SMatthias Ringwald }; 43003deb3ec6SMatthias Ringwald 4301f9bda154SMatthias Ringwald if (packet_type != SM_DATA_PACKET) return 0; 4302f9bda154SMatthias Ringwald if (size == 0u) return 0; 43034c1d1092SMatthias Ringwald 43044c1d1092SMatthias Ringwald uint8_t sm_pdu_code = packet[0]; 43054c1d1092SMatthias Ringwald 43064c1d1092SMatthias Ringwald // validate pdu size 4307f9bda154SMatthias Ringwald if (sm_pdu_code >= sizeof(sm_pdu_size)) return 0; 4308f9bda154SMatthias Ringwald if (sm_pdu_size[sm_pdu_code] != size) return 0; 4309f9bda154SMatthias Ringwald 4310f9bda154SMatthias Ringwald return sm_pdu_code; 4311f9bda154SMatthias Ringwald } 4312f9bda154SMatthias Ringwald 4313f9bda154SMatthias Ringwald static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uint8_t *packet, uint16_t size){ 4314f9bda154SMatthias Ringwald 4315f9bda154SMatthias Ringwald if ((packet_type == HCI_EVENT_PACKET) && (packet[0] == L2CAP_EVENT_CAN_SEND_NOW)){ 4316f9bda154SMatthias Ringwald sm_run(); 4317f9bda154SMatthias Ringwald } 4318f9bda154SMatthias Ringwald 4319f9bda154SMatthias Ringwald uint8_t sm_pdu_code = sm_pdu_validate_and_get_opcode(packet_type, packet, size); 4320f9bda154SMatthias Ringwald if (sm_pdu_code == 0) return; 43213deb3ec6SMatthias Ringwald 4322711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 43233deb3ec6SMatthias Ringwald if (!sm_conn) return; 43243deb3ec6SMatthias Ringwald 43254c1d1092SMatthias Ringwald if (sm_pdu_code == SM_CODE_PAIRING_FAILED){ 432668a18fb9SMatthias Ringwald sm_reencryption_complete(sm_conn, ERROR_CODE_AUTHENTICATION_FAILURE); 43270ccf6c9cSMatthias Ringwald sm_pairing_complete(sm_conn, ERROR_CODE_AUTHENTICATION_FAILURE, packet[1]); 4328accbde80SMatthias Ringwald sm_done_for_handle(con_handle); 43293deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = sm_conn->sm_role ? SM_RESPONDER_IDLE : SM_INITIATOR_CONNECTED; 43303deb3ec6SMatthias Ringwald return; 43313deb3ec6SMatthias Ringwald } 43323deb3ec6SMatthias Ringwald 43334c1d1092SMatthias Ringwald log_debug("sm_pdu_handler: state %u, pdu 0x%02x", sm_conn->sm_engine_state, sm_pdu_code); 43343deb3ec6SMatthias Ringwald 43353deb3ec6SMatthias Ringwald int err; 433642134bc6SMatthias Ringwald UNUSED(err); 43373deb3ec6SMatthias Ringwald 43384c1d1092SMatthias Ringwald if (sm_pdu_code == SM_CODE_KEYPRESS_NOTIFICATION){ 43393d7fe1e9SMatthias Ringwald uint8_t buffer[5]; 43403d7fe1e9SMatthias Ringwald buffer[0] = SM_EVENT_KEYPRESS_NOTIFICATION; 43413d7fe1e9SMatthias Ringwald buffer[1] = 3; 43423d7fe1e9SMatthias Ringwald little_endian_store_16(buffer, 2, con_handle); 43433d7fe1e9SMatthias Ringwald buffer[4] = packet[1]; 43443d7fe1e9SMatthias Ringwald sm_dispatch_event(HCI_EVENT_PACKET, 0, buffer, sizeof(buffer)); 43453d7fe1e9SMatthias Ringwald return; 43463d7fe1e9SMatthias Ringwald } 43473d7fe1e9SMatthias Ringwald 43483deb3ec6SMatthias Ringwald switch (sm_conn->sm_engine_state){ 43493deb3ec6SMatthias Ringwald 4350c8d0ff33SMatthias Ringwald // a sm timeout requires a new physical connection 43513deb3ec6SMatthias Ringwald case SM_GENERAL_TIMEOUT: 43523deb3ec6SMatthias Ringwald return; 43533deb3ec6SMatthias Ringwald 435442134bc6SMatthias Ringwald #ifdef ENABLE_LE_CENTRAL 435542134bc6SMatthias Ringwald 43563deb3ec6SMatthias Ringwald // Initiator 43573deb3ec6SMatthias Ringwald case SM_INITIATOR_CONNECTED: 43584c1d1092SMatthias Ringwald if ((sm_pdu_code != SM_CODE_SECURITY_REQUEST) || (sm_conn->sm_role)){ 43593deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 43603deb3ec6SMatthias Ringwald break; 43613deb3ec6SMatthias Ringwald } 436236f0defaSMatthias Ringwald sm_initiator_connected_handle_security_request(sm_conn, packet); 4363dc8ca372SMatthias Ringwald break; 43643deb3ec6SMatthias Ringwald 43653deb3ec6SMatthias Ringwald case SM_INITIATOR_PH1_W4_PAIRING_RESPONSE: 4366aacfafc3SMatthias Ringwald // Core 5, Vol 3, Part H, 2.4.6: 4367aacfafc3SMatthias Ringwald // "The master shall ignore the slave’s Security Request if the master has sent a Pairing Request 4368aacfafc3SMatthias Ringwald // without receiving a Pairing Response from the slave or if the master has initiated encryption mode setup." 4369aacfafc3SMatthias Ringwald if (sm_pdu_code == SM_CODE_SECURITY_REQUEST){ 4370aacfafc3SMatthias Ringwald log_info("Ignoring Security Request"); 4371aacfafc3SMatthias Ringwald break; 4372aacfafc3SMatthias Ringwald } 4373aacfafc3SMatthias Ringwald 4374aacfafc3SMatthias Ringwald // all other pdus are incorrect 43754c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RESPONSE){ 43763deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 43773deb3ec6SMatthias Ringwald break; 43783deb3ec6SMatthias Ringwald } 43790af429c6SMatthias Ringwald 43803deb3ec6SMatthias Ringwald // store pairing request 43816535961aSMatthias Ringwald (void)memcpy(&setup->sm_s_pres, packet, 43826535961aSMatthias Ringwald sizeof(sm_pairing_packet_t)); 43833deb3ec6SMatthias Ringwald err = sm_stk_generation_init(sm_conn); 43840af429c6SMatthias Ringwald 43850af429c6SMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 43860af429c6SMatthias Ringwald if (0 < test_pairing_failure && test_pairing_failure < SM_REASON_DHKEY_CHECK_FAILED){ 43870af429c6SMatthias Ringwald log_info("testing_support: abort with pairing failure %u", test_pairing_failure); 43880af429c6SMatthias Ringwald err = test_pairing_failure; 43890af429c6SMatthias Ringwald } 43900af429c6SMatthias Ringwald #endif 43910af429c6SMatthias Ringwald 43929305033eSMatthias Ringwald if (err != 0){ 4393f4935286SMatthias Ringwald sm_pairing_error(sm_conn, err); 43943deb3ec6SMatthias Ringwald break; 43953deb3ec6SMatthias Ringwald } 4396b41539d5SMatthias Ringwald 4397b41539d5SMatthias Ringwald // generate random number first, if we need to show passkey 4398b41539d5SMatthias Ringwald if (setup->sm_stk_generation_method == PK_RESP_INPUT){ 4399f3582630SMatthias 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); 4400b41539d5SMatthias Ringwald break; 4401b41539d5SMatthias Ringwald } 4402b41539d5SMatthias Ringwald 4403136d331aSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4404136d331aSMatthias Ringwald if (setup->sm_use_secure_connections){ 44058cba5ca3SMatthias Ringwald // SC Numeric Comparison will trigger user response after public keys & nonces have been exchanged 44068cba5ca3SMatthias Ringwald if (setup->sm_stk_generation_method == JUST_WORKS){ 4407136d331aSMatthias Ringwald sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 4408136d331aSMatthias Ringwald sm_trigger_user_response(sm_conn); 4409136d331aSMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ 4410c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 4411136d331aSMatthias Ringwald } 44128cba5ca3SMatthias Ringwald } else { 4413c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 44148cba5ca3SMatthias Ringwald } 4415136d331aSMatthias Ringwald break; 4416136d331aSMatthias Ringwald } 4417136d331aSMatthias Ringwald #endif 44183deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 44193deb3ec6SMatthias Ringwald sm_trigger_user_response(sm_conn); 44203deb3ec6SMatthias Ringwald // response_idle == nothing <--> sm_trigger_user_response() did not require response 44213deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ 4422f3582630SMatthias 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); 44233deb3ec6SMatthias Ringwald } 44243deb3ec6SMatthias Ringwald break; 44253deb3ec6SMatthias Ringwald 44263deb3ec6SMatthias Ringwald case SM_INITIATOR_PH2_W4_PAIRING_CONFIRM: 44274c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_CONFIRM){ 44283deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 44293deb3ec6SMatthias Ringwald break; 44303deb3ec6SMatthias Ringwald } 44313deb3ec6SMatthias Ringwald 44323deb3ec6SMatthias Ringwald // store s_confirm 44339c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_confirm); 4434192365feSMatthias Ringwald 4435aa9b34e5SMatthias Ringwald // abort if s_confirm matches m_confirm 4436aa9b34e5SMatthias Ringwald if (memcmp(setup->sm_local_confirm, setup->sm_peer_confirm, 16) == 0){ 4437aa9b34e5SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4438aa9b34e5SMatthias Ringwald break; 4439aa9b34e5SMatthias Ringwald } 4440aa9b34e5SMatthias Ringwald 4441192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 4442192365feSMatthias Ringwald if (test_pairing_failure == SM_REASON_CONFIRM_VALUE_FAILED){ 4443192365feSMatthias Ringwald log_info("testing_support: reset confirm value"); 4444192365feSMatthias Ringwald memset(setup->sm_peer_confirm, 0, 16); 4445192365feSMatthias Ringwald } 4446192365feSMatthias Ringwald #endif 44473deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_SEND_PAIRING_RANDOM; 44483deb3ec6SMatthias Ringwald break; 44493deb3ec6SMatthias Ringwald 44503deb3ec6SMatthias Ringwald case SM_INITIATOR_PH2_W4_PAIRING_RANDOM: 44514c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RANDOM){ 44523deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 44533deb3ec6SMatthias Ringwald break;; 44543deb3ec6SMatthias Ringwald } 44553deb3ec6SMatthias Ringwald 44563deb3ec6SMatthias Ringwald // received random value 44579c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_random); 44583deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_C1_GET_ENC_C; 44593deb3ec6SMatthias Ringwald break; 4460dc542de1SMatthias Ringwald 4461dc542de1SMatthias Ringwald case SM_PH4_W4_CONNECTION_ENCRYPTED: 4462dc542de1SMatthias Ringwald // ignore Security Request, see SM_INITIATOR_PH1_W4_PAIRING_RESPONSE above 4463dc542de1SMatthias Ringwald if (sm_pdu_code != SM_CODE_SECURITY_REQUEST){ 4464dc542de1SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4465dc542de1SMatthias Ringwald } 4466dc542de1SMatthias Ringwald break; 446742134bc6SMatthias Ringwald #endif 44683deb3ec6SMatthias Ringwald 446942134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 44703deb3ec6SMatthias Ringwald // Responder 44713deb3ec6SMatthias Ringwald case SM_RESPONDER_IDLE: 44723deb3ec6SMatthias Ringwald case SM_RESPONDER_SEND_SECURITY_REQUEST: 44733deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_W4_PAIRING_REQUEST: 44744c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_REQUEST){ 44753deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 44763deb3ec6SMatthias Ringwald break;; 44773deb3ec6SMatthias Ringwald } 44783deb3ec6SMatthias Ringwald 44793deb3ec6SMatthias Ringwald // store pairing request 4480212d735eSMatthias Ringwald (void)memcpy(&sm_conn->sm_m_preq, packet, sizeof(sm_pairing_packet_t)); 4481212d735eSMatthias Ringwald 4482212d735eSMatthias Ringwald // check if IRK completed 4483212d735eSMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 4484212d735eSMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 4485212d735eSMatthias Ringwald case IRK_LOOKUP_FAILED: 44863deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED; 44873deb3ec6SMatthias Ringwald break; 4488212d735eSMatthias Ringwald default: 4489212d735eSMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED_W4_IRK; 4490212d735eSMatthias Ringwald break; 4491212d735eSMatthias Ringwald } 4492212d735eSMatthias Ringwald break; 449342134bc6SMatthias Ringwald #endif 44943deb3ec6SMatthias Ringwald 449527c32905SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4496c6b7cbd9SMatthias Ringwald case SM_SC_W4_PUBLIC_KEY_COMMAND: 44974c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_PUBLIC_KEY){ 449827c32905SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 449927c32905SMatthias Ringwald break; 450027c32905SMatthias Ringwald } 4501bccf5e67SMatthias Ringwald 4502e53be891SMatthias Ringwald // store public key for DH Key calculation 4503fc5bff5fSMatthias Ringwald reverse_256(&packet[01], &setup->sm_peer_q[0]); 4504fc5bff5fSMatthias Ringwald reverse_256(&packet[33], &setup->sm_peer_q[32]); 4505bccf5e67SMatthias Ringwald 450602658749SMatthias Ringwald // CVE-2020-26558: abort pairing if remote uses the same public key 450702658749SMatthias Ringwald if (memcmp(&setup->sm_peer_q, ec_q, 64) == 0){ 450802658749SMatthias Ringwald log_info("Remote PK matches ours"); 450902658749SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 451002658749SMatthias Ringwald break; 451102658749SMatthias Ringwald } 451202658749SMatthias Ringwald 4513d1a1f6a4SMatthias Ringwald // validate public key 4514d1a1f6a4SMatthias Ringwald err = btstack_crypto_ecc_p256_validate_public_key(setup->sm_peer_q); 45159305033eSMatthias Ringwald if (err != 0){ 451602658749SMatthias Ringwald log_info("sm: peer public key invalid %x", err); 4517349d0adbSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_DHKEY_CHECK_FAILED); 4518bccf5e67SMatthias Ringwald break; 4519bccf5e67SMatthias Ringwald } 4520891bb64aSMatthias Ringwald 4521d1a1f6a4SMatthias Ringwald // start calculating dhkey 4522f3582630SMatthias 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); 45233cf37b8cSMatthias Ringwald 452465a9a04eSMatthias Ringwald 452565a9a04eSMatthias Ringwald log_info("public key received, generation method %u", setup->sm_stk_generation_method); 452642134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 4527136d331aSMatthias Ringwald // responder 4528c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 4529136d331aSMatthias Ringwald } else { 4530136d331aSMatthias Ringwald // initiator 4531a1e31e9cSMatthias Ringwald // stk generation method 4532a1e31e9cSMatthias Ringwald // passkey entry: notify app to show passkey or to request passkey 4533a1e31e9cSMatthias Ringwald switch (setup->sm_stk_generation_method){ 4534a1e31e9cSMatthias Ringwald case JUST_WORKS: 453547fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 4536c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_CONFIRMATION; 4537a1e31e9cSMatthias Ringwald break; 4538a1e31e9cSMatthias Ringwald case PK_RESP_INPUT: 453907036a04SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 454007036a04SMatthias Ringwald break; 454107036a04SMatthias Ringwald case PK_INIT_INPUT: 454247fb4255SMatthias Ringwald case PK_BOTH_INPUT: 454307036a04SMatthias Ringwald if (setup->sm_user_response != SM_USER_RESPONSE_PASSKEY){ 454407036a04SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_USER_RESPONSE; 454507036a04SMatthias Ringwald break; 454607036a04SMatthias Ringwald } 4547b35a3de2SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 4548a1e31e9cSMatthias Ringwald break; 4549a1e31e9cSMatthias Ringwald case OOB: 4550d1a1f6a4SMatthias Ringwald // generate Nx 45514acf7b7bSMatthias Ringwald log_info("Generate Na"); 45526ca80073SMatthias 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); 4553a1e31e9cSMatthias Ringwald break; 45547bbeb3adSMilanka Ringwald default: 45557bbeb3adSMilanka Ringwald btstack_assert(false); 45567bbeb3adSMilanka Ringwald break; 4557a1e31e9cSMatthias Ringwald } 4558136d331aSMatthias Ringwald } 455927c32905SMatthias Ringwald break; 4560e53be891SMatthias Ringwald 4561c6b7cbd9SMatthias Ringwald case SM_SC_W4_CONFIRMATION: 45624c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_CONFIRM){ 456345a61d50SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 456445a61d50SMatthias Ringwald break; 456545a61d50SMatthias Ringwald } 456645a61d50SMatthias Ringwald // received confirm value 456745a61d50SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_confirm); 456845a61d50SMatthias Ringwald 4569192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 4570192365feSMatthias Ringwald if (test_pairing_failure == SM_REASON_CONFIRM_VALUE_FAILED){ 4571192365feSMatthias Ringwald log_info("testing_support: reset confirm value"); 4572192365feSMatthias Ringwald memset(setup->sm_peer_confirm, 0, 16); 4573192365feSMatthias Ringwald } 4574192365feSMatthias Ringwald #endif 457542134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 457645a61d50SMatthias Ringwald // responder 457707036a04SMatthias Ringwald if (sm_passkey_used(setup->sm_stk_generation_method)){ 457807036a04SMatthias Ringwald if (setup->sm_user_response != SM_USER_RESPONSE_PASSKEY){ 457907036a04SMatthias Ringwald // still waiting for passkey 458007036a04SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W4_USER_RESPONSE; 458107036a04SMatthias Ringwald break; 458207036a04SMatthias Ringwald } 458307036a04SMatthias Ringwald } 4584b35a3de2SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 458545a61d50SMatthias Ringwald } else { 458645a61d50SMatthias Ringwald // initiator 4587945888f5SMatthias Ringwald if (sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method)){ 45886ca80073SMatthias 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); 4589f1c1783eSMatthias Ringwald } else { 4590c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM; 459145a61d50SMatthias Ringwald } 4592f1c1783eSMatthias Ringwald } 459345a61d50SMatthias Ringwald break; 459445a61d50SMatthias Ringwald 4595c6b7cbd9SMatthias Ringwald case SM_SC_W4_PAIRING_RANDOM: 45964c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RANDOM){ 4597e53be891SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4598136d331aSMatthias Ringwald break; 4599e53be891SMatthias Ringwald } 4600e53be891SMatthias Ringwald 4601e53be891SMatthias Ringwald // received random value 4602e53be891SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_nonce); 4603e53be891SMatthias Ringwald 46045a293e6eSMatthias Ringwald // validate confirm value if Cb = f4(Pkb, Pka, Nb, z) 4605ae451ec5SMatthias Ringwald // only check for JUST WORK/NC in initiator role OR passkey entry 4606d686b2d0SMatthias Ringwald log_info("SM_SC_W4_PAIRING_RANDOM, responder: %u, just works: %u, passkey used %u, passkey entry %u", 4607d686b2d0SMatthias Ringwald IS_RESPONDER(sm_conn->sm_role), sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method), 4608d686b2d0SMatthias Ringwald sm_passkey_used(setup->sm_stk_generation_method), sm_passkey_entry(setup->sm_stk_generation_method)); 460965a9a04eSMatthias Ringwald if ( (!IS_RESPONDER(sm_conn->sm_role) && sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method)) 4610d686b2d0SMatthias Ringwald || (sm_passkey_entry(setup->sm_stk_generation_method)) ) { 4611688a08f9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION; 4612ae451ec5SMatthias Ringwald break; 46135a293e6eSMatthias Ringwald } 46146f52a196SMatthias Ringwald 46154acf7b7bSMatthias Ringwald // OOB 46164acf7b7bSMatthias Ringwald if (setup->sm_stk_generation_method == OOB){ 46174acf7b7bSMatthias Ringwald 46184acf7b7bSMatthias Ringwald // setup local random, set to zero if remote did not receive our data 46194acf7b7bSMatthias Ringwald log_info("Received nonce, setup local random ra/rb for dhkey check"); 46204acf7b7bSMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 46214ea43905SMatthias Ringwald if (sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq) == 0u){ 46224acf7b7bSMatthias Ringwald log_info("Reset rb as A does not have OOB data"); 46234acf7b7bSMatthias Ringwald memset(setup->sm_rb, 0, 16); 46244acf7b7bSMatthias Ringwald } else { 46256535961aSMatthias Ringwald (void)memcpy(setup->sm_rb, sm_sc_oob_random, 16); 46264acf7b7bSMatthias Ringwald log_info("Use stored rb"); 46274acf7b7bSMatthias Ringwald log_info_hexdump(setup->sm_rb, 16); 46284acf7b7bSMatthias Ringwald } 46294acf7b7bSMatthias Ringwald } else { 46304ea43905SMatthias Ringwald if (sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres) == 0u){ 46314acf7b7bSMatthias Ringwald log_info("Reset ra as B does not have OOB data"); 46324acf7b7bSMatthias Ringwald memset(setup->sm_ra, 0, 16); 46334acf7b7bSMatthias Ringwald } else { 46346535961aSMatthias Ringwald (void)memcpy(setup->sm_ra, sm_sc_oob_random, 16); 46354acf7b7bSMatthias Ringwald log_info("Use stored ra"); 46364acf7b7bSMatthias Ringwald log_info_hexdump(setup->sm_ra, 16); 46374acf7b7bSMatthias Ringwald } 46384acf7b7bSMatthias Ringwald } 46394acf7b7bSMatthias Ringwald 4640a680ba6bSMatthias Ringwald // validate confirm value if Cb = f4(PKb, Pkb, rb, 0) for OOB if data received 46414acf7b7bSMatthias Ringwald if (setup->sm_have_oob_data){ 4642a680ba6bSMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION; 4643a680ba6bSMatthias Ringwald break; 4644a680ba6bSMatthias Ringwald } 46454acf7b7bSMatthias Ringwald } 4646a680ba6bSMatthias Ringwald 4647a680ba6bSMatthias Ringwald // TODO: we only get here for Responder role with JW/NC 4648688a08f9SMatthias Ringwald sm_sc_state_after_receiving_random(sm_conn); 4649e53be891SMatthias Ringwald break; 4650e53be891SMatthias Ringwald 4651901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_G2: 4652901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_G2: 46533cf37b8cSMatthias Ringwald case SM_SC_W4_CALCULATE_DHKEY: 4654901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_SALT: 4655901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_SALT: 4656901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_MACKEY: 4657901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_MACKEY: 4658901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F5_LTK: 4659901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F5_LTK: 4660901c000fSMatthias Ringwald case SM_SC_W2_CALCULATE_F6_FOR_DHKEY_CHECK: 4661c6b7cbd9SMatthias Ringwald case SM_SC_W4_DHKEY_CHECK_COMMAND: 4662901c000fSMatthias Ringwald case SM_SC_W4_CALCULATE_F6_FOR_DHKEY_CHECK: 4663d08147dfSMatthias Ringwald case SM_SC_W4_USER_RESPONSE: 46644c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_DHKEY_CHECK){ 4665e53be891SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4666e53be891SMatthias Ringwald break; 4667e53be891SMatthias Ringwald } 4668e53be891SMatthias Ringwald // store DHKey Check 4669901c000fSMatthias Ringwald setup->sm_state_vars |= SM_STATE_VAR_DHKEY_COMMAND_RECEIVED; 4670e53be891SMatthias Ringwald reverse_128(&packet[01], setup->sm_peer_dhkey_check); 4671446a8c36SMatthias Ringwald 4672901c000fSMatthias Ringwald // have we been only waiting for dhkey check command? 4673901c000fSMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_DHKEY_CHECK_COMMAND){ 4674019005a0SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK; 4675bd57ffebSMatthias Ringwald } 4676bd57ffebSMatthias Ringwald break; 467727c32905SMatthias Ringwald #endif 467827c32905SMatthias Ringwald 467942134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 46803deb3ec6SMatthias Ringwald case SM_RESPONDER_PH1_W4_PAIRING_CONFIRM: 46814c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_CONFIRM){ 46823deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 468327c32905SMatthias Ringwald break; 46843deb3ec6SMatthias Ringwald } 46853deb3ec6SMatthias Ringwald 46863deb3ec6SMatthias Ringwald // received confirm value 46879c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_confirm); 46883deb3ec6SMatthias Ringwald 4689192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 4690192365feSMatthias Ringwald if (test_pairing_failure == SM_REASON_CONFIRM_VALUE_FAILED){ 4691192365feSMatthias Ringwald log_info("testing_support: reset confirm value"); 4692192365feSMatthias Ringwald memset(setup->sm_peer_confirm, 0, 16); 4693192365feSMatthias Ringwald } 4694192365feSMatthias Ringwald #endif 46953deb3ec6SMatthias Ringwald // notify client to hide shown passkey 46963deb3ec6SMatthias Ringwald if (setup->sm_stk_generation_method == PK_INIT_INPUT){ 46975611a760SMatthias 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); 46983deb3ec6SMatthias Ringwald } 46993deb3ec6SMatthias Ringwald 47003deb3ec6SMatthias Ringwald // handle user cancel pairing? 47013deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_DECLINE){ 4702f4935286SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_PASSKEY_ENTRY_FAILED); 47033deb3ec6SMatthias Ringwald break; 47043deb3ec6SMatthias Ringwald } 47053deb3ec6SMatthias Ringwald 47063deb3ec6SMatthias Ringwald // wait for user action? 47073deb3ec6SMatthias Ringwald if (setup->sm_user_response == SM_USER_RESPONSE_PENDING){ 47083deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE; 47093deb3ec6SMatthias Ringwald break; 47103deb3ec6SMatthias Ringwald } 47113deb3ec6SMatthias Ringwald 47123deb3ec6SMatthias Ringwald // calculate and send local_confirm 4713f3582630SMatthias 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); 47143deb3ec6SMatthias Ringwald break; 47153deb3ec6SMatthias Ringwald 47163deb3ec6SMatthias Ringwald case SM_RESPONDER_PH2_W4_PAIRING_RANDOM: 47174c1d1092SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RANDOM){ 47183deb3ec6SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 47193deb3ec6SMatthias Ringwald break;; 47203deb3ec6SMatthias Ringwald } 47213deb3ec6SMatthias Ringwald 47223deb3ec6SMatthias Ringwald // received random value 47239c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_random); 47243deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_PH2_C1_GET_ENC_C; 47253deb3ec6SMatthias Ringwald break; 472642134bc6SMatthias Ringwald #endif 47273deb3ec6SMatthias Ringwald 4728672dc582SMatthias Ringwald case SM_PH2_W4_CONNECTION_ENCRYPTED: 47293deb3ec6SMatthias Ringwald case SM_PH3_RECEIVE_KEYS: 47304c1d1092SMatthias Ringwald switch(sm_pdu_code){ 47313deb3ec6SMatthias Ringwald case SM_CODE_ENCRYPTION_INFORMATION: 47323deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; 47339c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_ltk); 47343deb3ec6SMatthias Ringwald break; 47353deb3ec6SMatthias Ringwald 47363deb3ec6SMatthias Ringwald case SM_CODE_MASTER_IDENTIFICATION: 47373deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_MASTER_IDENTIFICATION; 4738f8fbdce0SMatthias Ringwald setup->sm_peer_ediv = little_endian_read_16(packet, 1); 47399c80e4ccSMatthias Ringwald reverse_64(&packet[3], setup->sm_peer_rand); 47403deb3ec6SMatthias Ringwald break; 47413deb3ec6SMatthias Ringwald 47423deb3ec6SMatthias Ringwald case SM_CODE_IDENTITY_INFORMATION: 47433deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 47449c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_irk); 47453deb3ec6SMatthias Ringwald break; 47463deb3ec6SMatthias Ringwald 47473deb3ec6SMatthias Ringwald case SM_CODE_IDENTITY_ADDRESS_INFORMATION: 47483deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 47493deb3ec6SMatthias Ringwald setup->sm_peer_addr_type = packet[1]; 4750724d70a2SMatthias Ringwald reverse_bd_addr(&packet[2], setup->sm_peer_address); 47513deb3ec6SMatthias Ringwald break; 47523deb3ec6SMatthias Ringwald 47533deb3ec6SMatthias Ringwald case SM_CODE_SIGNING_INFORMATION: 47543deb3ec6SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 47559c80e4ccSMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_csrk); 47563deb3ec6SMatthias Ringwald break; 47573deb3ec6SMatthias Ringwald default: 47583deb3ec6SMatthias Ringwald // Unexpected PDU 47593deb3ec6SMatthias Ringwald log_info("Unexpected PDU %u in SM_PH3_RECEIVE_KEYS", packet[0]); 47603deb3ec6SMatthias Ringwald break; 47613deb3ec6SMatthias Ringwald } 47623deb3ec6SMatthias Ringwald // done with key distribution? 476361d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 47643deb3ec6SMatthias Ringwald 47653deb3ec6SMatthias Ringwald sm_key_distribution_handle_all_received(sm_conn); 47663deb3ec6SMatthias Ringwald 476742134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 47686f7422f1SMatthias Ringwald sm_key_distribution_complete_responder(sm_conn); 47693deb3ec6SMatthias Ringwald } else { 4770625f00b2SMatthias Ringwald if (setup->sm_use_secure_connections){ 4771625f00b2SMatthias Ringwald sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; 4772bbf8db22SMatthias Ringwald } else { 4773f3582630SMatthias 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); 4774625f00b2SMatthias Ringwald } 47753deb3ec6SMatthias Ringwald } 47763deb3ec6SMatthias Ringwald } 47773deb3ec6SMatthias Ringwald break; 4778c18be159SMatthias Ringwald 4779c18be159SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 4780b322498eSMatthias Ringwald 4781b322498eSMatthias Ringwald case SM_BR_EDR_W4_ENCRYPTION_COMPLETE: 4782b322498eSMatthias Ringwald // GAP/DM/LEP/BI-02-C - reject CTKD if P-192 encryption is used 4783b322498eSMatthias Ringwald if (sm_pdu_code == SM_CODE_PAIRING_REQUEST){ 4784b322498eSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_CROSS_TRANSPORT_KEY_DERIVATION_NOT_ALLOWED); 4785b322498eSMatthias Ringwald } 4786b322498eSMatthias Ringwald break; 4787b322498eSMatthias Ringwald 4788c18be159SMatthias Ringwald case SM_BR_EDR_INITIATOR_W4_PAIRING_RESPONSE: 4789553c9408SMatthias Ringwald 4790553c9408SMatthias Ringwald // dedicated bonding complete 4791f82b8f4bSMatthias Ringwald hci_dedicated_bonding_defer_disconnect(sm_conn->sm_handle, false); 4792553c9408SMatthias Ringwald 4793c18be159SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_RESPONSE){ 4794c18be159SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4795c18be159SMatthias Ringwald break; 4796c18be159SMatthias Ringwald } 4797c18be159SMatthias Ringwald // store pairing response 4798c18be159SMatthias Ringwald (void)memcpy(&setup->sm_s_pres, packet, sizeof(sm_pairing_packet_t)); 4799c18be159SMatthias Ringwald 4800c18be159SMatthias Ringwald // validate encryption key size 4801c18be159SMatthias Ringwald sm_conn->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(sm_pairing_packet_get_max_encryption_key_size(setup->sm_s_pres)); 4802c18be159SMatthias Ringwald // SC Only mandates 128 bit key size 4803c18be159SMatthias Ringwald if (sm_sc_only_mode && (sm_conn->sm_actual_encryption_key_size < 16)) { 4804c18be159SMatthias Ringwald sm_conn->sm_actual_encryption_key_size = 0; 4805c18be159SMatthias Ringwald } 4806c18be159SMatthias Ringwald if (sm_conn->sm_actual_encryption_key_size == 0){ 4807c18be159SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_ENCRYPTION_KEY_SIZE); 4808c18be159SMatthias Ringwald break; 4809c18be159SMatthias Ringwald } 4810c18be159SMatthias Ringwald 4811c18be159SMatthias Ringwald // prepare key exchange, LTK is derived locally 4812c18be159SMatthias Ringwald sm_setup_key_distribution(sm_pairing_packet_get_initiator_key_distribution(setup->sm_s_pres) & ~SM_KEYDIST_ENC_KEY, 4813c18be159SMatthias Ringwald sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres) & ~SM_KEYDIST_ENC_KEY); 4814c18be159SMatthias Ringwald 4815c18be159SMatthias Ringwald // skip receive if there are none 481661d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 4817c18be159SMatthias Ringwald // distribute keys in run handles 'no keys to send' 4818c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_DISTRIBUTE_KEYS; 4819c18be159SMatthias Ringwald } else { 4820c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_RECEIVE_KEYS; 4821c18be159SMatthias Ringwald } 4822c18be159SMatthias Ringwald break; 4823c18be159SMatthias Ringwald 4824c18be159SMatthias Ringwald case SM_BR_EDR_RESPONDER_W4_PAIRING_REQUEST: 4825c18be159SMatthias Ringwald if (sm_pdu_code != SM_CODE_PAIRING_REQUEST){ 4826c18be159SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 4827c18be159SMatthias Ringwald break; 4828c18be159SMatthias Ringwald } 4829c18be159SMatthias Ringwald // store pairing request 4830c18be159SMatthias Ringwald (void)memcpy(&sm_conn->sm_m_preq, packet, sizeof(sm_pairing_packet_t)); 4831c18be159SMatthias Ringwald // validate encryption key size 4832c18be159SMatthias Ringwald sm_conn->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(sm_pairing_packet_get_max_encryption_key_size(sm_conn->sm_m_preq)); 4833c18be159SMatthias Ringwald // SC Only mandates 128 bit key size 4834c18be159SMatthias Ringwald if (sm_sc_only_mode && (sm_conn->sm_actual_encryption_key_size < 16)) { 4835c18be159SMatthias Ringwald sm_conn->sm_actual_encryption_key_size = 0; 4836c18be159SMatthias Ringwald } 4837c18be159SMatthias Ringwald if (sm_conn->sm_actual_encryption_key_size == 0){ 4838c18be159SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_ENCRYPTION_KEY_SIZE); 4839c18be159SMatthias Ringwald break; 4840c18be159SMatthias Ringwald } 4841c18be159SMatthias Ringwald // trigger response 48426a718a5eSMatthias Ringwald if (sm_ctkd_from_classic(sm_conn)){ 4843c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_RESPONDER_PAIRING_REQUEST_RECEIVED; 48446a718a5eSMatthias Ringwald } else { 48456a718a5eSMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_CROSS_TRANSPORT_KEY_DERIVATION_NOT_ALLOWED); 48466a718a5eSMatthias Ringwald } 4847c18be159SMatthias Ringwald break; 4848c18be159SMatthias Ringwald 4849c18be159SMatthias Ringwald case SM_BR_EDR_RECEIVE_KEYS: 4850c18be159SMatthias Ringwald switch(sm_pdu_code){ 4851c18be159SMatthias Ringwald case SM_CODE_IDENTITY_INFORMATION: 4852c18be159SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION; 4853c18be159SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_irk); 4854c18be159SMatthias Ringwald break; 4855c18be159SMatthias Ringwald case SM_CODE_IDENTITY_ADDRESS_INFORMATION: 4856c18be159SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION; 4857c18be159SMatthias Ringwald setup->sm_peer_addr_type = packet[1]; 4858c18be159SMatthias Ringwald reverse_bd_addr(&packet[2], setup->sm_peer_address); 4859c18be159SMatthias Ringwald break; 4860c18be159SMatthias Ringwald case SM_CODE_SIGNING_INFORMATION: 4861c18be159SMatthias Ringwald setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION; 4862c18be159SMatthias Ringwald reverse_128(&packet[1], setup->sm_peer_csrk); 4863c18be159SMatthias Ringwald break; 4864c18be159SMatthias Ringwald default: 4865c18be159SMatthias Ringwald // Unexpected PDU 4866c18be159SMatthias Ringwald log_info("Unexpected PDU %u in SM_PH3_RECEIVE_KEYS", packet[0]); 4867c18be159SMatthias Ringwald break; 4868c18be159SMatthias Ringwald } 4869c18be159SMatthias Ringwald 4870c18be159SMatthias Ringwald // all keys received 487161d1a45eSMatthias Ringwald if (sm_key_distribution_all_received()){ 4872c18be159SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 4873c18be159SMatthias Ringwald // responder -> keys exchanged, derive LE LTK 4874c18be159SMatthias Ringwald sm_ctkd_start_from_br_edr(sm_conn); 4875c18be159SMatthias Ringwald } else { 4876c18be159SMatthias Ringwald // initiator -> send our keys if any 4877c18be159SMatthias Ringwald sm_conn->sm_engine_state = SM_BR_EDR_DISTRIBUTE_KEYS; 4878c18be159SMatthias Ringwald } 4879c18be159SMatthias Ringwald } 4880c18be159SMatthias Ringwald break; 4881c18be159SMatthias Ringwald #endif 4882c18be159SMatthias Ringwald 48833deb3ec6SMatthias Ringwald default: 48843deb3ec6SMatthias Ringwald // Unexpected PDU 48853deb3ec6SMatthias Ringwald log_info("Unexpected PDU %u in state %u", packet[0], sm_conn->sm_engine_state); 48862d095694SMatthias Ringwald sm_pdu_received_in_wrong_state(sm_conn); 48873deb3ec6SMatthias Ringwald break; 48883deb3ec6SMatthias Ringwald } 48893deb3ec6SMatthias Ringwald 489070b44dd4SMatthias Ringwald // try to send next pdu 489170b44dd4SMatthias Ringwald sm_trigger_run(); 48923deb3ec6SMatthias Ringwald } 48933deb3ec6SMatthias Ringwald 48943deb3ec6SMatthias Ringwald // Security Manager Client API 4895a680ba6bSMatthias Ringwald void sm_register_oob_data_callback( int (*get_oob_data_callback)(uint8_t address_type, bd_addr_t addr, uint8_t * oob_data)){ 48963deb3ec6SMatthias Ringwald sm_get_oob_data = get_oob_data_callback; 48973deb3ec6SMatthias Ringwald } 48983deb3ec6SMatthias Ringwald 48994acf7b7bSMatthias 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)){ 4900a680ba6bSMatthias Ringwald sm_get_sc_oob_data = get_sc_oob_data_callback; 4901a680ba6bSMatthias Ringwald } 4902a680ba6bSMatthias Ringwald 4903b96d60a6SMatthias 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)){ 4904b96d60a6SMatthias Ringwald sm_get_ltk_callback = get_ltk_callback; 4905b96d60a6SMatthias Ringwald } 4906b96d60a6SMatthias Ringwald 490789a78d34SMatthias Ringwald void sm_add_event_handler(btstack_packet_callback_registration_t * callback_handler){ 490889a78d34SMatthias Ringwald btstack_linked_list_add_tail(&sm_event_handlers, (btstack_linked_item_t*) callback_handler); 490989a78d34SMatthias Ringwald } 491089a78d34SMatthias Ringwald 491167f708e0SMatthias Ringwald void sm_remove_event_handler(btstack_packet_callback_registration_t * callback_handler){ 491267f708e0SMatthias Ringwald btstack_linked_list_remove(&sm_event_handlers, (btstack_linked_item_t*) callback_handler); 491367f708e0SMatthias Ringwald } 491467f708e0SMatthias Ringwald 49153deb3ec6SMatthias Ringwald void sm_set_accepted_stk_generation_methods(uint8_t accepted_stk_generation_methods){ 49163deb3ec6SMatthias Ringwald sm_accepted_stk_generation_methods = accepted_stk_generation_methods; 49173deb3ec6SMatthias Ringwald } 49183deb3ec6SMatthias Ringwald 49193deb3ec6SMatthias Ringwald void sm_set_encryption_key_size_range(uint8_t min_size, uint8_t max_size){ 49203deb3ec6SMatthias Ringwald sm_min_encryption_key_size = min_size; 49213deb3ec6SMatthias Ringwald sm_max_encryption_key_size = max_size; 49223deb3ec6SMatthias Ringwald } 49233deb3ec6SMatthias Ringwald 49243deb3ec6SMatthias Ringwald void sm_set_authentication_requirements(uint8_t auth_req){ 492598d95509SMatthias Ringwald #ifndef ENABLE_LE_SECURE_CONNECTIONS 492698d95509SMatthias Ringwald if (auth_req & SM_AUTHREQ_SECURE_CONNECTION){ 492798d95509SMatthias Ringwald log_error("ENABLE_LE_SECURE_CONNECTIONS not defined, but requested by app. Dropping SC flag"); 492898d95509SMatthias Ringwald auth_req &= ~SM_AUTHREQ_SECURE_CONNECTION; 492998d95509SMatthias Ringwald } 493098d95509SMatthias Ringwald #endif 49313deb3ec6SMatthias Ringwald sm_auth_req = auth_req; 49323deb3ec6SMatthias Ringwald } 49333deb3ec6SMatthias Ringwald 49343deb3ec6SMatthias Ringwald void sm_set_io_capabilities(io_capability_t io_capability){ 49353deb3ec6SMatthias Ringwald sm_io_capabilities = io_capability; 49363deb3ec6SMatthias Ringwald } 49373deb3ec6SMatthias Ringwald 493842134bc6SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 49393deb3ec6SMatthias Ringwald void sm_set_request_security(int enable){ 49403deb3ec6SMatthias Ringwald sm_slave_request_security = enable; 49413deb3ec6SMatthias Ringwald } 494242134bc6SMatthias Ringwald #endif 49433deb3ec6SMatthias Ringwald 49443deb3ec6SMatthias Ringwald void sm_set_er(sm_key_t er){ 49456535961aSMatthias Ringwald (void)memcpy(sm_persistent_er, er, 16); 49463deb3ec6SMatthias Ringwald } 49473deb3ec6SMatthias Ringwald 49483deb3ec6SMatthias Ringwald void sm_set_ir(sm_key_t ir){ 49496535961aSMatthias Ringwald (void)memcpy(sm_persistent_ir, ir, 16); 49503deb3ec6SMatthias Ringwald } 49513deb3ec6SMatthias Ringwald 49523deb3ec6SMatthias Ringwald // Testing support only 49533deb3ec6SMatthias Ringwald void sm_test_set_irk(sm_key_t irk){ 49546535961aSMatthias Ringwald (void)memcpy(sm_persistent_irk, irk, 16); 4955103fa6b0SMatthias Ringwald dkg_state = DKG_CALC_DHK; 4956841468bbSMatthias Ringwald test_use_fixed_local_irk = true; 49573deb3ec6SMatthias Ringwald } 49583deb3ec6SMatthias Ringwald 49593deb3ec6SMatthias Ringwald void sm_test_use_fixed_local_csrk(void){ 4960841468bbSMatthias Ringwald test_use_fixed_local_csrk = true; 49613deb3ec6SMatthias Ringwald } 49623deb3ec6SMatthias Ringwald 4963d1a1f6a4SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 4964d1a1f6a4SMatthias Ringwald static void sm_ec_generated(void * arg){ 4965d1a1f6a4SMatthias Ringwald UNUSED(arg); 4966d1a1f6a4SMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_DONE; 496734b6528fSMatthias Ringwald // trigger pairing if pending for ec key 496870b44dd4SMatthias Ringwald sm_trigger_run(); 4969d1a1f6a4SMatthias Ringwald } 4970674e5b4aSMatthias Ringwald static void sm_ec_generate_new_key(void) { 497134b6528fSMatthias Ringwald log_info("sm: generate new ec key"); 4972*db88441fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS_DEBUG_KEY 4973*db88441fSMatthias Ringwald // LE Secure Connections Debug Key 4974*db88441fSMatthias Ringwald const uint8_t debug_key_public[64] = { 4975*db88441fSMatthias Ringwald 0x20, 0xb0, 0x03, 0xd2, 0xf2, 0x97, 0xbe, 0x2c, 0x5e, 0x2c, 0x83, 0xa7, 0xe9, 0xf9, 0xa5, 0xb9, 4976*db88441fSMatthias Ringwald 0xef, 0xf4, 0x91, 0x11, 0xac, 0xf4, 0xfd, 0xdb, 0xcc, 0x03, 0x01, 0x48, 0x0e, 0x35, 0x9d, 0xe6, 4977*db88441fSMatthias Ringwald 0xdc, 0x80, 0x9c, 0x49, 0x65, 0x2a, 0xeb, 0x6d, 0x63, 0x32, 0x9a, 0xbf, 0x5a, 0x52, 0x15, 0x5c, 4978*db88441fSMatthias Ringwald 0x76, 0x63, 0x45, 0xc2, 0x8f, 0xed, 0x30, 0x24, 0x74, 0x1c, 0x8e, 0xd0, 0x15, 0x89, 0xd2, 0x8b 4979*db88441fSMatthias Ringwald }; 4980*db88441fSMatthias Ringwald const uint8_t debug_key_private[32] = { 4981*db88441fSMatthias Ringwald 0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, 0x74, 0xc9, 0xb3, 0xe3, 0xd2, 0x10, 0x3f, 0x50, 4982*db88441fSMatthias Ringwald 0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd 4983*db88441fSMatthias Ringwald }; 4984*db88441fSMatthias Ringwald if (sm_sc_debug_keys_enabled) { 4985*db88441fSMatthias Ringwald memcpy(ec_q, debug_key_public, 64); 4986*db88441fSMatthias Ringwald btstack_crypto_ecc_p256_set_key(debug_key_public, debug_key_private); 4987*db88441fSMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_DONE; 4988*db88441fSMatthias Ringwald } else 4989*db88441fSMatthias Ringwald #endif 4990*db88441fSMatthias Ringwald { 4991674e5b4aSMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_ACTIVE; 4992674e5b4aSMatthias Ringwald btstack_crypto_ecc_p256_generate_key(&sm_crypto_ecc_p256_request, ec_q, &sm_ec_generated, NULL); 4993674e5b4aSMatthias Ringwald } 4994*db88441fSMatthias Ringwald } 4995d1a1f6a4SMatthias Ringwald #endif 4996d1a1f6a4SMatthias Ringwald 4997192365feSMatthias Ringwald #ifdef ENABLE_TESTING_SUPPORT 4998192365feSMatthias Ringwald void sm_test_set_pairing_failure(int reason){ 4999192365feSMatthias Ringwald test_pairing_failure = reason; 5000192365feSMatthias Ringwald } 5001192365feSMatthias Ringwald #endif 5002192365feSMatthias Ringwald 50037887cd92SMatthias Ringwald static void sm_state_reset(void) { 50047f775357SMatthias Ringwald #ifdef USE_CMAC_ENGINE 50057f775357SMatthias Ringwald sm_cmac_active = 0; 50067f775357SMatthias Ringwald #endif 50077f775357SMatthias Ringwald dkg_state = DKG_W4_WORKING; 50087f775357SMatthias Ringwald rau_state = RAU_IDLE; 50097f775357SMatthias Ringwald sm_aes128_state = SM_AES128_IDLE; 50107f775357SMatthias Ringwald sm_address_resolution_test = -1; // no private address to resolve yet 50117f775357SMatthias Ringwald sm_address_resolution_mode = ADDRESS_RESOLUTION_IDLE; 50127f775357SMatthias Ringwald sm_address_resolution_general_queue = NULL; 50137f775357SMatthias Ringwald sm_active_connection_handle = HCI_CON_HANDLE_INVALID; 5014cbdd51cfSMatthias Ringwald sm_persistent_keys_random_active = false; 50157f775357SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 501615211b85SMatthias Ringwald ec_key_generation_state = EC_KEY_GENERATION_IDLE; 50177f775357SMatthias Ringwald #endif 50187f775357SMatthias Ringwald } 50197f775357SMatthias Ringwald 50203deb3ec6SMatthias Ringwald void sm_init(void){ 50212d2d4d3cSMatthias Ringwald 50222d2d4d3cSMatthias Ringwald if (sm_initialized) return; 50232d2d4d3cSMatthias Ringwald 5024899e6e02SMatthias Ringwald // set default ER and IR values (should be unique - set by app or sm later using TLV) 5025899e6e02SMatthias Ringwald sm_er_ir_set_default(); 5026899e6e02SMatthias Ringwald 50273deb3ec6SMatthias Ringwald // defaults 50283deb3ec6SMatthias Ringwald sm_accepted_stk_generation_methods = SM_STK_GENERATION_METHOD_JUST_WORKS 50293deb3ec6SMatthias Ringwald | SM_STK_GENERATION_METHOD_OOB 5030b4343428SMatthias Ringwald | SM_STK_GENERATION_METHOD_PASSKEY 5031b4343428SMatthias Ringwald | SM_STK_GENERATION_METHOD_NUMERIC_COMPARISON; 5032b4343428SMatthias Ringwald 50333deb3ec6SMatthias Ringwald sm_max_encryption_key_size = 16; 50343deb3ec6SMatthias Ringwald sm_min_encryption_key_size = 7; 50353deb3ec6SMatthias Ringwald 50365ce1359eSMatthias Ringwald sm_fixed_passkey_in_display_role = 0xffffffffU; 50371979f09cSMatthias Ringwald sm_reconstruct_ltk_without_le_device_db_entry = true; 5038caf15bf3SMatthias Ringwald 50393deb3ec6SMatthias Ringwald gap_random_adress_update_period = 15 * 60 * 1000L; 50403deb3ec6SMatthias Ringwald 5041841468bbSMatthias Ringwald test_use_fixed_local_csrk = false; 50423deb3ec6SMatthias Ringwald 50437f775357SMatthias Ringwald // other 504484c0c5c7SMatthias Ringwald btstack_run_loop_set_timer_handler(&sm_run_timer, &sm_run_timer_handler); 504584c0c5c7SMatthias Ringwald 5046a036ae12SMatthias Ringwald // register for HCI Events 5047e03e489aSMatthias Ringwald hci_event_callback_registration.callback = &sm_event_packet_handler; 5048e03e489aSMatthias Ringwald hci_add_event_handler(&hci_event_callback_registration); 5049e03e489aSMatthias Ringwald 5050bad51150SMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 5051a036ae12SMatthias Ringwald // register for L2CAP events 5052a036ae12SMatthias Ringwald l2cap_event_callback_registration.callback = &sm_event_packet_handler; 5053a036ae12SMatthias Ringwald l2cap_add_event_handler(&l2cap_event_callback_registration); 5054bad51150SMatthias Ringwald #endif 5055a036ae12SMatthias Ringwald 5056d1a1f6a4SMatthias Ringwald // 5057d1a1f6a4SMatthias Ringwald btstack_crypto_init(); 5058d1a1f6a4SMatthias Ringwald 505951bd74d1SMatthias Ringwald // init le_device_db 506051bd74d1SMatthias Ringwald le_device_db_init(); 506151bd74d1SMatthias Ringwald 5062b170b20fSMatthias Ringwald // and L2CAP PDUs + L2CAP_EVENT_CAN_SEND_NOW 5063e03e489aSMatthias Ringwald l2cap_register_fixed_channel(sm_pdu_handler, L2CAP_CID_SECURITY_MANAGER_PROTOCOL); 5064384eabd3SMatthias Ringwald #ifdef ENABLE_CLASSIC 5065384eabd3SMatthias Ringwald l2cap_register_fixed_channel(sm_pdu_handler, L2CAP_CID_BR_EDR_SECURITY_MANAGER); 5066384eabd3SMatthias Ringwald #endif 506727c32905SMatthias Ringwald 50687f775357SMatthias Ringwald // state 50697f775357SMatthias Ringwald sm_state_reset(); 50702d2d4d3cSMatthias Ringwald 50712d2d4d3cSMatthias Ringwald sm_initialized = true; 50723deb3ec6SMatthias Ringwald } 50733deb3ec6SMatthias Ringwald 507415537ea4SMatthias Ringwald void sm_deinit(void){ 507515537ea4SMatthias Ringwald sm_initialized = false; 507615537ea4SMatthias Ringwald btstack_run_loop_remove_timer(&sm_run_timer); 5077*db88441fSMatthias Ringwald #if defined(ENABLE_LE_SECURE_CONNECTIONS) || defined (ENABLE_LE_SECURE_CONNECTION_DEBUG_KEY) 5078*db88441fSMatthias Ringwald sm_sc_debug_keys_enabled = false; 5079*db88441fSMatthias Ringwald #endif 508015537ea4SMatthias Ringwald } 508115537ea4SMatthias Ringwald 50824b8c611fSMatthias Ringwald void sm_use_fixed_passkey_in_display_role(uint32_t passkey){ 50834b8c611fSMatthias Ringwald sm_fixed_passkey_in_display_role = passkey; 5084caf15bf3SMatthias Ringwald } 5085caf15bf3SMatthias Ringwald 50866c39055aSMatthias Ringwald void sm_allow_ltk_reconstruction_without_le_device_db_entry(int allow){ 50871979f09cSMatthias Ringwald sm_reconstruct_ltk_without_le_device_db_entry = allow != 0; 50886c39055aSMatthias Ringwald } 50896c39055aSMatthias Ringwald 5090711e6c80SMatthias Ringwald static sm_connection_t * sm_get_connection_for_handle(hci_con_handle_t con_handle){ 5091711e6c80SMatthias Ringwald hci_connection_t * hci_con = hci_connection_for_handle(con_handle); 50923deb3ec6SMatthias Ringwald if (!hci_con) return NULL; 50933deb3ec6SMatthias Ringwald return &hci_con->sm_connection; 50943deb3ec6SMatthias Ringwald } 50953deb3ec6SMatthias Ringwald 5096916ea5b2SMatthias Ringwald static void sm_cache_ltk(sm_connection_t * connection, const sm_key_t ltk){ 5097916ea5b2SMatthias Ringwald hci_connection_t * hci_con = hci_connection_for_handle(connection->sm_handle); 5098916ea5b2SMatthias Ringwald btstack_assert(hci_con != NULL); 5099916ea5b2SMatthias Ringwald memcpy(hci_con->link_key, ltk, 16); 5100916ea5b2SMatthias Ringwald hci_con->link_key_type = 1; 5101916ea5b2SMatthias Ringwald } 5102916ea5b2SMatthias Ringwald 510377e2e5edSMatthias Ringwald #ifdef ENABLE_CROSS_TRANSPORT_KEY_DERIVATION 510477e2e5edSMatthias Ringwald static sm_connection_t * sm_get_connection_for_bd_addr_and_type(bd_addr_t address, bd_addr_type_t addr_type){ 510577e2e5edSMatthias Ringwald hci_connection_t * hci_con = hci_connection_for_bd_addr_and_type(address, addr_type); 510677e2e5edSMatthias Ringwald if (!hci_con) return NULL; 510777e2e5edSMatthias Ringwald return &hci_con->sm_connection; 510877e2e5edSMatthias Ringwald } 510977e2e5edSMatthias Ringwald #endif 511077e2e5edSMatthias Ringwald 51116bc3aba4SMatthias Ringwald // @deprecated: map onto sm_request_pairing 5112711e6c80SMatthias Ringwald void sm_send_security_request(hci_con_handle_t con_handle){ 5113711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 51143deb3ec6SMatthias Ringwald if (!sm_conn) return; 51156bc3aba4SMatthias Ringwald if (!IS_RESPONDER(sm_conn->sm_role)) return; 51166bc3aba4SMatthias Ringwald sm_request_pairing(con_handle); 51173deb3ec6SMatthias Ringwald } 51183deb3ec6SMatthias Ringwald 51193deb3ec6SMatthias Ringwald // request pairing 5120711e6c80SMatthias Ringwald void sm_request_pairing(hci_con_handle_t con_handle){ 5121711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 51223deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 51233deb3ec6SMatthias Ringwald 51247af5dcd5SMatthias Ringwald bool have_ltk; 51257af5dcd5SMatthias Ringwald uint8_t ltk[16]; 51262d68601cSMatthias Ringwald bool auth_required; 51272d68601cSMatthias Ringwald int authenticated; 51282d68601cSMatthias Ringwald bool trigger_reencryption; 51293deb3ec6SMatthias Ringwald log_info("sm_request_pairing in role %u, state %u", sm_conn->sm_role, sm_conn->sm_engine_state); 513042134bc6SMatthias Ringwald if (IS_RESPONDER(sm_conn->sm_role)){ 513124c20dc4SMatthias Ringwald switch (sm_conn->sm_engine_state){ 513224c20dc4SMatthias Ringwald case SM_GENERAL_IDLE: 513324c20dc4SMatthias Ringwald case SM_RESPONDER_IDLE: 51347af5dcd5SMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 51357af5dcd5SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 51367af5dcd5SMatthias Ringwald le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, NULL, NULL, NULL); 51377af5dcd5SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 51387af5dcd5SMatthias Ringwald log_info("have ltk %u", have_ltk); 51397af5dcd5SMatthias Ringwald if (have_ltk){ 51407af5dcd5SMatthias Ringwald sm_conn->sm_pairing_requested = 1; 514124c20dc4SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 51427af5dcd5SMatthias Ringwald sm_reencryption_started(sm_conn); 51437af5dcd5SMatthias Ringwald break; 51447af5dcd5SMatthias Ringwald } 51457af5dcd5SMatthias Ringwald /* fall through */ 51467af5dcd5SMatthias Ringwald 51477af5dcd5SMatthias Ringwald case IRK_LOOKUP_FAILED: 51487af5dcd5SMatthias Ringwald sm_conn->sm_pairing_requested = 1; 51497af5dcd5SMatthias Ringwald sm_conn->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 51507af5dcd5SMatthias Ringwald sm_pairing_started(sm_conn); 51517af5dcd5SMatthias Ringwald break; 51527af5dcd5SMatthias Ringwald default: 51537af5dcd5SMatthias Ringwald log_info("irk lookup pending"); 51547af5dcd5SMatthias Ringwald sm_conn->sm_pairing_requested = 1; 51557af5dcd5SMatthias Ringwald break; 51567af5dcd5SMatthias Ringwald } 515724c20dc4SMatthias Ringwald break; 515824c20dc4SMatthias Ringwald default: 515924c20dc4SMatthias Ringwald break; 516024c20dc4SMatthias Ringwald } 51613deb3ec6SMatthias Ringwald } else { 51623deb3ec6SMatthias Ringwald // used as a trigger to start central/master/initiator security procedures 5163175b7faaSMatthias Ringwald switch (sm_conn->sm_engine_state){ 5164175b7faaSMatthias Ringwald case SM_INITIATOR_CONNECTED: 51653deb3ec6SMatthias Ringwald switch (sm_conn->sm_irk_lookup_state){ 51663deb3ec6SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 51672d68601cSMatthias Ringwald le_device_db_encryption_get(sm_conn->sm_le_db_index, NULL, NULL, ltk, NULL, &authenticated, NULL, NULL); 5168f53ec649SMatthias Ringwald have_ltk = !sm_is_null_key(ltk); 51692d68601cSMatthias Ringwald auth_required = sm_auth_req & SM_AUTHREQ_MITM_PROTECTION; 51702d68601cSMatthias Ringwald // re-encrypt is sufficient if we have ltk and that is either already authenticated or we don't require authentication 51712d68601cSMatthias Ringwald trigger_reencryption = have_ltk && ((authenticated != 0) || (auth_required == false)); 51722d68601cSMatthias Ringwald log_info("have ltk %u, authenticated %u, auth required %u => reencrypt %u", have_ltk, authenticated, auth_required, trigger_reencryption); 51732d68601cSMatthias Ringwald if (trigger_reencryption){ 5174c245ca32SMatthias Ringwald sm_conn->sm_pairing_requested = 1; 51755567aa60SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH4_HAS_LTK; 5176c245ca32SMatthias Ringwald break; 5177f53ec649SMatthias Ringwald } 5178cf373d3aSMatthias Ringwald /* fall through */ 5179c245ca32SMatthias Ringwald 518034c39fbdSMatthias Ringwald case IRK_LOOKUP_FAILED: 51813deb3ec6SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 51823deb3ec6SMatthias Ringwald break; 51833deb3ec6SMatthias Ringwald default: 5184d1a1f6a4SMatthias Ringwald log_info("irk lookup pending"); 518509ea1b62SMatthias Ringwald sm_conn->sm_pairing_requested = 1; 51863deb3ec6SMatthias Ringwald break; 51873deb3ec6SMatthias Ringwald } 5188175b7faaSMatthias Ringwald break; 5189cb6d7eb0SMatthias Ringwald case SM_GENERAL_REENCRYPTION_FAILED: 5190cb6d7eb0SMatthias Ringwald sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; 5191cb6d7eb0SMatthias Ringwald break; 5192175b7faaSMatthias Ringwald case SM_GENERAL_IDLE: 519309ea1b62SMatthias Ringwald sm_conn->sm_pairing_requested = 1; 5194175b7faaSMatthias Ringwald break; 5195175b7faaSMatthias Ringwald default: 5196175b7faaSMatthias Ringwald break; 51973deb3ec6SMatthias Ringwald } 51983deb3ec6SMatthias Ringwald } 519970b44dd4SMatthias Ringwald sm_trigger_run(); 52003deb3ec6SMatthias Ringwald } 52013deb3ec6SMatthias Ringwald 52023deb3ec6SMatthias Ringwald // called by client app on authorization request 5203711e6c80SMatthias Ringwald void sm_authorization_decline(hci_con_handle_t con_handle){ 5204711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 52053deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 52063deb3ec6SMatthias Ringwald sm_conn->sm_connection_authorization_state = AUTHORIZATION_DECLINED; 5207589f5a99SMatthias 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); 52083deb3ec6SMatthias Ringwald } 52093deb3ec6SMatthias Ringwald 5210711e6c80SMatthias Ringwald void sm_authorization_grant(hci_con_handle_t con_handle){ 5211711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 52123deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 52133deb3ec6SMatthias Ringwald sm_conn->sm_connection_authorization_state = AUTHORIZATION_GRANTED; 5214589f5a99SMatthias 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); 52153deb3ec6SMatthias Ringwald } 52163deb3ec6SMatthias Ringwald 52173deb3ec6SMatthias Ringwald // GAP Bonding API 52183deb3ec6SMatthias Ringwald 5219711e6c80SMatthias Ringwald void sm_bonding_decline(hci_con_handle_t con_handle){ 5220711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 52213deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 52223deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_DECLINE; 52230af429c6SMatthias Ringwald log_info("decline, state %u", sm_conn->sm_engine_state); 52240af429c6SMatthias Ringwald switch(sm_conn->sm_engine_state){ 52250af429c6SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 52260af429c6SMatthias Ringwald case SM_SC_W4_USER_RESPONSE: 52270af429c6SMatthias Ringwald case SM_SC_W4_CONFIRMATION: 52280af429c6SMatthias Ringwald case SM_SC_W4_PUBLIC_KEY_COMMAND: 52290af429c6SMatthias Ringwald #endif 52300af429c6SMatthias Ringwald case SM_PH1_W4_USER_RESPONSE: 5231de2fd182SMatthias Ringwald switch (setup->sm_stk_generation_method){ 5232de2fd182SMatthias Ringwald case PK_RESP_INPUT: 5233de2fd182SMatthias Ringwald case PK_INIT_INPUT: 523447fb4255SMatthias Ringwald case PK_BOTH_INPUT: 52350af429c6SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_PASSKEY_ENTRY_FAILED); 5236de2fd182SMatthias Ringwald break; 523747fb4255SMatthias Ringwald case NUMERIC_COMPARISON: 5238de2fd182SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_NUMERIC_COMPARISON_FAILED); 5239de2fd182SMatthias Ringwald break; 5240de2fd182SMatthias Ringwald case JUST_WORKS: 5241de2fd182SMatthias Ringwald case OOB: 5242de2fd182SMatthias Ringwald sm_pairing_error(sm_conn, SM_REASON_UNSPECIFIED_REASON); 5243de2fd182SMatthias Ringwald break; 52447bbeb3adSMilanka Ringwald default: 52457bbeb3adSMilanka Ringwald btstack_assert(false); 52467bbeb3adSMilanka Ringwald break; 5247de2fd182SMatthias Ringwald } 52480af429c6SMatthias Ringwald break; 52490af429c6SMatthias Ringwald default: 52500af429c6SMatthias Ringwald break; 52513deb3ec6SMatthias Ringwald } 525270b44dd4SMatthias Ringwald sm_trigger_run(); 52533deb3ec6SMatthias Ringwald } 52543deb3ec6SMatthias Ringwald 5255711e6c80SMatthias Ringwald void sm_just_works_confirm(hci_con_handle_t con_handle){ 5256711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 52573deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 52583deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_CONFIRM; 52593deb3ec6SMatthias Ringwald if (sm_conn->sm_engine_state == SM_PH1_W4_USER_RESPONSE){ 5260136d331aSMatthias Ringwald if (setup->sm_use_secure_connections){ 5261c6b7cbd9SMatthias Ringwald sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; 5262bbf8db22SMatthias Ringwald } else { 5263f3582630SMatthias 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); 5264136d331aSMatthias Ringwald } 52653deb3ec6SMatthias Ringwald } 52660346c37cSMatthias Ringwald 52670346c37cSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 5268c6b7cbd9SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_USER_RESPONSE){ 5269dc300847SMatthias Ringwald sm_sc_prepare_dhkey_check(sm_conn); 5270446a8c36SMatthias Ringwald } 52710346c37cSMatthias Ringwald #endif 52720346c37cSMatthias Ringwald 527370b44dd4SMatthias Ringwald sm_trigger_run(); 52743deb3ec6SMatthias Ringwald } 52753deb3ec6SMatthias Ringwald 5276c8c46d51SMatthias Ringwald void sm_numeric_comparison_confirm(hci_con_handle_t con_handle){ 5277c8c46d51SMatthias Ringwald // for now, it's the same 5278c8c46d51SMatthias Ringwald sm_just_works_confirm(con_handle); 5279c8c46d51SMatthias Ringwald } 5280c8c46d51SMatthias Ringwald 5281711e6c80SMatthias Ringwald void sm_passkey_input(hci_con_handle_t con_handle, uint32_t passkey){ 5282711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 52833deb3ec6SMatthias Ringwald if (!sm_conn) return; // wrong connection 52843deb3ec6SMatthias Ringwald sm_reset_tk(); 5285f8fbdce0SMatthias Ringwald big_endian_store_32(setup->sm_tk, 12, passkey); 52863deb3ec6SMatthias Ringwald setup->sm_user_response = SM_USER_RESPONSE_PASSKEY; 52873deb3ec6SMatthias Ringwald if (sm_conn->sm_engine_state == SM_PH1_W4_USER_RESPONSE){ 5288f3582630SMatthias 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); 52893deb3ec6SMatthias Ringwald } 52901c516d8fSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 52916535961aSMatthias Ringwald (void)memcpy(setup->sm_ra, setup->sm_tk, 16); 52926535961aSMatthias Ringwald (void)memcpy(setup->sm_rb, setup->sm_tk, 16); 529307036a04SMatthias Ringwald if (sm_conn->sm_engine_state == SM_SC_W4_USER_RESPONSE){ 529407036a04SMatthias Ringwald sm_sc_start_calculating_local_confirm(sm_conn); 529507036a04SMatthias Ringwald } 52961c516d8fSMatthias Ringwald #endif 529770b44dd4SMatthias Ringwald sm_trigger_run(); 52983deb3ec6SMatthias Ringwald } 52993deb3ec6SMatthias Ringwald 53003d7fe1e9SMatthias Ringwald void sm_keypress_notification(hci_con_handle_t con_handle, uint8_t action){ 53013d7fe1e9SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 53023d7fe1e9SMatthias Ringwald if (!sm_conn) return; // wrong connection 53033d7fe1e9SMatthias Ringwald if (action > SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED) return; 5304dd4a08fbSMatthias Ringwald uint8_t num_actions = setup->sm_keypress_notification >> 5; 53054ea43905SMatthias Ringwald uint8_t flags = setup->sm_keypress_notification & 0x1fu; 5306dd4a08fbSMatthias Ringwald switch (action){ 5307dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_STARTED: 5308dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED: 53094ea43905SMatthias Ringwald flags |= (1u << action); 5310dd4a08fbSMatthias Ringwald break; 5311dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_CLEARED: 5312dd4a08fbSMatthias Ringwald // clear counter, keypress & erased flags + set passkey cleared 53134ea43905SMatthias Ringwald flags = (flags & 0x19u) | (1u << SM_KEYPRESS_PASSKEY_CLEARED); 5314dd4a08fbSMatthias Ringwald break; 5315dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ENTERED: 53164ea43905SMatthias Ringwald if (flags & (1u << SM_KEYPRESS_PASSKEY_DIGIT_ERASED)){ 5317dd4a08fbSMatthias Ringwald // erase actions queued 5318dd4a08fbSMatthias Ringwald num_actions--; 53194ea43905SMatthias Ringwald if (num_actions == 0u){ 5320dd4a08fbSMatthias Ringwald // clear counter, keypress & erased flags 53214ea43905SMatthias Ringwald flags &= 0x19u; 5322dd4a08fbSMatthias Ringwald } 5323dd4a08fbSMatthias Ringwald break; 5324dd4a08fbSMatthias Ringwald } 5325dd4a08fbSMatthias Ringwald num_actions++; 53264ea43905SMatthias Ringwald flags |= (1u << SM_KEYPRESS_PASSKEY_DIGIT_ENTERED); 5327dd4a08fbSMatthias Ringwald break; 5328dd4a08fbSMatthias Ringwald case SM_KEYPRESS_PASSKEY_DIGIT_ERASED: 53294ea43905SMatthias Ringwald if (flags & (1u << SM_KEYPRESS_PASSKEY_DIGIT_ENTERED)){ 5330dd4a08fbSMatthias Ringwald // enter actions queued 5331dd4a08fbSMatthias Ringwald num_actions--; 53324ea43905SMatthias Ringwald if (num_actions == 0u){ 5333dd4a08fbSMatthias Ringwald // clear counter, keypress & erased flags 53344ea43905SMatthias Ringwald flags &= 0x19u; 5335dd4a08fbSMatthias Ringwald } 5336dd4a08fbSMatthias Ringwald break; 5337dd4a08fbSMatthias Ringwald } 5338dd4a08fbSMatthias Ringwald num_actions++; 53394ea43905SMatthias Ringwald flags |= (1u << SM_KEYPRESS_PASSKEY_DIGIT_ERASED); 5340dd4a08fbSMatthias Ringwald break; 5341dd4a08fbSMatthias Ringwald default: 5342dd4a08fbSMatthias Ringwald break; 5343dd4a08fbSMatthias Ringwald } 5344dd4a08fbSMatthias Ringwald setup->sm_keypress_notification = (num_actions << 5) | flags; 534570b44dd4SMatthias Ringwald sm_trigger_run(); 53463d7fe1e9SMatthias Ringwald } 53473d7fe1e9SMatthias Ringwald 5348c59d0c92SMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 5349d1a1f6a4SMatthias Ringwald static void sm_handle_random_result_oob(void * arg){ 5350d1a1f6a4SMatthias Ringwald UNUSED(arg); 5351d1a1f6a4SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_W2_CALC_CONFIRM; 535270b44dd4SMatthias Ringwald sm_trigger_run(); 5353d1a1f6a4SMatthias Ringwald } 5354c59d0c92SMatthias Ringwald uint8_t sm_generate_sc_oob_data(void (*callback)(const uint8_t * confirm_value, const uint8_t * random_value)){ 53558334d3d8SMatthias Ringwald 53568334d3d8SMatthias Ringwald static btstack_crypto_random_t sm_crypto_random_oob_request; 53578334d3d8SMatthias Ringwald 5358c59d0c92SMatthias Ringwald if (sm_sc_oob_state != SM_SC_OOB_IDLE) return ERROR_CODE_COMMAND_DISALLOWED; 5359c59d0c92SMatthias Ringwald sm_sc_oob_callback = callback; 5360d1a1f6a4SMatthias Ringwald sm_sc_oob_state = SM_SC_OOB_W4_RANDOM; 5361d1a1f6a4SMatthias Ringwald btstack_crypto_random_generate(&sm_crypto_random_oob_request, sm_sc_oob_random, 16, &sm_handle_random_result_oob, NULL); 5362c59d0c92SMatthias Ringwald return 0; 5363c59d0c92SMatthias Ringwald } 5364c59d0c92SMatthias Ringwald #endif 5365c59d0c92SMatthias Ringwald 53663deb3ec6SMatthias Ringwald /** 5367ba394633SMatthias Ringwald * @brief Get Identity Resolving state 5368ba394633SMatthias Ringwald * @param con_handle 5369ba394633SMatthias Ringwald * @return irk_lookup_state_t 5370ba394633SMatthias Ringwald */ 5371ba394633SMatthias Ringwald irk_lookup_state_t sm_identity_resolving_state(hci_con_handle_t con_handle){ 5372ba394633SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 5373ba394633SMatthias Ringwald if (!sm_conn) return IRK_LOOKUP_IDLE; 5374ba394633SMatthias Ringwald return sm_conn->sm_irk_lookup_state; 5375ba394633SMatthias Ringwald } 5376ba394633SMatthias Ringwald 5377ba394633SMatthias Ringwald /** 53783deb3ec6SMatthias Ringwald * @brief Identify device in LE Device DB 53793deb3ec6SMatthias Ringwald * @param handle 53806b65794dSMilanka Ringwald * @return index from le_device_db or -1 if not found/identified 53813deb3ec6SMatthias Ringwald */ 5382711e6c80SMatthias Ringwald int sm_le_device_index(hci_con_handle_t con_handle ){ 5383711e6c80SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 53843deb3ec6SMatthias Ringwald if (!sm_conn) return -1; 53853deb3ec6SMatthias Ringwald return sm_conn->sm_le_db_index; 53863deb3ec6SMatthias Ringwald } 53873deb3ec6SMatthias Ringwald 5388916ea5b2SMatthias Ringwald uint8_t sm_get_ltk(hci_con_handle_t con_handle, sm_key_t ltk){ 5389916ea5b2SMatthias Ringwald hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); 5390916ea5b2SMatthias Ringwald if (hci_connection == NULL){ 5391916ea5b2SMatthias Ringwald return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 5392916ea5b2SMatthias Ringwald } 5393916ea5b2SMatthias Ringwald if (hci_connection->link_key_type == 0){ 5394916ea5b2SMatthias Ringwald return ERROR_CODE_PIN_OR_KEY_MISSING; 5395916ea5b2SMatthias Ringwald } 5396916ea5b2SMatthias Ringwald memcpy(ltk, hci_connection->link_key, 16); 5397916ea5b2SMatthias Ringwald return ERROR_CODE_SUCCESS; 5398916ea5b2SMatthias Ringwald } 5399916ea5b2SMatthias Ringwald 54008f57b085SMatthias Ringwald static int gap_random_address_type_requires_updates(void){ 540147ba4de1SMatthias Ringwald switch (gap_random_adress_type){ 540247ba4de1SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_OFF: 540347ba4de1SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_STATIC: 540447ba4de1SMatthias Ringwald return 0; 540547ba4de1SMatthias Ringwald default: 54068f57b085SMatthias Ringwald return 1; 54078f57b085SMatthias Ringwald } 540847ba4de1SMatthias Ringwald } 5409d70217a2SMatthias Ringwald 541033373e40SMatthias Ringwald static uint8_t own_address_type(void){ 5411b95a5a35SMatthias Ringwald switch (gap_random_adress_type){ 5412b95a5a35SMatthias Ringwald case GAP_RANDOM_ADDRESS_TYPE_OFF: 5413b95a5a35SMatthias Ringwald return BD_ADDR_TYPE_LE_PUBLIC; 5414b95a5a35SMatthias Ringwald default: 5415b95a5a35SMatthias Ringwald return BD_ADDR_TYPE_LE_RANDOM; 5416b95a5a35SMatthias Ringwald } 541733373e40SMatthias Ringwald } 54188f57b085SMatthias Ringwald 54193deb3ec6SMatthias Ringwald // GAP LE API 54203deb3ec6SMatthias Ringwald void gap_random_address_set_mode(gap_random_address_type_t random_address_type){ 54213deb3ec6SMatthias Ringwald gap_random_address_update_stop(); 54223deb3ec6SMatthias Ringwald gap_random_adress_type = random_address_type; 5423b95a5a35SMatthias Ringwald hci_le_set_own_address_type(own_address_type()); 54248f57b085SMatthias Ringwald if (!gap_random_address_type_requires_updates()) return; 54253deb3ec6SMatthias Ringwald gap_random_address_update_start(); 54263deb3ec6SMatthias Ringwald gap_random_address_trigger(); 54273deb3ec6SMatthias Ringwald } 54283deb3ec6SMatthias Ringwald 54293deb3ec6SMatthias Ringwald gap_random_address_type_t gap_random_address_get_mode(void){ 54303deb3ec6SMatthias Ringwald return gap_random_adress_type; 54313deb3ec6SMatthias Ringwald } 54323deb3ec6SMatthias Ringwald 54333deb3ec6SMatthias Ringwald void gap_random_address_set_update_period(int period_ms){ 54343deb3ec6SMatthias Ringwald gap_random_adress_update_period = period_ms; 54358f57b085SMatthias Ringwald if (!gap_random_address_type_requires_updates()) return; 54363deb3ec6SMatthias Ringwald gap_random_address_update_stop(); 54373deb3ec6SMatthias Ringwald gap_random_address_update_start(); 54383deb3ec6SMatthias Ringwald } 54393deb3ec6SMatthias Ringwald 5440667ba9d1SMatthias Ringwald void gap_random_address_set(const bd_addr_t addr){ 54418f57b085SMatthias Ringwald gap_random_address_set_mode(GAP_RANDOM_ADDRESS_TYPE_STATIC); 54426535961aSMatthias Ringwald (void)memcpy(sm_random_address, addr, 6); 544363d302e8SMatthias Ringwald // assert msb bits are set to '11' 544463d302e8SMatthias Ringwald sm_random_address[0] |= 0xc0; 544563d302e8SMatthias Ringwald hci_le_random_address_set(sm_random_address); 54467e252622SMatthias Ringwald } 54477e252622SMatthias Ringwald 5448d70217a2SMatthias Ringwald #ifdef ENABLE_LE_PERIPHERAL 54493deb3ec6SMatthias Ringwald /* 54503deb3ec6SMatthias Ringwald * @brief Set Advertisement Paramters 54513deb3ec6SMatthias Ringwald * @param adv_int_min 54523deb3ec6SMatthias Ringwald * @param adv_int_max 54533deb3ec6SMatthias Ringwald * @param adv_type 54543deb3ec6SMatthias Ringwald * @param direct_address_type 54553deb3ec6SMatthias Ringwald * @param direct_address 54563deb3ec6SMatthias Ringwald * @param channel_map 54573deb3ec6SMatthias Ringwald * @param filter_policy 54583deb3ec6SMatthias Ringwald * 54593deb3ec6SMatthias Ringwald * @note own_address_type is used from gap_random_address_set_mode 54603deb3ec6SMatthias Ringwald */ 54613deb3ec6SMatthias Ringwald void gap_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, 54623deb3ec6SMatthias Ringwald uint8_t direct_address_typ, bd_addr_t direct_address, uint8_t channel_map, uint8_t filter_policy){ 5463b95a5a35SMatthias Ringwald hci_le_advertisements_set_params(adv_int_min, adv_int_max, adv_type, 54643deb3ec6SMatthias Ringwald direct_address_typ, direct_address, channel_map, filter_policy); 54653deb3ec6SMatthias Ringwald } 5466d70217a2SMatthias Ringwald #endif 5467dcd6c9b5SMatthias Ringwald 5468dcd6c9b5SMatthias Ringwald int gap_reconnect_security_setup_active(hci_con_handle_t con_handle){ 5469dcd6c9b5SMatthias Ringwald sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle); 5470dcd6c9b5SMatthias Ringwald // wrong connection 5471dcd6c9b5SMatthias Ringwald if (!sm_conn) return 0; 5472dcd6c9b5SMatthias Ringwald // already encrypted 5473dcd6c9b5SMatthias Ringwald if (sm_conn->sm_connection_encrypted) return 0; 5474dcd6c9b5SMatthias Ringwald // irk status? 5475dcd6c9b5SMatthias Ringwald switch(sm_conn->sm_irk_lookup_state){ 5476dcd6c9b5SMatthias Ringwald case IRK_LOOKUP_FAILED: 5477dcd6c9b5SMatthias Ringwald // done, cannot setup encryption 5478dcd6c9b5SMatthias Ringwald return 0; 5479dcd6c9b5SMatthias Ringwald case IRK_LOOKUP_SUCCEEDED: 5480dcd6c9b5SMatthias Ringwald break; 5481dcd6c9b5SMatthias Ringwald default: 5482dcd6c9b5SMatthias Ringwald // IR Lookup pending 5483dcd6c9b5SMatthias Ringwald return 1; 5484dcd6c9b5SMatthias Ringwald } 5485f0674e22SMatthias Ringwald // IRK Lookup Succeeded, re-encryption should be initiated. When done, state gets reset or indicates failure 5486f0674e22SMatthias Ringwald if (sm_conn->sm_engine_state == SM_GENERAL_REENCRYPTION_FAILED) return 0; 5487b15d5ceaSMatthias Ringwald if (sm_conn->sm_role){ 5488b15d5ceaSMatthias Ringwald return sm_conn->sm_engine_state != SM_RESPONDER_IDLE; 5489b15d5ceaSMatthias Ringwald } else { 5490dcd6c9b5SMatthias Ringwald return sm_conn->sm_engine_state != SM_INITIATOR_CONNECTED; 5491dcd6c9b5SMatthias Ringwald } 5492b15d5ceaSMatthias Ringwald } 54933cdbe9dbSMatthias Ringwald 54943cdbe9dbSMatthias Ringwald void sm_set_secure_connections_only_mode(bool enable){ 54953cdbe9dbSMatthias Ringwald #ifdef ENABLE_LE_SECURE_CONNECTIONS 54963cdbe9dbSMatthias Ringwald sm_sc_only_mode = enable; 54973cdbe9dbSMatthias Ringwald #else 54983cdbe9dbSMatthias Ringwald // SC Only mode not possible without support for SC 54993cdbe9dbSMatthias Ringwald btstack_assert(enable == false); 55003cdbe9dbSMatthias Ringwald #endif 55013cdbe9dbSMatthias Ringwald } 5502052bbdc5SMatthias Ringwald 5503*db88441fSMatthias Ringwald #if defined(ENABLE_LE_SECURE_CONNECTIONS) || defined (ENABLE_LE_SECURE_CONNECTION_DEBUG_KEY) 5504*db88441fSMatthias Ringwald void sm_test_enable_secure_connections_debug_keys(void) { 5505*db88441fSMatthias Ringwald log_info("Enable LE Secure Connection Debug Keys for testing"); 5506*db88441fSMatthias Ringwald sm_sc_debug_keys_enabled = true; 5507*db88441fSMatthias Ringwald // set debug key 5508*db88441fSMatthias Ringwald sm_ec_generate_new_key(); 5509*db88441fSMatthias Ringwald } 5510*db88441fSMatthias Ringwald #endif 5511*db88441fSMatthias Ringwald 5512052bbdc5SMatthias Ringwald const uint8_t * gap_get_persistent_irk(void){ 5513052bbdc5SMatthias Ringwald return sm_persistent_irk; 5514052bbdc5SMatthias Ringwald } 55154f384501SMatthias Ringwald 55164f384501SMatthias Ringwald void gap_delete_bonding(bd_addr_type_t address_type, bd_addr_t address){ 551722cb578bSMatthias Ringwald int index = sm_le_device_db_index_lookup(address_type, address); 551822cb578bSMatthias Ringwald if (index >= 0){ 551922cb578bSMatthias Ringwald sm_remove_le_device_db_entry(index); 55204f384501SMatthias Ringwald } 55214f384501SMatthias Ringwald } 5522