From 6603bc119c434537438577f730ea4aca1f9e04cc Mon Sep 17 00:00:00 2001 From: yocvito Date: Fri, 3 Feb 2023 19:39:30 +0100 Subject: [PATCH 1/3] Removes storing of bt peer key in internal flash for bad usb BLE --- applications/main/bad_usb/bad_usb_script.c | 6 +++++- applications/services/bt/bt_service/bt.c | 9 +++++++++ applications/services/bt/bt_service/bt.h | 11 +++++++++++ firmware/targets/f7/api_symbols.csv | 4 +++- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/applications/main/bad_usb/bad_usb_script.c b/applications/main/bad_usb/bad_usb_script.c index 51ce49df9..49e5329f0 100644 --- a/applications/main/bad_usb/bad_usb_script.c +++ b/applications/main/bad_usb/bad_usb_script.c @@ -655,6 +655,8 @@ static int32_t bad_usb_worker(void* context) { old_pairing_method = bt_get_profile_pairing_method(bad_usb->bt); bt_set_profile_pairing_method(bad_usb->bt, GapPairingNone); furi_hal_bt_start_advertising(); + // disable peer key adding to bt SRAM storage + bt_disable_peer_key_update(bad_usb->bt); bt_set_status_changed_callback(bad_usb->bt, bad_usb_bt_hid_state_callback, bad_usb); } else { usb_mode_prev = furi_hal_usb_get_config(); @@ -752,7 +754,6 @@ static int32_t bad_usb_worker(void* context) { furi_thread_flags_wait(0, FuriFlagWaitAny, 1500); if (bad_usb->bt) { update_bt_timeout(bad_usb->bt); - FURI_LOG_I(WORKER_TAG, "BLE Key timeout : %u", bt_timeout); } bad_usb_script_set_keyboard_layout(bad_usb, bad_usb->keyboard_layout); worker_state = BadUsbStateRunning; @@ -852,6 +853,9 @@ static int32_t bad_usb_worker(void* context) { // fails if ble radio stack isn't ready when switching profile // if it happens, maybe we should increase the delay after bt_disconnect bt_set_profile(bad_usb->bt, BtProfileSerial); + + // starts saving peer keys (bounded devices) + bt_enable_peer_key_update(bad_usb->bt); } else { furi_hal_hid_set_state_callback(NULL, NULL); diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c index 6108a7790..b002254f0 100644 --- a/applications/services/bt/bt_service/bt.c +++ b/applications/services/bt/bt_service/bt.c @@ -446,6 +446,15 @@ GapPairing bt_get_profile_pairing_method(Bt* bt) { return furi_hal_bt_get_profile_pairing_method(get_hal_bt_profile(bt->profile)); } +void bt_disable_peer_key_update(Bt *bt) { + UNUSED(bt); + furi_hal_bt_set_key_storage_change_callback(NULL, NULL); +} + +void bt_enable_peer_key_update(Bt *bt) { + furi_hal_bt_set_key_storage_change_callback(bt_on_key_storage_change_callback, bt); +} + int32_t bt_srv(void* p) { UNUSED(p); Bt* bt = bt_alloc(); diff --git a/applications/services/bt/bt_service/bt.h b/applications/services/bt/bt_service/bt.h index 046887a2c..ddf9382e8 100644 --- a/applications/services/bt/bt_service/bt.h +++ b/applications/services/bt/bt_service/bt.h @@ -52,6 +52,17 @@ bool bt_remote_rssi(Bt* bt, BtRssi* rssi); void bt_set_profile_pairing_method(Bt* bt, GapPairing pairing_method); GapPairing bt_get_profile_pairing_method(Bt* bt); +/** Stop saving new peer key to flash (in .bt.keys file) + * +*/ +void bt_disable_peer_key_update(Bt *bt); + +/** Enable saving peer key to internal flash (enable by default) + * + * @note This function should be called if bt_disable_peer_key_update was called before +*/ +void bt_enable_peer_key_update(Bt *bt); + /** Disconnect from Central * * @param bt Bt instance diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 2129d0530..8cea0cdd3 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,13.2,, +Version,v,13.4,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -569,7 +569,9 @@ Function,+,ble_glue_start,_Bool, Function,+,ble_glue_thread_stop,void, Function,+,ble_glue_wait_for_c2_start,_Bool,int32_t Function,-,bsearch,void*,"const void*, const void*, size_t, size_t, __compar_fn_t" +Function,+,bt_disable_peer_key_update,void,Bt* Function,+,bt_disconnect,void,Bt* +Function,+,bt_enable_peer_key_update,void,Bt* Function,+,bt_forget_bonded_devices,void,Bt* Function,+,bt_get_profile_adv_name,const char*,Bt* Function,+,bt_get_profile_mac_address,const uint8_t*,Bt* From 935aee90ef91ca3dcc7c3adb2cd97f7d0463877b Mon Sep 17 00:00:00 2001 From: yocvito Date: Fri, 3 Feb 2023 21:06:55 +0100 Subject: [PATCH 2/3] Bad-KB: allows to go back to script selection and stay connected to the client when using BLE connection mode --- applications/main/bad_kb/bad_kb_app.c | 5 + applications/main/bad_kb/bad_kb_script.c | 108 ++++++++++-------- applications/main/bad_kb/bad_kb_script.h | 1 + firmware/targets/f7/api_symbols.csv | 3 +- firmware/targets/f7/furi_hal/furi_hal_bt.c | 4 + .../targets/furi_hal_include/furi_hal_bt.h | 2 + 6 files changed, 77 insertions(+), 46 deletions(-) diff --git a/applications/main/bad_kb/bad_kb_app.c b/applications/main/bad_kb/bad_kb_app.c index 4181b08d4..a449edf89 100644 --- a/applications/main/bad_kb/bad_kb_app.c +++ b/applications/main/bad_kb/bad_kb_app.c @@ -186,6 +186,11 @@ void bad_kb_app_free(BadKbApp* app) { view_dispatcher_free(app->view_dispatcher); scene_manager_free(app->scene_manager); + // disconnect victim and reset bt config + if (furi_hal_bt_is_connected()) { + bad_kb_script_bt_disconnect_and_reset_config(app->bt, GapPairingPinCodeVerifyYesNo); + } + // restores bt config // BtProfile have already been switched to the previous one // so we directly modify the right profile diff --git a/applications/main/bad_kb/bad_kb_script.c b/applications/main/bad_kb/bad_kb_script.c index eb671724d..a34b7e4c3 100644 --- a/applications/main/bad_kb/bad_kb_script.c +++ b/applications/main/bad_kb/bad_kb_script.c @@ -625,6 +625,22 @@ static void bad_kb_bt_hid_state_callback(BtStatus status, void* context) { furi_thread_flags_set(furi_thread_get_id(bad_kb->thread), WorkerEvtDisconnect); } +static inline BadKbWorkerState bad_kb_hid_get_initial_state(BadKbScript* bad_kb) { + if(bad_kb->bt) { + if(furi_hal_usb_is_connected(&usb_hid)) { + return BadKbStateIdle; + } else { + return BadKbStateNotConnected; + } + } else { + if(bt_get_status(bad_kb->bt) == BtStatusConnected) { + return BadKbStateIdle; + } else { + return BadKbStateNotConnected; + } + } +} + static void bad_kb_usb_hid_state_callback(bool state, void* context) { furi_assert(context); BadKbScript* bad_kb = context; @@ -635,6 +651,32 @@ static void bad_kb_usb_hid_state_callback(bool state, void* context) { furi_thread_flags_set(furi_thread_get_id(bad_kb->thread), WorkerEvtDisconnect); } +void bad_kb_script_bt_disconnect_and_reset_config(Bt* bt, GapPairing old_pairing_method) { + if(bt) { + // release all keys + bt_hid_hold_while_keyboard_buffer_full(6, 3000); + + // stop ble + bt_set_status_changed_callback(bt, NULL, NULL); + + bt_disconnect(bt); + + // Wait 2nd core to update nvm storage + furi_delay_ms(200); + + bt_keys_storage_set_default_path(bt); + + bt_set_profile_pairing_method(bt, old_pairing_method); + + // starts saving peer keys (bounded devices) + bt_enable_peer_key_update(bt); + + // fails if ble radio stack isn't ready when switching profile + // if it happens, maybe we should increase the delay after bt_disconnect + bt_set_profile(bt, BtProfileSerial); + } +} + static int32_t bad_kb_worker(void* context) { BadKbScript* bad_kb = context; @@ -642,22 +684,24 @@ static int32_t bad_kb_worker(void* context) { int32_t delay_val = 0; FuriHalUsbInterface* usb_mode_prev = NULL; - GapPairing old_pairing_method = GapPairingNone; + GapPairing old_pairing_method = GapPairingPinCodeVerifyYesNo; if(bad_kb->bt) { bt_timeout = bt_hid_delays[LevelRssi39_0]; - bt_disconnect(bad_kb->bt); - furi_delay_ms(200); - bt_keys_storage_set_storage_path(bad_kb->bt, HID_BT_KEYS_STORAGE_PATH); - if(!bt_set_profile(bad_kb->bt, BtProfileHidKeyboard)) { - FURI_LOG_E(TAG, "Failed to switch to HID profile"); - return -1; + if (!furi_hal_bt_is_connected()) { + bt_disconnect(bad_kb->bt); + furi_delay_ms(200); + bt_keys_storage_set_storage_path(bad_kb->bt, HID_BT_KEYS_STORAGE_PATH); + if(!bt_set_profile(bad_kb->bt, BtProfileHidKeyboard)) { + FURI_LOG_E(TAG, "Failed to switch to HID profile"); + return -1; + } + old_pairing_method = bt_get_profile_pairing_method(bad_kb->bt); + bt_set_profile_pairing_method(bad_kb->bt, GapPairingNone); + furi_hal_bt_start_advertising(); + // disable peer key adding to bt SRAM storage + bt_disable_peer_key_update(bad_kb->bt); + bt_set_status_changed_callback(bad_kb->bt, bad_kb_bt_hid_state_callback, bad_kb); } - old_pairing_method = bt_get_profile_pairing_method(bad_kb->bt); - bt_set_profile_pairing_method(bad_kb->bt, GapPairingNone); - furi_hal_bt_start_advertising(); - // disable peer key adding to bt SRAM storage - bt_disable_peer_key_update(bad_usb->bt); - bt_set_status_changed_callback(bad_usb->bt, bad_usb_bt_hid_state_callback, bad_usb); } else { usb_mode_prev = furi_hal_usb_get_config(); furi_hal_hid_set_state_callback(bad_kb_usb_hid_state_callback, bad_kb); @@ -676,15 +720,7 @@ static int32_t bad_kb_worker(void* context) { FSAM_READ, FSOM_OPEN_EXISTING)) { if((ducky_script_preload(bad_kb, script_file)) && (bad_kb->st.line_nb > 0)) { - if(bad_kb->bt) { - worker_state = BadKbStateNotConnected; // Ready to run - } else { - if(furi_hal_hid_is_connected()) { - worker_state = BadKbStateIdle; // Ready to run - } else { - worker_state = BadKbStateNotConnected; // Not connected - } - } + worker_state = bad_kb_hid_get_initial_state(bad_kb); } else { worker_state = BadKbStateScriptError; // Script preload error } @@ -752,8 +788,8 @@ static int32_t bad_kb_worker(void* context) { storage_file_seek(script_file, 0, true); // extra time for PC to recognize Flipper as keyboard furi_thread_flags_wait(0, FuriFlagWaitAny, 1500); - if(bad_usb->bt) { - update_bt_timeout(bad_usb->bt); + if(bad_kb->bt) { + update_bt_timeout(bad_kb->bt); } bad_kb_script_set_keyboard_layout(bad_kb, bad_kb->keyboard_layout); worker_state = BadKbStateRunning; @@ -835,27 +871,9 @@ static int32_t bad_kb_worker(void* context) { } if(bad_kb->bt) { - // release all keys - bt_hid_hold_while_keyboard_buffer_full(6, 3000); - - // stop ble - bt_set_status_changed_callback(bad_kb->bt, NULL, NULL); - - bt_disconnect(bad_kb->bt); - - // Wait 2nd core to update nvm storage - furi_delay_ms(200); - - bt_keys_storage_set_default_path(bad_kb->bt); - - bt_set_profile_pairing_method(bad_kb->bt, old_pairing_method); - - // fails if ble radio stack isn't ready when switching profile - // if it happens, maybe we should increase the delay after bt_disconnect - bt_set_profile(bad_usb->bt, BtProfileSerial); - - // starts saving peer keys (bounded devices) - bt_enable_peer_key_update(bad_usb->bt); + if (!furi_hal_bt_is_connected()) { + bad_kb_script_bt_disconnect_and_reset_config(bad_kb->bt, old_pairing_method); + } } else { furi_hal_hid_set_state_callback(NULL, NULL); diff --git a/applications/main/bad_kb/bad_kb_script.h b/applications/main/bad_kb/bad_kb_script.h index 35c57c112..aa18dbe9e 100644 --- a/applications/main/bad_kb/bad_kb_script.h +++ b/applications/main/bad_kb/bad_kb_script.h @@ -44,6 +44,7 @@ void bad_kb_script_toggle(BadKbScript* bad_kb); BadKbState* bad_kb_script_get_state(BadKbScript* bad_kb); +void bad_kb_script_bt_disconnect_and_reset_config(Bt *bt, GapPairing old_pairing_method); #ifdef __cplusplus } #endif diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 8cea0cdd3..32ec5f4ed 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,v,13.4,, +Version,v,13.5,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1030,6 +1030,7 @@ Function,-,furi_hal_bt_init,void, Function,+,furi_hal_bt_is_active,_Bool, Function,+,furi_hal_bt_is_alive,_Bool, Function,+,furi_hal_bt_is_ble_gatt_gap_supported,_Bool, +Function,+,furi_hal_bt_is_connected,_Bool, Function,+,furi_hal_bt_is_testing_supported,_Bool, Function,+,furi_hal_bt_lock_core2,void, Function,+,furi_hal_bt_nvm_sram_sem_acquire,void, diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index f33c92c62..e01669eb8 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -287,6 +287,10 @@ bool furi_hal_bt_is_active() { return gap_get_state() > GapStateIdle; } +bool furi_hal_bt_is_connected() { + return gap_get_state() == GapStateConnected; +} + void furi_hal_bt_start_advertising() { if(gap_get_state() == GapStateIdle) { gap_start_advertising(); diff --git a/firmware/targets/furi_hal_include/furi_hal_bt.h b/firmware/targets/furi_hal_include/furi_hal_bt.h index 3e554bb4f..03b9eb863 100644 --- a/firmware/targets/furi_hal_include/furi_hal_bt.h +++ b/firmware/targets/furi_hal_include/furi_hal_bt.h @@ -250,6 +250,8 @@ void furi_hal_bt_set_profile_pairing_method(FuriHalBtProfile profile, GapPairing GapPairing furi_hal_bt_get_profile_pairing_method(FuriHalBtProfile profile); +bool furi_hal_bt_is_connected(void); + #ifdef __cplusplus } #endif From dc38d57d6e31a9acc02cead314e6b704459ae8ed Mon Sep 17 00:00:00 2001 From: yocvito Date: Fri, 3 Feb 2023 21:20:44 +0100 Subject: [PATCH 3/3] Fix: vs-code and copilot mistakes (oups) --- applications/main/bad_kb/bad_kb_script.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/main/bad_kb/bad_kb_script.c b/applications/main/bad_kb/bad_kb_script.c index a34b7e4c3..6d5c7478c 100644 --- a/applications/main/bad_kb/bad_kb_script.c +++ b/applications/main/bad_kb/bad_kb_script.c @@ -627,13 +627,13 @@ static void bad_kb_bt_hid_state_callback(BtStatus status, void* context) { static inline BadKbWorkerState bad_kb_hid_get_initial_state(BadKbScript* bad_kb) { if(bad_kb->bt) { - if(furi_hal_usb_is_connected(&usb_hid)) { + if(furi_hal_bt_is_connected()) { return BadKbStateIdle; } else { return BadKbStateNotConnected; } } else { - if(bt_get_status(bad_kb->bt) == BtStatusConnected) { + if(furi_hal_hid_is_connected()) { return BadKbStateIdle; } else { return BadKbStateNotConnected;