From 9ec080fd8e38ba6546b8a549bac02f9436ae21bc Mon Sep 17 00:00:00 2001 From: "matthias.ringwald@gmail.com" Date: Tue, 3 Mar 2015 21:38:29 +0000 Subject: [PATCH] new states for re-establishing secure connection --- ble/sm.c | 76 ++++++++++++++++++++++++++++++------------------------- src/hci.h | 6 +++-- 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/ble/sm.c b/ble/sm.c index 9a1f0600b..e5eb2e807 100644 --- a/ble/sm.c +++ b/ble/sm.c @@ -919,7 +919,7 @@ static void sm_run(void){ // -- Continue with CSRK device lookup by public or resolvable private address if (sm_central_device_test >= 0){ - log_info("Central Device Lookup: device %u/%u", sm_central_device_test, le_device_db_count()); + log_info("LE Device Lookup: device %u/%u", sm_central_device_test, le_device_db_count()); while (sm_central_device_test < le_device_db_count()){ int addr_type; bd_addr_t addr; @@ -928,12 +928,21 @@ static void sm_run(void){ log_info("device type %u, addr: %s", addr_type, bd_addr_to_str(addr)); if (sm_central_device_addr_type == addr_type && memcmp(addr, sm_central_device_address, 6) == 0){ - log_info("Central Device Lookup: found CSRK by { addr_type, address} "); + log_info("LE Device Lookup: found CSRK by { addr_type, address} "); sm_central_device_matched = sm_central_device_test; sm_central_device_test = -1; + sm_notify_client(SM_IDENTITY_RESOLVING_SUCCEEDED, sm_central_device_addr_type, sm_central_device_address, 0, sm_central_device_matched); + + // re-use stored LTK/EDIV/RAND if requested & we're master + // TODO: replace global with flag in sm_connection_t + if (sm_authenticate_outgoing_connections && sm_csrk_connection_source->sm_role == 0){ + sm_csrk_connection_source->sm_engine_state = SM_INITIATOR_PH0_HAS_LTK; + log_info("sm: Setting up previous ltk/ediv/rand"); + } + + // ready for other requests sm_csrk_connection_source->sm_csrk_lookup_state = CSRK_LOOKUP_IDLE; sm_csrk_connection_source = NULL; - sm_notify_client(SM_IDENTITY_RESOLVING_SUCCEEDED, sm_central_device_addr_type, sm_central_device_address, 0, sm_central_device_matched); break; } @@ -944,7 +953,7 @@ static void sm_run(void){ if (sm_aes128_state == SM_AES128_ACTIVE) break; - log_info("Central Device Lookup: calculate AH"); + log_info("LE Device Lookup: calculate AH"); log_key("IRK", irk); sm_key_t r_prime; @@ -955,7 +964,7 @@ static void sm_run(void){ } if (sm_central_device_test >= le_device_db_count()){ - log_info("Central Device Lookup: not found"); + log_info("LE Device Lookup: not found"); sm_central_device_test = -1; sm_csrk_connection_source->sm_csrk_lookup_state = CSRK_LOOKUP_IDLE; sm_csrk_connection_source = NULL; @@ -997,7 +1006,13 @@ static void sm_run(void){ } sm_connection->sm_engine_state = SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE; break; - case SM_RESPONDER_RECEIVED_LTK: + case SM_INITIATOR_PH0_HAS_LTK: + // fetch data from device db + // ltk + // ediv + // rand + break; + case SM_RESPONDER_PH0_RECEIVED_LTK: // re-establish previously used LTK using Rand and EDIV memcpy(setup->sm_local_rand, sm_connection->sm_local_rand, 8); setup->sm_local_ediv = sm_connection->sm_local_ediv; @@ -1060,27 +1075,6 @@ static void sm_run(void){ return; } - case SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE: { - - // echo initiator for now - setup->sm_s_pres.code = SM_CODE_PAIRING_RESPONSE; - setup->sm_s_pres.initiator_key_distribution = setup->sm_m_preq.initiator_key_distribution; - setup->sm_s_pres.responder_key_distribution = setup->sm_m_preq.responder_key_distribution; - - connection->sm_engine_state = SM_RESPONDER_PH1_W4_PAIRING_CONFIRM; - l2cap_send_connectionless(connection->sm_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL, (uint8_t*) &setup->sm_s_pres, sizeof(sm_pairing_packet_t)); - sm_timeout_reset(connection); - - sm_trigger_user_response(connection); - - return; - } - - case SM_RESPONDER_SEND_LTK_REQUESTED_NEGATIVE_REPLY: - connection->sm_engine_state = SM_GENERAL_IDLE; - hci_send_cmd(&hci_le_long_term_key_negative_reply, connection->sm_handle); - return; - case SM_GENERAL_SEND_PAIRING_FAILED: { uint8_t buffer[2]; buffer[0] = SM_CODE_PAIRING_FAILED; @@ -1091,6 +1085,22 @@ static void sm_run(void){ break; } + case SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY: + connection->sm_engine_state = SM_GENERAL_IDLE; + hci_send_cmd(&hci_le_long_term_key_negative_reply, connection->sm_handle); + return; + + case SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE: + // echo initiator for now + setup->sm_s_pres.code = SM_CODE_PAIRING_RESPONSE; + setup->sm_s_pres.initiator_key_distribution = setup->sm_m_preq.initiator_key_distribution; + setup->sm_s_pres.responder_key_distribution = setup->sm_m_preq.responder_key_distribution; + connection->sm_engine_state = SM_RESPONDER_PH1_W4_PAIRING_CONFIRM; + l2cap_send_connectionless(connection->sm_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL, (uint8_t*) &setup->sm_s_pres, sizeof(sm_pairing_packet_t)); + sm_timeout_reset(connection); + sm_trigger_user_response(connection); + return; + case SM_PH2_SEND_PAIRING_RANDOM: { uint8_t buffer[17]; buffer[0] = SM_CODE_PAIRING_RANDOM; @@ -1313,7 +1323,7 @@ static void sm_handle_encryption_result(uint8_t * data){ sm_csrk_connection_source->sm_csrk_lookup_state = CSRK_LOOKUP_IDLE; sm_csrk_connection_source = NULL; sm_notify_client(SM_IDENTITY_RESOLVING_SUCCEEDED, sm_central_device_addr_type, sm_central_device_address, 0, sm_central_device_matched); - log_info("Central Device Lookup: matched resolvable private address"); + log_info("LE Device Lookup: matched resolvable private address"); return; } // no match @@ -1599,11 +1609,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint break; } else { // master - if (sm_authenticate_outgoing_connections){ - sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST; - } else { - sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; - } + sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED; } break; @@ -1621,14 +1627,14 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint // assume that we don't have a LTK for ediv == 0 and random == null if (READ_BT_16(packet, 13) == 0 && sm_is_null_random(&packet[5])){ log_info("LTK Request: ediv & random are empty"); - sm_conn->sm_engine_state = SM_RESPONDER_SEND_LTK_REQUESTED_NEGATIVE_REPLY; + sm_conn->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY; break; } // store rand and ediv swap64(&packet[5], sm_conn->sm_local_rand); sm_conn->sm_local_ediv = READ_BT_16(packet, 13); - sm_conn->sm_engine_state = SM_RESPONDER_RECEIVED_LTK; + sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK; break; default: diff --git a/src/hci.h b/src/hci.h index 3bf740f0a..cd19de945 100644 --- a/src/hci.h +++ b/src/hci.h @@ -394,9 +394,9 @@ typedef enum { SM_PH4_SEND_LTK, // RESPONDER ROLE - SM_RESPONDER_RECEIVED_LTK, SM_RESPONDER_SEND_SECURITY_REQUEST, - SM_RESPONDER_SEND_LTK_REQUESTED_NEGATIVE_REPLY, + SM_RESPONDER_PH0_RECEIVED_LTK, + SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY, SM_RESPONDER_PH1_W4_PAIRING_REQUEST, SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED, SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE, @@ -407,6 +407,8 @@ typedef enum { // INITITIATOR ROLE SM_INITIATOR_CONNECTED, + SM_INITIATOR_PH0_HAS_LTK, + SM_INITIATOR_PH0_SEND_START_ENCRYPTION, SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST, SM_INITIATOR_PH1_SEND_PAIRING_REQUEST, SM_INITIATOR_PH1_W4_PAIRING_RESPONSE,