sm: avoid potential use-after-free on immediate disconnect (lookup connection via con handle instead of storing pointer)

This commit is contained in:
Matthias Ringwald 2019-05-17 20:42:35 +02:00
parent b2bfd6ae96
commit f3582630aa
2 changed files with 89 additions and 41 deletions

View File

@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Bluetooth SIG web scraping tools updated - Bluetooth SIG web scraping tools updated
- ESP32: Configure SCO over HCI after power up - ESP32: Configure SCO over HCI after power up
- libusb: compiles for FreeBSD - libusb: compiles for FreeBSD
- SM: Avoid potential use-after-free on immediate disconnect (lookup connection via con handle instead of storing pointer)
### Added ### Added
- SM: Track if connection encryption is based on LE Secure Connection pairing - SM: Track if connection encryption is based on LE Secure Connection pairing

View File

@ -1685,7 +1685,10 @@ static void sm_sc_prepare_dhkey_check(sm_connection_t * sm_conn){
} }
static void sm_sc_dhkey_calculated(void * arg){ static void sm_sc_dhkey_calculated(void * arg){
sm_connection_t * sm_conn = (sm_connection_t *) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * sm_conn = sm_get_connection_for_handle(con_handle);
if (sm_conn == NULL) return;
log_info("dhkey"); log_info("dhkey");
log_info_hexdump(&setup->sm_dhkey[0], 32); log_info_hexdump(&setup->sm_dhkey[0], 32);
setup->sm_state_vars |= SM_STATE_VAR_DHKEY_CALCULATED; setup->sm_state_vars |= SM_STATE_VAR_DHKEY_CALCULATED;
@ -2073,7 +2076,7 @@ static void sm_run(void){
sm_timeout_start(sm_connection); sm_timeout_start(sm_connection);
// generate random number first, if we need to show passkey // generate random number first, if we need to show passkey
if (setup->sm_stk_generation_method == PK_INIT_INPUT){ if (setup->sm_stk_generation_method == PK_INIT_INPUT){
btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph2_tk, sm_connection); btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph2_tk, (void *)(uintptr_t) sm_connection->sm_handle);
break; break;
} }
sm_connection->sm_engine_state = SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE; sm_connection->sm_engine_state = SM_RESPONDER_PH1_SEND_PAIRING_RESPONSE;
@ -2481,7 +2484,7 @@ static void sm_run(void){
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); 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);
connection->sm_engine_state = SM_PH2_C1_W4_ENC_A; connection->sm_engine_state = SM_PH2_C1_W4_ENC_A;
sm_aes128_state = SM_AES128_ACTIVE; sm_aes128_state = SM_AES128_ACTIVE;
btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, setup->sm_tk, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_enc_a, connection); 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);
break; break;
case SM_PH2_C1_GET_ENC_C: case SM_PH2_C1_GET_ENC_C:
@ -2491,7 +2494,7 @@ static void sm_run(void){
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); 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);
connection->sm_engine_state = SM_PH2_C1_W4_ENC_C; connection->sm_engine_state = SM_PH2_C1_W4_ENC_C;
sm_aes128_state = SM_AES128_ACTIVE; sm_aes128_state = SM_AES128_ACTIVE;
btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, setup->sm_tk, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_enc_c, connection); 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);
break; break;
case SM_PH2_CALC_STK: case SM_PH2_CALC_STK:
@ -2505,7 +2508,7 @@ static void sm_run(void){
} }
connection->sm_engine_state = SM_PH2_W4_STK; connection->sm_engine_state = SM_PH2_W4_STK;
sm_aes128_state = SM_AES128_ACTIVE; sm_aes128_state = SM_AES128_ACTIVE;
btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, setup->sm_tk, sm_aes128_plaintext, setup->sm_ltk, sm_handle_encryption_result_enc_stk, connection); 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);
break; break;
case SM_PH3_Y_GET_ENC: case SM_PH3_Y_GET_ENC:
@ -2516,7 +2519,7 @@ static void sm_run(void){
sm_dm_r_prime(setup->sm_local_rand, sm_aes128_plaintext); sm_dm_r_prime(setup->sm_local_rand, sm_aes128_plaintext);
connection->sm_engine_state = SM_PH3_Y_W4_ENC; connection->sm_engine_state = SM_PH3_Y_W4_ENC;
sm_aes128_state = SM_AES128_ACTIVE; sm_aes128_state = SM_AES128_ACTIVE;
btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_dhk, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_enc_ph3_y, connection); 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);
break; break;
case SM_PH2_C1_SEND_PAIRING_CONFIRM: { case SM_PH2_C1_SEND_PAIRING_CONFIRM: {
@ -2556,7 +2559,7 @@ static void sm_run(void){
sm_dm_r_prime(setup->sm_local_rand, sm_aes128_plaintext); sm_dm_r_prime(setup->sm_local_rand, sm_aes128_plaintext);
connection->sm_engine_state = SM_RESPONDER_PH4_Y_W4_ENC; connection->sm_engine_state = SM_RESPONDER_PH4_Y_W4_ENC;
sm_aes128_state = SM_AES128_ACTIVE; sm_aes128_state = SM_AES128_ACTIVE;
btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_dhk, sm_aes128_plaintext, sm_aes128_ciphertext, sm_handle_encryption_result_enc_ph4_y, connection); 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);
return; return;
#endif #endif
#ifdef ENABLE_LE_CENTRAL #ifdef ENABLE_LE_CENTRAL
@ -2681,13 +2684,19 @@ static void sm_run(void){
// sm_aes128_state stays active // sm_aes128_state stays active
static void sm_handle_encryption_result_enc_a(void *arg){ static void sm_handle_encryption_result_enc_a(void *arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
sm_c1_t3(sm_aes128_ciphertext, setup->sm_m_address, setup->sm_s_address, setup->sm_c1_t3_value); sm_c1_t3(sm_aes128_ciphertext, setup->sm_m_address, setup->sm_s_address, setup->sm_c1_t3_value);
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, connection); 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);
} }
static void sm_handle_encryption_result_enc_b(void *arg){ static void sm_handle_encryption_result_enc_b(void *arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
sm_aes128_state = SM_AES128_IDLE; sm_aes128_state = SM_AES128_IDLE;
log_info_key("c1!", setup->sm_local_confirm); log_info_key("c1!", setup->sm_local_confirm);
connection->sm_engine_state = SM_PH2_C1_SEND_PAIRING_CONFIRM; connection->sm_engine_state = SM_PH2_C1_SEND_PAIRING_CONFIRM;
@ -2696,13 +2705,19 @@ static void sm_handle_encryption_result_enc_b(void *arg){
// sm_aes128_state stays active // sm_aes128_state stays active
static void sm_handle_encryption_result_enc_c(void *arg){ static void sm_handle_encryption_result_enc_c(void *arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
sm_c1_t3(sm_aes128_ciphertext, setup->sm_m_address, setup->sm_s_address, setup->sm_c1_t3_value); sm_c1_t3(sm_aes128_ciphertext, setup->sm_m_address, setup->sm_s_address, setup->sm_c1_t3_value);
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, connection); 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);
} }
static void sm_handle_encryption_result_enc_d(void * arg){ static void sm_handle_encryption_result_enc_d(void * arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
sm_aes128_state = SM_AES128_IDLE; sm_aes128_state = SM_AES128_IDLE;
log_info_key("c1!", sm_aes128_ciphertext); log_info_key("c1!", sm_aes128_ciphertext);
if (memcmp(setup->sm_peer_confirm, sm_aes128_ciphertext, 16) != 0){ if (memcmp(setup->sm_peer_confirm, sm_aes128_ciphertext, 16) != 0){
@ -2717,12 +2732,15 @@ static void sm_handle_encryption_result_enc_d(void * arg){
} else { } else {
sm_s1_r_prime(setup->sm_peer_random, setup->sm_local_random, sm_aes128_plaintext); sm_s1_r_prime(setup->sm_peer_random, setup->sm_local_random, sm_aes128_plaintext);
sm_aes128_state = SM_AES128_ACTIVE; sm_aes128_state = SM_AES128_ACTIVE;
btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, setup->sm_tk, sm_aes128_plaintext, setup->sm_ltk, sm_handle_encryption_result_enc_stk, connection); 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);
} }
} }
static void sm_handle_encryption_result_enc_stk(void *arg){ static void sm_handle_encryption_result_enc_stk(void *arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
sm_aes128_state = SM_AES128_IDLE; sm_aes128_state = SM_AES128_IDLE;
sm_truncate_key(setup->sm_ltk, connection->sm_actual_encryption_key_size); sm_truncate_key(setup->sm_ltk, connection->sm_actual_encryption_key_size);
log_info_key("stk", setup->sm_ltk); log_info_key("stk", setup->sm_ltk);
@ -2736,7 +2754,10 @@ static void sm_handle_encryption_result_enc_stk(void *arg){
// sm_aes128_state stays active // sm_aes128_state stays active
static void sm_handle_encryption_result_enc_ph3_y(void *arg){ static void sm_handle_encryption_result_enc_ph3_y(void *arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
setup->sm_local_y = big_endian_read_16(sm_aes128_ciphertext, 14); setup->sm_local_y = big_endian_read_16(sm_aes128_ciphertext, 14);
log_info_hex16("y", setup->sm_local_y); log_info_hex16("y", setup->sm_local_y);
// PH3B3 - calculate EDIV // PH3B3 - calculate EDIV
@ -2745,13 +2766,16 @@ static void sm_handle_encryption_result_enc_ph3_y(void *arg){
// PH3B4 - calculate LTK - enc // PH3B4 - calculate LTK - enc
// LTK = d1(ER, DIV, 0)) // LTK = d1(ER, DIV, 0))
sm_d1_d_prime(setup->sm_local_div, 0, sm_aes128_plaintext); sm_d1_d_prime(setup->sm_local_div, 0, sm_aes128_plaintext);
btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_er, sm_aes128_plaintext, setup->sm_ltk, sm_handle_encryption_result_enc_ph3_ltk, connection); 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);
} }
#ifdef ENABLE_LE_PERIPHERAL #ifdef ENABLE_LE_PERIPHERAL
// sm_aes128_state stays active // sm_aes128_state stays active
static void sm_handle_encryption_result_enc_ph4_y(void *arg){ static void sm_handle_encryption_result_enc_ph4_y(void *arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
setup->sm_local_y = big_endian_read_16(sm_aes128_ciphertext, 14); setup->sm_local_y = big_endian_read_16(sm_aes128_ciphertext, 14);
log_info_hex16("y", setup->sm_local_y); log_info_hex16("y", setup->sm_local_y);
@ -2761,21 +2785,27 @@ static void sm_handle_encryption_result_enc_ph4_y(void *arg){
// PH3B4 - calculate LTK - enc // PH3B4 - calculate LTK - enc
// LTK = d1(ER, DIV, 0)) // LTK = d1(ER, DIV, 0))
sm_d1_d_prime(setup->sm_local_div, 0, sm_aes128_plaintext); sm_d1_d_prime(setup->sm_local_div, 0, sm_aes128_plaintext);
btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_er, sm_aes128_plaintext, setup->sm_ltk, sm_handle_encryption_result_enc_ph4_ltk, connection); 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);
} }
#endif #endif
// sm_aes128_state stays active // sm_aes128_state stays active
static void sm_handle_encryption_result_enc_ph3_ltk(void *arg){ static void sm_handle_encryption_result_enc_ph3_ltk(void *arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
log_info_key("ltk", setup->sm_ltk); log_info_key("ltk", setup->sm_ltk);
// calc CSRK next // calc CSRK next
sm_d1_d_prime(setup->sm_local_div, 1, sm_aes128_plaintext); sm_d1_d_prime(setup->sm_local_div, 1, sm_aes128_plaintext);
btstack_crypto_aes128_encrypt(&sm_crypto_aes128_request, sm_persistent_er, sm_aes128_plaintext, setup->sm_local_csrk, sm_handle_encryption_result_enc_csrk, connection); 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);
} }
static void sm_handle_encryption_result_enc_csrk(void *arg){ static void sm_handle_encryption_result_enc_csrk(void *arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
sm_aes128_state = SM_AES128_IDLE; sm_aes128_state = SM_AES128_IDLE;
log_info_key("csrk", setup->sm_local_csrk); log_info_key("csrk", setup->sm_local_csrk);
if (setup->sm_key_distribution_send_set){ if (setup->sm_key_distribution_send_set){
@ -2800,7 +2830,10 @@ static void sm_handle_encryption_result_enc_csrk(void *arg){
#ifdef ENABLE_LE_PERIPHERAL #ifdef ENABLE_LE_PERIPHERAL
static void sm_handle_encryption_result_enc_ph4_ltk(void *arg){ static void sm_handle_encryption_result_enc_ph4_ltk(void *arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
sm_aes128_state = SM_AES128_IDLE; sm_aes128_state = SM_AES128_IDLE;
sm_truncate_key(setup->sm_ltk, connection->sm_actual_encryption_key_size); sm_truncate_key(setup->sm_ltk, connection->sm_actual_encryption_key_size);
log_info_key("ltk", setup->sm_ltk); log_info_key("ltk", setup->sm_ltk);
@ -2873,7 +2906,9 @@ static void sm_handle_random_result_rau(void * arg){
#ifdef ENABLE_LE_SECURE_CONNECTIONS #ifdef ENABLE_LE_SECURE_CONNECTIONS
static void sm_handle_random_result_sc_get_random(void * arg){ static void sm_handle_random_result_sc_get_random(void * arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
// OOB // OOB
if (setup->sm_stk_generation_method == OOB){ if (setup->sm_stk_generation_method == OOB){
@ -2893,13 +2928,19 @@ static void sm_handle_random_result_sc_get_random(void * arg){
#endif #endif
static void sm_handle_random_result_ph2_random(void * arg){ static void sm_handle_random_result_ph2_random(void * arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
connection->sm_engine_state = SM_PH2_C1_GET_ENC_A; connection->sm_engine_state = SM_PH2_C1_GET_ENC_A;
sm_run(); sm_run();
} }
static void sm_handle_random_result_ph2_tk(void * arg){ static void sm_handle_random_result_ph2_tk(void * arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
sm_reset_tk(); sm_reset_tk();
uint32_t tk; uint32_t tk;
if (sm_fixed_passkey_in_display_role == 0xffffffff){ if (sm_fixed_passkey_in_display_role == 0xffffffff){
@ -2924,7 +2965,7 @@ static void sm_handle_random_result_ph2_tk(void * arg){
sm_trigger_user_response(connection); sm_trigger_user_response(connection);
// response_idle == nothing <--> sm_trigger_user_response() did not require response // response_idle == nothing <--> sm_trigger_user_response() did not require response
if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){
btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_random, 16, &sm_handle_random_result_ph2_random, connection); 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);
} }
} }
} }
@ -2932,7 +2973,10 @@ static void sm_handle_random_result_ph2_tk(void * arg){
} }
static void sm_handle_random_result_ph3_div(void * arg){ static void sm_handle_random_result_ph3_div(void * arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
// use 16 bit from random value as div // use 16 bit from random value as div
setup->sm_local_div = big_endian_read_16(sm_random_data, 0); setup->sm_local_div = big_endian_read_16(sm_random_data, 0);
log_info_hex16("div", setup->sm_local_div); log_info_hex16("div", setup->sm_local_div);
@ -2941,7 +2985,10 @@ static void sm_handle_random_result_ph3_div(void * arg){
} }
static void sm_handle_random_result_ph3_random(void * arg){ static void sm_handle_random_result_ph3_random(void * arg){
sm_connection_t * connection = (sm_connection_t*) arg; hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) arg;
sm_connection_t * connection = sm_get_connection_for_handle(con_handle);
if (connection == NULL) return;
reverse_64(sm_random_data, setup->sm_local_rand); reverse_64(sm_random_data, setup->sm_local_rand);
// no db for encryption size hack: encryption size is stored in lowest nibble of setup->sm_local_rand // no db for encryption size hack: encryption size is stored in lowest nibble of setup->sm_local_rand
setup->sm_local_rand[7] = (setup->sm_local_rand[7] & 0xf0) + (connection->sm_actual_encryption_key_size - 1); setup->sm_local_rand[7] = (setup->sm_local_rand[7] & 0xf0) + (connection->sm_actual_encryption_key_size - 1);
@ -3182,14 +3229,14 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
if (setup->sm_use_secure_connections){ if (setup->sm_use_secure_connections){
sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS;
} else { } else {
btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph3_random, sm_conn); 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);
} }
} else { } else {
// master // master
if (sm_key_distribution_all_received(sm_conn)){ if (sm_key_distribution_all_received(sm_conn)){
// skip receiving keys as there are none // skip receiving keys as there are none
sm_key_distribution_handle_all_received(sm_conn); sm_key_distribution_handle_all_received(sm_conn);
btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph3_random, sm_conn); 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);
} else { } else {
sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS; sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS;
} }
@ -3216,7 +3263,7 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
case SM_PH2_W4_CONNECTION_ENCRYPTED: case SM_PH2_W4_CONNECTION_ENCRYPTED:
if (IS_RESPONDER(sm_conn->sm_role)){ if (IS_RESPONDER(sm_conn->sm_role)){
// slave // slave
btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph3_random, sm_conn); 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);
} else { } else {
// master // master
sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS; sm_conn->sm_engine_state = SM_PH3_RECEIVE_KEYS;
@ -3459,7 +3506,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
// generate random number first, if we need to show passkey // generate random number first, if we need to show passkey
if (setup->sm_stk_generation_method == PK_RESP_INPUT){ if (setup->sm_stk_generation_method == PK_RESP_INPUT){
btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph2_tk, sm_conn); 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);
break; break;
} }
@ -3482,7 +3529,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
sm_trigger_user_response(sm_conn); sm_trigger_user_response(sm_conn);
// response_idle == nothing <--> sm_trigger_user_response() did not require response // response_idle == nothing <--> sm_trigger_user_response() did not require response
if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){ if (setup->sm_user_response == SM_USER_RESPONSE_IDLE){
btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_random, 16, &sm_handle_random_result_ph2_random, sm_conn); 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);
} }
break; break;
@ -3552,7 +3599,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
} }
// start calculating dhkey // start calculating dhkey
btstack_crypto_ecc_p256_calculate_dhkey(&sm_crypto_ecc_p256_request, setup->sm_peer_q, setup->sm_dhkey, sm_sc_dhkey_calculated, sm_conn); 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);
log_info("public key received, generation method %u", setup->sm_stk_generation_method); log_info("public key received, generation method %u", setup->sm_stk_generation_method);
@ -3582,7 +3629,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
case OOB: case OOB:
// generate Nx // generate Nx
log_info("Generate Na"); log_info("Generate Na");
btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_nonce, 16, &sm_handle_random_result_sc_get_random, sm_conn); btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_nonce, 16, &sm_handle_random_result_sc_get_random, (void*)(uintptr_t) sm_conn->sm_handle);
break; break;
} }
} }
@ -3616,7 +3663,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
// initiator // initiator
if (sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method)){ if (sm_just_works_or_numeric_comparison(setup->sm_stk_generation_method)){
// sm_conn->sm_engine_state = SM_SC_W2_GET_RANDOM_A; // sm_conn->sm_engine_state = SM_SC_W2_GET_RANDOM_A;
btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_nonce, 16, &sm_handle_random_result_sc_get_random, sm_conn); btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_nonce, 16, &sm_handle_random_result_sc_get_random, (void*)(uintptr_t) sm_conn->sm_handle);
} else { } else {
sm_conn->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM; sm_conn->sm_engine_state = SM_SC_SEND_PAIRING_RANDOM;
} }
@ -3738,7 +3785,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
} }
// calculate and send local_confirm // calculate and send local_confirm
btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_random, 16, &sm_handle_random_result_ph2_random, sm_conn); 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);
break; break;
case SM_RESPONDER_PH2_W4_PAIRING_RANDOM: case SM_RESPONDER_PH2_W4_PAIRING_RANDOM:
@ -3803,7 +3850,7 @@ static void sm_pdu_handler(uint8_t packet_type, hci_con_handle_t con_handle, uin
if (setup->sm_use_secure_connections){ if (setup->sm_use_secure_connections){
sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS; sm_conn->sm_engine_state = SM_PH3_DISTRIBUTE_KEYS;
} else { } else {
btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 8, &sm_handle_random_result_ph3_random, sm_conn); 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);
} }
} }
} }
@ -4080,7 +4127,7 @@ void sm_just_works_confirm(hci_con_handle_t con_handle){
if (setup->sm_use_secure_connections){ if (setup->sm_use_secure_connections){
sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND; sm_conn->sm_engine_state = SM_SC_SEND_PUBLIC_KEY_COMMAND;
} else { } else {
btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_random, 16, &sm_handle_random_result_ph2_random, sm_conn); 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);
} }
} }
@ -4105,7 +4152,7 @@ void sm_passkey_input(hci_con_handle_t con_handle, uint32_t passkey){
big_endian_store_32(setup->sm_tk, 12, passkey); big_endian_store_32(setup->sm_tk, 12, passkey);
setup->sm_user_response = SM_USER_RESPONSE_PASSKEY; setup->sm_user_response = SM_USER_RESPONSE_PASSKEY;
if (sm_conn->sm_engine_state == SM_PH1_W4_USER_RESPONSE){ if (sm_conn->sm_engine_state == SM_PH1_W4_USER_RESPONSE){
btstack_crypto_random_generate(&sm_crypto_random_request, setup->sm_local_random, 16, &sm_handle_random_result_ph2_random, sm_conn); 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);
} }
#ifdef ENABLE_LE_SECURE_CONNECTIONS #ifdef ENABLE_LE_SECURE_CONNECTIONS
memcpy(setup->sm_ra, setup->sm_tk, 16); memcpy(setup->sm_ra, setup->sm_tk, 16);