mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-14 01:27:41 +00:00
sm: fix mbedTLS integration
This commit is contained in:
parent
aa29f5873d
commit
034d8e7065
254
src/ble/sm.c
254
src/ble/sm.c
@ -30,13 +30,13 @@
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Please inquire about commercial licensing options at
|
||||
* Please inquire about commercial licensing options at
|
||||
* contact@bluekitchen-gmbh.com
|
||||
*
|
||||
*/
|
||||
|
||||
#define __BTSTACK_FILE__ "sm.c"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
@ -76,7 +76,7 @@
|
||||
#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"
|
||||
#endif
|
||||
|
||||
// configure ECC implementations
|
||||
// configure ECC implementations
|
||||
#ifdef ENABLE_LE_SECURE_CONNECTIONS
|
||||
#if defined(ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS) && defined(HAVE_MBEDTLS_ECC_P256)
|
||||
#error "If you already have mbedTLS (HAVE_MBEDTLS_ECC_P256), please disable uECC (USE_MICRO_ECC_FOR_ECDH) in bstack_config.h"
|
||||
@ -143,7 +143,7 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
JUST_WORKS,
|
||||
PK_RESP_INPUT, // Initiator displays PK, responder inputs PK
|
||||
PK_RESP_INPUT, // Initiator displays PK, responder inputs PK
|
||||
PK_INIT_INPUT, // Responder displays PK, initiator inputs PK
|
||||
OK_BOTH_INPUT, // Only input on both, both input PK
|
||||
NK_BOTH_INPUT, // Only numerical compparison (yes/no) on on both sides
|
||||
@ -318,7 +318,7 @@ typedef struct sm_setup_context {
|
||||
sm_key_t sm_tk;
|
||||
uint8_t sm_use_secure_connections;
|
||||
|
||||
sm_key_t sm_c1_t3_value; // c1 calculation
|
||||
sm_key_t sm_c1_t3_value; // c1 calculation
|
||||
sm_pairing_packet_t sm_m_preq; // pairing request - needed only for c1
|
||||
sm_pairing_packet_t sm_s_pres; // pairing response - needed only for c1
|
||||
sm_key_t sm_local_random;
|
||||
@ -326,7 +326,7 @@ typedef struct sm_setup_context {
|
||||
sm_key_t sm_peer_random;
|
||||
sm_key_t sm_peer_confirm;
|
||||
uint8_t sm_m_addr_type; // address and type can be removed
|
||||
uint8_t sm_s_addr_type; // ''
|
||||
uint8_t sm_s_addr_type; // ''
|
||||
bd_addr_t sm_m_address; // ''
|
||||
bd_addr_t sm_s_address; // ''
|
||||
sm_key_t sm_ltk;
|
||||
@ -336,7 +336,7 @@ typedef struct sm_setup_context {
|
||||
uint8_t sm_peer_q[64]; // also stores random for EC key generation during init
|
||||
sm_key_t sm_peer_nonce; // might be combined with sm_peer_random
|
||||
sm_key_t sm_local_nonce; // might be combined with sm_local_random
|
||||
sm_key_t sm_dhkey;
|
||||
sm_key_t sm_dhkey;
|
||||
sm_key_t sm_peer_dhkey_check;
|
||||
sm_key_t sm_local_dhkey_check;
|
||||
sm_key_t sm_ra;
|
||||
@ -371,7 +371,7 @@ typedef struct sm_setup_context {
|
||||
|
||||
} sm_setup_context_t;
|
||||
|
||||
//
|
||||
//
|
||||
static sm_setup_context_t the_setup;
|
||||
static sm_setup_context_t * setup = &the_setup;
|
||||
|
||||
@ -481,14 +481,14 @@ static void sm_timeout_stop(void){
|
||||
}
|
||||
static void sm_timeout_reset(sm_connection_t * sm_conn){
|
||||
sm_timeout_stop();
|
||||
sm_timeout_start(sm_conn);
|
||||
sm_timeout_start(sm_conn);
|
||||
}
|
||||
|
||||
// end of sm timeout
|
||||
|
||||
// GAP Random Address updates
|
||||
static gap_random_address_type_t gap_random_adress_type;
|
||||
static btstack_timer_source_t gap_random_address_update_timer;
|
||||
static btstack_timer_source_t gap_random_address_update_timer;
|
||||
static uint32_t gap_random_adress_update_period;
|
||||
|
||||
static void gap_random_address_trigger(void){
|
||||
@ -598,7 +598,7 @@ static void sm_c1_t1(sm_key_t r, uint8_t preq[7], uint8_t pres[7], uint8_t iat,
|
||||
// For example, if the 8-bit iat’ is 0x01, the 8-bit rat’ is 0x00, the 56-bit preq
|
||||
// is 0x07071000000101 and the 56 bit pres is 0x05000800000302 then
|
||||
// p1 is 0x05000800000302070710000001010001."
|
||||
|
||||
|
||||
sm_key_t p1;
|
||||
reverse_56(pres, &p1[0]);
|
||||
reverse_56(preq, &p1[7]);
|
||||
@ -606,7 +606,7 @@ static void sm_c1_t1(sm_key_t r, uint8_t preq[7], uint8_t pres[7], uint8_t iat,
|
||||
p1[15] = iat;
|
||||
log_info_key("p1", p1);
|
||||
log_info_key("r", r);
|
||||
|
||||
|
||||
// t1 = r xor p1
|
||||
int i;
|
||||
for (i=0;i<16;i++){
|
||||
@ -622,7 +622,7 @@ static void sm_c1_t3(sm_key_t t2, bd_addr_t ia, bd_addr_t ra, uint8_t * t3){
|
||||
// the most significant octet of padding becomes the most significant octet of p2.
|
||||
// For example, if 48-bit ia is 0xA1A2A3A4A5A6 and the 48-bit ra is
|
||||
// 0xB1B2B3B4B5B6 then p2 is 0x00000000A1A2A3A4A5A6B1B2B3B4B5B6.
|
||||
|
||||
|
||||
sm_key_t p2;
|
||||
memset(p2, 0, 16);
|
||||
memcpy(&p2[4], ia, 6);
|
||||
@ -668,7 +668,7 @@ static void calc_subkeys(sm_key_t k0, sm_key_t k1, sm_key_t k2){
|
||||
sm_shift_left_by_one_bit_inplace(16, k2);
|
||||
if (k1[0] & 0x80){
|
||||
k2[15] ^= 0x87;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aes_cmac(sm_key_t aes_cmac, const sm_key_t key, const uint8_t * data, int cmac_message_len){
|
||||
@ -785,7 +785,7 @@ static void sm_notify_client_index(uint8_t type, hci_con_handle_t con_handle, ui
|
||||
static void sm_notify_client_authorization(uint8_t type, hci_con_handle_t con_handle, uint8_t addr_type, bd_addr_t address, uint8_t result){
|
||||
|
||||
uint8_t event[18];
|
||||
sm_setup_event_base(event, sizeof(event), type, con_handle, addr_type, address);
|
||||
sm_setup_event_base(event, sizeof(event), type, con_handle, addr_type, address);
|
||||
event[11] = result;
|
||||
sm_dispatch_event(HCI_EVENT_PACKET, 0, (uint8_t*) &event, sizeof(event));
|
||||
}
|
||||
@ -808,11 +808,11 @@ static void sm_setup_tk(void){
|
||||
#else
|
||||
setup->sm_use_secure_connections = 0;
|
||||
#endif
|
||||
|
||||
|
||||
// If both devices have not set the MITM option in the Authentication Requirements
|
||||
// Flags, then the IO capabilities shall be ignored and the Just Works association
|
||||
// model shall be used.
|
||||
if (((sm_pairing_packet_get_auth_req(setup->sm_m_preq) & SM_AUTHREQ_MITM_PROTECTION) == 0)
|
||||
// model shall be used.
|
||||
if (((sm_pairing_packet_get_auth_req(setup->sm_m_preq) & SM_AUTHREQ_MITM_PROTECTION) == 0)
|
||||
&& ((sm_pairing_packet_get_auth_req(setup->sm_s_pres) & SM_AUTHREQ_MITM_PROTECTION) == 0)){
|
||||
log_info("SM: MITM not required by both -> JUST WORKS");
|
||||
return;
|
||||
@ -849,7 +849,7 @@ static void sm_setup_tk(void){
|
||||
if (setup->sm_use_secure_connections){
|
||||
generation_method = stk_generation_method_with_secure_connection;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
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)];
|
||||
|
||||
log_info("sm_setup_tk: master io cap: %u, slave io cap: %u -> method %u",
|
||||
@ -860,11 +860,11 @@ static int sm_key_distribution_flags_for_set(uint8_t key_set){
|
||||
int flags = 0;
|
||||
if (key_set & SM_KEYDIST_ENC_KEY){
|
||||
flags |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION;
|
||||
flags |= SM_KEYDIST_FLAG_MASTER_IDENTIFICATION;
|
||||
flags |= SM_KEYDIST_FLAG_MASTER_IDENTIFICATION;
|
||||
}
|
||||
if (key_set & SM_KEYDIST_ID_KEY){
|
||||
flags |= SM_KEYDIST_FLAG_IDENTITY_INFORMATION;
|
||||
flags |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION;
|
||||
flags |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION;
|
||||
}
|
||||
if (key_set & SM_KEYDIST_SIGN){
|
||||
flags |= SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION;
|
||||
@ -909,7 +909,7 @@ int sm_address_resolution_lookup(uint8_t address_type, bd_addr_t address){
|
||||
if (!entry) return BTSTACK_MEMORY_ALLOC_FAILED;
|
||||
entry->address_type = (bd_addr_type_t) address_type;
|
||||
memcpy(entry->address, address, 6);
|
||||
btstack_linked_list_add(&sm_address_resolution_general_queue, (btstack_linked_item_t *) entry);
|
||||
btstack_linked_list_add(&sm_address_resolution_general_queue, (btstack_linked_item_t *) entry);
|
||||
sm_run();
|
||||
return 0;
|
||||
}
|
||||
@ -1025,7 +1025,7 @@ static void sm_cmac_handle_aes_engine_ready(void){
|
||||
int i;
|
||||
sm_key_t y;
|
||||
for (i=0;i<16;i++){
|
||||
y[i] = sm_cmac_x[i] ^ sm_cmac_m_last[i];
|
||||
y[i] = sm_cmac_x[i] ^ sm_cmac_m_last[i];
|
||||
}
|
||||
log_info_key("Y", y);
|
||||
sm_cmac_block_current++;
|
||||
@ -1064,7 +1064,7 @@ static void sm_cmac_handle_encryption_result(sm_key_t data){
|
||||
sm_shift_left_by_one_bit_inplace(16, k2);
|
||||
if (k1[0] & 0x80){
|
||||
k2[15] ^= 0x87;
|
||||
}
|
||||
}
|
||||
|
||||
log_info_key("k", sm_cmac_k);
|
||||
log_info_key("k1", k1);
|
||||
@ -1092,12 +1092,12 @@ static void sm_cmac_handle_encryption_result(sm_key_t data){
|
||||
}
|
||||
|
||||
// next
|
||||
sm_cmac_state = sm_cmac_block_current < sm_cmac_block_count - 1 ? CMAC_CALC_MI : CMAC_CALC_MLAST;
|
||||
sm_cmac_state = sm_cmac_block_current < sm_cmac_block_count - 1 ? CMAC_CALC_MI : CMAC_CALC_MLAST;
|
||||
break;
|
||||
}
|
||||
case CMAC_W4_MI:
|
||||
memcpy(sm_cmac_x, data, 16);
|
||||
sm_cmac_state = sm_cmac_block_current < sm_cmac_block_count - 1 ? CMAC_CALC_MI : CMAC_CALC_MLAST;
|
||||
sm_cmac_state = sm_cmac_block_current < sm_cmac_block_count - 1 ? CMAC_CALC_MI : CMAC_CALC_MLAST;
|
||||
break;
|
||||
case CMAC_W4_MLAST:
|
||||
// done
|
||||
@ -1120,26 +1120,26 @@ static void sm_trigger_user_response(sm_connection_t * sm_conn){
|
||||
case PK_RESP_INPUT:
|
||||
if (IS_RESPONDER(sm_conn->sm_role)){
|
||||
setup->sm_user_response = SM_USER_RESPONSE_PENDING;
|
||||
sm_notify_client_base(SM_EVENT_PASSKEY_INPUT_NUMBER, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address);
|
||||
sm_notify_client_base(SM_EVENT_PASSKEY_INPUT_NUMBER, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address);
|
||||
} else {
|
||||
sm_notify_client_passkey(SM_EVENT_PASSKEY_DISPLAY_NUMBER, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address, big_endian_read_32(setup->sm_tk, 12));
|
||||
sm_notify_client_passkey(SM_EVENT_PASSKEY_DISPLAY_NUMBER, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address, big_endian_read_32(setup->sm_tk, 12));
|
||||
}
|
||||
break;
|
||||
case PK_INIT_INPUT:
|
||||
if (IS_RESPONDER(sm_conn->sm_role)){
|
||||
sm_notify_client_passkey(SM_EVENT_PASSKEY_DISPLAY_NUMBER, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address, big_endian_read_32(setup->sm_tk, 12));
|
||||
sm_notify_client_passkey(SM_EVENT_PASSKEY_DISPLAY_NUMBER, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address, big_endian_read_32(setup->sm_tk, 12));
|
||||
} else {
|
||||
setup->sm_user_response = SM_USER_RESPONSE_PENDING;
|
||||
sm_notify_client_base(SM_EVENT_PASSKEY_INPUT_NUMBER, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address);
|
||||
sm_notify_client_base(SM_EVENT_PASSKEY_INPUT_NUMBER, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address);
|
||||
}
|
||||
break;
|
||||
case OK_BOTH_INPUT:
|
||||
setup->sm_user_response = SM_USER_RESPONSE_PENDING;
|
||||
sm_notify_client_base(SM_EVENT_PASSKEY_INPUT_NUMBER, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address);
|
||||
break;
|
||||
sm_notify_client_base(SM_EVENT_PASSKEY_INPUT_NUMBER, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address);
|
||||
break;
|
||||
case NK_BOTH_INPUT:
|
||||
setup->sm_user_response = SM_USER_RESPONSE_PENDING;
|
||||
sm_notify_client_passkey(SM_EVENT_NUMERIC_COMPARISON_REQUEST, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address, big_endian_read_32(setup->sm_tk, 12));
|
||||
sm_notify_client_passkey(SM_EVENT_NUMERIC_COMPARISON_REQUEST, sm_conn->sm_handle, sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address, big_endian_read_32(setup->sm_tk, 12));
|
||||
break;
|
||||
case JUST_WORKS:
|
||||
setup->sm_user_response = SM_USER_RESPONSE_PENDING;
|
||||
@ -1159,8 +1159,8 @@ static int sm_key_distribution_all_received(sm_connection_t * sm_conn){
|
||||
} else {
|
||||
// master / initiator
|
||||
recv_flags = sm_key_distribution_flags_for_set(sm_pairing_packet_get_responder_key_distribution(setup->sm_s_pres));
|
||||
}
|
||||
log_debug("sm_key_distribution_all_received: received 0x%02x, expecting 0x%02x", setup->sm_key_distribution_received_set, recv_flags);
|
||||
}
|
||||
log_debug("sm_key_distribution_all_received: received 0x%02x, expecting 0x%02x", setup->sm_key_distribution_received_set, recv_flags);
|
||||
return recv_flags == setup->sm_key_distribution_received_set;
|
||||
}
|
||||
|
||||
@ -1199,7 +1199,7 @@ static void sm_init_setup(sm_connection_t * sm_conn){
|
||||
if (sm_get_oob_data) {
|
||||
have_oob_data = (*sm_get_oob_data)(sm_conn->sm_peer_addr_type, sm_conn->sm_peer_address, setup->sm_tk);
|
||||
}
|
||||
|
||||
|
||||
sm_pairing_packet_t * local_packet;
|
||||
if (IS_RESPONDER(sm_conn->sm_role)){
|
||||
// slave
|
||||
@ -1266,7 +1266,7 @@ static void sm_address_resolution_handle_event(address_resolution_event_t event)
|
||||
int matched_device_id = sm_address_resolution_test;
|
||||
address_resolution_mode_t mode = sm_address_resolution_mode;
|
||||
void * context = sm_address_resolution_context;
|
||||
|
||||
|
||||
// reset context
|
||||
sm_address_resolution_mode = ADDRESS_RESOLUTION_IDLE;
|
||||
sm_address_resolution_context = NULL;
|
||||
@ -1384,7 +1384,7 @@ static void sm_key_distribution_handle_all_received(sm_connection_t * sm_conn){
|
||||
sm_notify_client_index(SM_EVENT_IDENTITY_CREATED, sm_conn->sm_handle, setup->sm_peer_addr_type, setup->sm_peer_address, le_db_index);
|
||||
|
||||
if (le_db_index >= 0){
|
||||
|
||||
|
||||
#ifdef ENABLE_LE_SIGNED_WRITE
|
||||
// store local CSRK
|
||||
if (setup->sm_key_distribution_send_set & SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION){
|
||||
@ -1407,10 +1407,10 @@ static void sm_key_distribution_handle_all_received(sm_connection_t * sm_conn){
|
||||
memset(zero_rand, 0, 8);
|
||||
le_device_db_encryption_set(le_db_index, 0, zero_rand, setup->sm_ltk, sm_conn->sm_actual_encryption_key_size,
|
||||
sm_conn->sm_connection_authenticated, sm_conn->sm_connection_authorization_state == AUTHORIZATION_GRANTED);
|
||||
}
|
||||
}
|
||||
|
||||
// store encryption information for legacy pairing: peer LTK, EDIV, RAND
|
||||
else if ( (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION)
|
||||
else if ( (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION)
|
||||
&& (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_MASTER_IDENTIFICATION )){
|
||||
log_info("sm: set encryption information (key size %u, authenticated %u)", sm_conn->sm_actual_encryption_key_size, sm_conn->sm_connection_authenticated);
|
||||
le_device_db_encryption_set(le_db_index, setup->sm_peer_ediv, setup->sm_peer_rand, setup->sm_peer_ltk,
|
||||
@ -1420,7 +1420,7 @@ static void sm_key_distribution_handle_all_received(sm_connection_t * sm_conn){
|
||||
}
|
||||
|
||||
// keep le_db_index
|
||||
sm_conn->sm_le_db_index = le_db_index;
|
||||
sm_conn->sm_le_db_index = le_db_index;
|
||||
}
|
||||
|
||||
static void sm_pairing_error(sm_connection_t * sm_conn, uint8_t reason){
|
||||
@ -1479,7 +1479,7 @@ static void sm_sc_state_after_receiving_random(sm_connection_t * sm_conn){
|
||||
case OOB:
|
||||
// TODO: implement SC OOB
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1496,7 +1496,7 @@ static void sm_sc_cmac_done(uint8_t * hash){
|
||||
#ifdef ENABLE_CLASSIC
|
||||
link_key_type_t link_key_type;
|
||||
#endif
|
||||
|
||||
|
||||
switch (sm_conn->sm_engine_state){
|
||||
case SM_SC_W4_CMAC_FOR_CONFIRMATION:
|
||||
memcpy(setup->sm_local_confirm, hash, 16);
|
||||
@ -1520,11 +1520,11 @@ static void sm_sc_cmac_done(uint8_t * hash){
|
||||
case SM_SC_W4_CALCULATE_F5_SALT:
|
||||
memcpy(setup->sm_t, hash, 16);
|
||||
sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_MACKEY;
|
||||
break;
|
||||
break;
|
||||
case SM_SC_W4_CALCULATE_F5_MACKEY:
|
||||
memcpy(setup->sm_mackey, hash, 16);
|
||||
sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F5_LTK;
|
||||
break;
|
||||
break;
|
||||
case SM_SC_W4_CALCULATE_F5_LTK:
|
||||
// truncate sm_ltk, but keep full LTK for cross-transport key derivation in sm_local_ltk
|
||||
// Errata Service Release to the Bluetooth Specification: ESR09
|
||||
@ -1534,7 +1534,7 @@ static void sm_sc_cmac_done(uint8_t * hash){
|
||||
memcpy(setup->sm_local_ltk, hash, 16);
|
||||
sm_truncate_key(setup->sm_ltk, sm_conn->sm_actual_encryption_key_size);
|
||||
sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_F6_FOR_DHKEY_CHECK;
|
||||
break;
|
||||
break;
|
||||
case SM_SC_W4_CALCULATE_F6_FOR_DHKEY_CHECK:
|
||||
memcpy(setup->sm_local_dhkey_check, hash, 16);
|
||||
if (IS_RESPONDER(sm_conn->sm_role)){
|
||||
@ -1546,7 +1546,7 @@ static void sm_sc_cmac_done(uint8_t * hash){
|
||||
}
|
||||
} else {
|
||||
sm_conn->sm_engine_state = SM_SC_SEND_DHKEY_CHECK_COMMAND;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SM_SC_W4_CALCULATE_F6_TO_VERIFY_DHKEY_CHECK:
|
||||
if (0 != memcmp(hash, setup->sm_peer_dhkey_check, 16) ){
|
||||
@ -1578,16 +1578,16 @@ static void sm_sc_cmac_done(uint8_t * hash){
|
||||
}
|
||||
#endif
|
||||
if (IS_RESPONDER(sm_conn->sm_role)){
|
||||
sm_conn->sm_engine_state = SM_RESPONDER_IDLE;
|
||||
sm_conn->sm_engine_state = SM_RESPONDER_IDLE;
|
||||
} else {
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED;
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED;
|
||||
}
|
||||
sm_done_for_handle(sm_conn->sm_handle);
|
||||
break;
|
||||
default:
|
||||
log_error("sm_sc_cmac_done in state %u", sm_conn->sm_engine_state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
sm_run();
|
||||
}
|
||||
|
||||
@ -1606,7 +1606,7 @@ static void f4_engine(sm_connection_t * sm_conn, const sm_key256_t u, const sm_k
|
||||
|
||||
static const sm_key_t f5_salt = { 0x6C ,0x88, 0x83, 0x91, 0xAA, 0xF5, 0xA5, 0x38, 0x60, 0x37, 0x0B, 0xDB, 0x5A, 0x60, 0x83, 0xBE};
|
||||
static const uint8_t f5_key_id[] = { 0x62, 0x74, 0x6c, 0x65 };
|
||||
static const uint8_t f5_length[] = { 0x01, 0x00};
|
||||
static const uint8_t f5_length[] = { 0x01, 0x00};
|
||||
|
||||
#ifdef USE_SOFTWARE_ECDH_IMPLEMENTATION
|
||||
|
||||
@ -1730,7 +1730,7 @@ static void f6_engine(sm_connection_t * sm_conn, const sm_key_t w, const sm_key_
|
||||
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){
|
||||
const uint16_t message_len = 80;
|
||||
sm_cmac_connection = sm_conn;
|
||||
memcpy(sm_cmac_sc_buffer, u, 32);
|
||||
memcpy(sm_cmac_sc_buffer, u, 32);
|
||||
memcpy(sm_cmac_sc_buffer+32, v, 32);
|
||||
memcpy(sm_cmac_sc_buffer+64, y, 16);
|
||||
log_info("g2 key");
|
||||
@ -1743,7 +1743,7 @@ static void g2_engine(sm_connection_t * sm_conn, const sm_key256_t u, const sm_k
|
||||
static void g2_calculate(sm_connection_t * sm_conn) {
|
||||
// calc Va if numeric comparison
|
||||
if (IS_RESPONDER(sm_conn->sm_role)){
|
||||
// responder
|
||||
// responder
|
||||
g2_engine(sm_conn, setup->sm_peer_q, ec_q, setup->sm_peer_nonce, setup->sm_local_nonce);;
|
||||
} else {
|
||||
// initiator
|
||||
@ -1878,7 +1878,7 @@ static void h6_calculate_br_edr_link_key(sm_connection_t * sm_conn){
|
||||
// - responder reconnects: responder uses LTK receveived from master
|
||||
|
||||
// key management secure connections:
|
||||
// - both devices store same LTK from ECDH key exchange.
|
||||
// - both devices store same LTK from ECDH key exchange.
|
||||
|
||||
#if defined(ENABLE_LE_SECURE_CONNECTIONS) || defined(ENABLE_LE_CENTRAL)
|
||||
static void sm_load_security_info(sm_connection_t * sm_connection){
|
||||
@ -1892,7 +1892,7 @@ static void sm_load_security_info(sm_connection_t * sm_connection){
|
||||
log_info("db index %u, key size %u, authenticated %u, authorized %u", sm_connection->sm_le_db_index, encryption_key_size, authenticated, authorized);
|
||||
sm_connection->sm_actual_encryption_key_size = encryption_key_size;
|
||||
sm_connection->sm_connection_authenticated = authenticated;
|
||||
sm_connection->sm_connection_authorization_state = authorized ? AUTHORIZATION_GRANTED : AUTHORIZATION_UNKNOWN;
|
||||
sm_connection->sm_connection_authorization_state = authorized ? AUTHORIZATION_GRANTED : AUTHORIZATION_UNKNOWN;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1913,7 +1913,7 @@ static void sm_start_calculating_ltk_from_ediv_and_rand(sm_connection_t * sm_con
|
||||
|
||||
static void sm_run(void){
|
||||
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_t it;
|
||||
|
||||
// assert that stack has already bootet
|
||||
if (hci_get_state() != HCI_STATE_WORKING) return;
|
||||
@ -1950,7 +1950,7 @@ static void sm_run(void){
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_LE_SECURE_CONNECTIONS
|
||||
@ -1961,7 +1961,7 @@ static void sm_run(void){
|
||||
ec_key_generation_state = EC_KEY_GENERATION_W4_KEY;
|
||||
hci_send_cmd(&hci_le_read_local_p256_public_key);
|
||||
#endif
|
||||
return;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2100,9 +2100,9 @@ static void sm_run(void){
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// active connection handling
|
||||
// -- use loop to handle next connection if lock on setup context is released
|
||||
// -- use loop to handle next connection if lock on setup context is released
|
||||
|
||||
while (1) {
|
||||
|
||||
@ -2121,7 +2121,7 @@ static void sm_run(void){
|
||||
// send packet if possible,
|
||||
if (l2cap_can_send_fixed_channel_packet_now(sm_connection->sm_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL)){
|
||||
const uint8_t buffer[2] = { SM_CODE_SECURITY_REQUEST, SM_AUTHREQ_BONDING};
|
||||
sm_connection->sm_engine_state = SM_RESPONDER_PH1_W4_PAIRING_REQUEST;
|
||||
sm_connection->sm_engine_state = SM_RESPONDER_PH1_W4_PAIRING_REQUEST;
|
||||
l2cap_send_connectionless(sm_connection->sm_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL, (uint8_t*) buffer, sizeof(buffer));
|
||||
} else {
|
||||
l2cap_request_can_send_fix_channel_now_event(sm_connection->sm_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL);
|
||||
@ -2203,9 +2203,9 @@ static void sm_run(void){
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// active connection handling
|
||||
//
|
||||
//
|
||||
|
||||
if (sm_active_connection_handle == HCI_CON_HANDLE_INVALID) return;
|
||||
|
||||
@ -2384,7 +2384,7 @@ static void sm_run(void){
|
||||
case OOB:
|
||||
// TODO: implement SC OOB
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
l2cap_send_connectionless(connection->sm_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL, (uint8_t*) buffer, sizeof(buffer));
|
||||
sm_timeout_reset(connection);
|
||||
@ -2414,7 +2414,7 @@ static void sm_run(void){
|
||||
} else {
|
||||
// initiator
|
||||
connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (IS_RESPONDER(connection->sm_role)){
|
||||
// responder
|
||||
@ -2426,7 +2426,7 @@ static void sm_run(void){
|
||||
} else {
|
||||
// initiator
|
||||
connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM;
|
||||
}
|
||||
}
|
||||
}
|
||||
l2cap_send_connectionless(connection->sm_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL, (uint8_t*) buffer, sizeof(buffer));
|
||||
sm_timeout_reset(connection);
|
||||
@ -2444,7 +2444,7 @@ static void sm_run(void){
|
||||
}
|
||||
|
||||
l2cap_send_connectionless(connection->sm_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL, (uint8_t*) buffer, sizeof(buffer));
|
||||
sm_timeout_reset(connection);
|
||||
sm_timeout_reset(connection);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2691,14 +2691,14 @@ static void sm_run(void){
|
||||
// slave -> receive master keys if any
|
||||
if (sm_key_distribution_all_received(connection)){
|
||||
sm_key_distribution_handle_all_received(connection);
|
||||
connection->sm_engine_state = SM_RESPONDER_IDLE;
|
||||
connection->sm_engine_state = SM_RESPONDER_IDLE;
|
||||
sm_done_for_handle(connection->sm_handle);
|
||||
} else {
|
||||
connection->sm_engine_state = SM_PH3_RECEIVE_KEYS;
|
||||
}
|
||||
} else {
|
||||
// master -> all done
|
||||
connection->sm_engine_state = SM_INITIATOR_CONNECTED;
|
||||
connection->sm_engine_state = SM_INITIATOR_CONNECTED;
|
||||
sm_done_for_handle(connection->sm_handle);
|
||||
}
|
||||
break;
|
||||
@ -2866,19 +2866,19 @@ static void sm_handle_encryption_result(uint8_t * data){
|
||||
connection->sm_engine_state = SM_SC_W2_CALCULATE_H6_ILK;
|
||||
} else {
|
||||
// master -> all done
|
||||
connection->sm_engine_state = SM_INITIATOR_CONNECTED;
|
||||
connection->sm_engine_state = SM_INITIATOR_CONNECTED;
|
||||
sm_done_for_handle(connection->sm_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
return;
|
||||
#ifdef ENABLE_LE_PERIPHERAL
|
||||
case SM_RESPONDER_PH4_LTK_W4_ENC:
|
||||
reverse_128(data, setup->sm_ltk);
|
||||
sm_truncate_key(setup->sm_ltk, connection->sm_actual_encryption_key_size);
|
||||
log_info_key("ltk", setup->sm_ltk);
|
||||
connection->sm_engine_state = SM_RESPONDER_PH4_SEND_LTK_REPLY;
|
||||
return;
|
||||
return;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
@ -2905,7 +2905,7 @@ static int sm_generate_f_rng(unsigned char * buffer, unsigned size){
|
||||
// @return error - just wrap sm_generate_f_rng
|
||||
static int sm_generate_f_rng_mbedtls(void * context, unsigned char * buffer, size_t size){
|
||||
UNUSED(context);
|
||||
return sm_generate_f_rng(buffer, size) == 1;
|
||||
return sm_generate_f_rng(buffer, size) == 0;
|
||||
}
|
||||
#endif /* USE_MBEDTLS_FOR_ECDH */
|
||||
#endif /* ENABLE_LE_SECURE_CONNECTIONS */
|
||||
@ -2945,7 +2945,7 @@ static void sm_handle_random_result(uint8_t * data){
|
||||
#else
|
||||
// static version
|
||||
uECC_make_key(ec_q, ec_d);
|
||||
#endif
|
||||
#endif
|
||||
#endif /* USE_MICRO_ECC_FOR_ECDH */
|
||||
|
||||
#ifdef USE_MBEDTLS_FOR_ECDH
|
||||
@ -2960,7 +2960,7 @@ static void sm_handle_random_result(uint8_t * data){
|
||||
mbedtls_mpi_write_binary(&d, ec_d, 32);
|
||||
mbedtls_ecp_point_free(&P);
|
||||
mbedtls_mpi_free(&d);
|
||||
#endif /* USE_MBEDTLS_FOR_ECDH */
|
||||
#endif /* USE_MBEDTLS_FOR_ECDH */
|
||||
|
||||
ec_key_generation_state = EC_KEY_GENERATION_DONE;
|
||||
log_info("Elliptic curve: d");
|
||||
@ -2969,7 +2969,7 @@ static void sm_handle_random_result(uint8_t * data){
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
switch (rau_state){
|
||||
case RAU_W4_RANDOM:
|
||||
// non-resolvable vs. resolvable
|
||||
@ -2986,7 +2986,7 @@ static void sm_handle_random_result(uint8_t * data){
|
||||
default:
|
||||
// "The two most significant bits of the address shall be equal to ‘0’""
|
||||
memcpy(sm_random_address, data, 6);
|
||||
sm_random_address[0] &= 0x3f;
|
||||
sm_random_address[0] &= 0x3f;
|
||||
rau_state = RAU_SET_ADDRESS;
|
||||
break;
|
||||
}
|
||||
@ -3026,7 +3026,7 @@ static void sm_handle_random_result(uint8_t * data){
|
||||
tk = tk & 0xfffff; // 1048575
|
||||
if (tk >= 999999){
|
||||
tk = tk - 999999;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// override with pre-defined passkey
|
||||
tk = sm_fixed_legacy_pairing_passkey_in_display_role;
|
||||
@ -3084,7 +3084,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
hci_con_handle_t con_handle;
|
||||
|
||||
switch (packet_type) {
|
||||
|
||||
|
||||
case HCI_EVENT_PACKET:
|
||||
switch (hci_event_packet_get_type(packet)) {
|
||||
|
||||
@ -3106,7 +3106,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
case GAP_RANDOM_ADDRESS_TYPE_OFF:
|
||||
rau_state = RAU_IDLE;
|
||||
break;
|
||||
case GAP_RANDOM_ADDRESS_TYPE_STATIC:
|
||||
case GAP_RANDOM_ADDRESS_TYPE_STATIC:
|
||||
rau_state = RAU_SET_ADDRESS;
|
||||
break;
|
||||
default:
|
||||
@ -3116,7 +3116,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
sm_run();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case HCI_EVENT_LE_META:
|
||||
switch (packet[2]) {
|
||||
case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
|
||||
@ -3153,7 +3153,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
// request security if requested by app
|
||||
sm_conn->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST;
|
||||
} else {
|
||||
// otherwise, wait for pairing request
|
||||
// otherwise, wait for pairing request
|
||||
sm_conn->sm_engine_state = SM_RESPONDER_IDLE;
|
||||
}
|
||||
}
|
||||
@ -3216,7 +3216,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if defined(ENABLE_LE_SECURE_CONNECTIONS) && !defined(USE_MICRO_ECC_FOR_ECDH)
|
||||
#if defined(ENABLE_LE_SECURE_CONNECTIONS) && !defined(USE_SOFTWARE_ECDH_IMPLEMENTATION)
|
||||
case HCI_SUBEVENT_LE_READ_LOCAL_P256_PUBLIC_KEY_COMPLETE:
|
||||
if (hci_subevent_le_read_local_p256_public_key_complete_get_status(packet)){
|
||||
log_error("Read Local P256 Public Key failed");
|
||||
@ -3225,7 +3225,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
|
||||
hci_subevent_le_read_local_p256_public_key_complete_get_dhkey_x(packet, &ec_q[0]);
|
||||
hci_subevent_le_read_local_p256_public_key_complete_get_dhkey_y(packet, &ec_q[32]);
|
||||
|
||||
|
||||
ec_key_generation_state = EC_KEY_GENERATION_DONE;
|
||||
sm_log_ec_keypair();
|
||||
break;
|
||||
@ -3254,7 +3254,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_EVENT_ENCRYPTION_CHANGE:
|
||||
case HCI_EVENT_ENCRYPTION_CHANGE:
|
||||
con_handle = little_endian_read_16(packet, 3);
|
||||
sm_conn = sm_get_connection_for_handle(con_handle);
|
||||
if (!sm_conn) break;
|
||||
@ -3267,9 +3267,9 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
// continue if part of initial pairing
|
||||
switch (sm_conn->sm_engine_state){
|
||||
case SM_INITIATOR_PH0_W4_CONNECTION_ENCRYPTED:
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED;
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED;
|
||||
sm_done_for_handle(sm_conn->sm_handle);
|
||||
break;
|
||||
break;
|
||||
case SM_PH2_W4_CONNECTION_ENCRYPTED:
|
||||
if (IS_RESPONDER(sm_conn->sm_role)){
|
||||
// slave
|
||||
@ -3283,7 +3283,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
if (sm_key_distribution_all_received(sm_conn)){
|
||||
// skip receiving keys as there are none
|
||||
sm_key_distribution_handle_all_received(sm_conn);
|
||||
sm_conn->sm_engine_state = SM_PH3_GET_RANDOM;
|
||||
sm_conn->sm_engine_state = SM_PH3_GET_RANDOM;
|
||||
} else {
|
||||
sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS;
|
||||
}
|
||||
@ -3304,9 +3304,9 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
// continue if part of initial pairing
|
||||
switch (sm_conn->sm_engine_state){
|
||||
case SM_INITIATOR_PH0_W4_CONNECTION_ENCRYPTED:
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED;
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_CONNECTED;
|
||||
sm_done_for_handle(sm_conn->sm_handle);
|
||||
break;
|
||||
break;
|
||||
case SM_PH2_W4_CONNECTION_ENCRYPTED:
|
||||
if (IS_RESPONDER(sm_conn->sm_role)){
|
||||
// slave
|
||||
@ -3320,7 +3320,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||
con_handle = little_endian_read_16(packet, 3);
|
||||
@ -3329,7 +3329,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
if (!sm_conn) break;
|
||||
|
||||
// delete stored bonding on disconnect with authentication failure in ph0
|
||||
if (sm_conn->sm_role == 0
|
||||
if (sm_conn->sm_role == 0
|
||||
&& sm_conn->sm_engine_state == SM_INITIATOR_PH0_W4_CONNECTION_ENCRYPTED
|
||||
&& packet[2] == ERROR_CODE_AUTHENTICATION_FAILURE){
|
||||
le_device_db_remove(sm_conn->sm_le_db_index);
|
||||
@ -3338,7 +3338,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
sm_conn->sm_engine_state = SM_GENERAL_IDLE;
|
||||
sm_conn->sm_handle = 0;
|
||||
break;
|
||||
|
||||
|
||||
case HCI_EVENT_COMMAND_COMPLETE:
|
||||
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_le_encrypt)){
|
||||
sm_handle_encryption_result(&packet[6]);
|
||||
@ -3355,8 +3355,9 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
||||
le_device_db_set_local_bd_addr(addr);
|
||||
}
|
||||
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_supported_commands)){
|
||||
#if defined(ENABLE_LE_SECURE_CONNECTIONS) && !defined(USE_MICRO_ECC_FOR_ECDH)
|
||||
#if defined(ENABLE_LE_SECURE_CONNECTIONS) && !defined(USE_SOFTWARE_ECDH_IMPLEMENTATION)
|
||||
if ((packet[OFFSET_OF_DATA_IN_COMMAND_COMPLETE+1+34] & 0x06) != 0x06){
|
||||
// mbedTLS can also be used if already available (and malloc is supported)
|
||||
log_error("LE Secure Connections enabled, but HCI Controller doesn't support it. Please add USE_MICRO_ECC_FOR_ECDH to btstack_config.h");
|
||||
}
|
||||
#endif
|
||||
@ -3387,7 +3388,7 @@ static int sm_just_works_or_numeric_comparison(stk_generation_method_t method){
|
||||
case NK_BOTH_INPUT:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// responder
|
||||
@ -3397,7 +3398,7 @@ static int sm_passkey_used(stk_generation_method_t method){
|
||||
case PK_RESP_INPUT:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -3482,7 +3483,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
|
||||
}
|
||||
|
||||
switch (sm_conn->sm_engine_state){
|
||||
|
||||
|
||||
// a sm timeout requries a new physical connection
|
||||
case SM_GENERAL_TIMEOUT:
|
||||
return;
|
||||
@ -3506,7 +3507,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
|
||||
log_info("sm: Setting up previous ltk/ediv/rand for device index %u", sm_conn->sm_le_db_index);
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_PH0_HAS_LTK;
|
||||
} else {
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST;
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3536,26 +3537,26 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
|
||||
|
||||
#ifdef ENABLE_LE_SECURE_CONNECTIONS
|
||||
if (setup->sm_use_secure_connections){
|
||||
// SC Numeric Comparison will trigger user response after public keys & nonces have been exchanged
|
||||
// SC Numeric Comparison will trigger user response after public keys & nonces have been exchanged
|
||||
if (setup->sm_stk_generation_method == JUST_WORKS){
|
||||
sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE;
|
||||
sm_trigger_user_response(sm_conn);
|
||||
if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){
|
||||
sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
sm_conn->sm_engine_state = SM_PH1_W4_USER_RESPONSE;
|
||||
sm_trigger_user_response(sm_conn);
|
||||
// response_idle == nothing <--> sm_trigger_user_response() did not require response
|
||||
if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){
|
||||
sm_conn->sm_engine_state = SM_PH2_C1_GET_RANDOM_A;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SM_INITIATOR_PH2_W4_PAIRING_CONFIRM:
|
||||
if (sm_pdu_code != SM_CODE_PAIRING_CONFIRM){
|
||||
@ -3583,7 +3584,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
|
||||
#ifdef ENABLE_LE_PERIPHERAL
|
||||
// Responder
|
||||
case SM_RESPONDER_IDLE:
|
||||
case SM_RESPONDER_SEND_SECURITY_REQUEST:
|
||||
case SM_RESPONDER_SEND_SECURITY_REQUEST:
|
||||
case SM_RESPONDER_PH1_W4_PAIRING_REQUEST:
|
||||
if (sm_pdu_code != SM_CODE_PAIRING_REQUEST){
|
||||
sm_pdu_received_in_wrong_state(sm_conn);
|
||||
@ -3637,9 +3638,9 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef USE_MICRO_ECC_FOR_ECDH
|
||||
// start calculating dhkey
|
||||
setup->sm_state_vars |= SM_STATE_VAR_DHKEY_NEEDED;
|
||||
#ifndef USE_SOFTWARE_ECDH_IMPLEMENTATION
|
||||
// ask controller to calculate dhkey
|
||||
setup->sm_state_vars |= SM_STATE_VAR_DHKEY_NEEDED;
|
||||
#endif
|
||||
|
||||
if (IS_RESPONDER(sm_conn->sm_role)){
|
||||
@ -3668,7 +3669,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
|
||||
case OOB:
|
||||
// TODO: implement SC OOB
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -3687,7 +3688,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
|
||||
// still waiting for passkey
|
||||
sm_conn->sm_engine_state = SM_SC_W4_USER_RESPONSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
sm_sc_start_calculating_local_confirm(sm_conn);
|
||||
} else {
|
||||
@ -3695,10 +3696,10 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
|
||||
if (sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method)){
|
||||
sm_conn->sm_engine_state = SM_SC_W2_GET_RANDOM_A;
|
||||
} else {
|
||||
sm_conn->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM;
|
||||
sm_conn->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case SM_SC_W4_PAIRING_RANDOM:
|
||||
if (sm_pdu_code != SM_CODE_PAIRING_RANDOM){
|
||||
@ -3709,7 +3710,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
|
||||
// received random value
|
||||
reverse_128(&packet[1], setup->sm_peer_nonce);
|
||||
|
||||
// validate confirm value if Cb = f4(Pkb, Pka, Nb, z)
|
||||
// validate confirm value if Cb = f4(Pkb, Pka, Nb, z)
|
||||
// only check for JUST WORK/NC in initiator role AND passkey entry
|
||||
if (sm_conn->sm_role || sm_passkey_used(setup->sm_stk_generation_method)) {
|
||||
sm_conn->sm_engine_state = SM_SC_W2_CMAC_FOR_CHECK_CONFIRMATION;
|
||||
@ -3810,7 +3811,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
|
||||
case SM_CODE_IDENTITY_ADDRESS_INFORMATION:
|
||||
setup->sm_key_distribution_received_set |= SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION;
|
||||
setup->sm_peer_addr_type = packet[1];
|
||||
reverse_bd_addr(&packet[2], setup->sm_peer_address);
|
||||
reverse_bd_addr(&packet[2], setup->sm_peer_address);
|
||||
break;
|
||||
|
||||
case SM_CODE_SIGNING_INFORMATION:
|
||||
@ -3821,8 +3822,8 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
|
||||
// Unexpected PDU
|
||||
log_info("Unexpected PDU %u in SM_PH3_RECEIVE_KEYS", packet[0]);
|
||||
break;
|
||||
}
|
||||
// done with key distribution?
|
||||
}
|
||||
// done with key distribution?
|
||||
if (sm_key_distribution_all_received(sm_conn)){
|
||||
|
||||
sm_key_distribution_handle_all_received(sm_conn);
|
||||
@ -3831,14 +3832,14 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
|
||||
if (setup->sm_use_secure_connections && (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION)){
|
||||
sm_conn->sm_engine_state = SM_SC_W2_CALCULATE_H6_ILK;
|
||||
} else {
|
||||
sm_conn->sm_engine_state = SM_RESPONDER_IDLE;
|
||||
sm_conn->sm_engine_state = SM_RESPONDER_IDLE;
|
||||
sm_done_for_handle(sm_conn->sm_handle);
|
||||
}
|
||||
} else {
|
||||
if (setup->sm_use_secure_connections){
|
||||
sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS;
|
||||
} else {
|
||||
sm_conn->sm_engine_state = SM_PH3_GET_RANDOM;
|
||||
sm_conn->sm_engine_state = SM_PH3_GET_RANDOM;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3925,7 +3926,7 @@ void sm_init(void){
|
||||
|
||||
sm_fixed_legacy_pairing_passkey_in_display_role = 0xffffffff;
|
||||
sm_reconstruct_ltk_without_le_device_db_entry = 1;
|
||||
|
||||
|
||||
#ifdef ENABLE_CMAC_ENGINE
|
||||
sm_cmac_state = CMAC_IDLE;
|
||||
#endif
|
||||
@ -3936,7 +3937,7 @@ void sm_init(void){
|
||||
sm_address_resolution_ah_calculation_active = 0;
|
||||
sm_address_resolution_mode = ADDRESS_RESOLUTION_IDLE;
|
||||
sm_address_resolution_general_queue = NULL;
|
||||
|
||||
|
||||
gap_random_adress_update_period = 15 * 60 * 1000L;
|
||||
sm_active_connection_handle = HCI_CON_HANDLE_INVALID;
|
||||
|
||||
@ -4007,7 +4008,7 @@ void sm_allow_ltk_reconstruction_without_le_device_db_entry(int allow){
|
||||
static sm_connection_t * sm_get_connection_for_handle(hci_con_handle_t con_handle){
|
||||
hci_connection_t * hci_con = hci_connection_for_handle(con_handle);
|
||||
if (!hci_con) return NULL;
|
||||
return &hci_con->sm_connection;
|
||||
return &hci_con->sm_connection;
|
||||
}
|
||||
|
||||
// @returns 0 if not encrypted, 7-16 otherwise
|
||||
@ -4045,7 +4046,7 @@ static void sm_send_security_request_for_connection(sm_connection_t * sm_conn){
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Trigger Security Request
|
||||
*/
|
||||
void sm_send_security_request(hci_con_handle_t con_handle){
|
||||
@ -4069,7 +4070,7 @@ void sm_request_pairing(hci_con_handle_t con_handle){
|
||||
if (sm_conn->sm_engine_state == SM_INITIATOR_CONNECTED){
|
||||
switch (sm_conn->sm_irk_lookup_state){
|
||||
case IRK_LOOKUP_FAILED:
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST;
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST;
|
||||
break;
|
||||
case IRK_LOOKUP_SUCCEEDED:
|
||||
le_device_db_encryption_get(sm_conn->sm_le_db_index, &ediv, NULL, ltk, NULL, NULL, NULL);
|
||||
@ -4077,7 +4078,7 @@ void sm_request_pairing(hci_con_handle_t con_handle){
|
||||
log_info("sm: Setting up previous ltk/ediv/rand for device index %u", sm_conn->sm_le_db_index);
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_PH0_HAS_LTK;
|
||||
} else {
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST;
|
||||
sm_conn->sm_engine_state = SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -4119,7 +4120,7 @@ void sm_bonding_decline(hci_con_handle_t con_handle){
|
||||
case PK_INIT_INPUT:
|
||||
case OK_BOTH_INPUT:
|
||||
sm_pairing_error(sm_conn, SM_GENERAL_SEND_PAIRING_FAILED);
|
||||
break;
|
||||
break;
|
||||
case NK_BOTH_INPUT:
|
||||
sm_pairing_error(sm_conn, SM_REASON_NUMERIC_COMPARISON_FAILED);
|
||||
break;
|
||||
@ -4259,4 +4260,3 @@ void gap_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, u
|
||||
direct_address_typ, direct_address, channel_map, filter_policy);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user