diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fc76ccab..678f0b2fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,18 @@ ### New changes -* PR: SubGHz Bruteforcer v3 (improved speed of all protos (example CAME -> was 17:48, now 5:58), fixed issue with BF existing dump) (by @derskythe | PR #97) -* PR: SubGHz: Detect RAW fixes (now files are split properly, and random noise added before and after signal to allow decoding) (by @derskythe | PR #98) -* Plugins: RFID Fuzzer fix +* SubGHz: Fix Nice Smilo, MHouse encoder +* SubGHz: Add support for JCM (keeloq) +* SubGHz: Fix random changes of manufacturer (now manufacturer is saved into file, also you can change it if wrong one is set) +* PR: SubGHz improvements (Show full information about preset in Read/ReadRAW screens, Frequency analyzer sound setting saving) (by @derskythe | PR #103) +* PR: SubGHz: Detect RAW fixes (Fix for running Plan B, if Plain A failed) (by @derskythe | PR #102) +* Infrared: Update universal remote assets (by @Amec0e) +* Plugins: Added TOTP (Authenticator) [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) +* Plugins: Added Metronome [(by panki27)](https://github.com/panki27/Metronome) +* Plugins: Added Minesweeper [(by panki27)](https://github.com/panki27/minesweeper) +* OFW PR: allow 36-bit AWID (L11601 Lenel) (OFW PR 1838 by ae5au) +* OFW PR: BLE tiktok controller... (OFW PR 1859 by gornekich) +* OFW PR: MFC Improvements Part 2/2 (OFW PR 1868 by Astrrra) +* OFW: NFC: bank card rework reading +* OFW: Dolphin score points update **(WARNING!!! Dolphin Level will be reset after installing of this release!!!!)** #### [🎲 Download extra apps pack](https://download-directory.github.io/?url=https://github.com/UberGuidoZ/Flipper/tree/main/Applications/Unleashed) diff --git a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c index 8889dac83..1a0992f94 100644 --- a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c +++ b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c @@ -14,6 +14,10 @@ void subghz_scene_frequency_analyzer_on_enter(void* context) { DOLPHIN_DEED(DolphinDeedSubGhzFrequencyAnalyzer); subghz_frequency_analyzer_set_callback( subghz->subghz_frequency_analyzer, subghz_scene_frequency_analyzer_callback, subghz); + subghz_frequency_analyzer_feedback_level( + subghz->subghz_frequency_analyzer, + subghz->last_settings->frequency_analyzer_feedback_level, + true); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdFrequencyAnalyzer); } @@ -44,4 +48,8 @@ bool subghz_scene_frequency_analyzer_on_event(void* context, SceneManagerEvent e void subghz_scene_frequency_analyzer_on_exit(void* context) { SubGhz* subghz = context; notification_message(subghz->notifications, &sequence_reset_rgb); + + subghz->last_settings->frequency_analyzer_feedback_level = + subghz_frequency_analyzer_feedback_level(subghz->subghz_frequency_analyzer, 0, false); + subghz_last_settings_save(subghz->last_settings); } diff --git a/applications/main/subghz/scenes/subghz_scene_read_raw.c b/applications/main/subghz/scenes/subghz_scene_read_raw.c index 1727ecb00..ca691d830 100644 --- a/applications/main/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_read_raw.c @@ -43,7 +43,12 @@ static void subghz_scene_read_raw_update_statusbar(void* context) { frequency_str = furi_string_alloc(); modulation_str = furi_string_alloc(); +#ifdef SUBGHZ_EXT_PRESET_NAME + subghz_get_frequency_modulation(subghz, frequency_str, NULL); + furi_string_printf(modulation_str, "%s", furi_string_get_cstr(subghz->txrx->preset->name)); +#else subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); +#endif subghz_read_raw_add_data_statusbar( subghz->subghz_read_raw, furi_string_get_cstr(frequency_str), diff --git a/applications/main/subghz/scenes/subghz_scene_receiver.c b/applications/main/subghz/scenes/subghz_scene_receiver.c index cafa8b927..87a7c9552 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver.c @@ -46,7 +46,17 @@ static void subghz_scene_receiver_update_statusbar(void* context) { frequency_str = furi_string_alloc(); modulation_str = furi_string_alloc(); +#ifdef SUBGHZ_EXT_PRESET_NAME + if(subghz_history_get_last_index(subghz->txrx->history) > 0) { + subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); + } else { + subghz_get_frequency_modulation(subghz, frequency_str, NULL); + furi_string_printf( + modulation_str, "Mod: %s", furi_string_get_cstr(subghz->txrx->preset->name)); + } +#else subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); +#endif subghz_view_receiver_add_data_statusbar( subghz->subghz_receiver, diff --git a/applications/main/subghz/subghz_history.c b/applications/main/subghz/subghz_history.c index 961be06ad..2db76e456 100644 --- a/applications/main/subghz/subghz_history.c +++ b/applications/main/subghz/subghz_history.c @@ -309,6 +309,10 @@ bool subghz_history_get_text_space_left(SubGhzHistory* instance, FuriString* out return false; } +uint16_t subghz_history_get_last_index(SubGhzHistory* instance) { + return instance->last_index_write; +} + void subghz_history_get_text_item_menu(SubGhzHistory* instance, FuriString* output, uint16_t idx) { SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx); furi_string_set(output, item->item_str); @@ -445,6 +449,10 @@ bool subghz_history_add_to_history( // Plan B! subghz_history_tmp_write_file_full(instance, item, dir_path); } + if (item->is_file) { + flipper_format_free(item->flipper_string); + item->flipper_string = NULL; + } furi_string_free(filename); furi_string_free(dir_path); @@ -857,9 +865,8 @@ bool subghz_history_tmp_write_file_split( flipper_format_file_close(flipper_format_file); flipper_format_free(flipper_format_file); furi_string_free(temp_str); - flipper_format_free(item->flipper_string); - item->flipper_string = NULL; - item->is_file = true; + + item->is_file = result; return result; } @@ -876,8 +883,6 @@ void subghz_history_tmp_write_file_full( stream_rewind(dst); if(stream_save_to_file( dst, instance->storage, furi_string_get_cstr(dir_path), FSOM_CREATE_ALWAYS) > 0) { - flipper_format_free(item->flipper_string); - item->flipper_string = NULL; #ifdef FURI_DEBUG FURI_LOG_I(TAG, "Save done!"); #endif diff --git a/applications/main/subghz/subghz_history.h b/applications/main/subghz/subghz_history.h index 6ab3603d8..f14253896 100644 --- a/applications/main/subghz/subghz_history.h +++ b/applications/main/subghz/subghz_history.h @@ -84,6 +84,13 @@ void subghz_history_get_text_item_menu(SubGhzHistory* instance, FuriString* outp */ bool subghz_history_get_text_space_left(SubGhzHistory* instance, FuriString* output); +/** Return last index + * + * @param instance - SubGhzHistory instance + * @return + */ +uint16_t subghz_history_get_last_index(SubGhzHistory* instance); + /** Add protocol to history * * @param instance - SubGhzHistory instance diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index 1b6496bbc..e3d22ed73 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -431,7 +431,7 @@ bool subghz_save_protocol_to_file( do { //removing additional fields flipper_format_delete_key(flipper_format, "Repeat"); - flipper_format_delete_key(flipper_format, "Manufacture"); + //flipper_format_delete_key(flipper_format, "Manufacture"); // Create subghz folder directory if necessary if(!storage_simply_mkdir(storage, furi_string_get_cstr(file_dir))) { diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index baf3ae82a..e7b03e94f 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -44,6 +44,7 @@ #include "rpc/rpc_app.h" #define SUBGHZ_MAX_LEN_NAME 64 +#define SUBGHZ_EXT_PRESET_NAME true typedef struct { uint8_t fix[4]; diff --git a/applications/main/subghz/subghz_last_settings.c b/applications/main/subghz/subghz_last_settings.c index 6382253b8..bf3638908 100644 --- a/applications/main/subghz/subghz_last_settings.c +++ b/applications/main/subghz/subghz_last_settings.c @@ -13,6 +13,7 @@ // "AM270", "AM650", "FM238", "FM476", #define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1 #define SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY 433920000 +#define SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL 2 #ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING #define SUBGHZ_LAST_SETTING_DEFAULT_READ_RAW 0 @@ -21,6 +22,7 @@ #define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY "Frequency" #define SUBGHZ_LAST_SETTING_FIELD_PRESET "Preset" +#define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_FEEDBACK_LEVEL "FeedbackLevel" SubGhzLastSettings* subghz_last_settings_alloc(void) { SubGhzLastSettings* instance = malloc(sizeof(SubGhzLastSettings)); @@ -42,7 +44,9 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); uint32_t temp_frequency = 0; + uint32_t temp_frequency_analyzer_feedback_level = 0; int32_t temp_preset = 0; + bool frequency_analyzer_feedback_level_was_read = false; #ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING uint32_t temp_read_raw = 0; #endif @@ -53,6 +57,11 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count fff_data_file, SUBGHZ_LAST_SETTING_FIELD_PRESET, (int32_t*)&temp_preset, 1); flipper_format_read_uint32( fff_data_file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, (uint32_t*)&temp_frequency, 1); + frequency_analyzer_feedback_level_was_read = flipper_format_read_uint32( + fff_data_file, + SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_FEEDBACK_LEVEL, + (uint32_t*)&temp_frequency_analyzer_feedback_level, + 1); #ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING flipper_format_read_uint32( fff_data_file, SUBGHZ_LAST_SETTING_FIELD_DETECT_RAW, (uint32_t*)&temp_read_raw, 1); @@ -65,11 +74,17 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count FURI_LOG_W(TAG, "Last used frequency not found or can't be used!"); instance->frequency = SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY; instance->preset = SUBGHZ_LAST_SETTING_DEFAULT_PRESET; + instance->frequency_analyzer_feedback_level = + SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL; #ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING instance->detect_raw = SUBGHZ_LAST_SETTING_DEFAULT_READ_RAW; #endif } else { instance->frequency = temp_frequency; + instance->frequency_analyzer_feedback_level = + frequency_analyzer_feedback_level_was_read ? + temp_frequency_analyzer_feedback_level : + SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL; #ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING instance->detect_raw = temp_read_raw; #endif @@ -118,6 +133,13 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) { file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, &instance->frequency, 1)) { break; } + if(!flipper_format_insert_or_update_uint32( + file, + SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_FEEDBACK_LEVEL, + &instance->frequency_analyzer_feedback_level, + 1)) { + break; + } #ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING if(!flipper_format_insert_or_update_uint32( file, SUBGHZ_LAST_SETTING_FIELD_DETECT_RAW, &instance->detect_raw, 1)) { diff --git a/applications/main/subghz/subghz_last_settings.h b/applications/main/subghz/subghz_last_settings.h index 116eacadd..cb6a058fe 100644 --- a/applications/main/subghz/subghz_last_settings.h +++ b/applications/main/subghz/subghz_last_settings.h @@ -19,6 +19,7 @@ typedef struct { uint32_t detect_raw; #endif int32_t preset; + uint32_t frequency_analyzer_feedback_level; } SubGhzLastSettings; SubGhzLastSettings* subghz_last_settings_alloc(void); diff --git a/applications/main/subghz/views/receiver.c b/applications/main/subghz/views/receiver.c index 05c6e7908..30372a51d 100644 --- a/applications/main/subghz/views/receiver.c +++ b/applications/main/subghz/views/receiver.c @@ -265,11 +265,30 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { canvas_draw_icon(canvas, 64, 55, &I_Unlock_7x8); canvas_draw_str(canvas, 74, 62, "Unlocked"); break; - default: - canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str)); + default: { + const char* frequency_str = furi_string_get_cstr(model->frequency_str); + canvas_draw_str(canvas, 44, 62, frequency_str); +#ifdef SUBGHZ_EXT_PRESET_NAME + if(model->history_item == 0 && model->mode == SubGhzViewReceiverModeLive) { + canvas_draw_str( + canvas, 44 + canvas_string_width(canvas, frequency_str) + 1, 62, "MHz"); + const char* str = furi_string_get_cstr(model->preset_str); + const uint8_t vertical_offset = 7; + const uint8_t horizontal_offset = 3; + const uint8_t string_width = canvas_string_width(canvas, str); + canvas_draw_str( + canvas, + canvas_width(canvas) - (string_width + horizontal_offset), + vertical_offset, + str); + } else { + canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str)); + } +#else canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str)); +#endif canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); - break; + } break; } } diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.c b/applications/main/subghz/views/subghz_frequency_analyzer.c index 53f0c8dd0..aed21b698 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.c +++ b/applications/main/subghz/views/subghz_frequency_analyzer.c @@ -517,4 +517,21 @@ uint32_t subghz_frequency_analyzer_get_frequency_to_save(SubGhzFrequencyAnalyzer false); return frequency; +} + +uint8_t subghz_frequency_analyzer_feedback_level( + SubGhzFrequencyAnalyzer* instance, + uint8_t level, + bool update) { + furi_assert(instance); + if(update) { + instance->feedback_level = level; + with_view_model( + instance->view, + SubGhzFrequencyAnalyzerModel * model, + { model->feedback_level = instance->feedback_level; }, + true); + } + + return instance->feedback_level; } \ No newline at end of file diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.h b/applications/main/subghz/views/subghz_frequency_analyzer.h index 5e00c6444..196d69c79 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.h +++ b/applications/main/subghz/views/subghz_frequency_analyzer.h @@ -19,3 +19,8 @@ void subghz_frequency_analyzer_free(SubGhzFrequencyAnalyzer* subghz_static); View* subghz_frequency_analyzer_get_view(SubGhzFrequencyAnalyzer* subghz_static); uint32_t subghz_frequency_analyzer_get_frequency_to_save(SubGhzFrequencyAnalyzer* instance); + +uint8_t subghz_frequency_analyzer_feedback_level( + SubGhzFrequencyAnalyzer* instance, + uint8_t level, + bool update); diff --git a/applications/main/unirfremix/unirfremix_app.c b/applications/main/unirfremix/unirfremix_app.c index 7bb26b48f..b9f7aa5e6 100644 --- a/applications/main/unirfremix/unirfremix_app.c +++ b/applications/main/unirfremix/unirfremix_app.c @@ -562,7 +562,7 @@ bool unirfremix_save_protocol_to_file(FlipperFormat* fff_file, const char* dev_f path_extract_dirname(dev_file_name, file_dir); do { flipper_format_delete_key(fff_file, "Repeat"); - flipper_format_delete_key(fff_file, "Manufacture"); + //flipper_format_delete_key(fff_file, "Manufacture"); if(!storage_simply_mkdir(storage, furi_string_get_cstr(file_dir))) { FURI_LOG_E(TAG, "(save) Cannot mkdir"); diff --git a/applications/plugins/application.fam b/applications/plugins/application.fam index c88f6d289..6d25e45aa 100644 --- a/applications/plugins/application.fam +++ b/applications/plugins/application.fam @@ -5,6 +5,5 @@ App( provides=[ "music_player", "snake_game", - "bt_hid", ], ) diff --git a/applications/plugins/arkanoid/arkanoid_game.c b/applications/plugins/arkanoid/arkanoid_game.c index 70b8da256..91ae8e736 100644 --- a/applications/plugins/arkanoid/arkanoid_game.c +++ b/applications/plugins/arkanoid/arkanoid_game.c @@ -75,8 +75,8 @@ int rand_range(int min, int max) { void move_ball(Canvas* canvas, ArkanoidState* st) { st->tick++; - int current_speed = abs(st->speed-1 - MAX_SPEED); - if (st->tick % current_speed != 0 && st->tick % (current_speed + 1) != 0) { + int current_speed = abs(st->speed - 1 - MAX_SPEED); + if(st->tick % current_speed != 0 && st->tick % (current_speed + 1) != 0) { return; } diff --git a/applications/plugins/bt_hid_app/application.fam b/applications/plugins/bt_hid_app/application.fam index 42cb73a38..ae5339c31 100644 --- a/applications/plugins/bt_hid_app/application.fam +++ b/applications/plugins/bt_hid_app/application.fam @@ -4,12 +4,7 @@ App( apptype=FlipperAppType.EXTERNAL, entry_point="bt_hid_app", stack_size=1 * 1024, - cdefines=["APP_BLE_HID"], - requires=[ - "bt", - "gui", - ], - order=10, - fap_icon="bt_remote_10px.png", fap_category="Tools", + fap_icon="bt_remote_10px.png", + fap_icon_assets="assets", ) diff --git a/applications/plugins/bt_hid_app/assets/Arr_dwn_7x9.png b/applications/plugins/bt_hid_app/assets/Arr_dwn_7x9.png new file mode 100644 index 000000000..d4034efc4 Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Arr_dwn_7x9.png differ diff --git a/applications/plugins/bt_hid_app/assets/Arr_up_7x9.png b/applications/plugins/bt_hid_app/assets/Arr_up_7x9.png new file mode 100644 index 000000000..28b4236a2 Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Arr_up_7x9.png differ diff --git a/applications/plugins/bt_hid_app/assets/Ble_connected_15x15.png b/applications/plugins/bt_hid_app/assets/Ble_connected_15x15.png new file mode 100644 index 000000000..64dab9b53 Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Ble_connected_15x15.png differ diff --git a/applications/plugins/bt_hid_app/assets/Ble_disconnected_15x15.png b/applications/plugins/bt_hid_app/assets/Ble_disconnected_15x15.png new file mode 100644 index 000000000..0858bb93f Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Ble_disconnected_15x15.png differ diff --git a/applications/plugins/bt_hid_app/assets/Button_18x18.png b/applications/plugins/bt_hid_app/assets/Button_18x18.png new file mode 100644 index 000000000..30a5b4fab Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Button_18x18.png differ diff --git a/applications/plugins/bt_hid_app/assets/Circles_47x47.png b/applications/plugins/bt_hid_app/assets/Circles_47x47.png new file mode 100644 index 000000000..6a16ebf7b Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Circles_47x47.png differ diff --git a/applications/plugins/bt_hid_app/assets/Left_mouse_icon_9x9.png b/applications/plugins/bt_hid_app/assets/Left_mouse_icon_9x9.png new file mode 100644 index 000000000..c533d8572 Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Left_mouse_icon_9x9.png differ diff --git a/applications/plugins/bt_hid_app/assets/Like_def_11x9.png b/applications/plugins/bt_hid_app/assets/Like_def_11x9.png new file mode 100644 index 000000000..555bea3d4 Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Like_def_11x9.png differ diff --git a/applications/plugins/bt_hid_app/assets/Like_pressed_17x17.png b/applications/plugins/bt_hid_app/assets/Like_pressed_17x17.png new file mode 100644 index 000000000..f5bf276f3 Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Like_pressed_17x17.png differ diff --git a/applications/plugins/bt_hid_app/assets/Ok_btn_pressed_13x13.png b/applications/plugins/bt_hid_app/assets/Ok_btn_pressed_13x13.png new file mode 100644 index 000000000..6b46ba3a8 Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Ok_btn_pressed_13x13.png differ diff --git a/applications/plugins/bt_hid_app/assets/Pressed_Button_13x13.png b/applications/plugins/bt_hid_app/assets/Pressed_Button_13x13.png new file mode 100644 index 000000000..823926b84 Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Pressed_Button_13x13.png differ diff --git a/applications/plugins/bt_hid_app/assets/Right_mouse_icon_9x9.png b/applications/plugins/bt_hid_app/assets/Right_mouse_icon_9x9.png new file mode 100644 index 000000000..446d7176c Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Right_mouse_icon_9x9.png differ diff --git a/applications/plugins/bt_hid_app/assets/Space_65x18.png b/applications/plugins/bt_hid_app/assets/Space_65x18.png new file mode 100644 index 000000000..b60ae5097 Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Space_65x18.png differ diff --git a/applications/plugins/bt_hid_app/assets/Voldwn_6x6.png b/applications/plugins/bt_hid_app/assets/Voldwn_6x6.png new file mode 100644 index 000000000..d7a82a2df Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Voldwn_6x6.png differ diff --git a/applications/plugins/bt_hid_app/assets/Volup_8x6.png b/applications/plugins/bt_hid_app/assets/Volup_8x6.png new file mode 100644 index 000000000..4b7ec66d6 Binary files /dev/null and b/applications/plugins/bt_hid_app/assets/Volup_8x6.png differ diff --git a/applications/plugins/bt_hid_app/bt_hid.c b/applications/plugins/bt_hid_app/bt_hid.c index a470f7bc6..4a77a2490 100644 --- a/applications/plugins/bt_hid_app/bt_hid.c +++ b/applications/plugins/bt_hid_app/bt_hid.c @@ -9,6 +9,7 @@ enum BtDebugSubmenuIndex { BtHidSubmenuIndexKeynote, BtHidSubmenuIndexKeyboard, BtHidSubmenuIndexMedia, + BtHidSubmenuIndexTikTok, BtHidSubmenuIndexMouse, }; @@ -27,6 +28,9 @@ void bt_hid_submenu_callback(void* context, uint32_t index) { } else if(index == BtHidSubmenuIndexMouse) { app->view_id = BtHidViewMouse; view_dispatcher_switch_to_view(app->view_dispatcher, BtHidViewMouse); + } else if(index == BtHidSubmenuIndexTikTok) { + app->view_id = BtHidViewTikTok; + view_dispatcher_switch_to_view(app->view_dispatcher, BtHidViewTikTok); } } @@ -65,6 +69,7 @@ void bt_hid_connection_status_changed_callback(BtStatus status, void* context) { bt_hid_keyboard_set_connected_status(bt_hid->bt_hid_keyboard, connected); bt_hid_media_set_connected_status(bt_hid->bt_hid_media, connected); bt_hid_mouse_set_connected_status(bt_hid->bt_hid_mouse, connected); + bt_hid_tiktok_set_connected_status(bt_hid->bt_hid_tiktok, connected); } BtHid* bt_hid_app_alloc() { @@ -91,6 +96,8 @@ BtHid* bt_hid_app_alloc() { submenu_add_item( app->submenu, "Keyboard", BtHidSubmenuIndexKeyboard, bt_hid_submenu_callback, app); submenu_add_item(app->submenu, "Media", BtHidSubmenuIndexMedia, bt_hid_submenu_callback, app); + submenu_add_item( + app->submenu, "TikTok Controller", BtHidSubmenuIndexTikTok, bt_hid_submenu_callback, app); submenu_add_item(app->submenu, "Mouse", BtHidSubmenuIndexMouse, bt_hid_submenu_callback, app); view_set_previous_callback(submenu_get_view(app->submenu), bt_hid_exit); view_dispatcher_add_view( @@ -127,6 +134,13 @@ BtHid* bt_hid_app_alloc() { view_dispatcher_add_view( app->view_dispatcher, BtHidViewMedia, bt_hid_media_get_view(app->bt_hid_media)); + // TikTok view + app->bt_hid_tiktok = bt_hid_tiktok_alloc(); + view_set_previous_callback( + bt_hid_tiktok_get_view(app->bt_hid_tiktok), bt_hid_exit_confirm_view); + view_dispatcher_add_view( + app->view_dispatcher, BtHidViewTikTok, bt_hid_tiktok_get_view(app->bt_hid_tiktok)); + // Mouse view app->bt_hid_mouse = bt_hid_mouse_alloc(); view_set_previous_callback(bt_hid_mouse_get_view(app->bt_hid_mouse), bt_hid_exit_confirm_view); @@ -159,6 +173,8 @@ void bt_hid_app_free(BtHid* app) { bt_hid_media_free(app->bt_hid_media); view_dispatcher_remove_view(app->view_dispatcher, BtHidViewMouse); bt_hid_mouse_free(app->bt_hid_mouse); + view_dispatcher_remove_view(app->view_dispatcher, BtHidViewTikTok); + bt_hid_tiktok_free(app->bt_hid_tiktok); view_dispatcher_free(app->view_dispatcher); // Close records diff --git a/applications/plugins/bt_hid_app/bt_hid.h b/applications/plugins/bt_hid_app/bt_hid.h index 0f4c7be9f..89e8807fe 100644 --- a/applications/plugins/bt_hid_app/bt_hid.h +++ b/applications/plugins/bt_hid_app/bt_hid.h @@ -13,6 +13,7 @@ #include "views/bt_hid_keyboard.h" #include "views/bt_hid_media.h" #include "views/bt_hid_mouse.h" +#include "views/bt_hid_tiktok.h" typedef struct { Bt* bt; @@ -25,6 +26,7 @@ typedef struct { BtHidKeyboard* bt_hid_keyboard; BtHidMedia* bt_hid_media; BtHidMouse* bt_hid_mouse; + BtHidTikTok* bt_hid_tiktok; uint32_t view_id; } BtHid; @@ -34,5 +36,6 @@ typedef enum { BtHidViewKeyboard, BtHidViewMedia, BtHidViewMouse, + BtHidViewTikTok, BtHidViewExitConfirm, } BtHidView; diff --git a/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c b/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c index 2c65f6ab1..b88a38325 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c @@ -5,6 +5,8 @@ #include #include +#include "Bluetooth_Remote_icons.h" + struct BtHidKeyboard { View* view; }; diff --git a/applications/plugins/bt_hid_app/views/bt_hid_keynote.c b/applications/plugins/bt_hid_app/views/bt_hid_keynote.c index db88b8000..090422521 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_keynote.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_keynote.c @@ -4,6 +4,8 @@ #include #include +#include "Bluetooth_Remote_icons.h" + struct BtHidKeynote { View* view; }; diff --git a/applications/plugins/bt_hid_app/views/bt_hid_media.c b/applications/plugins/bt_hid_app/views/bt_hid_media.c index 181cd347b..c0480852f 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_media.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_media.c @@ -4,6 +4,8 @@ #include #include +#include "Bluetooth_Remote_icons.h" + struct BtHidMedia { View* view; }; diff --git a/applications/plugins/bt_hid_app/views/bt_hid_mouse.c b/applications/plugins/bt_hid_app/views/bt_hid_mouse.c index 098adb732..5fb0cf358 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_mouse.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_mouse.c @@ -4,6 +4,8 @@ #include #include +#include "Bluetooth_Remote_icons.h" + struct BtHidMouse { View* view; }; diff --git a/applications/plugins/bt_hid_app/views/bt_hid_tiktok.c b/applications/plugins/bt_hid_app/views/bt_hid_tiktok.c new file mode 100644 index 000000000..d39034069 --- /dev/null +++ b/applications/plugins/bt_hid_app/views/bt_hid_tiktok.c @@ -0,0 +1,207 @@ +#include "bt_hid_tiktok.h" +#include +#include +#include +#include + +#include "Bluetooth_Remote_icons.h" + +struct BtHidTikTok { + View* view; +}; + +typedef struct { + bool left_pressed; + bool up_pressed; + bool right_pressed; + bool down_pressed; + bool ok_pressed; + bool connected; +} BtHidTikTokModel; + +static void bt_hid_tiktok_draw_callback(Canvas* canvas, void* context) { + furi_assert(context); + BtHidTikTokModel* model = context; + + // Header + if(model->connected) { + canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15); + } else { + canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); + } + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "TikTok"); + canvas_set_font(canvas, FontSecondary); + + // Keypad circles + canvas_draw_icon(canvas, 76, 8, &I_Circles_47x47); + + // Up + if(model->up_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 93, 9, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 96, 11, &I_Arr_up_7x9); + canvas_set_color(canvas, ColorBlack); + + // Down + if(model->down_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 93, 41, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 96, 44, &I_Arr_dwn_7x9); + canvas_set_color(canvas, ColorBlack); + + // Left + if(model->left_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 77, 25, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 81, 29, &I_Voldwn_6x6); + canvas_set_color(canvas, ColorBlack); + + // Right + if(model->right_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 109, 25, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 111, 29, &I_Volup_8x6); + canvas_set_color(canvas, ColorBlack); + + // Ok + if(model->ok_pressed) { + canvas_draw_icon(canvas, 91, 23, &I_Like_pressed_17x17); + } else { + canvas_draw_icon(canvas, 94, 27, &I_Like_def_11x9); + } + // Exit + canvas_draw_icon(canvas, 0, 54, &I_Pin_back_arrow_10x8); + canvas_set_font(canvas, FontSecondary); + elements_multiline_text_aligned(canvas, 13, 62, AlignLeft, AlignBottom, "Hold to exit"); +} + +static void bt_hid_tiktok_process_press(BtHidTikTok* bt_hid_tiktok, InputEvent* event) { + with_view_model( + bt_hid_tiktok->view, + BtHidTikTokModel * model, + { + if(event->key == InputKeyUp) { + model->up_pressed = true; + } else if(event->key == InputKeyDown) { + model->down_pressed = true; + } else if(event->key == InputKeyLeft) { + model->left_pressed = true; + furi_hal_bt_hid_consumer_key_press(HID_CONSUMER_VOLUME_DECREMENT); + } else if(event->key == InputKeyRight) { + model->right_pressed = true; + furi_hal_bt_hid_consumer_key_press(HID_CONSUMER_VOLUME_INCREMENT); + } else if(event->key == InputKeyOk) { + model->ok_pressed = true; + } + }, + true); +} + +static void bt_hid_tiktok_process_release(BtHidTikTok* bt_hid_tiktok, InputEvent* event) { + with_view_model( + bt_hid_tiktok->view, + BtHidTikTokModel * model, + { + if(event->key == InputKeyUp) { + model->up_pressed = false; + } else if(event->key == InputKeyDown) { + model->down_pressed = false; + } else if(event->key == InputKeyLeft) { + model->left_pressed = false; + furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_VOLUME_DECREMENT); + } else if(event->key == InputKeyRight) { + model->right_pressed = false; + furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_VOLUME_INCREMENT); + } else if(event->key == InputKeyOk) { + model->ok_pressed = false; + } + }, + true); +} + +static bool bt_hid_tiktok_input_callback(InputEvent* event, void* context) { + furi_assert(context); + BtHidTikTok* bt_hid_tiktok = context; + bool consumed = false; + + if(event->type == InputTypePress) { + bt_hid_tiktok_process_press(bt_hid_tiktok, event); + consumed = true; + } else if(event->type == InputTypeRelease) { + bt_hid_tiktok_process_release(bt_hid_tiktok, event); + consumed = true; + } else if(event->type == InputTypeShort) { + if(event->key == InputKeyOk) { + furi_hal_bt_hid_mouse_press(HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + furi_hal_bt_hid_mouse_release(HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + furi_hal_bt_hid_mouse_press(HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + furi_hal_bt_hid_mouse_release(HID_MOUSE_BTN_LEFT); + consumed = true; + } else if(event->key == InputKeyUp) { + // Emulate up swipe + furi_hal_bt_hid_mouse_scroll(-6); + furi_hal_bt_hid_mouse_scroll(-12); + furi_hal_bt_hid_mouse_scroll(-19); + furi_hal_bt_hid_mouse_scroll(-12); + furi_hal_bt_hid_mouse_scroll(-6); + consumed = true; + } else if(event->key == InputKeyDown) { + // Emulate down swipe + furi_hal_bt_hid_mouse_scroll(6); + furi_hal_bt_hid_mouse_scroll(12); + furi_hal_bt_hid_mouse_scroll(19); + furi_hal_bt_hid_mouse_scroll(12); + furi_hal_bt_hid_mouse_scroll(6); + consumed = true; + } else if(event->key == InputKeyBack) { + furi_hal_bt_hid_consumer_key_release_all(); + consumed = true; + } + } + + return consumed; +} + +BtHidTikTok* bt_hid_tiktok_alloc() { + BtHidTikTok* bt_hid_tiktok = malloc(sizeof(BtHidTikTok)); + bt_hid_tiktok->view = view_alloc(); + view_set_context(bt_hid_tiktok->view, bt_hid_tiktok); + view_allocate_model(bt_hid_tiktok->view, ViewModelTypeLocking, sizeof(BtHidTikTokModel)); + view_set_draw_callback(bt_hid_tiktok->view, bt_hid_tiktok_draw_callback); + view_set_input_callback(bt_hid_tiktok->view, bt_hid_tiktok_input_callback); + + return bt_hid_tiktok; +} + +void bt_hid_tiktok_free(BtHidTikTok* bt_hid_tiktok) { + furi_assert(bt_hid_tiktok); + view_free(bt_hid_tiktok->view); + free(bt_hid_tiktok); +} + +View* bt_hid_tiktok_get_view(BtHidTikTok* bt_hid_tiktok) { + furi_assert(bt_hid_tiktok); + return bt_hid_tiktok->view; +} + +void bt_hid_tiktok_set_connected_status(BtHidTikTok* bt_hid_tiktok, bool connected) { + furi_assert(bt_hid_tiktok); + with_view_model( + bt_hid_tiktok->view, BtHidTikTokModel * model, { model->connected = connected; }, true); +} diff --git a/applications/plugins/bt_hid_app/views/bt_hid_tiktok.h b/applications/plugins/bt_hid_app/views/bt_hid_tiktok.h new file mode 100644 index 000000000..03c9afeca --- /dev/null +++ b/applications/plugins/bt_hid_app/views/bt_hid_tiktok.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +typedef struct BtHidTikTok BtHidTikTok; + +BtHidTikTok* bt_hid_tiktok_alloc(); + +void bt_hid_tiktok_free(BtHidTikTok* bt_hid_tiktok); + +View* bt_hid_tiktok_get_view(BtHidTikTok* bt_hid_tiktok); + +void bt_hid_tiktok_set_connected_status(BtHidTikTok* bt_hid_tiktok, bool connected); diff --git a/applications/plugins/metronome/README.md b/applications/plugins/metronome/README.md index a8af47722..4b6cd3122 100644 --- a/applications/plugins/metronome/README.md +++ b/applications/plugins/metronome/README.md @@ -1,5 +1,7 @@ # Metronome +[Original link](https://github.com/panki27/Metronome) + A metronome for the [Flipper Zero](https://flipperzero.one/) device. Goes along perfectly with my [BPM tapper](https://github.com/panki27/bpm-tapper). ![screenshot](img/screenshot.png) diff --git a/applications/plugins/minesweeper/README.md b/applications/plugins/minesweeper/README.md index 4297cbed7..ab253a4a6 100644 --- a/applications/plugins/minesweeper/README.md +++ b/applications/plugins/minesweeper/README.md @@ -1,5 +1,7 @@ # Minesweeper +[Original Link](https://github.com/panki27/minesweeper) + This is a Minesweeper implementation for the Flipper Zero device. ![screenshot](img/screenshot.png) diff --git a/applications/plugins/minesweeper/minesweeper.c b/applications/plugins/minesweeper/minesweeper.c index e37a34eac..e825dfcdc 100644 --- a/applications/plugins/minesweeper/minesweeper.c +++ b/applications/plugins/minesweeper/minesweeper.c @@ -28,18 +28,18 @@ typedef struct { } PluginEvent; typedef enum { - TileType0, // this HAS to be in order, for hint assignment to be ez pz - TileType1, - TileType2, - TileType3, - TileType4, - TileType5, - TileType6, - TileType7, - TileType8, - TileTypeUncleared, - TileTypeFlag, - TileTypeMine + TileType0, // this HAS to be in order, for hint assignment to be ez pz + TileType1, + TileType2, + TileType3, + TileType4, + TileType5, + TileType6, + TileType7, + TileType8, + TileTypeUncleared, + TileTypeFlag, + TileTypeMine } TileType; typedef enum { @@ -48,27 +48,27 @@ typedef enum { } Field; typedef struct { - Field minefield[PLAYFIELD_WIDTH][PLAYFIELD_HEIGHT]; - TileType playfield[PLAYFIELD_WIDTH][PLAYFIELD_HEIGHT]; - FuriTimer* timer; - int cursor_x; - int cursor_y; - int mines_left; - int fields_cleared; - int flags_set; - bool game_started; - uint32_t game_started_tick; + Field minefield[PLAYFIELD_WIDTH][PLAYFIELD_HEIGHT]; + TileType playfield[PLAYFIELD_WIDTH][PLAYFIELD_HEIGHT]; + FuriTimer* timer; + int cursor_x; + int cursor_y; + int mines_left; + int fields_cleared; + int flags_set; + bool game_started; + uint32_t game_started_tick; } Minesweeper; static void timer_callback(void* ctx) { - UNUSED(ctx); - NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - notification_message(notification, &sequence_reset_vibro); - furi_record_close(RECORD_NOTIFICATION); + UNUSED(ctx); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + notification_message(notification, &sequence_reset_vibro); + furi_record_close(RECORD_NOTIFICATION); } static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); + furi_assert(event_queue); PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); @@ -76,8 +76,8 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu static void render_callback(Canvas* const canvas, void* ctx) { const Minesweeper* minesweeper_state = acquire_mutex((ValueMutex*)ctx, 25); - if (minesweeper_state == NULL) { - return; + if(minesweeper_state == NULL) { + return; } FuriString* mineStr; FuriString* timeStr; @@ -90,134 +90,134 @@ static void render_callback(Canvas* const canvas, void* ctx) { int seconds = 0; int minutes = 0; - if (minesweeper_state->game_started) { - uint32_t ticks_elapsed = furi_get_tick() - minesweeper_state->game_started_tick; - seconds = (int) ticks_elapsed / furi_kernel_get_tick_frequency(); - minutes = (int) seconds / 60; - seconds = seconds % 60; + if(minesweeper_state->game_started) { + uint32_t ticks_elapsed = furi_get_tick() - minesweeper_state->game_started_tick; + seconds = (int)ticks_elapsed / furi_kernel_get_tick_frequency(); + minutes = (int)seconds / 60; + seconds = seconds % 60; } furi_string_printf(timeStr, "%01d:%02d", minutes, seconds); canvas_draw_str_aligned(canvas, 128, 0, AlignRight, AlignTop, furi_string_get_cstr(timeStr)); - for (int y = 0; y < PLAYFIELD_HEIGHT; y++) { - for (int x = 0; x < PLAYFIELD_WIDTH; x++) { - if ( x == minesweeper_state->cursor_x && y == minesweeper_state->cursor_y) { - canvas_invert_color(canvas); + for(int y = 0; y < PLAYFIELD_HEIGHT; y++) { + for(int x = 0; x < PLAYFIELD_WIDTH; x++) { + if(x == minesweeper_state->cursor_x && y == minesweeper_state->cursor_y) { + canvas_invert_color(canvas); + } + switch(minesweeper_state->playfield[x][y]) { + case TileType0: + canvas_draw_xbm( + canvas, + x * TILE_HEIGHT, // x + 8 + (y * TILE_WIDTH), // y + TILE_WIDTH, + TILE_HEIGHT, + tile_0_bits); + break; + case TileType1: + canvas_draw_xbm( + canvas, + x * TILE_HEIGHT, // x + 8 + (y * TILE_WIDTH), // y + TILE_WIDTH, + TILE_HEIGHT, + tile_1_bits); + break; + case TileType2: + canvas_draw_xbm( + canvas, + x * TILE_HEIGHT, // x + 8 + (y * TILE_WIDTH), // y + TILE_WIDTH, + TILE_HEIGHT, + tile_2_bits); + break; + case TileType3: + canvas_draw_xbm( + canvas, + x * TILE_HEIGHT, // x + 8 + (y * TILE_WIDTH), // y + TILE_WIDTH, + TILE_HEIGHT, + tile_3_bits); + break; + case TileType4: + canvas_draw_xbm( + canvas, + x * TILE_HEIGHT, // x + 8 + (y * TILE_WIDTH), // y + TILE_WIDTH, + TILE_HEIGHT, + tile_4_bits); + break; + case TileType5: + canvas_draw_xbm( + canvas, + x * TILE_HEIGHT, // x + 8 + (y * TILE_WIDTH), // y + TILE_WIDTH, + TILE_HEIGHT, + tile_5_bits); + break; + case TileType6: + canvas_draw_xbm( + canvas, + x * TILE_HEIGHT, // x + 8 + (y * TILE_WIDTH), // y + TILE_WIDTH, + TILE_HEIGHT, + tile_6_bits); + break; + case TileType7: + canvas_draw_xbm( + canvas, + x * TILE_HEIGHT, // x + 8 + (y * TILE_WIDTH), // y + TILE_WIDTH, + TILE_HEIGHT, + tile_7_bits); + break; + case TileType8: + canvas_draw_xbm( + canvas, + x * TILE_HEIGHT, // x + 8 + (y * TILE_WIDTH), // y + TILE_WIDTH, + TILE_HEIGHT, + tile_8_bits); + break; + case TileTypeFlag: + canvas_draw_xbm( + canvas, + x * TILE_HEIGHT, // x + 8 + (y * TILE_WIDTH), // y + TILE_WIDTH, + TILE_HEIGHT, + tile_flag_bits); + break; + case TileTypeUncleared: + canvas_draw_xbm( + canvas, + x * TILE_HEIGHT, // x + 8 + (y * TILE_WIDTH), // y + TILE_WIDTH, + TILE_HEIGHT, + tile_uncleared_bits); + break; + case TileTypeMine: + canvas_draw_xbm( + canvas, + x * TILE_HEIGHT, // x + 8 + (y * TILE_WIDTH), // y + TILE_WIDTH, + TILE_HEIGHT, + tile_mine_bits); + break; + } + if(x == minesweeper_state->cursor_x && y == minesweeper_state->cursor_y) { + canvas_invert_color(canvas); + } } - switch (minesweeper_state->playfield[x][y]) { - case TileType0: - canvas_draw_xbm( - canvas, - x*TILE_HEIGHT, // x - 8 + (y * TILE_WIDTH), // y - TILE_WIDTH, - TILE_HEIGHT, - tile_0_bits); - break; - case TileType1: - canvas_draw_xbm( - canvas, - x*TILE_HEIGHT, // x - 8 + (y * TILE_WIDTH), // y - TILE_WIDTH, - TILE_HEIGHT, - tile_1_bits); - break; - case TileType2: - canvas_draw_xbm( - canvas, - x*TILE_HEIGHT, // x - 8 + (y * TILE_WIDTH), // y - TILE_WIDTH, - TILE_HEIGHT, - tile_2_bits); - break; - case TileType3: - canvas_draw_xbm( - canvas, - x*TILE_HEIGHT, // x - 8 + (y * TILE_WIDTH), // y - TILE_WIDTH, - TILE_HEIGHT, - tile_3_bits); - break; - case TileType4: - canvas_draw_xbm( - canvas, - x*TILE_HEIGHT, // x - 8 + (y * TILE_WIDTH), // y - TILE_WIDTH, - TILE_HEIGHT, - tile_4_bits); - break; - case TileType5: - canvas_draw_xbm( - canvas, - x*TILE_HEIGHT, // x - 8 + (y * TILE_WIDTH), // y - TILE_WIDTH, - TILE_HEIGHT, - tile_5_bits); - break; - case TileType6: - canvas_draw_xbm( - canvas, - x*TILE_HEIGHT, // x - 8 + (y * TILE_WIDTH), // y - TILE_WIDTH, - TILE_HEIGHT, - tile_6_bits); - break; - case TileType7: - canvas_draw_xbm( - canvas, - x*TILE_HEIGHT, // x - 8 + (y * TILE_WIDTH), // y - TILE_WIDTH, - TILE_HEIGHT, - tile_7_bits); - break; - case TileType8: - canvas_draw_xbm( - canvas, - x*TILE_HEIGHT, // x - 8 + (y * TILE_WIDTH), // y - TILE_WIDTH, - TILE_HEIGHT, - tile_8_bits); - break; - case TileTypeFlag: - canvas_draw_xbm( - canvas, - x*TILE_HEIGHT, // x - 8 + (y * TILE_WIDTH), // y - TILE_WIDTH, - TILE_HEIGHT, - tile_flag_bits); - break; - case TileTypeUncleared: - canvas_draw_xbm( - canvas, - x*TILE_HEIGHT, // x - 8 + (y * TILE_WIDTH), // y - TILE_WIDTH, - TILE_HEIGHT, - tile_uncleared_bits); - break; - case TileTypeMine: - canvas_draw_xbm( - canvas, - x*TILE_HEIGHT, // x - 8 + (y * TILE_WIDTH), // y - TILE_WIDTH, - TILE_HEIGHT, - tile_mine_bits); - break; - } - if ( x == minesweeper_state->cursor_x && y == minesweeper_state->cursor_y) { - canvas_invert_color(canvas); - } - } } furi_string_free(mineStr); @@ -226,294 +226,302 @@ static void render_callback(Canvas* const canvas, void* ctx) { } static void setup_playfield(Minesweeper* minesweeper_state) { - int mines_left = MINECOUNT; - for (int y = 0; y < PLAYFIELD_HEIGHT; y++) { - for (int x = 0; x < PLAYFIELD_WIDTH; x++){ - minesweeper_state->minefield[x][y] = FieldEmpty; - minesweeper_state->playfield[x][y] = TileTypeUncleared; + int mines_left = MINECOUNT; + for(int y = 0; y < PLAYFIELD_HEIGHT; y++) { + for(int x = 0; x < PLAYFIELD_WIDTH; x++) { + minesweeper_state->minefield[x][y] = FieldEmpty; + minesweeper_state->playfield[x][y] = TileTypeUncleared; + } } - } - while(mines_left > 0) { - int rand_x = rand() % PLAYFIELD_WIDTH; - int rand_y = rand() % PLAYFIELD_HEIGHT; - // make sure first guess isn't a mine - if (minesweeper_state->minefield[rand_x][rand_y] == FieldEmpty && - (minesweeper_state->cursor_x != rand_x && minesweeper_state->cursor_y != rand_y )) { - minesweeper_state->minefield[rand_x][rand_y] = FieldMine; - mines_left--; + while(mines_left > 0) { + int rand_x = rand() % PLAYFIELD_WIDTH; + int rand_y = rand() % PLAYFIELD_HEIGHT; + // make sure first guess isn't a mine + if(minesweeper_state->minefield[rand_x][rand_y] == FieldEmpty && + (minesweeper_state->cursor_x != rand_x && minesweeper_state->cursor_y != rand_y)) { + minesweeper_state->minefield[rand_x][rand_y] = FieldMine; + mines_left--; + } } - } - minesweeper_state->mines_left = MINECOUNT; - minesweeper_state->fields_cleared = 0; - minesweeper_state->flags_set = 0; - minesweeper_state->game_started_tick = furi_get_tick(); - minesweeper_state->game_started = false; + minesweeper_state->mines_left = MINECOUNT; + minesweeper_state->fields_cleared = 0; + minesweeper_state->flags_set = 0; + minesweeper_state->game_started_tick = furi_get_tick(); + minesweeper_state->game_started = false; } static void place_flag(Minesweeper* minesweeper_state) { - if (minesweeper_state->playfield[minesweeper_state->cursor_x][minesweeper_state->cursor_y] == TileTypeUncleared) { - minesweeper_state->playfield[minesweeper_state->cursor_x][minesweeper_state->cursor_y] = TileTypeFlag; - minesweeper_state->flags_set++; - } else if (minesweeper_state->playfield[minesweeper_state->cursor_x][minesweeper_state->cursor_y] == TileTypeFlag) { - minesweeper_state->playfield[minesweeper_state->cursor_x][minesweeper_state->cursor_y] = TileTypeUncleared; - minesweeper_state->flags_set--; - } + if(minesweeper_state->playfield[minesweeper_state->cursor_x][minesweeper_state->cursor_y] == + TileTypeUncleared) { + minesweeper_state->playfield[minesweeper_state->cursor_x][minesweeper_state->cursor_y] = + TileTypeFlag; + minesweeper_state->flags_set++; + } else if( + minesweeper_state->playfield[minesweeper_state->cursor_x][minesweeper_state->cursor_y] == + TileTypeFlag) { + minesweeper_state->playfield[minesweeper_state->cursor_x][minesweeper_state->cursor_y] = + TileTypeUncleared; + minesweeper_state->flags_set--; + } } static bool game_lost(Minesweeper* minesweeper_state) { - // returns true if the player wants to restart, otherwise false - DialogsApp *dialogs = furi_record_open(RECORD_DIALOGS); + // returns true if the player wants to restart, otherwise false + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); - DialogMessage* message = dialog_message_alloc(); - const char* header_text = "Game Over"; - const char* message_text = "You hit a mine!"; + DialogMessage* message = dialog_message_alloc(); + const char* header_text = "Game Over"; + const char* message_text = "You hit a mine!"; - dialog_message_set_header(message, header_text, 64, 3, AlignCenter, AlignTop); - dialog_message_set_text(message, message_text, 64, 32, AlignCenter, AlignCenter); - dialog_message_set_buttons(message, NULL, "Play again", NULL); + dialog_message_set_header(message, header_text, 64, 3, AlignCenter, AlignTop); + dialog_message_set_text(message, message_text, 64, 32, AlignCenter, AlignCenter); + dialog_message_set_buttons(message, NULL, "Play again", NULL); - dialog_message_set_icon(message, NULL, 0, 10); - - NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION); - notification_message(notifications, &sequence_set_vibro_on); - furi_record_close(RECORD_NOTIFICATION); - furi_timer_start(minesweeper_state->timer, (uint32_t) furi_kernel_get_tick_frequency() * 0.2); + dialog_message_set_icon(message, NULL, 0, 10); - DialogMessageButton choice = dialog_message_show(dialogs, message); - dialog_message_free(message); - furi_record_close(RECORD_DIALOGS); + NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION); + notification_message(notifications, &sequence_set_vibro_on); + furi_record_close(RECORD_NOTIFICATION); + furi_timer_start(minesweeper_state->timer, (uint32_t)furi_kernel_get_tick_frequency() * 0.2); - return choice == DialogMessageButtonCenter; + DialogMessageButton choice = dialog_message_show(dialogs, message); + dialog_message_free(message); + furi_record_close(RECORD_DIALOGS); + + return choice == DialogMessageButtonCenter; } static bool game_won(Minesweeper* minesweeper_state) { - DialogsApp *dialogs = furi_record_open(RECORD_DIALOGS); + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); - FuriString* tempStr; - tempStr = furi_string_alloc(); + FuriString* tempStr; + tempStr = furi_string_alloc(); - int seconds = 0; - int minutes = 0; - uint32_t ticks_elapsed = furi_get_tick() - minesweeper_state->game_started_tick; - seconds = (int) ticks_elapsed / furi_kernel_get_tick_frequency(); - minutes = (int) seconds / 60; - seconds = seconds % 60; + int seconds = 0; + int minutes = 0; + uint32_t ticks_elapsed = furi_get_tick() - minesweeper_state->game_started_tick; + seconds = (int)ticks_elapsed / furi_kernel_get_tick_frequency(); + minutes = (int)seconds / 60; + seconds = seconds % 60; - DialogMessage* message = dialog_message_alloc(); - const char* header_text = "Game won!"; - furi_string_cat_printf(tempStr, "Minefield cleared in %01d:%02d", minutes, seconds); - dialog_message_set_header(message, header_text, 64, 3, AlignCenter, AlignTop); - dialog_message_set_text(message, furi_string_get_cstr(tempStr), 64, 32, AlignCenter, AlignCenter); - dialog_message_set_buttons(message, NULL, "Play again", NULL); - // TODO: create icon - dialog_message_set_icon(message, NULL, 72, 17); + DialogMessage* message = dialog_message_alloc(); + const char* header_text = "Game won!"; + furi_string_cat_printf(tempStr, "Minefield cleared in %01d:%02d", minutes, seconds); + dialog_message_set_header(message, header_text, 64, 3, AlignCenter, AlignTop); + dialog_message_set_text( + message, furi_string_get_cstr(tempStr), 64, 32, AlignCenter, AlignCenter); + dialog_message_set_buttons(message, NULL, "Play again", NULL); + // TODO: create icon + dialog_message_set_icon(message, NULL, 72, 17); - DialogMessageButton choice = dialog_message_show(dialogs, message); - dialog_message_free(message); - furi_string_free(tempStr); - furi_record_close(RECORD_DIALOGS); - return choice == DialogMessageButtonCenter; + DialogMessageButton choice = dialog_message_show(dialogs, message); + dialog_message_free(message); + furi_string_free(tempStr); + furi_record_close(RECORD_DIALOGS); + return choice == DialogMessageButtonCenter; } static bool play_move(Minesweeper* minesweeper_state, int cursor_x, int cursor_y) { - if (minesweeper_state->playfield[cursor_x][cursor_y] != TileTypeUncleared) { - // we're on an already uncovered field - return true; - } - if (minesweeper_state->minefield[cursor_x][cursor_y] == FieldMine) { - // TODO: player loses! - minesweeper_state->playfield[cursor_x][cursor_y] = TileTypeMine; - return false; - } else { - // get number of surrounding mines. - int hint = 0; - for (int y = cursor_y-1; y <= cursor_y+1; y++) { - for (int x = cursor_x-1; x <= cursor_x+1; x++) { - if ( x == cursor_x && y == cursor_y ) { - // we're on the cell the user selected, so ignore. - continue; - } - // make sure we don't go OOB - if ( x >= 0 && x < PLAYFIELD_WIDTH && y >= 0 && y < PLAYFIELD_HEIGHT) { - if(minesweeper_state->minefield[x][y] == FieldMine) { - hint ++; - } - } - } + if(minesweeper_state->playfield[cursor_x][cursor_y] != TileTypeUncleared) { + // we're on an already uncovered field + return true; } - // 〜( ̄▽ ̄〜) don't judge me (〜 ̄▽ ̄)〜 - minesweeper_state->playfield[cursor_x][cursor_y] = hint; - minesweeper_state->fields_cleared++; - FURI_LOG_D("Minesweeper", "Setting %d,%d to %d", cursor_x, cursor_y, hint); - if (hint == 0) { - // auto open surrounding fields. - for (int auto_y = cursor_y-1; auto_y <= cursor_y+1; auto_y++) { - for (int auto_x = cursor_x-1; auto_x <= cursor_x+1; auto_x++) { - if ( auto_x == cursor_x && auto_y == cursor_y ) { - continue; - } - if ( auto_x >= 0 && auto_x < PLAYFIELD_WIDTH && auto_y >= 0 && auto_y < PLAYFIELD_HEIGHT) { - if (minesweeper_state->playfield[auto_x][auto_y] == TileTypeUncleared) { - play_move(minesweeper_state, auto_x, auto_y); + if(minesweeper_state->minefield[cursor_x][cursor_y] == FieldMine) { + // TODO: player loses! + minesweeper_state->playfield[cursor_x][cursor_y] = TileTypeMine; + return false; + } else { + // get number of surrounding mines. + int hint = 0; + for(int y = cursor_y - 1; y <= cursor_y + 1; y++) { + for(int x = cursor_x - 1; x <= cursor_x + 1; x++) { + if(x == cursor_x && y == cursor_y) { + // we're on the cell the user selected, so ignore. + continue; + } + // make sure we don't go OOB + if(x >= 0 && x < PLAYFIELD_WIDTH && y >= 0 && y < PLAYFIELD_HEIGHT) { + if(minesweeper_state->minefield[x][y] == FieldMine) { + hint++; + } + } } - } } - } + // 〜( ̄▽ ̄〜) don't judge me (〜 ̄▽ ̄)〜 + minesweeper_state->playfield[cursor_x][cursor_y] = hint; + minesweeper_state->fields_cleared++; + FURI_LOG_D("Minesweeper", "Setting %d,%d to %d", cursor_x, cursor_y, hint); + if(hint == 0) { + // auto open surrounding fields. + for(int auto_y = cursor_y - 1; auto_y <= cursor_y + 1; auto_y++) { + for(int auto_x = cursor_x - 1; auto_x <= cursor_x + 1; auto_x++) { + if(auto_x == cursor_x && auto_y == cursor_y) { + continue; + } + if(auto_x >= 0 && auto_x < PLAYFIELD_WIDTH && auto_y >= 0 && + auto_y < PLAYFIELD_HEIGHT) { + if(minesweeper_state->playfield[auto_x][auto_y] == TileTypeUncleared) { + play_move(minesweeper_state, auto_x, auto_y); + } + } + } + } + } + return true; } - return true; - } } static void minesweeper_state_init(Minesweeper* const minesweeper_state) { - minesweeper_state->cursor_x = minesweeper_state->cursor_y = 0; + minesweeper_state->cursor_x = minesweeper_state->cursor_y = 0; minesweeper_state->game_started = false; - for (int y = 0; y < PLAYFIELD_HEIGHT; y++) { - for (int x = 0; x < PLAYFIELD_WIDTH; x++){ - minesweeper_state->playfield[x][y] = TileTypeUncleared; - } + for(int y = 0; y < PLAYFIELD_HEIGHT; y++) { + for(int x = 0; x < PLAYFIELD_WIDTH; x++) { + minesweeper_state->playfield[x][y] = TileTypeUncleared; + } } } int32_t minesweeper_app(void* p) { - UNUSED(p); - DialogsApp *dialogs = furi_record_open(RECORD_DIALOGS); + UNUSED(p); + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); - DialogMessage* message = dialog_message_alloc(); - const char* header_text = "Minesweeper"; - const char* message_text = "Hold OK pressed to toggle flags.\ngithub.com/panki27"; + DialogMessage* message = dialog_message_alloc(); + const char* header_text = "Minesweeper"; + const char* message_text = "Hold OK pressed to toggle flags.\ngithub.com/panki27"; - dialog_message_set_header(message, header_text, 64, 3, AlignCenter, AlignTop); - dialog_message_set_text(message, message_text, 64, 32, AlignCenter, AlignCenter); - dialog_message_set_buttons(message, NULL, "Play", NULL); + dialog_message_set_header(message, header_text, 64, 3, AlignCenter, AlignTop); + dialog_message_set_text(message, message_text, 64, 32, AlignCenter, AlignCenter); + dialog_message_set_buttons(message, NULL, "Play", NULL); - dialog_message_set_icon(message, NULL, 0, 10); + dialog_message_set_icon(message, NULL, 0, 10); - dialog_message_show(dialogs, message); - dialog_message_free(message); - furi_record_close(RECORD_DIALOGS); + dialog_message_show(dialogs, message); + dialog_message_free(message); + furi_record_close(RECORD_DIALOGS); - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - - Minesweeper* minesweeper_state = malloc(sizeof(Minesweeper)); - // setup - minesweeper_state_init(minesweeper_state); - - ValueMutex state_mutex; - if (!init_mutex(&state_mutex, minesweeper_state, sizeof(minesweeper_state))) { - FURI_LOG_E("Minesweeper", "cannot create mutex\r\n"); - free(minesweeper_state); - return 255; - } - // BEGIN IMPLEMENTATION + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - // Set system callbacks - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, &state_mutex); - view_port_input_callback_set(view_port, input_callback, event_queue); - minesweeper_state->timer = furi_timer_alloc(timer_callback, FuriTimerTypeOnce, &state_mutex); - - // Open GUI and register view_port - Gui* gui = furi_record_open("gui"); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); + Minesweeper* minesweeper_state = malloc(sizeof(Minesweeper)); + // setup + minesweeper_state_init(minesweeper_state); - PluginEvent event; - for (bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - Minesweeper* minesweeper_state = (Minesweeper*)acquire_mutex_block(&state_mutex); - if(event_status == FuriStatusOk) { - // press events - if(event.type == EventTypeKey) { - if(event.input.type == InputTypeShort) { - switch(event.input.key) { - case InputKeyUp: - minesweeper_state->cursor_y--; - if(minesweeper_state->cursor_y < 0) { - minesweeper_state->cursor_y = 0; - } - break; - case InputKeyDown: - minesweeper_state->cursor_y++; - if(minesweeper_state->cursor_y >= PLAYFIELD_HEIGHT) { - minesweeper_state->cursor_y = PLAYFIELD_HEIGHT-1; - } - break; - case InputKeyRight: - minesweeper_state->cursor_x++; - if(minesweeper_state->cursor_x >= PLAYFIELD_WIDTH) { - minesweeper_state->cursor_x = PLAYFIELD_WIDTH-1; - } - break; - case InputKeyLeft: - minesweeper_state->cursor_x--; - if(minesweeper_state->cursor_x < 0) { - minesweeper_state->cursor_x = 0; - } - break; - case InputKeyOk: - if (!minesweeper_state->game_started) { - setup_playfield(minesweeper_state); - minesweeper_state->game_started = true; - } - if (!play_move(minesweeper_state, minesweeper_state->cursor_x, minesweeper_state->cursor_y)) { - // ooops. looks like we hit a mine! - if (game_lost(minesweeper_state)) { - // player wants to restart. - setup_playfield(minesweeper_state); - } else { - // player wants to exit :( - processing = false; - } - } else { - // check win condition. - if (minesweeper_state->fields_cleared == (PLAYFIELD_HEIGHT*PLAYFIELD_WIDTH) - MINECOUNT){ - if (game_won(minesweeper_state)) { - //player wants to restart - setup_playfield(minesweeper_state); - } else { - processing = false; - } - } - } - break; - case InputKeyBack: - // Exit the plugin - processing = false; - break; - } - } else if (event.input.type == InputTypeLong) { - // hold events - FURI_LOG_D("Minesweeper", "Got a long press!"); - switch(event.input.key) { - case InputKeyUp: - case InputKeyDown: - case InputKeyRight: - case InputKeyLeft: - break; - case InputKeyOk: - FURI_LOG_D("Minesweeper", "Toggling flag"); - place_flag(minesweeper_state); - break; - case InputKeyBack: - processing = false; - break; - } - } - } - } else { - // event timeout - ; + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, minesweeper_state, sizeof(minesweeper_state))) { + FURI_LOG_E("Minesweeper", "cannot create mutex\r\n"); + free(minesweeper_state); + return 255; } - view_port_update(view_port); - release_mutex(&state_mutex, minesweeper_state); - } - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close("gui"); - view_port_free(view_port); - furi_message_queue_free(event_queue); - delete_mutex(&state_mutex); - furi_timer_free(minesweeper_state->timer); - free(minesweeper_state); + // BEGIN IMPLEMENTATION - return 0; + // Set system callbacks + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, render_callback, &state_mutex); + view_port_input_callback_set(view_port, input_callback, event_queue); + minesweeper_state->timer = furi_timer_alloc(timer_callback, FuriTimerTypeOnce, &state_mutex); + + // Open GUI and register view_port + Gui* gui = furi_record_open("gui"); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + PluginEvent event; + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + Minesweeper* minesweeper_state = (Minesweeper*)acquire_mutex_block(&state_mutex); + if(event_status == FuriStatusOk) { + // press events + if(event.type == EventTypeKey) { + if(event.input.type == InputTypeShort) { + switch(event.input.key) { + case InputKeyUp: + minesweeper_state->cursor_y--; + if(minesweeper_state->cursor_y < 0) { + minesweeper_state->cursor_y = 0; + } + break; + case InputKeyDown: + minesweeper_state->cursor_y++; + if(minesweeper_state->cursor_y >= PLAYFIELD_HEIGHT) { + minesweeper_state->cursor_y = PLAYFIELD_HEIGHT - 1; + } + break; + case InputKeyRight: + minesweeper_state->cursor_x++; + if(minesweeper_state->cursor_x >= PLAYFIELD_WIDTH) { + minesweeper_state->cursor_x = PLAYFIELD_WIDTH - 1; + } + break; + case InputKeyLeft: + minesweeper_state->cursor_x--; + if(minesweeper_state->cursor_x < 0) { + minesweeper_state->cursor_x = 0; + } + break; + case InputKeyOk: + if(!minesweeper_state->game_started) { + setup_playfield(minesweeper_state); + minesweeper_state->game_started = true; + } + if(!play_move( + minesweeper_state, + minesweeper_state->cursor_x, + minesweeper_state->cursor_y)) { + // ooops. looks like we hit a mine! + if(game_lost(minesweeper_state)) { + // player wants to restart. + setup_playfield(minesweeper_state); + } else { + // player wants to exit :( + processing = false; + } + } else { + // check win condition. + if(minesweeper_state->fields_cleared == + (PLAYFIELD_HEIGHT * PLAYFIELD_WIDTH) - MINECOUNT) { + if(game_won(minesweeper_state)) { + //player wants to restart + setup_playfield(minesweeper_state); + } else { + processing = false; + } + } + } + break; + case InputKeyBack: + // Exit the plugin + processing = false; + break; + } + } else if(event.input.type == InputTypeLong) { + // hold events + FURI_LOG_D("Minesweeper", "Got a long press!"); + switch(event.input.key) { + case InputKeyUp: + case InputKeyDown: + case InputKeyRight: + case InputKeyLeft: + break; + case InputKeyOk: + FURI_LOG_D("Minesweeper", "Toggling flag"); + place_flag(minesweeper_state); + break; + case InputKeyBack: + processing = false; + break; + } + } + } + } + view_port_update(view_port); + release_mutex(&state_mutex, minesweeper_state); + } + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close("gui"); + view_port_free(view_port); + furi_message_queue_free(event_queue); + delete_mutex(&state_mutex); + furi_timer_free(minesweeper_state->timer); + free(minesweeper_state); + + return 0; } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index e632b0cf2..c1207af47 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -72,12 +72,11 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) notification_message(instance->notifications, &sequence_display_backlight_on); notification_message(instance->notifications, &sequence_double_vibro); - scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); } else if( event.event == SubBruteCustomEventTypeTransmitNotStarted || event.event == SubBruteCustomEventTypeBackPressed) { - if (subbrute_worker_is_running(instance->worker)) { + if(subbrute_worker_is_running(instance->worker)) { // Notify notification_message(instance->notifications, &sequence_single_vibro); } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c b/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c index b5919ae5a..bb129e948 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c @@ -47,9 +47,14 @@ bool subbrute_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(strcmp(instance->text_store, "")) { furi_string_reset(instance->file_path); furi_string_cat_printf( - instance->file_path, "%s/%s%s", SUBBRUTE_PATH, instance->text_store, SUBBRUTE_FILE_EXT); + instance->file_path, + "%s/%s%s", + SUBBRUTE_PATH, + instance->text_store, + SUBBRUTE_FILE_EXT); - if(subbrute_device_save_file(instance->device, furi_string_get_cstr(instance->file_path))) { + if(subbrute_device_save_file( + instance->device, furi_string_get_cstr(instance->file_path))) { scene_manager_next_scene(instance->scene_manager, SubBruteSceneSaveSuccess); success = true; consumed = true; diff --git a/applications/plugins/totp/.clang-format b/applications/plugins/totp/.clang-format new file mode 100644 index 000000000..4b76f7fa4 --- /dev/null +++ b/applications/plugins/totp/.clang-format @@ -0,0 +1,191 @@ +--- +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: AlwaysBreak +AlignArrayOfStructures: None +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: false +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +AttributeMacros: + - __capability +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: true +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: false +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeComma +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: false +ColumnLimit: 99 +CommentPragmas: '^ IWYU pragma:' +QualifierAlignment: Leave +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +PackConstructorInitializers: BinPack +BasedOnStyle: '' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +AllowAllConstructorInitializersOnNextLine: true +FixNamespaceComments: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequires: false +IndentWidth: 4 +IndentWrappedFunctionNames: true +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 10 +PenaltyBreakBeforeFirstCallParameter: 30 +PenaltyBreakComment: 10 +PenaltyBreakFirstLessLess: 0 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 10 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 100 +PenaltyReturnTypeOnItsOwnLine: 60 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Left +PPIndentWidth: -1 +ReferenceAlignment: Pointer +ReflowComments: false +RemoveBracesLLVM: false +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: Never +SortJavaStaticImport: Before +SortUsingDeclarations: false +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: Never +SpaceBeforeParensOptions: + AfterControlStatements: false + AfterForeachMacros: false + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: false + AfterOverloadedOperator: false + BeforeNonEmptyParentheses: false +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: c++03 +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 4 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME +... + diff --git a/applications/plugins/totp/LICENSE b/applications/plugins/totp/LICENSE new file mode 100644 index 000000000..65504e7b1 --- /dev/null +++ b/applications/plugins/totp/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Alexander Kopachov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/applications/plugins/totp/application.fam b/applications/plugins/totp/application.fam index 84aa43f09..08f54619c 100644 --- a/applications/plugins/totp/application.fam +++ b/applications/plugins/totp/application.fam @@ -12,17 +12,8 @@ App( "input", "notification" ], - provides=["totp_start"], stack_size=2 * 1024, order=20, fap_category="Misc", fap_icon="totp_10px.png" ) - -# App( -# appid="totp_start", -# apptype=FlipperAppType.STARTUP, -# entry_point="totp_on_system_start", -# requires=["totp"], -# order=30, -# ) diff --git a/applications/plugins/totp/scenes/add_new_token/totp_input_text.c b/applications/plugins/totp/scenes/add_new_token/totp_input_text.c index 2cf2c9c14..e3a7f68a6 100644 --- a/applications/plugins/totp/scenes/add_new_token/totp_input_text.c +++ b/applications/plugins/totp/scenes/add_new_token/totp_input_text.c @@ -29,8 +29,8 @@ void view_unlock_model(View* view) { } static void commit_text_input_callback(void* context) { - InputTextSceneState* text_input_state = (InputTextSceneState *)context; - if (text_input_state->callback != 0) { + InputTextSceneState* text_input_state = (InputTextSceneState*)context; + if(text_input_state->callback != 0) { InputTextSceneCallbackResult* result = malloc(sizeof(InputTextSceneCallbackResult)); result->user_input_length = strlen(text_input_state->text_input_buffer); result->user_input = malloc(result->user_input_length + 1); diff --git a/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.c b/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.c index fd49c586f..e3ec7cb46 100644 --- a/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.c +++ b/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.c @@ -11,9 +11,9 @@ #include "../generate_token/totp_scene_generate_token.h" #define TOKEN_ALGO_LIST_LENGTH 3 -char* TOKEN_ALGO_LIST[] = { "SHA1", "SHA256", "SHA512" }; +char* TOKEN_ALGO_LIST[] = {"SHA1", "SHA256", "SHA512"}; #define TOKEN_DIGITS_LIST_LENGTH 2 -char* TOKEN_DIGITS_LIST[] = { "6 digits", "8 digits" }; +char* TOKEN_DIGITS_LIST[] = {"6 digits", "8 digits"}; typedef enum { TokenNameTextBox, @@ -62,7 +62,9 @@ static void on_token_secret_user_comitted(InputTextSceneCallbackResult* result) free(result); } -void totp_scene_add_new_token_activate(PluginState* plugin_state, const TokenAddEditSceneContext* context) { +void totp_scene_add_new_token_activate( + PluginState* plugin_state, + const TokenAddEditSceneContext* context) { SceneState* scene_state = malloc(sizeof(SceneState)); plugin_state->current_scene_state = scene_state; scene_state->token_name = "Name"; @@ -84,7 +86,7 @@ void totp_scene_add_new_token_activate(PluginState* plugin_state, const TokenAdd scene_state->input_state = NULL; - if (context == NULL) { + if(context == NULL) { scene_state->current_token_index = -1; } else { scene_state->current_token_index = context->current_token_index; @@ -92,17 +94,40 @@ void totp_scene_add_new_token_activate(PluginState* plugin_state, const TokenAdd } void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state) { - SceneState* scene_state = (SceneState *)plugin_state->current_scene_state; - if (scene_state->input_started_at > 0) { + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; + if(scene_state->input_started_at > 0) { totp_input_text_render(canvas, scene_state->input_state); return; } - ui_control_text_box_render(canvas, 10 - scene_state->screen_y_offset, scene_state->token_name, scene_state->selected_control == TokenNameTextBox); - ui_control_text_box_render(canvas, 27 - scene_state->screen_y_offset, scene_state->token_secret, scene_state->selected_control == TokenSecretTextBox); - ui_control_select_render(canvas, 44 - scene_state->screen_y_offset, TOKEN_ALGO_LIST[scene_state->algo], scene_state->selected_control == TokenAlgoSelect); - ui_control_select_render(canvas, 63 - scene_state->screen_y_offset, TOKEN_DIGITS_LIST[scene_state->digits_count], scene_state->selected_control == TokenLengthSelect); - ui_control_button_render(canvas, SCREEN_WIDTH_CENTER - 24, 85 - scene_state->screen_y_offset, 48, 13, "Confirm", scene_state->selected_control == ConfirmButton); + ui_control_text_box_render( + canvas, + 10 - scene_state->screen_y_offset, + scene_state->token_name, + scene_state->selected_control == TokenNameTextBox); + ui_control_text_box_render( + canvas, + 27 - scene_state->screen_y_offset, + scene_state->token_secret, + scene_state->selected_control == TokenSecretTextBox); + ui_control_select_render( + canvas, + 44 - scene_state->screen_y_offset, + TOKEN_ALGO_LIST[scene_state->algo], + scene_state->selected_control == TokenAlgoSelect); + ui_control_select_render( + canvas, + 63 - scene_state->screen_y_offset, + TOKEN_DIGITS_LIST[scene_state->digits_count], + scene_state->selected_control == TokenLengthSelect); + ui_control_button_render( + canvas, + SCREEN_WIDTH_CENTER - 24, + 85 - scene_state->screen_y_offset, + 48, + 13, + "Confirm", + scene_state->selected_control == ConfirmButton); canvas_set_color(canvas, ColorWhite); canvas_draw_box(canvas, 0, 0, SCREEN_WIDTH, 10); @@ -113,7 +138,7 @@ void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_s } void update_screen_y_offset(SceneState* scene_state) { - if (scene_state->selected_control > TokenAlgoSelect) { + if(scene_state->selected_control > TokenAlgoSelect) { scene_state->screen_y_offset = 35; } else { scene_state->screen_y_offset = 0; @@ -122,119 +147,128 @@ void update_screen_y_offset(SceneState* scene_state) { bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState* plugin_state) { if(event->type == EventTypeKey) { - SceneState* scene_state = (SceneState *)plugin_state->current_scene_state; - if (scene_state->input_started_at > 0 && furi_get_tick() - scene_state->input_started_at > 300) { + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; + if(scene_state->input_started_at > 0 && + furi_get_tick() - scene_state->input_started_at > 300) { return totp_input_text_handle_event(event, scene_state->input_state); } - if (event->input.type == InputTypeLong && event->input.key == InputKeyBack) { + if(event->input.type == InputTypeLong && event->input.key == InputKeyBack) { return false; } else if(event->input.type == InputTypePress) { switch(event->input.key) { - case InputKeyUp: - if (scene_state->selected_control > TokenNameTextBox) { - scene_state->selected_control--; - update_screen_y_offset(scene_state); - } - break; - case InputKeyDown: - if (scene_state->selected_control < ConfirmButton) { - scene_state->selected_control++; - update_screen_y_offset(scene_state); - } - break; - case InputKeyRight: - if (scene_state->selected_control == TokenAlgoSelect) { - if (scene_state->algo < SHA512) { - scene_state->algo++; - } else { - scene_state->algo = SHA1; - } - } - else if (scene_state->selected_control == TokenLengthSelect) { - if (scene_state->digits_count < TOTP_8_DIGITS) { - scene_state->digits_count++; - } else { - scene_state->digits_count = TOTP_6_DIGITS; - } - } - break; - case InputKeyLeft: - if (scene_state->selected_control == TokenAlgoSelect) { - if (scene_state->algo > SHA1) { - scene_state->algo--; - } else { - scene_state->algo = SHA512; - } - } - else if (scene_state->selected_control == TokenLengthSelect) { - if (scene_state->digits_count > TOTP_6_DIGITS) { - scene_state->digits_count--; - } else { - scene_state->digits_count = TOTP_8_DIGITS; - } - } - break; - case InputKeyOk: - switch (scene_state->selected_control) { - case TokenNameTextBox: - if (scene_state->input_state != NULL) { - totp_input_text_free(scene_state->input_state); - } - scene_state->input_state = totp_input_text_activate(scene_state->token_name_input_context); - scene_state->input_started_at = furi_get_tick(); - break; - case TokenSecretTextBox: - if (scene_state->input_state != NULL) { - totp_input_text_free(scene_state->input_state); - } - scene_state->input_state = totp_input_text_activate(scene_state->token_secret_input_context); - scene_state->input_started_at = furi_get_tick(); - break; - case TokenAlgoSelect: - break; - case TokenLengthSelect: - break; - case ConfirmButton: { - TokenInfo* tokenInfo = token_info_alloc(); - tokenInfo->name = malloc(scene_state->token_name_length + 1); - strcpy(tokenInfo->name, scene_state->token_name); - - token_info_set_secret(tokenInfo, scene_state->token_secret, scene_state->token_secret_length, &plugin_state->iv[0]); - - tokenInfo->algo = scene_state->algo; - tokenInfo->digits = scene_state->digits_count; - - if (plugin_state->tokens_list == NULL) { - plugin_state->tokens_list = list_init_head(tokenInfo); - } else { - list_add(plugin_state->tokens_list, tokenInfo); - } - plugin_state->tokens_count++; - - Storage* cfg_storage = totp_open_storage(); - FlipperFormat* cfg_file = totp_open_config_file(cfg_storage); - - flipper_format_seek_to_end(cfg_file); - totp_config_file_save_new_token(cfg_file, tokenInfo); - - totp_close_config_file(cfg_file); - totp_close_storage(); - - GenerateTokenSceneContext generate_scene_context = { .current_token_index = plugin_state->tokens_count - 1 }; - totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, &generate_scene_context); - break; - } - } - break; - case InputKeyBack: - if (scene_state->current_token_index >= 0) { - GenerateTokenSceneContext generate_scene_context = { .current_token_index = scene_state->current_token_index }; - totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, &generate_scene_context); + case InputKeyUp: + if(scene_state->selected_control > TokenNameTextBox) { + scene_state->selected_control--; + update_screen_y_offset(scene_state); + } + break; + case InputKeyDown: + if(scene_state->selected_control < ConfirmButton) { + scene_state->selected_control++; + update_screen_y_offset(scene_state); + } + break; + case InputKeyRight: + if(scene_state->selected_control == TokenAlgoSelect) { + if(scene_state->algo < SHA512) { + scene_state->algo++; } else { - totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL); + scene_state->algo = SHA1; } + } else if(scene_state->selected_control == TokenLengthSelect) { + if(scene_state->digits_count < TOTP_8_DIGITS) { + scene_state->digits_count++; + } else { + scene_state->digits_count = TOTP_6_DIGITS; + } + } + break; + case InputKeyLeft: + if(scene_state->selected_control == TokenAlgoSelect) { + if(scene_state->algo > SHA1) { + scene_state->algo--; + } else { + scene_state->algo = SHA512; + } + } else if(scene_state->selected_control == TokenLengthSelect) { + if(scene_state->digits_count > TOTP_6_DIGITS) { + scene_state->digits_count--; + } else { + scene_state->digits_count = TOTP_8_DIGITS; + } + } + break; + case InputKeyOk: + switch(scene_state->selected_control) { + case TokenNameTextBox: + if(scene_state->input_state != NULL) { + totp_input_text_free(scene_state->input_state); + } + scene_state->input_state = + totp_input_text_activate(scene_state->token_name_input_context); + scene_state->input_started_at = furi_get_tick(); break; + case TokenSecretTextBox: + if(scene_state->input_state != NULL) { + totp_input_text_free(scene_state->input_state); + } + scene_state->input_state = + totp_input_text_activate(scene_state->token_secret_input_context); + scene_state->input_started_at = furi_get_tick(); + break; + case TokenAlgoSelect: + break; + case TokenLengthSelect: + break; + case ConfirmButton: { + TokenInfo* tokenInfo = token_info_alloc(); + tokenInfo->name = malloc(scene_state->token_name_length + 1); + strcpy(tokenInfo->name, scene_state->token_name); + + token_info_set_secret( + tokenInfo, + scene_state->token_secret, + scene_state->token_secret_length, + &plugin_state->iv[0]); + + tokenInfo->algo = scene_state->algo; + tokenInfo->digits = scene_state->digits_count; + + if(plugin_state->tokens_list == NULL) { + plugin_state->tokens_list = list_init_head(tokenInfo); + } else { + list_add(plugin_state->tokens_list, tokenInfo); + } + plugin_state->tokens_count++; + + Storage* cfg_storage = totp_open_storage(); + FlipperFormat* cfg_file = totp_open_config_file(cfg_storage); + + flipper_format_seek_to_end(cfg_file); + totp_config_file_save_new_token(cfg_file, tokenInfo); + + totp_close_config_file(cfg_file); + totp_close_storage(); + + GenerateTokenSceneContext generate_scene_context = { + .current_token_index = plugin_state->tokens_count - 1}; + totp_scene_director_activate_scene( + plugin_state, TotpSceneGenerateToken, &generate_scene_context); + break; + } + } + break; + case InputKeyBack: + if(scene_state->current_token_index >= 0) { + GenerateTokenSceneContext generate_scene_context = { + .current_token_index = scene_state->current_token_index}; + totp_scene_director_activate_scene( + plugin_state, TotpSceneGenerateToken, &generate_scene_context); + } else { + totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL); + } + break; } } } @@ -242,8 +276,8 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState } void totp_scene_add_new_token_deactivate(PluginState* plugin_state) { - if (plugin_state->current_scene_state == NULL) return; - SceneState* scene_state = (SceneState *)plugin_state->current_scene_state; + if(plugin_state->current_scene_state == NULL) return; + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; free(scene_state->token_name); free(scene_state->token_secret); @@ -253,7 +287,7 @@ void totp_scene_add_new_token_deactivate(PluginState* plugin_state) { free(scene_state->token_secret_input_context->header_text); free(scene_state->token_secret_input_context); - if (scene_state->input_state != NULL) { + if(scene_state->input_state != NULL) { totp_input_text_free(scene_state->input_state); } diff --git a/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.h b/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.h index c68e94a8b..b65c567a2 100644 --- a/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.h +++ b/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.h @@ -11,7 +11,9 @@ typedef struct { } TokenAddEditSceneContext; void totp_scene_add_new_token_init(PluginState* plugin_state); -void totp_scene_add_new_token_activate(PluginState* plugin_state, const TokenAddEditSceneContext* context); +void totp_scene_add_new_token_activate( + PluginState* plugin_state, + const TokenAddEditSceneContext* context); void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state); bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState* plugin_state); void totp_scene_add_new_token_deactivate(PluginState* plugin_state); diff --git a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c b/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c index 336d4c175..180d7b9a1 100644 --- a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c +++ b/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c @@ -28,28 +28,46 @@ void totp_scene_authenticate_activate(PluginState* plugin_state) { } void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_state) { - SceneState* scene_state = (SceneState *)plugin_state->current_scene_state; + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; int v_shift = 0; - if (scene_state->code_length > 0) { + if(scene_state->code_length > 0) { v_shift = -10; } - if (plugin_state->crypto_verify_data == NULL) { - canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER - 10 + v_shift, AlignCenter, AlignCenter, "Use arrow keys"); - canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER + 5 + v_shift, AlignCenter, AlignCenter, "to setup new PIN"); + if(plugin_state->crypto_verify_data == NULL) { + canvas_draw_str_aligned( + canvas, + SCREEN_WIDTH_CENTER, + SCREEN_HEIGHT_CENTER - 10 + v_shift, + AlignCenter, + AlignCenter, + "Use arrow keys"); + canvas_draw_str_aligned( + canvas, + SCREEN_WIDTH_CENTER, + SCREEN_HEIGHT_CENTER + 5 + v_shift, + AlignCenter, + AlignCenter, + "to setup new PIN"); } else { - canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER + v_shift, AlignCenter, AlignCenter, "Use arrow keys to enter PIN"); + canvas_draw_str_aligned( + canvas, + SCREEN_WIDTH_CENTER, + SCREEN_HEIGHT_CENTER + v_shift, + AlignCenter, + AlignCenter, + "Use arrow keys to enter PIN"); } const uint8_t PIN_ASTERISK_RADIUS = 3; const uint8_t PIN_ASTERISK_STEP = (PIN_ASTERISK_RADIUS << 1) + 2; - if (scene_state->code_length > 0) { + if(scene_state->code_length > 0) { uint8_t left_start_x = (scene_state->code_length - 1) * PIN_ASTERISK_STEP >> 1; - for (uint8_t i = 0; i < scene_state->code_length; i++) { + for(uint8_t i = 0; i < scene_state->code_length; i++) { canvas_draw_disc( - canvas, - SCREEN_WIDTH_CENTER - left_start_x + i * PIN_ASTERISK_STEP, - SCREEN_HEIGHT_CENTER + 10, + canvas, + SCREEN_WIDTH_CENTER - left_start_x + i * PIN_ASTERISK_STEP, + SCREEN_HEIGHT_CENTER + 10, PIN_ASTERISK_RADIUS); } } @@ -57,10 +75,10 @@ void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_st bool totp_scene_authenticate_handle_event(PluginEvent* const event, PluginState* plugin_state) { if(event->type == EventTypeKey) { - if (event->input.type == InputTypeLong && event->input.key == InputKeyBack) { + if(event->input.type == InputTypeLong && event->input.key == InputKeyBack) { return false; } else if(event->input.type == InputTypePress) { - SceneState* scene_state = (SceneState *)plugin_state->current_scene_state; + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; const uint8_t ARROW_UP_CODE = 2; const uint8_t ARROW_RIGHT_CODE = 8; @@ -68,89 +86,105 @@ bool totp_scene_authenticate_handle_event(PluginEvent* const event, PluginState* const uint8_t ARROW_LEFT_CODE = 5; switch(event->input.key) { - case InputKeyUp: - if (scene_state->code_length < MAX_CODE_LENGTH) { - scene_state->code_input[scene_state->code_length] = ARROW_UP_CODE; - scene_state->code_length++; - } - break; - case InputKeyDown: - if (scene_state->code_length < MAX_CODE_LENGTH) { - scene_state->code_input[scene_state->code_length] = ARROW_DOWN_CODE; - scene_state->code_length++; - } - break; - case InputKeyRight: - if (scene_state->code_length < MAX_CODE_LENGTH) { - scene_state->code_input[scene_state->code_length] = ARROW_RIGHT_CODE; - scene_state->code_length++; - } - break; - case InputKeyLeft: - if (scene_state->code_length < MAX_CODE_LENGTH) { - scene_state->code_input[scene_state->code_length] = ARROW_LEFT_CODE; - scene_state->code_length++; - } - break; - case InputKeyOk: - if (plugin_state->crypto_verify_data == NULL) { - FURI_LOG_D(LOGGING_TAG, "Generating new IV"); - furi_hal_random_fill_buf(&plugin_state->base_iv[0], TOTP_IV_SIZE); - } + case InputKeyUp: + if(scene_state->code_length < MAX_CODE_LENGTH) { + scene_state->code_input[scene_state->code_length] = ARROW_UP_CODE; + scene_state->code_length++; + } + break; + case InputKeyDown: + if(scene_state->code_length < MAX_CODE_LENGTH) { + scene_state->code_input[scene_state->code_length] = ARROW_DOWN_CODE; + scene_state->code_length++; + } + break; + case InputKeyRight: + if(scene_state->code_length < MAX_CODE_LENGTH) { + scene_state->code_input[scene_state->code_length] = ARROW_RIGHT_CODE; + scene_state->code_length++; + } + break; + case InputKeyLeft: + if(scene_state->code_length < MAX_CODE_LENGTH) { + scene_state->code_input[scene_state->code_length] = ARROW_LEFT_CODE; + scene_state->code_length++; + } + break; + case InputKeyOk: + if(plugin_state->crypto_verify_data == NULL) { + FURI_LOG_D(LOGGING_TAG, "Generating new IV"); + furi_hal_random_fill_buf(&plugin_state->base_iv[0], TOTP_IV_SIZE); + } - memcpy(&plugin_state->iv[0], &plugin_state->base_iv[0], TOTP_IV_SIZE); - for (uint8_t i = 0; i < scene_state->code_length; i++) { - plugin_state->iv[i] = plugin_state->iv[i] ^ (uint8_t)(scene_state->code_input[i] * (i + 1)); - } + memcpy(&plugin_state->iv[0], &plugin_state->base_iv[0], TOTP_IV_SIZE); + for(uint8_t i = 0; i < scene_state->code_length; i++) { + plugin_state->iv[i] = plugin_state->iv[i] ^ + (uint8_t)(scene_state->code_input[i] * (i + 1)); + } - if (plugin_state->crypto_verify_data == NULL) { - FURI_LOG_D(LOGGING_TAG, "Generating crypto verify data"); - plugin_state->crypto_verify_data = malloc(CRYPTO_VERIFY_KEY_LENGTH); - plugin_state->crypto_verify_data_length = CRYPTO_VERIFY_KEY_LENGTH; - Storage* storage = totp_open_storage(); - FlipperFormat* config_file = totp_open_config_file(storage); - furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, &plugin_state->iv[0]); - furi_hal_crypto_encrypt((uint8_t* )CRYPTO_VERIFY_KEY, plugin_state->crypto_verify_data, CRYPTO_VERIFY_KEY_LENGTH); - furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT); - flipper_format_insert_or_update_hex(config_file, TOTP_CONFIG_KEY_BASE_IV, plugin_state->base_iv, TOTP_IV_SIZE); - flipper_format_insert_or_update_hex(config_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, plugin_state->crypto_verify_data, CRYPTO_VERIFY_KEY_LENGTH); - totp_close_config_file(config_file); - totp_close_storage(); - } - - uint8_t decrypted_key[CRYPTO_VERIFY_KEY_LENGTH]; + if(plugin_state->crypto_verify_data == NULL) { + FURI_LOG_D(LOGGING_TAG, "Generating crypto verify data"); + plugin_state->crypto_verify_data = malloc(CRYPTO_VERIFY_KEY_LENGTH); + plugin_state->crypto_verify_data_length = CRYPTO_VERIFY_KEY_LENGTH; + Storage* storage = totp_open_storage(); + FlipperFormat* config_file = totp_open_config_file(storage); furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, &plugin_state->iv[0]); - furi_hal_crypto_decrypt(plugin_state->crypto_verify_data, &decrypted_key[0], CRYPTO_VERIFY_KEY_LENGTH); + furi_hal_crypto_encrypt( + (uint8_t*)CRYPTO_VERIFY_KEY, + plugin_state->crypto_verify_data, + CRYPTO_VERIFY_KEY_LENGTH); furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT); + flipper_format_insert_or_update_hex( + config_file, TOTP_CONFIG_KEY_BASE_IV, plugin_state->base_iv, TOTP_IV_SIZE); + flipper_format_insert_or_update_hex( + config_file, + TOTP_CONFIG_KEY_CRYPTO_VERIFY, + plugin_state->crypto_verify_data, + CRYPTO_VERIFY_KEY_LENGTH); + totp_close_config_file(config_file); + totp_close_storage(); + } - bool key_valid = true; - for (uint8_t i = 0; i < CRYPTO_VERIFY_KEY_LENGTH && key_valid; i++) { - if (decrypted_key[i] != CRYPTO_VERIFY_KEY[i]) key_valid = false; - } + uint8_t decrypted_key[CRYPTO_VERIFY_KEY_LENGTH]; + furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, &plugin_state->iv[0]); + furi_hal_crypto_decrypt( + plugin_state->crypto_verify_data, &decrypted_key[0], CRYPTO_VERIFY_KEY_LENGTH); + furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT); - if (key_valid) { - FURI_LOG_D(LOGGING_TAG, "PIN is valid"); - totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL); - } else { - FURI_LOG_D(LOGGING_TAG, "PIN is NOT valid"); - memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH); - memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE); - scene_state->code_length = 0; + bool key_valid = true; + for(uint8_t i = 0; i < CRYPTO_VERIFY_KEY_LENGTH && key_valid; i++) { + if(decrypted_key[i] != CRYPTO_VERIFY_KEY[i]) key_valid = false; + } - DialogMessage* message = dialog_message_alloc(); - dialog_message_set_buttons(message, "Try again", NULL, NULL); - dialog_message_set_header(message, "You entered\ninvalid PIN", SCREEN_WIDTH_CENTER - 25, SCREEN_HEIGHT_CENTER - 5, AlignCenter, AlignCenter); - dialog_message_set_icon(message, &I_DolphinCommon_56x48, 72, 17); - dialog_message_show(plugin_state->dialogs, message); - dialog_message_free(message); - } - break; - case InputKeyBack: - if (scene_state->code_length > 0) { - scene_state->code_input[scene_state->code_length - 1] = 0; - scene_state->code_length--; - } - break; + if(key_valid) { + FURI_LOG_D(LOGGING_TAG, "PIN is valid"); + totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL); + } else { + FURI_LOG_D(LOGGING_TAG, "PIN is NOT valid"); + memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH); + memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE); + scene_state->code_length = 0; + + DialogMessage* message = dialog_message_alloc(); + dialog_message_set_buttons(message, "Try again", NULL, NULL); + dialog_message_set_header( + message, + "You entered\ninvalid PIN", + SCREEN_WIDTH_CENTER - 25, + SCREEN_HEIGHT_CENTER - 5, + AlignCenter, + AlignCenter); + dialog_message_set_icon(message, &I_DolphinCommon_56x48, 72, 17); + dialog_message_show(plugin_state->dialogs, message); + dialog_message_free(message); + } + break; + case InputKeyBack: + if(scene_state->code_length > 0) { + scene_state->code_input[scene_state->code_length - 1] = 0; + scene_state->code_length--; + } + break; } } } @@ -159,7 +193,7 @@ bool totp_scene_authenticate_handle_event(PluginEvent* const event, PluginState* } void totp_scene_authenticate_deactivate(PluginState* plugin_state) { - if (plugin_state->current_scene_state == NULL) return; + if(plugin_state->current_scene_state == NULL) return; free(plugin_state->current_scene_state); plugin_state->current_scene_state = NULL; } diff --git a/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c b/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c index 700d141d0..97ef599bd 100644 --- a/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c +++ b/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c @@ -34,14 +34,14 @@ static const NotificationSequence sequence_short_vibro_and_sound = { }; static void i_token_to_str(uint32_t i_token_code, char* str, TokenDigitsCount len) { - if (len == TOTP_8_DIGITS) { + if(len == TOTP_8_DIGITS) { str[8] = '\0'; - } else if (len == TOTP_6_DIGITS) { + } else if(len == TOTP_6_DIGITS) { str[6] = '\0'; } - if (i_token_code == 0) { - if (len > TOTP_6_DIGITS) { + if(i_token_code == 0) { + if(len > TOTP_6_DIGITS) { str[7] = '-'; str[6] = '-'; } @@ -53,14 +53,14 @@ static void i_token_to_str(uint32_t i_token_code, char* str, TokenDigitsCount le str[1] = '-'; str[0] = '-'; } else { - if (len == TOTP_8_DIGITS) { + if(len == TOTP_8_DIGITS) { str[7] = DIGIT_TO_CHAR(i_token_code % 10); str[6] = DIGIT_TO_CHAR((i_token_code = i_token_code / 10) % 10); str[5] = DIGIT_TO_CHAR((i_token_code = i_token_code / 10) % 10); - } else if (len == TOTP_6_DIGITS) { + } else if(len == TOTP_6_DIGITS) { str[5] = DIGIT_TO_CHAR(i_token_code % 10); } - + str[4] = DIGIT_TO_CHAR((i_token_code = i_token_code / 10) % 10); str[3] = DIGIT_TO_CHAR((i_token_code = i_token_code / 10) % 10); str[2] = DIGIT_TO_CHAR((i_token_code = i_token_code / 10) % 10); @@ -70,20 +70,26 @@ static void i_token_to_str(uint32_t i_token_code, char* str, TokenDigitsCount le } TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) { - switch (algo) { - case SHA1: return TOTP_ALGO_SHA1; - case SHA256: return TOTP_ALGO_SHA256; - case SHA512: return TOTP_ALGO_SHA512; + switch(algo) { + case SHA1: + return TOTP_ALGO_SHA1; + case SHA256: + return TOTP_ALGO_SHA256; + case SHA512: + return TOTP_ALGO_SHA512; } return NULL; } void update_totp_params(PluginState* const plugin_state) { - SceneState* scene_state = (SceneState *)plugin_state->current_scene_state; + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; - if (scene_state->current_token_index < plugin_state->tokens_count) { - TokenInfo* tokenInfo = (TokenInfo *)(list_element_at(plugin_state->tokens_list, scene_state->current_token_index)->data); + if(scene_state->current_token_index < plugin_state->tokens_count) { + TokenInfo* tokenInfo = + (TokenInfo*)(list_element_at( + plugin_state->tokens_list, scene_state->current_token_index) + ->data); scene_state->need_token_update = true; scene_state->last_code_name = tokenInfo->name; @@ -94,12 +100,14 @@ void totp_scene_generate_token_init(PluginState* plugin_state) { UNUSED(plugin_state); } -void totp_scene_generate_token_activate(PluginState* plugin_state, const GenerateTokenSceneContext* context) { - if (!plugin_state->token_list_loaded) { +void totp_scene_generate_token_activate( + PluginState* plugin_state, + const GenerateTokenSceneContext* context) { + if(!plugin_state->token_list_loaded) { totp_config_file_load_tokens(plugin_state); } SceneState* scene_state = malloc(sizeof(SceneState)); - if (context == NULL) { + if(context == NULL) { scene_state->current_token_index = 0; } else { scene_state->current_token_index = context->current_token_index; @@ -111,27 +119,42 @@ void totp_scene_generate_token_activate(PluginState* plugin_state, const Generat } void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_state) { - if (plugin_state->tokens_count == 0) { - canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER - 10, AlignCenter, AlignCenter, "Token list is empty"); - canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER + 10, AlignCenter, AlignCenter, "Press OK button to add"); + if(plugin_state->tokens_count == 0) { + canvas_draw_str_aligned( + canvas, + SCREEN_WIDTH_CENTER, + SCREEN_HEIGHT_CENTER - 10, + AlignCenter, + AlignCenter, + "Token list is empty"); + canvas_draw_str_aligned( + canvas, + SCREEN_WIDTH_CENTER, + SCREEN_HEIGHT_CENTER + 10, + AlignCenter, + AlignCenter, + "Press OK button to add"); return; } - SceneState* scene_state = (SceneState *)plugin_state->current_scene_state; + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; FuriHalRtcDateTime curr_dt; furi_hal_rtc_get_datetime(&curr_dt); uint32_t curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt); bool is_new_token_time = curr_ts % TOKEN_LIFETIME == 0; - if (is_new_token_time && scene_state->last_token_gen_time != curr_ts) { + if(is_new_token_time && scene_state->last_token_gen_time != curr_ts) { scene_state->need_token_update = true; } - if (scene_state->need_token_update) { + if(scene_state->need_token_update) { scene_state->need_token_update = false; scene_state->last_token_gen_time = curr_ts; - TokenInfo* tokenInfo = (TokenInfo*)(list_element_at(plugin_state->tokens_list, scene_state->current_token_index)->data); + TokenInfo* tokenInfo = + (TokenInfo*)(list_element_at( + plugin_state->tokens_list, scene_state->current_token_index) + ->data); uint8_t* key = malloc(tokenInfo->token_length); @@ -139,21 +162,43 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ furi_hal_crypto_decrypt(tokenInfo->token, key, tokenInfo->token_length); furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT); - i_token_to_str(totp_at(get_totp_algo_impl(tokenInfo->algo), token_info_get_digits_count(tokenInfo), key, tokenInfo->token_length, curr_ts, plugin_state->timezone_offset, TOKEN_LIFETIME), scene_state->last_code, tokenInfo->digits); + i_token_to_str( + totp_at( + get_totp_algo_impl(tokenInfo->algo), + token_info_get_digits_count(tokenInfo), + key, + tokenInfo->token_length, + curr_ts, + plugin_state->timezone_offset, + TOKEN_LIFETIME), + scene_state->last_code, + tokenInfo->digits); memset(key, 0, tokenInfo->token_length); free(key); - if (is_new_token_time) { + if(is_new_token_time) { notification_message(plugin_state->notification, &sequence_short_vibro_and_sound); } } canvas_set_font(canvas, FontPrimary); uint16_t token_name_width = canvas_string_width(canvas, scene_state->last_code_name); - if (SCREEN_WIDTH - token_name_width > 18) { - canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER - 20, AlignCenter, AlignCenter, scene_state->last_code_name); + if(SCREEN_WIDTH - token_name_width > 18) { + canvas_draw_str_aligned( + canvas, + SCREEN_WIDTH_CENTER, + SCREEN_HEIGHT_CENTER - 20, + AlignCenter, + AlignCenter, + scene_state->last_code_name); } else { - canvas_draw_str_aligned(canvas, 9, SCREEN_HEIGHT_CENTER - 20, AlignLeft, AlignCenter, scene_state->last_code_name); + canvas_draw_str_aligned( + canvas, + 9, + SCREEN_HEIGHT_CENTER - 20, + AlignLeft, + AlignCenter, + scene_state->last_code_name); canvas_set_color(canvas, ColorWhite); canvas_draw_box(canvas, 0, SCREEN_HEIGHT_CENTER - 24, 9, 9); canvas_draw_box(canvas, SCREEN_WIDTH - 10, SCREEN_HEIGHT_CENTER - 24, 9, 9); @@ -161,7 +206,13 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ } canvas_set_font(canvas, FontBigNumbers); - canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER, AlignCenter, AlignCenter, scene_state->last_code); + canvas_draw_str_aligned( + canvas, + SCREEN_WIDTH_CENTER, + SCREEN_HEIGHT_CENTER, + AlignCenter, + AlignCenter, + scene_state->last_code); const uint8_t BAR_MARGIN = 3; const uint8_t BAR_HEIGHT = 4; @@ -169,56 +220,64 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ uint8_t barWidth = (uint8_t)((float)(SCREEN_WIDTH - (BAR_MARGIN << 1)) * percentDone); uint8_t barX = ((SCREEN_WIDTH - (BAR_MARGIN << 1) - barWidth) >> 1) + BAR_MARGIN; - canvas_draw_box( - canvas, - barX, - SCREEN_HEIGHT - BAR_MARGIN - BAR_HEIGHT, - barWidth, - BAR_HEIGHT); + canvas_draw_box(canvas, barX, SCREEN_HEIGHT - BAR_MARGIN - BAR_HEIGHT, barWidth, BAR_HEIGHT); - if (plugin_state->tokens_count > 1) { - canvas_draw_xbm(canvas, 0, SCREEN_HEIGHT_CENTER - 24, ICON_ARROW_LEFT_8x9_WIDTH, ICON_ARROW_LEFT_8x9_HEIGHT, &ICON_ARROW_LEFT_8x9[0]); - canvas_draw_xbm(canvas, SCREEN_WIDTH - 9, SCREEN_HEIGHT_CENTER - 24, ICON_ARROW_RIGHT_8x9_WIDTH, ICON_ARROW_RIGHT_8x9_HEIGHT, &ICON_ARROW_RIGHT_8x9[0]); + if(plugin_state->tokens_count > 1) { + canvas_draw_xbm( + canvas, + 0, + SCREEN_HEIGHT_CENTER - 24, + ICON_ARROW_LEFT_8x9_WIDTH, + ICON_ARROW_LEFT_8x9_HEIGHT, + &ICON_ARROW_LEFT_8x9[0]); + canvas_draw_xbm( + canvas, + SCREEN_WIDTH - 9, + SCREEN_HEIGHT_CENTER - 24, + ICON_ARROW_RIGHT_8x9_WIDTH, + ICON_ARROW_RIGHT_8x9_HEIGHT, + &ICON_ARROW_RIGHT_8x9[0]); } } bool totp_scene_generate_token_handle_event(PluginEvent* const event, PluginState* plugin_state) { if(event->type == EventTypeKey) { - if (event->input.type == InputTypeLong && event->input.key == InputKeyBack) { + if(event->input.type == InputTypeLong && event->input.key == InputKeyBack) { return false; } else if(event->input.type == InputTypePress) { - SceneState* scene_state = (SceneState *)plugin_state->current_scene_state; + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; switch(event->input.key) { - case InputKeyUp: - break; - case InputKeyDown: - break; - case InputKeyRight: - if (scene_state->current_token_index < plugin_state->tokens_count - 1) { - scene_state->current_token_index++; - } else { - scene_state->current_token_index = 0; - } - update_totp_params(plugin_state); - break; - case InputKeyLeft: - if (scene_state->current_token_index > 0) { - scene_state->current_token_index--; - } else { - scene_state->current_token_index = plugin_state->tokens_count - 1; - } - update_totp_params(plugin_state); - break; - case InputKeyOk: - if (plugin_state->tokens_count == 0) { - totp_scene_director_activate_scene(plugin_state, TotpSceneAddNewToken, NULL); - } else { - TokenMenuSceneContext ctx = { .current_token_index = scene_state->current_token_index }; - totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu, &ctx); - } - break; - case InputKeyBack: - break; + case InputKeyUp: + break; + case InputKeyDown: + break; + case InputKeyRight: + if(scene_state->current_token_index < plugin_state->tokens_count - 1) { + scene_state->current_token_index++; + } else { + scene_state->current_token_index = 0; + } + update_totp_params(plugin_state); + break; + case InputKeyLeft: + if(scene_state->current_token_index > 0) { + scene_state->current_token_index--; + } else { + scene_state->current_token_index = plugin_state->tokens_count - 1; + } + update_totp_params(plugin_state); + break; + case InputKeyOk: + if(plugin_state->tokens_count == 0) { + totp_scene_director_activate_scene(plugin_state, TotpSceneAddNewToken, NULL); + } else { + TokenMenuSceneContext ctx = { + .current_token_index = scene_state->current_token_index}; + totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu, &ctx); + } + break; + case InputKeyBack: + break; } } } @@ -227,8 +286,8 @@ bool totp_scene_generate_token_handle_event(PluginEvent* const event, PluginStat } void totp_scene_generate_token_deactivate(PluginState* plugin_state) { - if (plugin_state->current_scene_state == NULL) return; - SceneState* scene_state = (SceneState *)plugin_state->current_scene_state; + if(plugin_state->current_scene_state == NULL) return; + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; free(scene_state->last_code); free(scene_state); diff --git a/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.h b/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.h index c13bc7073..1284c7b41 100644 --- a/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.h +++ b/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.h @@ -11,7 +11,9 @@ typedef struct { } GenerateTokenSceneContext; void totp_scene_generate_token_init(PluginState* plugin_state); -void totp_scene_generate_token_activate(PluginState* plugin_state, const GenerateTokenSceneContext* context); +void totp_scene_generate_token_activate( + PluginState* plugin_state, + const GenerateTokenSceneContext* context); void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_state); bool totp_scene_generate_token_handle_event(PluginEvent* const event, PluginState* plugin_state); void totp_scene_generate_token_deactivate(PluginState* plugin_state); diff --git a/applications/plugins/totp/scenes/scene_director.c b/applications/plugins/totp/scenes/scene_director.c index 428df9080..37cbe28c6 100644 --- a/applications/plugins/totp/scenes/scene_director.c +++ b/applications/plugins/totp/scenes/scene_director.c @@ -5,22 +5,25 @@ #include "add_new_token/totp_scene_add_new_token.h" #include "token_menu/totp_scene_token_menu.h" -void totp_scene_director_activate_scene(PluginState* const plugin_state, Scene scene, const void* context) { +void totp_scene_director_activate_scene( + PluginState* const plugin_state, + Scene scene, + const void* context) { plugin_state->changing_scene = true; totp_scene_director_deactivate_active_scene(plugin_state); - switch (scene) { - case TotpSceneGenerateToken: - totp_scene_generate_token_activate(plugin_state, context); - break; - case TotpSceneAuthentication: - totp_scene_authenticate_activate(plugin_state); - break; - case TotpSceneAddNewToken: - totp_scene_add_new_token_activate(plugin_state, context); - break; - case TotpSceneTokenMenu: - totp_scene_token_menu_activate(plugin_state, context); - break; + switch(scene) { + case TotpSceneGenerateToken: + totp_scene_generate_token_activate(plugin_state, context); + break; + case TotpSceneAuthentication: + totp_scene_authenticate_activate(plugin_state); + break; + case TotpSceneAddNewToken: + totp_scene_add_new_token_activate(plugin_state, context); + break; + case TotpSceneTokenMenu: + totp_scene_token_menu_activate(plugin_state, context); + break; } plugin_state->current_scene = scene; @@ -28,19 +31,19 @@ void totp_scene_director_activate_scene(PluginState* const plugin_state, Scene s } void totp_scene_director_deactivate_active_scene(PluginState* const plugin_state) { - switch (plugin_state->current_scene) { - case TotpSceneGenerateToken: - totp_scene_generate_token_deactivate(plugin_state); - break; - case TotpSceneAuthentication: - totp_scene_authenticate_deactivate(plugin_state); - break; - case TotpSceneAddNewToken: - totp_scene_add_new_token_deactivate(plugin_state); - break; - case TotpSceneTokenMenu: - totp_scene_token_menu_deactivate(plugin_state); - break; + switch(plugin_state->current_scene) { + case TotpSceneGenerateToken: + totp_scene_generate_token_deactivate(plugin_state); + break; + case TotpSceneAuthentication: + totp_scene_authenticate_deactivate(plugin_state); + break; + case TotpSceneAddNewToken: + totp_scene_add_new_token_deactivate(plugin_state); + break; + case TotpSceneTokenMenu: + totp_scene_token_menu_deactivate(plugin_state); + break; } } @@ -52,19 +55,19 @@ void totp_scene_director_init_scenes(PluginState* const plugin_state) { } void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_state) { - switch (plugin_state->current_scene) { - case TotpSceneGenerateToken: - totp_scene_generate_token_render(canvas, plugin_state); - break; - case TotpSceneAuthentication: - totp_scene_authenticate_render(canvas, plugin_state); - break; - case TotpSceneAddNewToken: - totp_scene_add_new_token_render(canvas, plugin_state); - break; - case TotpSceneTokenMenu: - totp_scene_token_menu_render(canvas, plugin_state); - break; + switch(plugin_state->current_scene) { + case TotpSceneGenerateToken: + totp_scene_generate_token_render(canvas, plugin_state); + break; + case TotpSceneAuthentication: + totp_scene_authenticate_render(canvas, plugin_state); + break; + case TotpSceneAddNewToken: + totp_scene_add_new_token_render(canvas, plugin_state); + break; + case TotpSceneTokenMenu: + totp_scene_token_menu_render(canvas, plugin_state); + break; } } @@ -77,19 +80,19 @@ void totp_scene_director_dispose(PluginState* const plugin_state) { bool totp_scene_director_handle_event(PluginEvent* const event, PluginState* const plugin_state) { bool processing = true; - switch (plugin_state->current_scene) { - case TotpSceneGenerateToken: - processing = totp_scene_generate_token_handle_event(event, plugin_state); - break; - case TotpSceneAuthentication: - processing = totp_scene_authenticate_handle_event(event, plugin_state); - break; - case TotpSceneAddNewToken: - processing = totp_scene_add_new_token_handle_event(event, plugin_state); - break; - case TotpSceneTokenMenu: - processing = totp_scene_token_menu_handle_event(event, plugin_state); - break; + switch(plugin_state->current_scene) { + case TotpSceneGenerateToken: + processing = totp_scene_generate_token_handle_event(event, plugin_state); + break; + case TotpSceneAuthentication: + processing = totp_scene_authenticate_handle_event(event, plugin_state); + break; + case TotpSceneAddNewToken: + processing = totp_scene_add_new_token_handle_event(event, plugin_state); + break; + case TotpSceneTokenMenu: + processing = totp_scene_token_menu_handle_event(event, plugin_state); + break; } return processing; diff --git a/applications/plugins/totp/scenes/scene_director.h b/applications/plugins/totp/scenes/scene_director.h index 0cd9ecfec..3c25afff6 100644 --- a/applications/plugins/totp/scenes/scene_director.h +++ b/applications/plugins/totp/scenes/scene_director.h @@ -5,7 +5,10 @@ #include "../types/plugin_event.h" #include "totp_scenes_enum.h" -void totp_scene_director_activate_scene(PluginState* const plugin_state, Scene scene, const void* context); +void totp_scene_director_activate_scene( + PluginState* const plugin_state, + Scene scene, + const void* context); void totp_scene_director_deactivate_active_scene(PluginState* const plugin_state); void totp_scene_director_init_scenes(PluginState* const plugin_state); void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_state); diff --git a/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c b/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c index 26c5985aa..6e1cd5439 100644 --- a/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c +++ b/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c @@ -10,10 +10,7 @@ #include "../generate_token/totp_scene_generate_token.h" #include "../add_new_token/totp_scene_add_new_token.h" -typedef enum { - AddNewToken, - DeleteToken -} Control; +typedef enum { AddNewToken, DeleteToken } Control; typedef struct { Control selected_control; @@ -24,77 +21,106 @@ void totp_scene_token_menu_init(PluginState* plugin_state) { UNUSED(plugin_state); } -void totp_scene_token_menu_activate(PluginState* plugin_state, const TokenMenuSceneContext* context) { +void totp_scene_token_menu_activate( + PluginState* plugin_state, + const TokenMenuSceneContext* context) { SceneState* scene_state = malloc(sizeof(SceneState)); plugin_state->current_scene_state = scene_state; scene_state->current_token_index = context->current_token_index; } void totp_scene_token_menu_render(Canvas* const canvas, PluginState* plugin_state) { - SceneState* scene_state = (SceneState *)plugin_state->current_scene_state; - ui_control_button_render(canvas, SCREEN_WIDTH_CENTER - 36, 5, 72, 21, "Add new token", scene_state->selected_control == AddNewToken); - ui_control_button_render(canvas, SCREEN_WIDTH_CENTER - 36, 39, 72, 21, "Delete token", scene_state->selected_control == DeleteToken); + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; + ui_control_button_render( + canvas, + SCREEN_WIDTH_CENTER - 36, + 5, + 72, + 21, + "Add new token", + scene_state->selected_control == AddNewToken); + ui_control_button_render( + canvas, + SCREEN_WIDTH_CENTER - 36, + 39, + 72, + 21, + "Delete token", + scene_state->selected_control == DeleteToken); } bool totp_scene_token_menu_handle_event(PluginEvent* const event, PluginState* plugin_state) { - if (event->type == EventTypeKey) { - SceneState* scene_state = (SceneState *)plugin_state->current_scene_state; + if(event->type == EventTypeKey) { + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; if(event->input.type == InputTypePress) { switch(event->input.key) { - case InputKeyUp: - if (scene_state->selected_control > AddNewToken) { - scene_state->selected_control--; - } - break; - case InputKeyDown: - if (scene_state->selected_control < DeleteToken) { - scene_state->selected_control++; - } - break; - case InputKeyRight: - break; - case InputKeyLeft: - break; - case InputKeyOk: - switch (scene_state->selected_control) { - case AddNewToken: { - TokenAddEditSceneContext add_new_token_scene_context = { .current_token_index = scene_state->current_token_index }; - totp_scene_director_activate_scene(plugin_state, TotpSceneAddNewToken, &add_new_token_scene_context); - break; - } - case DeleteToken: { - DialogMessage* message = dialog_message_alloc(); - dialog_message_set_buttons(message, "No", NULL, "Yes"); - dialog_message_set_header(message, "Confirmation", 0, 0, AlignLeft, AlignTop); - dialog_message_set_text(message, "Are you sure want to delete?", SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER, AlignCenter, AlignCenter); - DialogMessageButton dialog_result = dialog_message_show(plugin_state->dialogs, message); - dialog_message_free(message); - if (dialog_result == DialogMessageButtonRight) { - uint8_t i = 0; - - ListNode* list_node = plugin_state->tokens_list; - while (i < scene_state->current_token_index && list_node->next != NULL) { - list_node = list_node->next; - i++; - } - - TokenInfo* tokenInfo = list_node->data; - token_info_free(tokenInfo); - plugin_state->tokens_list = list_remove(plugin_state->tokens_list, list_node); - plugin_state->tokens_count--; - - totp_full_save_config_file(plugin_state); - totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL); - } - break; - } - } - break; - case InputKeyBack: { - GenerateTokenSceneContext generate_scene_context = { .current_token_index = scene_state->current_token_index }; - totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, &generate_scene_context); + case InputKeyUp: + if(scene_state->selected_control > AddNewToken) { + scene_state->selected_control--; + } + break; + case InputKeyDown: + if(scene_state->selected_control < DeleteToken) { + scene_state->selected_control++; + } + break; + case InputKeyRight: + break; + case InputKeyLeft: + break; + case InputKeyOk: + switch(scene_state->selected_control) { + case AddNewToken: { + TokenAddEditSceneContext add_new_token_scene_context = { + .current_token_index = scene_state->current_token_index}; + totp_scene_director_activate_scene( + plugin_state, TotpSceneAddNewToken, &add_new_token_scene_context); break; } + case DeleteToken: { + DialogMessage* message = dialog_message_alloc(); + dialog_message_set_buttons(message, "No", NULL, "Yes"); + dialog_message_set_header(message, "Confirmation", 0, 0, AlignLeft, AlignTop); + dialog_message_set_text( + message, + "Are you sure want to delete?", + SCREEN_WIDTH_CENTER, + SCREEN_HEIGHT_CENTER, + AlignCenter, + AlignCenter); + DialogMessageButton dialog_result = + dialog_message_show(plugin_state->dialogs, message); + dialog_message_free(message); + if(dialog_result == DialogMessageButtonRight) { + uint8_t i = 0; + + ListNode* list_node = plugin_state->tokens_list; + while(i < scene_state->current_token_index && list_node->next != NULL) { + list_node = list_node->next; + i++; + } + + TokenInfo* tokenInfo = list_node->data; + token_info_free(tokenInfo); + plugin_state->tokens_list = + list_remove(plugin_state->tokens_list, list_node); + plugin_state->tokens_count--; + + totp_full_save_config_file(plugin_state); + totp_scene_director_activate_scene( + plugin_state, TotpSceneGenerateToken, NULL); + } + break; + } + } + break; + case InputKeyBack: { + GenerateTokenSceneContext generate_scene_context = { + .current_token_index = scene_state->current_token_index}; + totp_scene_director_activate_scene( + plugin_state, TotpSceneGenerateToken, &generate_scene_context); + break; + } } } } @@ -102,8 +128,8 @@ bool totp_scene_token_menu_handle_event(PluginEvent* const event, PluginState* p } void totp_scene_token_menu_deactivate(PluginState* plugin_state) { - if (plugin_state->current_scene_state == NULL) return; - + if(plugin_state->current_scene_state == NULL) return; + free(plugin_state->current_scene_state); plugin_state->current_scene_state = NULL; } diff --git a/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.h b/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.h index e544e73eb..0b117cb25 100644 --- a/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.h +++ b/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.h @@ -11,7 +11,9 @@ typedef struct { } TokenMenuSceneContext; void totp_scene_token_menu_init(PluginState* plugin_state); -void totp_scene_token_menu_activate(PluginState* plugin_state, const TokenMenuSceneContext* context); +void totp_scene_token_menu_activate( + PluginState* plugin_state, + const TokenMenuSceneContext* context); void totp_scene_token_menu_render(Canvas* const canvas, PluginState* plugin_state); bool totp_scene_token_menu_handle_event(PluginEvent* const event, PluginState* plugin_state); void totp_scene_token_menu_deactivate(PluginState* plugin_state); diff --git a/applications/plugins/totp/services/base32/base32.c b/applications/plugins/totp/services/base32/base32.c index 9c8e30236..ce1a16720 100644 --- a/applications/plugins/totp/services/base32/base32.c +++ b/applications/plugins/totp/services/base32/base32.c @@ -19,77 +19,76 @@ #include "base32.h" -int base32_decode(const uint8_t *encoded, uint8_t *result, int bufSize) { - int buffer = 0; - int bitsLeft = 0; - int count = 0; - for (const uint8_t *ptr = encoded; count < bufSize && *ptr; ++ptr) { - uint8_t ch = *ptr; - if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '-') { - continue; - } - buffer <<= 5; - - // Deal with commonly mistyped characters - if (ch == '0') { - ch = 'O'; - } else if (ch == '1') { - ch = 'L'; - } else if (ch == '8') { - ch = 'B'; - } - - // Look up one base32 digit - if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) { - ch = (ch & 0x1F) - 1; - } else if (ch >= '2' && ch <= '7') { - ch -= '2' - 26; - } else { - return -1; - } - - buffer |= ch; - bitsLeft += 5; - if (bitsLeft >= 8) { - result[count++] = buffer >> (bitsLeft - 8); - bitsLeft -= 8; - } - } - if (count < bufSize) { - result[count] = '\000'; - } - return count; -} - -int base32_encode(const uint8_t *data, int length, uint8_t *result, - int bufSize) { - if (length < 0 || length > (1 << 28)) { - return -1; - } - int count = 0; - if (length > 0) { - int buffer = data[0]; - int next = 1; - int bitsLeft = 8; - while (count < bufSize && (bitsLeft > 0 || next < length)) { - if (bitsLeft < 5) { - if (next < length) { - buffer <<= 8; - buffer |= data[next++] & 0xFF; - bitsLeft += 8; - } else { - int pad = 5 - bitsLeft; - buffer <<= pad; - bitsLeft += pad; +int base32_decode(const uint8_t* encoded, uint8_t* result, int bufSize) { + int buffer = 0; + int bitsLeft = 0; + int count = 0; + for(const uint8_t* ptr = encoded; count < bufSize && *ptr; ++ptr) { + uint8_t ch = *ptr; + if(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '-') { + continue; + } + buffer <<= 5; + + // Deal with commonly mistyped characters + if(ch == '0') { + ch = 'O'; + } else if(ch == '1') { + ch = 'L'; + } else if(ch == '8') { + ch = 'B'; + } + + // Look up one base32 digit + if((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) { + ch = (ch & 0x1F) - 1; + } else if(ch >= '2' && ch <= '7') { + ch -= '2' - 26; + } else { + return -1; + } + + buffer |= ch; + bitsLeft += 5; + if(bitsLeft >= 8) { + result[count++] = buffer >> (bitsLeft - 8); + bitsLeft -= 8; } - } - int index = 0x1F & (buffer >> (bitsLeft - 5)); - bitsLeft -= 5; - result[count++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"[index]; } - } - if (count < bufSize) { - result[count] = '\000'; - } - return count; + if(count < bufSize) { + result[count] = '\000'; + } + return count; +} + +int base32_encode(const uint8_t* data, int length, uint8_t* result, int bufSize) { + if(length < 0 || length > (1 << 28)) { + return -1; + } + int count = 0; + if(length > 0) { + int buffer = data[0]; + int next = 1; + int bitsLeft = 8; + while(count < bufSize && (bitsLeft > 0 || next < length)) { + if(bitsLeft < 5) { + if(next < length) { + buffer <<= 8; + buffer |= data[next++] & 0xFF; + bitsLeft += 8; + } else { + int pad = 5 - bitsLeft; + buffer <<= pad; + bitsLeft += pad; + } + } + int index = 0x1F & (buffer >> (bitsLeft - 5)); + bitsLeft -= 5; + result[count++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"[index]; + } + } + if(count < bufSize) { + result[count] = '\000'; + } + return count; } diff --git a/applications/plugins/totp/services/base32/base32.h b/applications/plugins/totp/services/base32/base32.h index c3e5b3756..db235195c 100644 --- a/applications/plugins/totp/services/base32/base32.h +++ b/applications/plugins/totp/services/base32/base32.h @@ -29,8 +29,7 @@ #include -int base32_decode(const uint8_t *encoded, uint8_t *result, int bufSize) +int base32_decode(const uint8_t* encoded, uint8_t* result, int bufSize) __attribute__((visibility("hidden"))); -int base32_encode(const uint8_t *data, int length, uint8_t *result, - int bufSize) +int base32_encode(const uint8_t* data, int length, uint8_t* result, int bufSize) __attribute__((visibility("hidden"))); diff --git a/applications/plugins/totp/services/config/config.c b/applications/plugins/totp/services/config/config.c index 60264268c..44e6b4bb7 100644 --- a/applications/plugins/totp/services/config/config.c +++ b/applications/plugins/totp/services/config/config.c @@ -11,41 +11,46 @@ #define CONFIG_FILE_BACKUP_PATH CONFIG_FILE_PATH ".backup" uint8_t token_info_get_digits_as_int(TokenInfo* token_info) { - switch (token_info->digits) { - case TOTP_6_DIGITS: return 6; - case TOTP_8_DIGITS: return 8; + switch(token_info->digits) { + case TOTP_6_DIGITS: + return 6; + case TOTP_8_DIGITS: + return 8; } return 6; } void token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits) { - switch (digits) { - case 6: - token_info->digits = TOTP_6_DIGITS; - break; - case 8: - token_info->digits = TOTP_8_DIGITS; - break; + switch(digits) { + case 6: + token_info->digits = TOTP_6_DIGITS; + break; + case 8: + token_info->digits = TOTP_8_DIGITS; + break; } } char* token_info_get_algo_as_cstr(TokenInfo* token_info) { - switch (token_info->algo) { - case SHA1: return TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME; - case SHA256: return TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME; - case SHA512: return TOTP_CONFIG_TOKEN_ALGO_SHA512_NAME; + switch(token_info->algo) { + case SHA1: + return TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME; + case SHA256: + return TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME; + case SHA512: + return TOTP_CONFIG_TOKEN_ALGO_SHA512_NAME; } return NULL; } void token_info_set_algo_from_str(TokenInfo* token_info, FuriString* str) { - if (furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME) == 0) { + if(furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME) == 0) { token_info->algo = SHA1; - } else if (furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME)) { + } else if(furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME)) { token_info->algo = SHA256; - } else if (furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA512_NAME)) { + } else if(furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA512_NAME)) { token_info->algo = SHA512; } } @@ -61,7 +66,7 @@ void totp_close_storage() { FlipperFormat* totp_open_config_file(Storage* storage) { FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); - if (storage_common_stat(storage, CONFIG_FILE_PATH, NULL) == FSE_OK) { + if(storage_common_stat(storage, CONFIG_FILE_PATH, NULL) == FSE_OK) { FURI_LOG_D(LOGGING_TAG, "Config file %s found", CONFIG_FILE_PATH); if(!flipper_format_file_open_existing(fff_data_file, CONFIG_FILE_PATH)) { FURI_LOG_E(LOGGING_TAG, "Error opening existing file %s", CONFIG_FILE_PATH); @@ -70,47 +75,65 @@ FlipperFormat* totp_open_config_file(Storage* storage) { } } else { FURI_LOG_D(LOGGING_TAG, "Config file %s is not found. Will create new.", CONFIG_FILE_PATH); - if (storage_common_stat(storage, CONFIG_FILE_DIRECTORY_PATH, NULL) == FSE_NOT_EXIST) { - FURI_LOG_D(LOGGING_TAG, "Directory %s doesn't exist. Will create new.", CONFIG_FILE_DIRECTORY_PATH); - if (!storage_simply_mkdir(storage, CONFIG_FILE_DIRECTORY_PATH)) { + if(storage_common_stat(storage, CONFIG_FILE_DIRECTORY_PATH, NULL) == FSE_NOT_EXIST) { + FURI_LOG_D( + LOGGING_TAG, + "Directory %s doesn't exist. Will create new.", + CONFIG_FILE_DIRECTORY_PATH); + if(!storage_simply_mkdir(storage, CONFIG_FILE_DIRECTORY_PATH)) { FURI_LOG_E(LOGGING_TAG, "Error creating directory %s", CONFIG_FILE_DIRECTORY_PATH); return NULL; } } - if (!flipper_format_file_open_new(fff_data_file, CONFIG_FILE_PATH)) { + if(!flipper_format_file_open_new(fff_data_file, CONFIG_FILE_PATH)) { totp_close_config_file(fff_data_file); FURI_LOG_E(LOGGING_TAG, "Error creating new file %s", CONFIG_FILE_PATH); return NULL; } - flipper_format_write_header_cstr(fff_data_file, CONFIG_FILE_HEADER, CONFIG_FILE_ACTUAL_VERSION); + flipper_format_write_header_cstr( + fff_data_file, CONFIG_FILE_HEADER, CONFIG_FILE_ACTUAL_VERSION); float tmp_tz = 0; flipper_format_write_comment_cstr(fff_data_file, " "); - flipper_format_write_comment_cstr(fff_data_file, "Timezone offset in hours. Important note: do not put '+' sign for positive values"); + flipper_format_write_comment_cstr( + fff_data_file, + "Timezone offset in hours. Important note: do not put '+' sign for positive values"); flipper_format_write_float(fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &tmp_tz, 1); FuriString* temp_str = furi_string_alloc(); - + flipper_format_write_comment_cstr(fff_data_file, " "); flipper_format_write_comment_cstr(fff_data_file, "=== TOKEN SAMPLE BEGIN ==="); flipper_format_write_comment_cstr(fff_data_file, " "); - flipper_format_write_comment_cstr(fff_data_file, "# Token name which will be visible in the UI."); + flipper_format_write_comment_cstr( + fff_data_file, "# Token name which will be visible in the UI."); furi_string_printf(temp_str, "%s: Sample token name", TOTP_CONFIG_KEY_TOKEN_NAME); flipper_format_write_comment(fff_data_file, temp_str); flipper_format_write_comment_cstr(fff_data_file, " "); - flipper_format_write_comment_cstr(fff_data_file, "# Plain token secret without spaces, dashes and etc, just pure alpha-numeric characters. Important note: plain token will be encrypted and replaced by TOTP app"); + flipper_format_write_comment_cstr( + fff_data_file, + "# Plain token secret without spaces, dashes and etc, just pure alpha-numeric characters. Important note: plain token will be encrypted and replaced by TOTP app"); furi_string_printf(temp_str, "%s: plaintokensecret", TOTP_CONFIG_KEY_TOKEN_SECRET); flipper_format_write_comment(fff_data_file, temp_str); flipper_format_write_comment_cstr(fff_data_file, " "); - furi_string_printf(temp_str, " # Token hashing algorithm to use during code generation. Supported options are %s, %s and %s. If you are not use which one to use - use %s", TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME, TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME, TOTP_CONFIG_TOKEN_ALGO_SHA512_NAME, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME); + furi_string_printf( + temp_str, + " # Token hashing algorithm to use during code generation. Supported options are %s, %s and %s. If you are not use which one to use - use %s", + TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME, + TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME, + TOTP_CONFIG_TOKEN_ALGO_SHA512_NAME, + TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME); flipper_format_write_comment(fff_data_file, temp_str); - furi_string_printf(temp_str, "%s: %s", TOTP_CONFIG_KEY_TOKEN_ALGO, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME); + furi_string_printf( + temp_str, "%s: %s", TOTP_CONFIG_KEY_TOKEN_ALGO, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME); flipper_format_write_comment(fff_data_file, temp_str); flipper_format_write_comment_cstr(fff_data_file, " "); - flipper_format_write_comment_cstr(fff_data_file, "# How many digits there should be in generated code. Available options are 6 and 8. Majority websites requires 6 digits code, however some rare websites wants to get 8 digits code. If you are not sure which one to use - use 6"); + flipper_format_write_comment_cstr( + fff_data_file, + "# How many digits there should be in generated code. Available options are 6 and 8. Majority websites requires 6 digits code, however some rare websites wants to get 8 digits code. If you are not sure which one to use - use 6"); furi_string_printf(temp_str, "%s: 6", TOTP_CONFIG_KEY_TOKEN_DIGITS); flipper_format_write_comment(fff_data_file, temp_str); flipper_format_write_comment_cstr(fff_data_file, " "); @@ -125,14 +148,16 @@ FlipperFormat* totp_open_config_file(Storage* storage) { return NULL; } } - + return fff_data_file; } void totp_config_file_save_new_token(FlipperFormat* file, TokenInfo* token_info) { flipper_format_write_string_cstr(file, TOTP_CONFIG_KEY_TOKEN_NAME, token_info->name); - flipper_format_write_hex(file, TOTP_CONFIG_KEY_TOKEN_SECRET, token_info->token, token_info->token_length); - flipper_format_write_string_cstr(file, TOTP_CONFIG_KEY_TOKEN_ALGO, token_info_get_algo_as_cstr(token_info)); + flipper_format_write_hex( + file, TOTP_CONFIG_KEY_TOKEN_SECRET, token_info->token, token_info->token_length); + flipper_format_write_string_cstr( + file, TOTP_CONFIG_KEY_TOKEN_ALGO, token_info_get_algo_as_cstr(token_info)); uint32_t digits_count_as_uint32 = token_info_get_digits_as_int(token_info); flipper_format_write_uint32(file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &digits_count_as_uint32, 1); } @@ -142,16 +167,23 @@ void totp_full_save_config_file(PluginState* const plugin_state) { FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); flipper_format_file_open_always(fff_data_file, CONFIG_FILE_PATH); - flipper_format_write_header_cstr(fff_data_file, CONFIG_FILE_HEADER, CONFIG_FILE_ACTUAL_VERSION); - flipper_format_write_hex(fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE); - flipper_format_write_hex(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, plugin_state->crypto_verify_data, plugin_state->crypto_verify_data_length); - flipper_format_write_float(fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1); + flipper_format_write_header_cstr( + fff_data_file, CONFIG_FILE_HEADER, CONFIG_FILE_ACTUAL_VERSION); + flipper_format_write_hex( + fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE); + flipper_format_write_hex( + fff_data_file, + TOTP_CONFIG_KEY_CRYPTO_VERIFY, + plugin_state->crypto_verify_data, + plugin_state->crypto_verify_data_length); + flipper_format_write_float( + fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1); ListNode* node = plugin_state->tokens_list; - while (node != NULL) { + while(node != NULL) { TokenInfo* token_info = node->data; totp_config_file_save_new_token(fff_data_file, token_info); node = node->next; - } + } totp_close_config_file(fff_data_file); totp_close_storage(); @@ -172,22 +204,26 @@ void totp_config_file_load_base(PluginState* const plugin_state) { return; } - if (file_version < CONFIG_FILE_ACTUAL_VERSION) { - FURI_LOG_I(LOGGING_TAG, "Obsolete config file version detected. Current version: %d; Actual version: %d", file_version, CONFIG_FILE_ACTUAL_VERSION); + if(file_version < CONFIG_FILE_ACTUAL_VERSION) { + FURI_LOG_I( + LOGGING_TAG, + "Obsolete config file version detected. Current version: %ld; Actual version: %d", + file_version, + CONFIG_FILE_ACTUAL_VERSION); totp_close_config_file(fff_data_file); - if (storage_common_stat(storage, CONFIG_FILE_BACKUP_PATH, NULL) == FSE_OK) { + if(storage_common_stat(storage, CONFIG_FILE_BACKUP_PATH, NULL) == FSE_OK) { storage_simply_remove(storage, CONFIG_FILE_BACKUP_PATH); } - - if (storage_common_copy(storage, CONFIG_FILE_PATH, CONFIG_FILE_BACKUP_PATH) == FSE_OK) { + + if(storage_common_copy(storage, CONFIG_FILE_PATH, CONFIG_FILE_BACKUP_PATH) == FSE_OK) { FURI_LOG_I(LOGGING_TAG, "Took config file backup to %s", CONFIG_FILE_BACKUP_PATH); fff_data_file = totp_open_config_file(storage); FlipperFormat* fff_backup_data_file = flipper_format_file_alloc(storage); flipper_format_file_open_existing(fff_backup_data_file, CONFIG_FILE_BACKUP_PATH); - - if (file_version == 1) { - if (totp_config_migrate_v1_to_v2(fff_data_file, fff_backup_data_file)) { + + if(file_version == 1) { + if(totp_config_migrate_v1_to_v2(fff_data_file, fff_backup_data_file)) { FURI_LOG_I(LOGGING_TAG, "Applied migration from v1 to v2"); } else { FURI_LOG_W(LOGGING_TAG, "An error occurred during migration from v1 to v2"); @@ -198,21 +234,30 @@ void totp_config_file_load_base(PluginState* const plugin_state) { flipper_format_free(fff_backup_data_file); flipper_format_rewind(fff_data_file); } else { - FURI_LOG_E(LOGGING_TAG, "An error occurred during taking backup of %s into %s before migration", CONFIG_FILE_PATH, CONFIG_FILE_BACKUP_PATH); + FURI_LOG_E( + LOGGING_TAG, + "An error occurred during taking backup of %s into %s before migration", + CONFIG_FILE_PATH, + CONFIG_FILE_BACKUP_PATH); } } - if (!flipper_format_read_hex(fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE)) { + if(!flipper_format_read_hex( + fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE)) { FURI_LOG_D(LOGGING_TAG, "Missing base IV"); } flipper_format_rewind(fff_data_file); uint32_t crypto_size; - if (flipper_format_get_value_count(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, &crypto_size)) { + if(flipper_format_get_value_count(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, &crypto_size)) { plugin_state->crypto_verify_data = malloc(sizeof(uint8_t) * crypto_size); plugin_state->crypto_verify_data_length = crypto_size; - if (!flipper_format_read_hex(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, plugin_state->crypto_verify_data, crypto_size)) { + if(!flipper_format_read_hex( + fff_data_file, + TOTP_CONFIG_KEY_CRYPTO_VERIFY, + plugin_state->crypto_verify_data, + crypto_size)) { FURI_LOG_D(LOGGING_TAG, "Missing crypto verify token"); free(plugin_state->crypto_verify_data); plugin_state->crypto_verify_data = NULL; @@ -221,7 +266,8 @@ void totp_config_file_load_base(PluginState* const plugin_state) { flipper_format_rewind(fff_data_file); - if (!flipper_format_read_float(fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) { + if(!flipper_format_read_float( + fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) { plugin_state->timezone_offset = 0; FURI_LOG_D(LOGGING_TAG, "Missing timezone offset information, defaulting to 0"); } @@ -247,25 +293,26 @@ void totp_config_file_load_tokens(PluginState* const plugin_state) { uint8_t index = 0; bool has_any_plain_secret = false; - while (true) { - if (!flipper_format_read_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_NAME, temp_str)) { + while(true) { + if(!flipper_format_read_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_NAME, temp_str)) { break; } - + TokenInfo* tokenInfo = token_info_alloc(); const char* temp_cstr = furi_string_get_cstr(temp_str); - tokenInfo->name = (char *)malloc(strlen(temp_cstr) + 1); + tokenInfo->name = (char*)malloc(strlen(temp_cstr) + 1); strcpy(tokenInfo->name, temp_cstr); uint32_t secret_bytes_count; - if (!flipper_format_get_value_count(fff_data_file, TOTP_CONFIG_KEY_TOKEN_SECRET, &secret_bytes_count)) { + if(!flipper_format_get_value_count( + fff_data_file, TOTP_CONFIG_KEY_TOKEN_SECRET, &secret_bytes_count)) { token_info_free(tokenInfo); continue; } - if (secret_bytes_count == 1) { // Plain secret key - if (!flipper_format_read_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_SECRET, temp_str)) { + if(secret_bytes_count == 1) { // Plain secret key + if(!flipper_format_read_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_SECRET, temp_str)) { token_info_free(tokenInfo); continue; } @@ -277,20 +324,25 @@ void totp_config_file_load_tokens(PluginState* const plugin_state) { } else { // encrypted tokenInfo->token_length = secret_bytes_count; tokenInfo->token = malloc(tokenInfo->token_length); - if (!flipper_format_read_hex(fff_data_file, TOTP_CONFIG_KEY_TOKEN_SECRET, tokenInfo->token, tokenInfo->token_length)) { + if(!flipper_format_read_hex( + fff_data_file, + TOTP_CONFIG_KEY_TOKEN_SECRET, + tokenInfo->token, + tokenInfo->token_length)) { token_info_free(tokenInfo); continue; } } - if (!flipper_format_read_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, temp_str)) { + if(!flipper_format_read_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, temp_str)) { token_info_free(tokenInfo); continue; } - + token_info_set_algo_from_str(tokenInfo, temp_str); - if (!flipper_format_read_uint32(fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &temp_data32, 1)) { + if(!flipper_format_read_uint32( + fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &temp_data32, 1)) { token_info_free(tokenInfo); continue; } @@ -299,7 +351,7 @@ void totp_config_file_load_tokens(PluginState* const plugin_state) { FURI_LOG_D(LOGGING_TAG, "Found token \"%s\"", tokenInfo->name); - if (plugin_state->tokens_list == NULL) { + if(plugin_state->tokens_list == NULL) { plugin_state->tokens_list = list_init_head(tokenInfo); } else { list_add(plugin_state->tokens_list, tokenInfo); @@ -317,13 +369,13 @@ void totp_config_file_load_tokens(PluginState* const plugin_state) { totp_close_config_file(fff_data_file); totp_close_storage(); - if (has_any_plain_secret) { + if(has_any_plain_secret) { totp_full_save_config_file(plugin_state); } } void totp_close_config_file(FlipperFormat* file) { - if (file == NULL) return; + if(file == NULL) return; flipper_format_file_close(file); flipper_format_free(file); } diff --git a/applications/plugins/totp/services/config/migrations/config_migration_v1_to_v2.c b/applications/plugins/totp/services/config/migrations/config_migration_v1_to_v2.c index ad1b8d795..1ed8c37f0 100644 --- a/applications/plugins/totp/services/config/migrations/config_migration_v1_to_v2.c +++ b/applications/plugins/totp/services/config/migrations/config_migration_v1_to_v2.c @@ -4,25 +4,28 @@ #define NEW_VERSION 2 -bool totp_config_migrate_v1_to_v2(FlipperFormat* fff_data_file, FlipperFormat* fff_backup_data_file) { +bool totp_config_migrate_v1_to_v2( + FlipperFormat* fff_data_file, + FlipperFormat* fff_backup_data_file) { flipper_format_write_header_cstr(fff_data_file, CONFIG_FILE_HEADER, NEW_VERSION); FuriString* temp_str = furi_string_alloc(); - if (flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_BASE_IV, temp_str)) { + if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_BASE_IV, temp_str)) { flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_BASE_IV, temp_str); } - if (flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, temp_str)) { + if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, temp_str)) { flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, temp_str); } - if (flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_TIMEZONE, temp_str)) { + if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_TIMEZONE, temp_str)) { flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, temp_str); } - while (true) { - if (!flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_NAME, temp_str)) { + while(true) { + if(!flipper_format_read_string( + fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_NAME, temp_str)) { break; } @@ -30,10 +33,12 @@ bool totp_config_migrate_v1_to_v2(FlipperFormat* fff_data_file, FlipperFormat* f flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_SECRET, temp_str); flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_SECRET, temp_str); - - flipper_format_write_string_cstr(fff_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME); + + flipper_format_write_string_cstr( + fff_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME); uint32_t default_digits = 6; - flipper_format_write_uint32(fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &default_digits, 1); + flipper_format_write_uint32( + fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &default_digits, 1); } furi_string_free(temp_str); diff --git a/applications/plugins/totp/services/config/migrations/config_migration_v1_to_v2.h b/applications/plugins/totp/services/config/migrations/config_migration_v1_to_v2.h index 58b7f08d7..99470f04d 100644 --- a/applications/plugins/totp/services/config/migrations/config_migration_v1_to_v2.h +++ b/applications/plugins/totp/services/config/migrations/config_migration_v1_to_v2.h @@ -2,4 +2,6 @@ #include -bool totp_config_migrate_v1_to_v2(FlipperFormat* fff_data_file, FlipperFormat* fff_backup_data_file); +bool totp_config_migrate_v1_to_v2( + FlipperFormat* fff_data_file, + FlipperFormat* fff_backup_data_file); diff --git a/applications/plugins/totp/services/hmac/byteswap.c b/applications/plugins/totp/services/hmac/byteswap.c index 2a649fe64..e922deec0 100644 --- a/applications/plugins/totp/services/hmac/byteswap.c +++ b/applications/plugins/totp/services/hmac/byteswap.c @@ -1,14 +1,12 @@ #include "byteswap.h" -uint32_t swap_uint32( uint32_t val ) -{ - val = ((val << 8) & 0xFF00FF00 ) | ((val >> 8) & 0xFF00FF ); +uint32_t swap_uint32(uint32_t val) { + val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF); return (val << 16) | (val >> 16); } -uint64_t swap_uint64( uint64_t val ) -{ - val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL ); - val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL ); +uint64_t swap_uint64(uint64_t val) { + val = ((val << 8) & 0xFF00FF00FF00FF00ULL) | ((val >> 8) & 0x00FF00FF00FF00FFULL); + val = ((val << 16) & 0xFFFF0000FFFF0000ULL) | ((val >> 16) & 0x0000FFFF0000FFFFULL); return (val << 32) | (val >> 32); } diff --git a/applications/plugins/totp/services/hmac/byteswap.h b/applications/plugins/totp/services/hmac/byteswap.h index 42a4abf22..6e88d7c05 100644 --- a/applications/plugins/totp/services/hmac/byteswap.h +++ b/applications/plugins/totp/services/hmac/byteswap.h @@ -2,5 +2,5 @@ #include -uint32_t swap_uint32( uint32_t val ); -uint64_t swap_uint64( uint64_t val ); +uint32_t swap_uint32(uint32_t val); +uint64_t swap_uint64(uint64_t val); \ No newline at end of file diff --git a/applications/plugins/totp/services/hmac/hmac_common.h b/applications/plugins/totp/services/hmac/hmac_common.h new file mode 100644 index 000000000..9c5b5828f --- /dev/null +++ b/applications/plugins/totp/services/hmac/hmac_common.h @@ -0,0 +1,64 @@ +#include +#include "sha256.h" +#include "memxor.h" + +#define IPAD 0x36 +#define OPAD 0x5c + +/* Concatenate two preprocessor tokens. */ +#define _GLHMAC_CONCAT_(prefix, suffix) prefix##suffix +#define _GLHMAC_CONCAT(prefix, suffix) _GLHMAC_CONCAT_(prefix, suffix) + +#if GL_HMAC_NAME == 5 +#define HMAC_ALG md5 +#else +#define HMAC_ALG _GLHMAC_CONCAT(sha, GL_HMAC_NAME) +#endif + +#define GL_HMAC_CTX _GLHMAC_CONCAT(HMAC_ALG, _ctx) +#define GL_HMAC_FN _GLHMAC_CONCAT(hmac_, HMAC_ALG) +#define GL_HMAC_FN_INIT _GLHMAC_CONCAT(HMAC_ALG, _init_ctx) +#define GL_HMAC_FN_BLOC _GLHMAC_CONCAT(HMAC_ALG, _process_block) +#define GL_HMAC_FN_PROC _GLHMAC_CONCAT(HMAC_ALG, _process_bytes) +#define GL_HMAC_FN_FINI _GLHMAC_CONCAT(HMAC_ALG, _finish_ctx) + +static void + hmac_hash(const void* key, size_t keylen, const void* in, size_t inlen, int pad, void* resbuf) { + struct GL_HMAC_CTX hmac_ctx; + char block[GL_HMAC_BLOCKSIZE]; + + memset(block, pad, sizeof block); + memxor(block, key, keylen); + + GL_HMAC_FN_INIT(&hmac_ctx); + GL_HMAC_FN_BLOC(block, sizeof block, &hmac_ctx); + GL_HMAC_FN_PROC(in, inlen, &hmac_ctx); + GL_HMAC_FN_FINI(&hmac_ctx, resbuf); +} + +int GL_HMAC_FN(const void* key, size_t keylen, const void* in, size_t inlen, void* resbuf) { + char optkeybuf[GL_HMAC_HASHSIZE]; + char innerhash[GL_HMAC_HASHSIZE]; + + /* Ensure key size is <= block size. */ + if(keylen > GL_HMAC_BLOCKSIZE) { + struct GL_HMAC_CTX keyhash; + + GL_HMAC_FN_INIT(&keyhash); + GL_HMAC_FN_PROC(key, keylen, &keyhash); + GL_HMAC_FN_FINI(&keyhash, optkeybuf); + + key = optkeybuf; + /* zero padding of the key to the block size + is implicit in the memxor. */ + keylen = sizeof optkeybuf; + } + + /* Compute INNERHASH from KEY and IN. */ + hmac_hash(key, keylen, in, inlen, IPAD, innerhash); + + /* Compute result from KEY and INNERHASH. */ + hmac_hash(key, keylen, innerhash, sizeof innerhash, OPAD, resbuf); + + return 0; +} diff --git a/applications/plugins/totp/services/hmac/hmac_sha1.c b/applications/plugins/totp/services/hmac/hmac_sha1.c new file mode 100644 index 000000000..a597ecb3a --- /dev/null +++ b/applications/plugins/totp/services/hmac/hmac_sha1.c @@ -0,0 +1,24 @@ +/* hmac_sha1.c -- hashed message authentication codes + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include "hmac_sha1.h" + +#include "sha1.h" + +#define GL_HMAC_NAME 1 +#define GL_HMAC_BLOCKSIZE 64 +#define GL_HMAC_HASHSIZE 20 +#include "hmac_common.h" diff --git a/applications/plugins/totp/services/hmac/hmac_sha1.h b/applications/plugins/totp/services/hmac/hmac_sha1.h new file mode 100644 index 000000000..25ff2f648 --- /dev/null +++ b/applications/plugins/totp/services/hmac/hmac_sha1.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +#define HMAC_SHA1_RESULT_SIZE 20 + +/* Compute Hashed Message Authentication Code with SHA-1, over BUFFER + data of BUFLEN bytes using the KEY of KEYLEN bytes, writing the + output to pre-allocated 20 byte minimum RESBUF buffer. Return 0 on + success. */ +int hmac_sha1(const void* key, size_t keylen, const void* in, size_t inlen, void* restrict resbuf); diff --git a/applications/plugins/totp/services/hmac/hmac_sha256.c b/applications/plugins/totp/services/hmac/hmac_sha256.c new file mode 100644 index 000000000..dbf027101 --- /dev/null +++ b/applications/plugins/totp/services/hmac/hmac_sha256.c @@ -0,0 +1,23 @@ +/* hmac_sha256.c -- hashed message authentication codes + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include "hmac_sha256.h" + +#define GL_HMAC_NAME 256 +#define GL_HMAC_BLOCKSIZE 64 +#define GL_HMAC_HASHSIZE 32 + +#include "hmac_common.h" diff --git a/applications/plugins/totp/services/hmac/hmac_sha256.h b/applications/plugins/totp/services/hmac/hmac_sha256.h new file mode 100644 index 000000000..9aeaf10d6 --- /dev/null +++ b/applications/plugins/totp/services/hmac/hmac_sha256.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +#define HMAC_SHA256_RESULT_SIZE 32 + +/* Compute Hashed Message Authentication Code with SHA-256, over BUFFER + data of BUFLEN bytes using the KEY of KEYLEN bytes, writing the + output to pre-allocated 32 byte minimum RESBUF buffer. Return 0 on + success. */ +int hmac_sha256(const void* key, size_t keylen, const void* in, size_t inlen, void* restrict resbuf); diff --git a/applications/plugins/totp/services/hmac/hmac_sha512.c b/applications/plugins/totp/services/hmac/hmac_sha512.c new file mode 100644 index 000000000..eafe80fd2 --- /dev/null +++ b/applications/plugins/totp/services/hmac/hmac_sha512.c @@ -0,0 +1,24 @@ +/* hmac_sha512.c -- hashed message authentication codes + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include "hmac_sha512.h" + +#include "sha512.h" + +#define GL_HMAC_NAME 512 +#define GL_HMAC_BLOCKSIZE 128 +#define GL_HMAC_HASHSIZE 64 +#include "hmac_common.h" diff --git a/applications/plugins/totp/services/hmac/hmac_sha512.h b/applications/plugins/totp/services/hmac/hmac_sha512.h new file mode 100644 index 000000000..712b7f4a0 --- /dev/null +++ b/applications/plugins/totp/services/hmac/hmac_sha512.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +#define HMAC_SHA512_RESULT_SIZE 64 + +/* Compute Hashed Message Authentication Code with SHA-512, over BUFFER + data of BUFLEN bytes using the KEY of KEYLEN bytes, writing the + output to pre-allocated 64 byte minimum RESBUF buffer. Return 0 on + success. */ +int hmac_sha512(const void* key, size_t keylen, const void* in, size_t inlen, void* restrict resbuf); diff --git a/applications/plugins/totp/services/hmac/memxor.c b/applications/plugins/totp/services/hmac/memxor.c index 60fc7529a..6824ea33b 100644 --- a/applications/plugins/totp/services/hmac/memxor.c +++ b/applications/plugins/totp/services/hmac/memxor.c @@ -22,13 +22,11 @@ #include "memxor.h" -void* memxor (void */*restrict*/ dest, const void */*restrict*/ src, size_t n) -{ - char const *s = (char const*)src; - char *d = (char*)dest; +void* memxor(void* /*restrict*/ dest, const void* /*restrict*/ src, size_t n) { + char const* s = (char const*)src; + char* d = (char*)dest; - for (; n > 0; n--) - *d++ ^= *s++; + for(; n > 0; n--) *d++ ^= *s++; - return dest; + return dest; } diff --git a/applications/plugins/totp/services/hmac/memxor.h b/applications/plugins/totp/services/hmac/memxor.h index 20f3e9817..71aa604c8 100644 --- a/applications/plugins/totp/services/hmac/memxor.h +++ b/applications/plugins/totp/services/hmac/memxor.h @@ -25,4 +25,4 @@ /* Compute binary exclusive OR of memory areas DEST and SRC, putting the result in DEST, of length N bytes. Returns a pointer to DEST. */ -void *memxor (void */*restrict*/ dest, const void */*restrict*/ src, size_t n); +void* memxor(void* /*restrict*/ dest, const void* /*restrict*/ src, size_t n); diff --git a/applications/plugins/totp/services/hmac/sha1.c b/applications/plugins/totp/services/hmac/sha1.c index 5913271da..5679e489d 100644 --- a/applications/plugins/totp/services/hmac/sha1.c +++ b/applications/plugins/totp/services/hmac/sha1.c @@ -23,7 +23,7 @@ /* Specification. */ #if HAVE_OPENSSL_SHA1 -# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#define GL_OPENSSL_INLINE _GL_EXTERN_INLINE #endif #include "sha1.h" @@ -31,170 +31,148 @@ #include #ifdef WORDS_BIGENDIAN -# define SWAP(n) (n) +#define SWAP(n) (n) #else #include "byteswap.h" -# define SWAP(n) swap_uint32(n) +#define SWAP(n) swap_uint32(n) #endif -#if ! HAVE_OPENSSL_SHA1 +#if !HAVE_OPENSSL_SHA1 /* This array contains the bytes used to pad the buffer to the next 64-byte boundary. (RFC 1321, 3.1: Step 1) */ -static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; - +static const unsigned char fillbuf[64] = {0x80, 0 /* , 0, 0, ... */}; /* Take a pointer to a 160 bit block of data (five 32 bit ints) and initialize it to the start constants of the SHA1 algorithm. This must be called before using hash in the call to sha1_hash. */ -void -sha1_init_ctx (struct sha1_ctx *ctx) -{ - ctx->A = 0x67452301; - ctx->B = 0xefcdab89; - ctx->C = 0x98badcfe; - ctx->D = 0x10325476; - ctx->E = 0xc3d2e1f0; +void sha1_init_ctx(struct sha1_ctx* ctx) { + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + ctx->E = 0xc3d2e1f0; - ctx->total[0] = ctx->total[1] = 0; - ctx->buflen = 0; + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; } /* Copy the 4 byte value from v into the memory location pointed to by *cp, If your architecture allows unaligned access this is equivalent to * (uint32_t *) cp = v */ -static void -set_uint32 (char *cp, uint32_t v) -{ - memcpy (cp, &v, sizeof v); +static void set_uint32(char* cp, uint32_t v) { + memcpy(cp, &v, sizeof v); } /* Put result from CTX in first 20 bytes following RESBUF. The result must be in little endian byte order. */ -void * -sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf) -{ - char *r = resbuf; - set_uint32 (r + 0 * sizeof ctx->A, SWAP (ctx->A)); - set_uint32 (r + 1 * sizeof ctx->B, SWAP (ctx->B)); - set_uint32 (r + 2 * sizeof ctx->C, SWAP (ctx->C)); - set_uint32 (r + 3 * sizeof ctx->D, SWAP (ctx->D)); - set_uint32 (r + 4 * sizeof ctx->E, SWAP (ctx->E)); +void* sha1_read_ctx(const struct sha1_ctx* ctx, void* resbuf) { + char* r = resbuf; + set_uint32(r + 0 * sizeof ctx->A, SWAP(ctx->A)); + set_uint32(r + 1 * sizeof ctx->B, SWAP(ctx->B)); + set_uint32(r + 2 * sizeof ctx->C, SWAP(ctx->C)); + set_uint32(r + 3 * sizeof ctx->D, SWAP(ctx->D)); + set_uint32(r + 4 * sizeof ctx->E, SWAP(ctx->E)); - return resbuf; + return resbuf; } /* Process the remaining bytes in the internal buffer and the usual prolog according to the standard and write the result to RESBUF. */ -void * -sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf) -{ - /* Take yet unprocessed bytes into account. */ - uint32_t bytes = ctx->buflen; - size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4; +void* sha1_finish_ctx(struct sha1_ctx* ctx, void* resbuf) { + /* Take yet unprocessed bytes into account. */ + uint32_t bytes = ctx->buflen; + size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4; - /* Now count remaining bytes. */ - ctx->total[0] += bytes; - if (ctx->total[0] < bytes) - ++ctx->total[1]; + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if(ctx->total[0] < bytes) ++ctx->total[1]; - /* Put the 64-bit file length in *bits* at the end of the buffer. */ - ctx->buffer[size - 2] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); - ctx->buffer[size - 1] = SWAP (ctx->total[0] << 3); + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + ctx->buffer[size - 2] = SWAP((ctx->total[1] << 3) | (ctx->total[0] >> 29)); + ctx->buffer[size - 1] = SWAP(ctx->total[0] << 3); - memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes); + memcpy(&((char*)ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes); - /* Process last bytes. */ - sha1_process_block (ctx->buffer, size * 4, ctx); + /* Process last bytes. */ + sha1_process_block(ctx->buffer, size * 4, ctx); - return sha1_read_ctx (ctx, resbuf); + return sha1_read_ctx(ctx, resbuf); } /* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -void * -sha1_buffer (const char *buffer, size_t len, void *resblock) -{ - struct sha1_ctx ctx; +void* sha1_buffer(const char* buffer, size_t len, void* resblock) { + struct sha1_ctx ctx; - /* Initialize the computation context. */ - sha1_init_ctx (&ctx); + /* Initialize the computation context. */ + sha1_init_ctx(&ctx); - /* Process whole buffer but last len % 64 bytes. */ - sha1_process_bytes (buffer, len, &ctx); + /* Process whole buffer but last len % 64 bytes. */ + sha1_process_bytes(buffer, len, &ctx); - /* Put result in desired memory area. */ - return sha1_finish_ctx (&ctx, resblock); + /* Put result in desired memory area. */ + return sha1_finish_ctx(&ctx, resblock); } -void -sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) -{ - /* When we already have some bits in our internal buffer concatenate +void sha1_process_bytes(const void* buffer, size_t len, struct sha1_ctx* ctx) { + /* When we already have some bits in our internal buffer concatenate both inputs first. */ - if (ctx->buflen != 0) - { - size_t left_over = ctx->buflen; - size_t add = 128 - left_over > len ? len : 128 - left_over; + if(ctx->buflen != 0) { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; - memcpy (&((char *) ctx->buffer)[left_over], buffer, add); - ctx->buflen += add; + memcpy(&((char*)ctx->buffer)[left_over], buffer, add); + ctx->buflen += add; - if (ctx->buflen > 64) - { - sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + if(ctx->buflen > 64) { + sha1_process_block(ctx->buffer, ctx->buflen & ~63, ctx); - ctx->buflen &= 63; - /* The regions in the following copy operation cannot overlap, + ctx->buflen &= 63; + /* The regions in the following copy operation cannot overlap, because ctx->buflen < 64 ≤ (left_over + add) & ~63. */ - memcpy (ctx->buffer, - &((char *) ctx->buffer)[(left_over + add) & ~63], - ctx->buflen); + memcpy(ctx->buffer, &((char*)ctx->buffer)[(left_over + add) & ~63], ctx->buflen); } - buffer = (const char *) buffer + add; - len -= add; + buffer = (const char*)buffer + add; + len -= add; } - /* Process available complete blocks. */ - if (len >= 64) - { + /* Process available complete blocks. */ + if(len >= 64) { #if !(_STRING_ARCH_unaligned || _STRING_INLINE_unaligned) -# define UNALIGNED_P(p) ((uintptr_t) (p) % sizeof (uint32_t) != 0) - if (UNALIGNED_P (buffer)) - while (len > 64) - { - sha1_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); - buffer = (const char *) buffer + 64; - len -= 64; - } - else +#define UNALIGNED_P(p) ((uintptr_t)(p) % sizeof(uint32_t) != 0) + if(UNALIGNED_P(buffer)) + while(len > 64) { + sha1_process_block(memcpy(ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char*)buffer + 64; + len -= 64; + } + else #endif { - sha1_process_block (buffer, len & ~63, ctx); - buffer = (const char *) buffer + (len & ~63); - len &= 63; + sha1_process_block(buffer, len & ~63, ctx); + buffer = (const char*)buffer + (len & ~63); + len &= 63; } } - /* Move remaining bytes in internal buffer. */ - if (len > 0) - { - size_t left_over = ctx->buflen; + /* Move remaining bytes in internal buffer. */ + if(len > 0) { + size_t left_over = ctx->buflen; - memcpy (&((char *) ctx->buffer)[left_over], buffer, len); - left_over += len; - if (left_over >= 64) - { - sha1_process_block (ctx->buffer, 64, ctx); - left_over -= 64; - /* The regions in the following copy operation cannot overlap, + memcpy(&((char*)ctx->buffer)[left_over], buffer, len); + left_over += len; + if(left_over >= 64) { + sha1_process_block(ctx->buffer, 64, ctx); + left_over -= 64; + /* The regions in the following copy operation cannot overlap, because left_over ≤ 64. */ - memcpy (ctx->buffer, &ctx->buffer[16], left_over); + memcpy(ctx->buffer, &ctx->buffer[16], left_over); } - ctx->buflen = left_over; + ctx->buflen = left_over; } } @@ -207,144 +185,139 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) #define K4 0xca62c1d6 /* Round functions. Note that F2 is the same as F4. */ -#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) ) -#define F2(B,C,D) (B ^ C ^ D) -#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) ) -#define F4(B,C,D) (B ^ C ^ D) +#define F1(B, C, D) (D ^ (B & (C ^ D))) +#define F2(B, C, D) (B ^ C ^ D) +#define F3(B, C, D) ((B & C) | (D & (B | C))) +#define F4(B, C, D) (B ^ C ^ D) /* Process LEN bytes of BUFFER, accumulating context into CTX. It is assumed that LEN % 64 == 0. Most of this code comes from GnuPG's cipher/sha1.c. */ -void -sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx) -{ - const uint32_t *words = buffer; - size_t nwords = len / sizeof (uint32_t); - const uint32_t *endp = words + nwords; - uint32_t x[16]; - uint32_t a = ctx->A; - uint32_t b = ctx->B; - uint32_t c = ctx->C; - uint32_t d = ctx->D; - uint32_t e = ctx->E; - uint32_t lolen = len; +void sha1_process_block(const void* buffer, size_t len, struct sha1_ctx* ctx) { + const uint32_t* words = buffer; + size_t nwords = len / sizeof(uint32_t); + const uint32_t* endp = words + nwords; + uint32_t x[16]; + uint32_t a = ctx->A; + uint32_t b = ctx->B; + uint32_t c = ctx->C; + uint32_t d = ctx->D; + uint32_t e = ctx->E; + uint32_t lolen = len; - /* First increment the byte count. RFC 1321 specifies the possible + /* First increment the byte count. RFC 1321 specifies the possible length of the file up to 2^64 bits. Here we only compute the number of bytes. Do a double word increment. */ - ctx->total[0] += lolen; - ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen); + ctx->total[0] += lolen; + ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen); -#define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n)))) +#define rol(x, n) (((x) << (n)) | ((uint32_t)(x) >> (32 - (n)))) -#define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \ - ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \ - , (x[I&0x0f] = rol(tm, 1)) ) +#define M(I) \ + (tm = x[I & 0x0f] ^ x[(I - 14) & 0x0f] ^ x[(I - 8) & 0x0f] ^ x[(I - 3) & 0x0f], \ + (x[I & 0x0f] = rol(tm, 1))) -#define R(A,B,C,D,E,F,K,M) do { E += rol( A, 5 ) \ - + F( B, C, D ) \ - + K \ - + M; \ - B = rol( B, 30 ); \ - } while(0) +#define R(A, B, C, D, E, F, K, M) \ + do { \ + E += rol(A, 5) + F(B, C, D) + K + M; \ + B = rol(B, 30); \ + } while(0) - while (words < endp) - { - uint32_t tm; - int t; - for (t = 0; t < 16; t++) - { - x[t] = SWAP (*words); - words++; + while(words < endp) { + uint32_t tm; + int t; + for(t = 0; t < 16; t++) { + x[t] = SWAP(*words); + words++; } - R( a, b, c, d, e, F1, K1, x[ 0] ); - R( e, a, b, c, d, F1, K1, x[ 1] ); - R( d, e, a, b, c, F1, K1, x[ 2] ); - R( c, d, e, a, b, F1, K1, x[ 3] ); - R( b, c, d, e, a, F1, K1, x[ 4] ); - R( a, b, c, d, e, F1, K1, x[ 5] ); - R( e, a, b, c, d, F1, K1, x[ 6] ); - R( d, e, a, b, c, F1, K1, x[ 7] ); - R( c, d, e, a, b, F1, K1, x[ 8] ); - R( b, c, d, e, a, F1, K1, x[ 9] ); - R( a, b, c, d, e, F1, K1, x[10] ); - R( e, a, b, c, d, F1, K1, x[11] ); - R( d, e, a, b, c, F1, K1, x[12] ); - R( c, d, e, a, b, F1, K1, x[13] ); - R( b, c, d, e, a, F1, K1, x[14] ); - R( a, b, c, d, e, F1, K1, x[15] ); - R( e, a, b, c, d, F1, K1, M(16) ); - R( d, e, a, b, c, F1, K1, M(17) ); - R( c, d, e, a, b, F1, K1, M(18) ); - R( b, c, d, e, a, F1, K1, M(19) ); - R( a, b, c, d, e, F2, K2, M(20) ); - R( e, a, b, c, d, F2, K2, M(21) ); - R( d, e, a, b, c, F2, K2, M(22) ); - R( c, d, e, a, b, F2, K2, M(23) ); - R( b, c, d, e, a, F2, K2, M(24) ); - R( a, b, c, d, e, F2, K2, M(25) ); - R( e, a, b, c, d, F2, K2, M(26) ); - R( d, e, a, b, c, F2, K2, M(27) ); - R( c, d, e, a, b, F2, K2, M(28) ); - R( b, c, d, e, a, F2, K2, M(29) ); - R( a, b, c, d, e, F2, K2, M(30) ); - R( e, a, b, c, d, F2, K2, M(31) ); - R( d, e, a, b, c, F2, K2, M(32) ); - R( c, d, e, a, b, F2, K2, M(33) ); - R( b, c, d, e, a, F2, K2, M(34) ); - R( a, b, c, d, e, F2, K2, M(35) ); - R( e, a, b, c, d, F2, K2, M(36) ); - R( d, e, a, b, c, F2, K2, M(37) ); - R( c, d, e, a, b, F2, K2, M(38) ); - R( b, c, d, e, a, F2, K2, M(39) ); - R( a, b, c, d, e, F3, K3, M(40) ); - R( e, a, b, c, d, F3, K3, M(41) ); - R( d, e, a, b, c, F3, K3, M(42) ); - R( c, d, e, a, b, F3, K3, M(43) ); - R( b, c, d, e, a, F3, K3, M(44) ); - R( a, b, c, d, e, F3, K3, M(45) ); - R( e, a, b, c, d, F3, K3, M(46) ); - R( d, e, a, b, c, F3, K3, M(47) ); - R( c, d, e, a, b, F3, K3, M(48) ); - R( b, c, d, e, a, F3, K3, M(49) ); - R( a, b, c, d, e, F3, K3, M(50) ); - R( e, a, b, c, d, F3, K3, M(51) ); - R( d, e, a, b, c, F3, K3, M(52) ); - R( c, d, e, a, b, F3, K3, M(53) ); - R( b, c, d, e, a, F3, K3, M(54) ); - R( a, b, c, d, e, F3, K3, M(55) ); - R( e, a, b, c, d, F3, K3, M(56) ); - R( d, e, a, b, c, F3, K3, M(57) ); - R( c, d, e, a, b, F3, K3, M(58) ); - R( b, c, d, e, a, F3, K3, M(59) ); - R( a, b, c, d, e, F4, K4, M(60) ); - R( e, a, b, c, d, F4, K4, M(61) ); - R( d, e, a, b, c, F4, K4, M(62) ); - R( c, d, e, a, b, F4, K4, M(63) ); - R( b, c, d, e, a, F4, K4, M(64) ); - R( a, b, c, d, e, F4, K4, M(65) ); - R( e, a, b, c, d, F4, K4, M(66) ); - R( d, e, a, b, c, F4, K4, M(67) ); - R( c, d, e, a, b, F4, K4, M(68) ); - R( b, c, d, e, a, F4, K4, M(69) ); - R( a, b, c, d, e, F4, K4, M(70) ); - R( e, a, b, c, d, F4, K4, M(71) ); - R( d, e, a, b, c, F4, K4, M(72) ); - R( c, d, e, a, b, F4, K4, M(73) ); - R( b, c, d, e, a, F4, K4, M(74) ); - R( a, b, c, d, e, F4, K4, M(75) ); - R( e, a, b, c, d, F4, K4, M(76) ); - R( d, e, a, b, c, F4, K4, M(77) ); - R( c, d, e, a, b, F4, K4, M(78) ); - R( b, c, d, e, a, F4, K4, M(79) ); + R(a, b, c, d, e, F1, K1, x[0]); + R(e, a, b, c, d, F1, K1, x[1]); + R(d, e, a, b, c, F1, K1, x[2]); + R(c, d, e, a, b, F1, K1, x[3]); + R(b, c, d, e, a, F1, K1, x[4]); + R(a, b, c, d, e, F1, K1, x[5]); + R(e, a, b, c, d, F1, K1, x[6]); + R(d, e, a, b, c, F1, K1, x[7]); + R(c, d, e, a, b, F1, K1, x[8]); + R(b, c, d, e, a, F1, K1, x[9]); + R(a, b, c, d, e, F1, K1, x[10]); + R(e, a, b, c, d, F1, K1, x[11]); + R(d, e, a, b, c, F1, K1, x[12]); + R(c, d, e, a, b, F1, K1, x[13]); + R(b, c, d, e, a, F1, K1, x[14]); + R(a, b, c, d, e, F1, K1, x[15]); + R(e, a, b, c, d, F1, K1, M(16)); + R(d, e, a, b, c, F1, K1, M(17)); + R(c, d, e, a, b, F1, K1, M(18)); + R(b, c, d, e, a, F1, K1, M(19)); + R(a, b, c, d, e, F2, K2, M(20)); + R(e, a, b, c, d, F2, K2, M(21)); + R(d, e, a, b, c, F2, K2, M(22)); + R(c, d, e, a, b, F2, K2, M(23)); + R(b, c, d, e, a, F2, K2, M(24)); + R(a, b, c, d, e, F2, K2, M(25)); + R(e, a, b, c, d, F2, K2, M(26)); + R(d, e, a, b, c, F2, K2, M(27)); + R(c, d, e, a, b, F2, K2, M(28)); + R(b, c, d, e, a, F2, K2, M(29)); + R(a, b, c, d, e, F2, K2, M(30)); + R(e, a, b, c, d, F2, K2, M(31)); + R(d, e, a, b, c, F2, K2, M(32)); + R(c, d, e, a, b, F2, K2, M(33)); + R(b, c, d, e, a, F2, K2, M(34)); + R(a, b, c, d, e, F2, K2, M(35)); + R(e, a, b, c, d, F2, K2, M(36)); + R(d, e, a, b, c, F2, K2, M(37)); + R(c, d, e, a, b, F2, K2, M(38)); + R(b, c, d, e, a, F2, K2, M(39)); + R(a, b, c, d, e, F3, K3, M(40)); + R(e, a, b, c, d, F3, K3, M(41)); + R(d, e, a, b, c, F3, K3, M(42)); + R(c, d, e, a, b, F3, K3, M(43)); + R(b, c, d, e, a, F3, K3, M(44)); + R(a, b, c, d, e, F3, K3, M(45)); + R(e, a, b, c, d, F3, K3, M(46)); + R(d, e, a, b, c, F3, K3, M(47)); + R(c, d, e, a, b, F3, K3, M(48)); + R(b, c, d, e, a, F3, K3, M(49)); + R(a, b, c, d, e, F3, K3, M(50)); + R(e, a, b, c, d, F3, K3, M(51)); + R(d, e, a, b, c, F3, K3, M(52)); + R(c, d, e, a, b, F3, K3, M(53)); + R(b, c, d, e, a, F3, K3, M(54)); + R(a, b, c, d, e, F3, K3, M(55)); + R(e, a, b, c, d, F3, K3, M(56)); + R(d, e, a, b, c, F3, K3, M(57)); + R(c, d, e, a, b, F3, K3, M(58)); + R(b, c, d, e, a, F3, K3, M(59)); + R(a, b, c, d, e, F4, K4, M(60)); + R(e, a, b, c, d, F4, K4, M(61)); + R(d, e, a, b, c, F4, K4, M(62)); + R(c, d, e, a, b, F4, K4, M(63)); + R(b, c, d, e, a, F4, K4, M(64)); + R(a, b, c, d, e, F4, K4, M(65)); + R(e, a, b, c, d, F4, K4, M(66)); + R(d, e, a, b, c, F4, K4, M(67)); + R(c, d, e, a, b, F4, K4, M(68)); + R(b, c, d, e, a, F4, K4, M(69)); + R(a, b, c, d, e, F4, K4, M(70)); + R(e, a, b, c, d, F4, K4, M(71)); + R(d, e, a, b, c, F4, K4, M(72)); + R(c, d, e, a, b, F4, K4, M(73)); + R(b, c, d, e, a, F4, K4, M(74)); + R(a, b, c, d, e, F4, K4, M(75)); + R(e, a, b, c, d, F4, K4, M(76)); + R(d, e, a, b, c, F4, K4, M(77)); + R(c, d, e, a, b, F4, K4, M(78)); + R(b, c, d, e, a, F4, K4, M(79)); - a = ctx->A += a; - b = ctx->B += b; - c = ctx->C += c; - d = ctx->D += d; - e = ctx->E += e; + a = ctx->A += a; + b = ctx->B += b; + c = ctx->C += c; + d = ctx->D += d; + e = ctx->E += e; } } diff --git a/applications/plugins/totp/services/hmac/sha1.h b/applications/plugins/totp/services/hmac/sha1.h index e85163385..d602d26fd 100644 --- a/applications/plugins/totp/services/hmac/sha1.h +++ b/applications/plugins/totp/services/hmac/sha1.h @@ -18,78 +18,72 @@ #pragma once -# include -# include +#include +#include -# if HAVE_OPENSSL_SHA1 -# ifndef OPENSSL_API_COMPAT -# define OPENSSL_API_COMPAT 0x10101000L /* FIXME: Use OpenSSL 1.1+ API. */ -# endif -# include -# endif +#if HAVE_OPENSSL_SHA1 +#ifndef OPENSSL_API_COMPAT +#define OPENSSL_API_COMPAT 0x10101000L /* FIXME: Use OpenSSL 1.1+ API. */ +#endif +#include +#endif -# ifdef __cplusplus +#ifdef __cplusplus extern "C" { -# endif +#endif -# define SHA1_DIGEST_SIZE 20 +#define SHA1_DIGEST_SIZE 20 -# if HAVE_OPENSSL_SHA1 -# define GL_OPENSSL_NAME 1 -# include "gl_openssl.h" -# else +#if HAVE_OPENSSL_SHA1 +#define GL_OPENSSL_NAME 1 +#include "gl_openssl.h" +#else /* Structure to save state of computation between the single steps. */ -struct sha1_ctx -{ - uint32_t A; - uint32_t B; - uint32_t C; - uint32_t D; - uint32_t E; +struct sha1_ctx { + uint32_t A; + uint32_t B; + uint32_t C; + uint32_t D; + uint32_t E; - uint32_t total[2]; - uint32_t buflen; /* ≥ 0, ≤ 128 */ - uint32_t buffer[32]; /* 128 bytes; the first buflen bytes are in use */ + uint32_t total[2]; + uint32_t buflen; /* ≥ 0, ≤ 128 */ + uint32_t buffer[32]; /* 128 bytes; the first buflen bytes are in use */ }; /* Initialize structure containing state of computation. */ -extern void sha1_init_ctx (struct sha1_ctx *ctx); +extern void sha1_init_ctx(struct sha1_ctx* ctx); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is necessary that LEN is a multiple of 64!!! */ -extern void sha1_process_block (const void *buffer, size_t len, - struct sha1_ctx *ctx); +extern void sha1_process_block(const void* buffer, size_t len, struct sha1_ctx* ctx); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is NOT required that LEN is a multiple of 64. */ -extern void sha1_process_bytes (const void *buffer, size_t len, - struct sha1_ctx *ctx); +extern void sha1_process_bytes(const void* buffer, size_t len, struct sha1_ctx* ctx); /* Process the remaining bytes in the buffer and put result from CTX in first 20 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *restrict resbuf); - +extern void* sha1_finish_ctx(struct sha1_ctx* ctx, void* restrict resbuf); /* Put result from CTX in first 20 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *restrict resbuf); - +extern void* sha1_read_ctx(const struct sha1_ctx* ctx, void* restrict resbuf); /* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha1_buffer (const char *buffer, size_t len, - void *restrict resblock); +extern void* sha1_buffer(const char* buffer, size_t len, void* restrict resblock); -# endif +#endif /* Compute SHA1 message digest for bytes read from STREAM. STREAM is an open file stream. Regular files are handled more efficiently. @@ -97,12 +91,11 @@ extern void *sha1_buffer (const char *buffer, size_t len, The case that the last operation on STREAM was an 'ungetc' is not supported. The resulting message digest number will be written into the 20 bytes beginning at RESBLOCK. */ -extern int sha1_stream (FILE *stream, void *resblock); +extern int sha1_stream(FILE* stream, void* resblock); - -# ifdef __cplusplus +#ifdef __cplusplus } -# endif +#endif /* * Hey Emacs! diff --git a/applications/plugins/totp/services/hmac/sha256.c b/applications/plugins/totp/services/hmac/sha256.c index 4a6fe5424..2ea63dd37 100644 --- a/applications/plugins/totp/services/hmac/sha256.c +++ b/applications/plugins/totp/services/hmac/sha256.c @@ -22,7 +22,7 @@ /* Specification. */ #if HAVE_OPENSSL_SHA256 -# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#define GL_OPENSSL_INLINE _GL_EXTERN_INLINE #endif #include "sha256.h" @@ -30,233 +30,197 @@ #include #ifdef WORDS_BIGENDIAN -# define SWAP(n) (n) +#define SWAP(n) (n) #else #include "byteswap.h" -# define SWAP(n) swap_uint32 (n) +#define SWAP(n) swap_uint32(n) #endif -#if ! HAVE_OPENSSL_SHA256 +#if !HAVE_OPENSSL_SHA256 /* This array contains the bytes used to pad the buffer to the next 64-byte boundary. */ -static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; - +static const unsigned char fillbuf[64] = {0x80, 0 /* , 0, 0, ... */}; /* Takes a pointer to a 256 bit block of data (eight 32 bit ints) and initializes it to the start constants of the SHA256 algorithm. This must be called before using hash in the call to sha256_hash */ -void -sha256_init_ctx (struct sha256_ctx *ctx) -{ - ctx->state[0] = 0x6a09e667UL; - ctx->state[1] = 0xbb67ae85UL; - ctx->state[2] = 0x3c6ef372UL; - ctx->state[3] = 0xa54ff53aUL; - ctx->state[4] = 0x510e527fUL; - ctx->state[5] = 0x9b05688cUL; - ctx->state[6] = 0x1f83d9abUL; - ctx->state[7] = 0x5be0cd19UL; +void sha256_init_ctx(struct sha256_ctx* ctx) { + ctx->state[0] = 0x6a09e667UL; + ctx->state[1] = 0xbb67ae85UL; + ctx->state[2] = 0x3c6ef372UL; + ctx->state[3] = 0xa54ff53aUL; + ctx->state[4] = 0x510e527fUL; + ctx->state[5] = 0x9b05688cUL; + ctx->state[6] = 0x1f83d9abUL; + ctx->state[7] = 0x5be0cd19UL; - ctx->total[0] = ctx->total[1] = 0; - ctx->buflen = 0; + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; } -void -sha224_init_ctx (struct sha256_ctx *ctx) -{ - ctx->state[0] = 0xc1059ed8UL; - ctx->state[1] = 0x367cd507UL; - ctx->state[2] = 0x3070dd17UL; - ctx->state[3] = 0xf70e5939UL; - ctx->state[4] = 0xffc00b31UL; - ctx->state[5] = 0x68581511UL; - ctx->state[6] = 0x64f98fa7UL; - ctx->state[7] = 0xbefa4fa4UL; +void sha224_init_ctx(struct sha256_ctx* ctx) { + ctx->state[0] = 0xc1059ed8UL; + ctx->state[1] = 0x367cd507UL; + ctx->state[2] = 0x3070dd17UL; + ctx->state[3] = 0xf70e5939UL; + ctx->state[4] = 0xffc00b31UL; + ctx->state[5] = 0x68581511UL; + ctx->state[6] = 0x64f98fa7UL; + ctx->state[7] = 0xbefa4fa4UL; - ctx->total[0] = ctx->total[1] = 0; - ctx->buflen = 0; + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; } /* Copy the value from v into the memory location pointed to by *CP, If your architecture allows unaligned access, this is equivalent to * (__typeof__ (v) *) cp = v */ -static void -set_uint32 (char *cp, uint32_t v) -{ - memcpy (cp, &v, sizeof v); +static void set_uint32(char* cp, uint32_t v) { + memcpy(cp, &v, sizeof v); } /* Put result from CTX in first 32 bytes following RESBUF. The result must be in little endian byte order. */ -void * -sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf) -{ - int i; - char *r = resbuf; +void* sha256_read_ctx(const struct sha256_ctx* ctx, void* resbuf) { + int i; + char* r = resbuf; - for (i = 0; i < 8; i++) - set_uint32 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i])); + for(i = 0; i < 8; i++) set_uint32(r + i * sizeof ctx->state[0], SWAP(ctx->state[i])); - return resbuf; + return resbuf; } -void * -sha224_read_ctx (const struct sha256_ctx *ctx, void *resbuf) -{ - int i; - char *r = resbuf; +void* sha224_read_ctx(const struct sha256_ctx* ctx, void* resbuf) { + int i; + char* r = resbuf; - for (i = 0; i < 7; i++) - set_uint32 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i])); + for(i = 0; i < 7; i++) set_uint32(r + i * sizeof ctx->state[0], SWAP(ctx->state[i])); - return resbuf; + return resbuf; } /* Process the remaining bytes in the internal buffer and the usual prolog according to the standard and write the result to RESBUF. */ -static void -sha256_conclude_ctx (struct sha256_ctx *ctx) -{ - /* Take yet unprocessed bytes into account. */ - size_t bytes = ctx->buflen; - size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4; +static void sha256_conclude_ctx(struct sha256_ctx* ctx) { + /* Take yet unprocessed bytes into account. */ + size_t bytes = ctx->buflen; + size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4; - /* Now count remaining bytes. */ - ctx->total[0] += bytes; - if (ctx->total[0] < bytes) - ++ctx->total[1]; + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if(ctx->total[0] < bytes) ++ctx->total[1]; - /* Put the 64-bit file length in *bits* at the end of the buffer. + /* Put the 64-bit file length in *bits* at the end of the buffer. Use set_uint32 rather than a simple assignment, to avoid risk of unaligned access. */ - set_uint32 ((char *) &ctx->buffer[size - 2], - SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29))); - set_uint32 ((char *) &ctx->buffer[size - 1], - SWAP (ctx->total[0] << 3)); + set_uint32((char*)&ctx->buffer[size - 2], SWAP((ctx->total[1] << 3) | (ctx->total[0] >> 29))); + set_uint32((char*)&ctx->buffer[size - 1], SWAP(ctx->total[0] << 3)); - memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes); + memcpy(&((char*)ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes); - /* Process last bytes. */ - sha256_process_block (ctx->buffer, size * 4, ctx); + /* Process last bytes. */ + sha256_process_block(ctx->buffer, size * 4, ctx); } -void * -sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf) -{ - sha256_conclude_ctx (ctx); - return sha256_read_ctx (ctx, resbuf); +void* sha256_finish_ctx(struct sha256_ctx* ctx, void* resbuf) { + sha256_conclude_ctx(ctx); + return sha256_read_ctx(ctx, resbuf); } -void * -sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf) -{ - sha256_conclude_ctx (ctx); - return sha224_read_ctx (ctx, resbuf); +void* sha224_finish_ctx(struct sha256_ctx* ctx, void* resbuf) { + sha256_conclude_ctx(ctx); + return sha224_read_ctx(ctx, resbuf); } /* Compute SHA256 message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -void * -sha256_buffer (const char *buffer, size_t len, void *resblock) -{ - struct sha256_ctx ctx; +void* sha256_buffer(const char* buffer, size_t len, void* resblock) { + struct sha256_ctx ctx; - /* Initialize the computation context. */ - sha256_init_ctx (&ctx); + /* Initialize the computation context. */ + sha256_init_ctx(&ctx); - /* Process whole buffer but last len % 64 bytes. */ - sha256_process_bytes (buffer, len, &ctx); + /* Process whole buffer but last len % 64 bytes. */ + sha256_process_bytes(buffer, len, &ctx); - /* Put result in desired memory area. */ - return sha256_finish_ctx (&ctx, resblock); + /* Put result in desired memory area. */ + return sha256_finish_ctx(&ctx, resblock); } -void * -sha224_buffer (const char *buffer, size_t len, void *resblock) -{ - struct sha256_ctx ctx; +void* sha224_buffer(const char* buffer, size_t len, void* resblock) { + struct sha256_ctx ctx; - /* Initialize the computation context. */ - sha224_init_ctx (&ctx); + /* Initialize the computation context. */ + sha224_init_ctx(&ctx); - /* Process whole buffer but last len % 64 bytes. */ - sha256_process_bytes (buffer, len, &ctx); + /* Process whole buffer but last len % 64 bytes. */ + sha256_process_bytes(buffer, len, &ctx); - /* Put result in desired memory area. */ - return sha224_finish_ctx (&ctx, resblock); + /* Put result in desired memory area. */ + return sha224_finish_ctx(&ctx, resblock); } -void -sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx) -{ - /* When we already have some bits in our internal buffer concatenate +void sha256_process_bytes(const void* buffer, size_t len, struct sha256_ctx* ctx) { + /* When we already have some bits in our internal buffer concatenate both inputs first. */ - if (ctx->buflen != 0) - { - size_t left_over = ctx->buflen; - size_t add = 128 - left_over > len ? len : 128 - left_over; + if(ctx->buflen != 0) { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; - memcpy (&((char *) ctx->buffer)[left_over], buffer, add); - ctx->buflen += add; + memcpy(&((char*)ctx->buffer)[left_over], buffer, add); + ctx->buflen += add; - if (ctx->buflen > 64) - { - sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + if(ctx->buflen > 64) { + sha256_process_block(ctx->buffer, ctx->buflen & ~63, ctx); - ctx->buflen &= 63; - /* The regions in the following copy operation cannot overlap, + ctx->buflen &= 63; + /* The regions in the following copy operation cannot overlap, because ctx->buflen < 64 ≤ (left_over + add) & ~63. */ - memcpy (ctx->buffer, - &((char *) ctx->buffer)[(left_over + add) & ~63], - ctx->buflen); + memcpy(ctx->buffer, &((char*)ctx->buffer)[(left_over + add) & ~63], ctx->buflen); } - buffer = (const char *) buffer + add; - len -= add; + buffer = (const char*)buffer + add; + len -= add; } - /* Process available complete blocks. */ - if (len >= 64) - { + /* Process available complete blocks. */ + if(len >= 64) { #if !(_STRING_ARCH_unaligned || _STRING_INLINE_unaligned) -# define UNALIGNED_P(p) ((uintptr_t) (p) % sizeof (uint32_t) != 0) - if (UNALIGNED_P (buffer)) - while (len > 64) - { - sha256_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); - buffer = (const char *) buffer + 64; - len -= 64; - } - else +#define UNALIGNED_P(p) ((uintptr_t)(p) % sizeof(uint32_t) != 0) + if(UNALIGNED_P(buffer)) + while(len > 64) { + sha256_process_block(memcpy(ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char*)buffer + 64; + len -= 64; + } + else #endif { - sha256_process_block (buffer, len & ~63, ctx); - buffer = (const char *) buffer + (len & ~63); - len &= 63; + sha256_process_block(buffer, len & ~63, ctx); + buffer = (const char*)buffer + (len & ~63); + len &= 63; } } - /* Move remaining bytes in internal buffer. */ - if (len > 0) - { - size_t left_over = ctx->buflen; + /* Move remaining bytes in internal buffer. */ + if(len > 0) { + size_t left_over = ctx->buflen; - memcpy (&((char *) ctx->buffer)[left_over], buffer, len); - left_over += len; - if (left_over >= 64) - { - sha256_process_block (ctx->buffer, 64, ctx); - left_over -= 64; - /* The regions in the following copy operation cannot overlap, + memcpy(&((char*)ctx->buffer)[left_over], buffer, len); + left_over += len; + if(left_over >= 64) { + sha256_process_block(ctx->buffer, 64, ctx); + left_over -= 64; + /* The regions in the following copy operation cannot overlap, because left_over ≤ 64. */ - memcpy (ctx->buffer, &ctx->buffer[16], left_over); + memcpy(ctx->buffer, &ctx->buffer[16], left_over); } - ctx->buflen = left_over; + ctx->buflen = left_over; } } @@ -265,158 +229,149 @@ sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx) /* SHA256 round constants */ #define K(I) sha256_round_constants[I] static const uint32_t sha256_round_constants[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL, + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, + 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, + 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 0xa2bfe8a1UL, 0xa81a664bUL, + 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, + 0x5b9cca4fUL, 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL, }; /* Round functions. */ -#define F2(A,B,C) ( ( A & B ) | ( C & ( A | B ) ) ) -#define F1(E,F,G) ( G ^ ( E & ( F ^ G ) ) ) +#define F2(A, B, C) ((A & B) | (C & (A | B))) +#define F1(E, F, G) (G ^ (E & (F ^ G))) /* Process LEN bytes of BUFFER, accumulating context into CTX. It is assumed that LEN % 64 == 0. Most of this code comes from GnuPG's cipher/sha1.c. */ -void -sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx) -{ - const uint32_t *words = buffer; - size_t nwords = len / sizeof (uint32_t); - const uint32_t *endp = words + nwords; - uint32_t x[16]; - uint32_t a = ctx->state[0]; - uint32_t b = ctx->state[1]; - uint32_t c = ctx->state[2]; - uint32_t d = ctx->state[3]; - uint32_t e = ctx->state[4]; - uint32_t f = ctx->state[5]; - uint32_t g = ctx->state[6]; - uint32_t h = ctx->state[7]; - uint32_t lolen = len; +void sha256_process_block(const void* buffer, size_t len, struct sha256_ctx* ctx) { + const uint32_t* words = buffer; + size_t nwords = len / sizeof(uint32_t); + const uint32_t* endp = words + nwords; + uint32_t x[16]; + uint32_t a = ctx->state[0]; + uint32_t b = ctx->state[1]; + uint32_t c = ctx->state[2]; + uint32_t d = ctx->state[3]; + uint32_t e = ctx->state[4]; + uint32_t f = ctx->state[5]; + uint32_t g = ctx->state[6]; + uint32_t h = ctx->state[7]; + uint32_t lolen = len; - /* First increment the byte count. FIPS PUB 180-2 specifies the possible + /* First increment the byte count. FIPS PUB 180-2 specifies the possible length of the file up to 2^64 bits. Here we only compute the number of bytes. Do a double word increment. */ - ctx->total[0] += lolen; - ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen); + ctx->total[0] += lolen; + ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen); #define rol(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) -#define S0(x) (rol(x,25)^rol(x,14)^(x>>3)) -#define S1(x) (rol(x,15)^rol(x,13)^(x>>10)) -#define SS0(x) (rol(x,30)^rol(x,19)^rol(x,10)) -#define SS1(x) (rol(x,26)^rol(x,21)^rol(x,7)) +#define S0(x) (rol(x, 25) ^ rol(x, 14) ^ (x >> 3)) +#define S1(x) (rol(x, 15) ^ rol(x, 13) ^ (x >> 10)) +#define SS0(x) (rol(x, 30) ^ rol(x, 19) ^ rol(x, 10)) +#define SS1(x) (rol(x, 26) ^ rol(x, 21) ^ rol(x, 7)) -#define M(I) ( tm = S1(x[(I-2)&0x0f]) + x[(I-7)&0x0f] \ - + S0(x[(I-15)&0x0f]) + x[I&0x0f] \ - , x[I&0x0f] = tm ) +#define M(I) \ + (tm = S1(x[(I - 2) & 0x0f]) + x[(I - 7) & 0x0f] + S0(x[(I - 15) & 0x0f]) + x[I & 0x0f], \ + x[I & 0x0f] = tm) -#define R(A,B,C,D,E,F,G,H,K,M) do { t0 = SS0(A) + F2(A,B,C); \ - t1 = H + SS1(E) \ - + F1(E,F,G) \ - + K \ - + M; \ - D += t1; H = t0 + t1; \ - } while(0) +#define R(A, B, C, D, E, F, G, H, K, M) \ + do { \ + t0 = SS0(A) + F2(A, B, C); \ + t1 = H + SS1(E) + F1(E, F, G) + K + M; \ + D += t1; \ + H = t0 + t1; \ + } while(0) - while (words < endp) - { - uint32_t tm; - uint32_t t0, t1; - int t; - /* FIXME: see sha1.c for a better implementation. */ - for (t = 0; t < 16; t++) - { - x[t] = SWAP (*words); - words++; + while(words < endp) { + uint32_t tm; + uint32_t t0, t1; + int t; + /* FIXME: see sha1.c for a better implementation. */ + for(t = 0; t < 16; t++) { + x[t] = SWAP(*words); + words++; } - R( a, b, c, d, e, f, g, h, K( 0), x[ 0] ); - R( h, a, b, c, d, e, f, g, K( 1), x[ 1] ); - R( g, h, a, b, c, d, e, f, K( 2), x[ 2] ); - R( f, g, h, a, b, c, d, e, K( 3), x[ 3] ); - R( e, f, g, h, a, b, c, d, K( 4), x[ 4] ); - R( d, e, f, g, h, a, b, c, K( 5), x[ 5] ); - R( c, d, e, f, g, h, a, b, K( 6), x[ 6] ); - R( b, c, d, e, f, g, h, a, K( 7), x[ 7] ); - R( a, b, c, d, e, f, g, h, K( 8), x[ 8] ); - R( h, a, b, c, d, e, f, g, K( 9), x[ 9] ); - R( g, h, a, b, c, d, e, f, K(10), x[10] ); - R( f, g, h, a, b, c, d, e, K(11), x[11] ); - R( e, f, g, h, a, b, c, d, K(12), x[12] ); - R( d, e, f, g, h, a, b, c, K(13), x[13] ); - R( c, d, e, f, g, h, a, b, K(14), x[14] ); - R( b, c, d, e, f, g, h, a, K(15), x[15] ); - R( a, b, c, d, e, f, g, h, K(16), M(16) ); - R( h, a, b, c, d, e, f, g, K(17), M(17) ); - R( g, h, a, b, c, d, e, f, K(18), M(18) ); - R( f, g, h, a, b, c, d, e, K(19), M(19) ); - R( e, f, g, h, a, b, c, d, K(20), M(20) ); - R( d, e, f, g, h, a, b, c, K(21), M(21) ); - R( c, d, e, f, g, h, a, b, K(22), M(22) ); - R( b, c, d, e, f, g, h, a, K(23), M(23) ); - R( a, b, c, d, e, f, g, h, K(24), M(24) ); - R( h, a, b, c, d, e, f, g, K(25), M(25) ); - R( g, h, a, b, c, d, e, f, K(26), M(26) ); - R( f, g, h, a, b, c, d, e, K(27), M(27) ); - R( e, f, g, h, a, b, c, d, K(28), M(28) ); - R( d, e, f, g, h, a, b, c, K(29), M(29) ); - R( c, d, e, f, g, h, a, b, K(30), M(30) ); - R( b, c, d, e, f, g, h, a, K(31), M(31) ); - R( a, b, c, d, e, f, g, h, K(32), M(32) ); - R( h, a, b, c, d, e, f, g, K(33), M(33) ); - R( g, h, a, b, c, d, e, f, K(34), M(34) ); - R( f, g, h, a, b, c, d, e, K(35), M(35) ); - R( e, f, g, h, a, b, c, d, K(36), M(36) ); - R( d, e, f, g, h, a, b, c, K(37), M(37) ); - R( c, d, e, f, g, h, a, b, K(38), M(38) ); - R( b, c, d, e, f, g, h, a, K(39), M(39) ); - R( a, b, c, d, e, f, g, h, K(40), M(40) ); - R( h, a, b, c, d, e, f, g, K(41), M(41) ); - R( g, h, a, b, c, d, e, f, K(42), M(42) ); - R( f, g, h, a, b, c, d, e, K(43), M(43) ); - R( e, f, g, h, a, b, c, d, K(44), M(44) ); - R( d, e, f, g, h, a, b, c, K(45), M(45) ); - R( c, d, e, f, g, h, a, b, K(46), M(46) ); - R( b, c, d, e, f, g, h, a, K(47), M(47) ); - R( a, b, c, d, e, f, g, h, K(48), M(48) ); - R( h, a, b, c, d, e, f, g, K(49), M(49) ); - R( g, h, a, b, c, d, e, f, K(50), M(50) ); - R( f, g, h, a, b, c, d, e, K(51), M(51) ); - R( e, f, g, h, a, b, c, d, K(52), M(52) ); - R( d, e, f, g, h, a, b, c, K(53), M(53) ); - R( c, d, e, f, g, h, a, b, K(54), M(54) ); - R( b, c, d, e, f, g, h, a, K(55), M(55) ); - R( a, b, c, d, e, f, g, h, K(56), M(56) ); - R( h, a, b, c, d, e, f, g, K(57), M(57) ); - R( g, h, a, b, c, d, e, f, K(58), M(58) ); - R( f, g, h, a, b, c, d, e, K(59), M(59) ); - R( e, f, g, h, a, b, c, d, K(60), M(60) ); - R( d, e, f, g, h, a, b, c, K(61), M(61) ); - R( c, d, e, f, g, h, a, b, K(62), M(62) ); - R( b, c, d, e, f, g, h, a, K(63), M(63) ); + R(a, b, c, d, e, f, g, h, K(0), x[0]); + R(h, a, b, c, d, e, f, g, K(1), x[1]); + R(g, h, a, b, c, d, e, f, K(2), x[2]); + R(f, g, h, a, b, c, d, e, K(3), x[3]); + R(e, f, g, h, a, b, c, d, K(4), x[4]); + R(d, e, f, g, h, a, b, c, K(5), x[5]); + R(c, d, e, f, g, h, a, b, K(6), x[6]); + R(b, c, d, e, f, g, h, a, K(7), x[7]); + R(a, b, c, d, e, f, g, h, K(8), x[8]); + R(h, a, b, c, d, e, f, g, K(9), x[9]); + R(g, h, a, b, c, d, e, f, K(10), x[10]); + R(f, g, h, a, b, c, d, e, K(11), x[11]); + R(e, f, g, h, a, b, c, d, K(12), x[12]); + R(d, e, f, g, h, a, b, c, K(13), x[13]); + R(c, d, e, f, g, h, a, b, K(14), x[14]); + R(b, c, d, e, f, g, h, a, K(15), x[15]); + R(a, b, c, d, e, f, g, h, K(16), M(16)); + R(h, a, b, c, d, e, f, g, K(17), M(17)); + R(g, h, a, b, c, d, e, f, K(18), M(18)); + R(f, g, h, a, b, c, d, e, K(19), M(19)); + R(e, f, g, h, a, b, c, d, K(20), M(20)); + R(d, e, f, g, h, a, b, c, K(21), M(21)); + R(c, d, e, f, g, h, a, b, K(22), M(22)); + R(b, c, d, e, f, g, h, a, K(23), M(23)); + R(a, b, c, d, e, f, g, h, K(24), M(24)); + R(h, a, b, c, d, e, f, g, K(25), M(25)); + R(g, h, a, b, c, d, e, f, K(26), M(26)); + R(f, g, h, a, b, c, d, e, K(27), M(27)); + R(e, f, g, h, a, b, c, d, K(28), M(28)); + R(d, e, f, g, h, a, b, c, K(29), M(29)); + R(c, d, e, f, g, h, a, b, K(30), M(30)); + R(b, c, d, e, f, g, h, a, K(31), M(31)); + R(a, b, c, d, e, f, g, h, K(32), M(32)); + R(h, a, b, c, d, e, f, g, K(33), M(33)); + R(g, h, a, b, c, d, e, f, K(34), M(34)); + R(f, g, h, a, b, c, d, e, K(35), M(35)); + R(e, f, g, h, a, b, c, d, K(36), M(36)); + R(d, e, f, g, h, a, b, c, K(37), M(37)); + R(c, d, e, f, g, h, a, b, K(38), M(38)); + R(b, c, d, e, f, g, h, a, K(39), M(39)); + R(a, b, c, d, e, f, g, h, K(40), M(40)); + R(h, a, b, c, d, e, f, g, K(41), M(41)); + R(g, h, a, b, c, d, e, f, K(42), M(42)); + R(f, g, h, a, b, c, d, e, K(43), M(43)); + R(e, f, g, h, a, b, c, d, K(44), M(44)); + R(d, e, f, g, h, a, b, c, K(45), M(45)); + R(c, d, e, f, g, h, a, b, K(46), M(46)); + R(b, c, d, e, f, g, h, a, K(47), M(47)); + R(a, b, c, d, e, f, g, h, K(48), M(48)); + R(h, a, b, c, d, e, f, g, K(49), M(49)); + R(g, h, a, b, c, d, e, f, K(50), M(50)); + R(f, g, h, a, b, c, d, e, K(51), M(51)); + R(e, f, g, h, a, b, c, d, K(52), M(52)); + R(d, e, f, g, h, a, b, c, K(53), M(53)); + R(c, d, e, f, g, h, a, b, K(54), M(54)); + R(b, c, d, e, f, g, h, a, K(55), M(55)); + R(a, b, c, d, e, f, g, h, K(56), M(56)); + R(h, a, b, c, d, e, f, g, K(57), M(57)); + R(g, h, a, b, c, d, e, f, K(58), M(58)); + R(f, g, h, a, b, c, d, e, K(59), M(59)); + R(e, f, g, h, a, b, c, d, K(60), M(60)); + R(d, e, f, g, h, a, b, c, K(61), M(61)); + R(c, d, e, f, g, h, a, b, K(62), M(62)); + R(b, c, d, e, f, g, h, a, K(63), M(63)); - a = ctx->state[0] += a; - b = ctx->state[1] += b; - c = ctx->state[2] += c; - d = ctx->state[3] += d; - e = ctx->state[4] += e; - f = ctx->state[5] += f; - g = ctx->state[6] += g; - h = ctx->state[7] += h; + a = ctx->state[0] += a; + b = ctx->state[1] += b; + c = ctx->state[2] += c; + d = ctx->state[3] += d; + e = ctx->state[4] += e; + f = ctx->state[5] += f; + g = ctx->state[6] += g; + h = ctx->state[7] += h; } } diff --git a/applications/plugins/totp/services/hmac/sha256.h b/applications/plugins/totp/services/hmac/sha256.h index 5612bd75b..2f99d1428 100644 --- a/applications/plugins/totp/services/hmac/sha256.h +++ b/applications/plugins/totp/services/hmac/sha256.h @@ -17,84 +17,75 @@ #pragma once -# include -# include +#include +#include -# if HAVE_OPENSSL_SHA256 -# ifndef OPENSSL_API_COMPAT -# define OPENSSL_API_COMPAT 0x10101000L /* FIXME: Use OpenSSL 1.1+ API. */ -# endif -# include -# endif +#if HAVE_OPENSSL_SHA256 +#ifndef OPENSSL_API_COMPAT +#define OPENSSL_API_COMPAT 0x10101000L /* FIXME: Use OpenSSL 1.1+ API. */ +#endif +#include +#endif -# ifdef __cplusplus +#ifdef __cplusplus extern "C" { -# endif +#endif enum { SHA224_DIGEST_SIZE = 224 / 8 }; enum { SHA256_DIGEST_SIZE = 256 / 8 }; -# if HAVE_OPENSSL_SHA256 -# define GL_OPENSSL_NAME 224 -# include "gl_openssl.h" -# define GL_OPENSSL_NAME 256 -# include "gl_openssl.h" -# else +#if HAVE_OPENSSL_SHA256 +#define GL_OPENSSL_NAME 224 +#include "gl_openssl.h" +#define GL_OPENSSL_NAME 256 +#include "gl_openssl.h" +#else /* Structure to save state of computation between the single steps. */ -struct sha256_ctx -{ - uint32_t state[8]; +struct sha256_ctx { + uint32_t state[8]; - uint32_t total[2]; - size_t buflen; /* ≥ 0, ≤ 128 */ - uint32_t buffer[32]; /* 128 bytes; the first buflen bytes are in use */ + uint32_t total[2]; + size_t buflen; /* ≥ 0, ≤ 128 */ + uint32_t buffer[32]; /* 128 bytes; the first buflen bytes are in use */ }; /* Initialize structure containing state of computation. */ -extern void sha256_init_ctx (struct sha256_ctx *ctx); -extern void sha224_init_ctx (struct sha256_ctx *ctx); +extern void sha256_init_ctx(struct sha256_ctx* ctx); +extern void sha224_init_ctx(struct sha256_ctx* ctx); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is necessary that LEN is a multiple of 64!!! */ -extern void sha256_process_block (const void *buffer, size_t len, - struct sha256_ctx *ctx); +extern void sha256_process_block(const void* buffer, size_t len, struct sha256_ctx* ctx); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is NOT required that LEN is a multiple of 64. */ -extern void sha256_process_bytes (const void *buffer, size_t len, - struct sha256_ctx *ctx); +extern void sha256_process_bytes(const void* buffer, size_t len, struct sha256_ctx* ctx); /* Process the remaining bytes in the buffer and put result from CTX in first 32 (28) bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha256_finish_ctx (struct sha256_ctx *ctx, void *restrict resbuf); -extern void *sha224_finish_ctx (struct sha256_ctx *ctx, void *restrict resbuf); - +extern void* sha256_finish_ctx(struct sha256_ctx* ctx, void* restrict resbuf); +extern void* sha224_finish_ctx(struct sha256_ctx* ctx, void* restrict resbuf); /* Put result from CTX in first 32 (28) bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha256_read_ctx (const struct sha256_ctx *ctx, - void *restrict resbuf); -extern void *sha224_read_ctx (const struct sha256_ctx *ctx, - void *restrict resbuf); - +extern void* sha256_read_ctx(const struct sha256_ctx* ctx, void* restrict resbuf); +extern void* sha224_read_ctx(const struct sha256_ctx* ctx, void* restrict resbuf); /* Compute SHA256 (SHA224) message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha256_buffer (const char *buffer, size_t len, - void *restrict resblock); -extern void *sha224_buffer (const char *buffer, size_t len, - void *restrict resblock); +extern void* sha256_buffer(const char* buffer, size_t len, void* restrict resblock); +extern void* sha224_buffer(const char* buffer, size_t len, void* restrict resblock); -# endif +#endif /* Compute SHA256 (SHA224) message digest for bytes read from STREAM. STREAM is an open file stream. Regular files are handled more efficiently. @@ -102,13 +93,12 @@ extern void *sha224_buffer (const char *buffer, size_t len, The case that the last operation on STREAM was an 'ungetc' is not supported. The resulting message digest number will be written into the 32 (28) bytes beginning at RESBLOCK. */ -extern int sha256_stream (FILE *stream, void *resblock); -extern int sha224_stream (FILE *stream, void *resblock); +extern int sha256_stream(FILE* stream, void* resblock); +extern int sha224_stream(FILE* stream, void* resblock); - -# ifdef __cplusplus +#ifdef __cplusplus } -# endif +#endif /* * Hey Emacs! diff --git a/applications/plugins/totp/services/hmac/sha512.c b/applications/plugins/totp/services/hmac/sha512.c index a22f39545..53d3bad2e 100644 --- a/applications/plugins/totp/services/hmac/sha512.c +++ b/applications/plugins/totp/services/hmac/sha512.c @@ -22,7 +22,7 @@ /* Specification. */ #if HAVE_OPENSSL_SHA512 -# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#define GL_OPENSSL_INLINE _GL_EXTERN_INLINE #endif #include "sha512.h" @@ -30,234 +30,199 @@ #include #ifdef WORDS_BIGENDIAN -# define SWAP(n) (n) +#define SWAP(n) (n) #else #include "byteswap.h" -# define SWAP(n) swap_uint64 (n) +#define SWAP(n) swap_uint64(n) #endif -#if ! HAVE_OPENSSL_SHA512 +#if !HAVE_OPENSSL_SHA512 /* This array contains the bytes used to pad the buffer to the next 128-byte boundary. */ -static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ... */ }; - +static const unsigned char fillbuf[128] = {0x80, 0 /* , 0, 0, ... */}; /* Takes a pointer to a 512 bit block of data (eight 64 bit ints) and initializes it to the start constants of the SHA512 algorithm. This must be called before using hash in the call to sha512_hash */ -void -sha512_init_ctx (struct sha512_ctx *ctx) -{ - ctx->state[0] = u64hilo (0x6a09e667, 0xf3bcc908); - ctx->state[1] = u64hilo (0xbb67ae85, 0x84caa73b); - ctx->state[2] = u64hilo (0x3c6ef372, 0xfe94f82b); - ctx->state[3] = u64hilo (0xa54ff53a, 0x5f1d36f1); - ctx->state[4] = u64hilo (0x510e527f, 0xade682d1); - ctx->state[5] = u64hilo (0x9b05688c, 0x2b3e6c1f); - ctx->state[6] = u64hilo (0x1f83d9ab, 0xfb41bd6b); - ctx->state[7] = u64hilo (0x5be0cd19, 0x137e2179); +void sha512_init_ctx(struct sha512_ctx* ctx) { + ctx->state[0] = u64hilo(0x6a09e667, 0xf3bcc908); + ctx->state[1] = u64hilo(0xbb67ae85, 0x84caa73b); + ctx->state[2] = u64hilo(0x3c6ef372, 0xfe94f82b); + ctx->state[3] = u64hilo(0xa54ff53a, 0x5f1d36f1); + ctx->state[4] = u64hilo(0x510e527f, 0xade682d1); + ctx->state[5] = u64hilo(0x9b05688c, 0x2b3e6c1f); + ctx->state[6] = u64hilo(0x1f83d9ab, 0xfb41bd6b); + ctx->state[7] = u64hilo(0x5be0cd19, 0x137e2179); - ctx->total[0] = ctx->total[1] = u64lo (0); - ctx->buflen = 0; + ctx->total[0] = ctx->total[1] = u64lo(0); + ctx->buflen = 0; } -void -sha384_init_ctx (struct sha512_ctx *ctx) -{ - ctx->state[0] = u64hilo (0xcbbb9d5d, 0xc1059ed8); - ctx->state[1] = u64hilo (0x629a292a, 0x367cd507); - ctx->state[2] = u64hilo (0x9159015a, 0x3070dd17); - ctx->state[3] = u64hilo (0x152fecd8, 0xf70e5939); - ctx->state[4] = u64hilo (0x67332667, 0xffc00b31); - ctx->state[5] = u64hilo (0x8eb44a87, 0x68581511); - ctx->state[6] = u64hilo (0xdb0c2e0d, 0x64f98fa7); - ctx->state[7] = u64hilo (0x47b5481d, 0xbefa4fa4); +void sha384_init_ctx(struct sha512_ctx* ctx) { + ctx->state[0] = u64hilo(0xcbbb9d5d, 0xc1059ed8); + ctx->state[1] = u64hilo(0x629a292a, 0x367cd507); + ctx->state[2] = u64hilo(0x9159015a, 0x3070dd17); + ctx->state[3] = u64hilo(0x152fecd8, 0xf70e5939); + ctx->state[4] = u64hilo(0x67332667, 0xffc00b31); + ctx->state[5] = u64hilo(0x8eb44a87, 0x68581511); + ctx->state[6] = u64hilo(0xdb0c2e0d, 0x64f98fa7); + ctx->state[7] = u64hilo(0x47b5481d, 0xbefa4fa4); - ctx->total[0] = ctx->total[1] = u64lo (0); - ctx->buflen = 0; + ctx->total[0] = ctx->total[1] = u64lo(0); + ctx->buflen = 0; } /* Copy the value from V into the memory location pointed to by *CP, If your architecture allows unaligned access, this is equivalent to * (__typeof__ (v) *) cp = v */ -static void -set_uint64 (char *cp, u64 v) -{ - memcpy (cp, &v, sizeof v); +static void set_uint64(char* cp, u64 v) { + memcpy(cp, &v, sizeof v); } /* Put result from CTX in first 64 bytes following RESBUF. The result must be in little endian byte order. */ -void * -sha512_read_ctx (const struct sha512_ctx *ctx, void *resbuf) -{ - int i; - char *r = resbuf; +void* sha512_read_ctx(const struct sha512_ctx* ctx, void* resbuf) { + int i; + char* r = resbuf; - for (i = 0; i < 8; i++) - set_uint64 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i])); + for(i = 0; i < 8; i++) set_uint64(r + i * sizeof ctx->state[0], SWAP(ctx->state[i])); - return resbuf; + return resbuf; } -void * -sha384_read_ctx (const struct sha512_ctx *ctx, void *resbuf) -{ - int i; - char *r = resbuf; +void* sha384_read_ctx(const struct sha512_ctx* ctx, void* resbuf) { + int i; + char* r = resbuf; - for (i = 0; i < 6; i++) - set_uint64 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i])); + for(i = 0; i < 6; i++) set_uint64(r + i * sizeof ctx->state[0], SWAP(ctx->state[i])); - return resbuf; + return resbuf; } /* Process the remaining bytes in the internal buffer and the usual prolog according to the standard and write the result to RESBUF. */ -static void -sha512_conclude_ctx (struct sha512_ctx *ctx) -{ - /* Take yet unprocessed bytes into account. */ - size_t bytes = ctx->buflen; - size_t size = (bytes < 112) ? 128 / 8 : 128 * 2 / 8; +static void sha512_conclude_ctx(struct sha512_ctx* ctx) { + /* Take yet unprocessed bytes into account. */ + size_t bytes = ctx->buflen; + size_t size = (bytes < 112) ? 128 / 8 : 128 * 2 / 8; - /* Now count remaining bytes. */ - ctx->total[0] = u64plus (ctx->total[0], u64lo (bytes)); - if (u64lt (ctx->total[0], u64lo (bytes))) - ctx->total[1] = u64plus (ctx->total[1], u64lo (1)); + /* Now count remaining bytes. */ + ctx->total[0] = u64plus(ctx->total[0], u64lo(bytes)); + if(u64lt(ctx->total[0], u64lo(bytes))) ctx->total[1] = u64plus(ctx->total[1], u64lo(1)); - /* Put the 128-bit file length in *bits* at the end of the buffer. + /* Put the 128-bit file length in *bits* at the end of the buffer. Use set_uint64 rather than a simple assignment, to avoid risk of unaligned access. */ - set_uint64 ((char *) &ctx->buffer[size - 2], - SWAP (u64or (u64shl (ctx->total[1], 3), - u64shr (ctx->total[0], 61)))); - set_uint64 ((char *) &ctx->buffer[size - 1], - SWAP (u64shl (ctx->total[0], 3))); + set_uint64( + (char*)&ctx->buffer[size - 2], + SWAP(u64or(u64shl(ctx->total[1], 3), u64shr(ctx->total[0], 61)))); + set_uint64((char*)&ctx->buffer[size - 1], SWAP(u64shl(ctx->total[0], 3))); - memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 8 - bytes); + memcpy(&((char*)ctx->buffer)[bytes], fillbuf, (size - 2) * 8 - bytes); - /* Process last bytes. */ - sha512_process_block (ctx->buffer, size * 8, ctx); + /* Process last bytes. */ + sha512_process_block(ctx->buffer, size * 8, ctx); } -void * -sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf) -{ - sha512_conclude_ctx (ctx); - return sha512_read_ctx (ctx, resbuf); +void* sha512_finish_ctx(struct sha512_ctx* ctx, void* resbuf) { + sha512_conclude_ctx(ctx); + return sha512_read_ctx(ctx, resbuf); } -void * -sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf) -{ - sha512_conclude_ctx (ctx); - return sha384_read_ctx (ctx, resbuf); +void* sha384_finish_ctx(struct sha512_ctx* ctx, void* resbuf) { + sha512_conclude_ctx(ctx); + return sha384_read_ctx(ctx, resbuf); } /* Compute SHA512 message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -void * -sha512_buffer (const char *buffer, size_t len, void *resblock) -{ - struct sha512_ctx ctx; +void* sha512_buffer(const char* buffer, size_t len, void* resblock) { + struct sha512_ctx ctx; - /* Initialize the computation context. */ - sha512_init_ctx (&ctx); + /* Initialize the computation context. */ + sha512_init_ctx(&ctx); - /* Process whole buffer but last len % 128 bytes. */ - sha512_process_bytes (buffer, len, &ctx); + /* Process whole buffer but last len % 128 bytes. */ + sha512_process_bytes(buffer, len, &ctx); - /* Put result in desired memory area. */ - return sha512_finish_ctx (&ctx, resblock); + /* Put result in desired memory area. */ + return sha512_finish_ctx(&ctx, resblock); } -void * -sha384_buffer (const char *buffer, size_t len, void *resblock) -{ - struct sha512_ctx ctx; +void* sha384_buffer(const char* buffer, size_t len, void* resblock) { + struct sha512_ctx ctx; - /* Initialize the computation context. */ - sha384_init_ctx (&ctx); + /* Initialize the computation context. */ + sha384_init_ctx(&ctx); - /* Process whole buffer but last len % 128 bytes. */ - sha512_process_bytes (buffer, len, &ctx); + /* Process whole buffer but last len % 128 bytes. */ + sha512_process_bytes(buffer, len, &ctx); - /* Put result in desired memory area. */ - return sha384_finish_ctx (&ctx, resblock); + /* Put result in desired memory area. */ + return sha384_finish_ctx(&ctx, resblock); } -void -sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx) -{ - /* When we already have some bits in our internal buffer concatenate +void sha512_process_bytes(const void* buffer, size_t len, struct sha512_ctx* ctx) { + /* When we already have some bits in our internal buffer concatenate both inputs first. */ - if (ctx->buflen != 0) - { - size_t left_over = ctx->buflen; - size_t add = 256 - left_over > len ? len : 256 - left_over; + if(ctx->buflen != 0) { + size_t left_over = ctx->buflen; + size_t add = 256 - left_over > len ? len : 256 - left_over; - memcpy (&((char *) ctx->buffer)[left_over], buffer, add); - ctx->buflen += add; + memcpy(&((char*)ctx->buffer)[left_over], buffer, add); + ctx->buflen += add; - if (ctx->buflen > 128) - { - sha512_process_block (ctx->buffer, ctx->buflen & ~127, ctx); + if(ctx->buflen > 128) { + sha512_process_block(ctx->buffer, ctx->buflen & ~127, ctx); - ctx->buflen &= 127; - /* The regions in the following copy operation cannot overlap, + ctx->buflen &= 127; + /* The regions in the following copy operation cannot overlap, because ctx->buflen < 128 ≤ (left_over + add) & ~127. */ - memcpy (ctx->buffer, - &((char *) ctx->buffer)[(left_over + add) & ~127], - ctx->buflen); + memcpy(ctx->buffer, &((char*)ctx->buffer)[(left_over + add) & ~127], ctx->buflen); } - buffer = (const char *) buffer + add; - len -= add; + buffer = (const char*)buffer + add; + len -= add; } - /* Process available complete blocks. */ - if (len >= 128) - { + /* Process available complete blocks. */ + if(len >= 128) { #if !(_STRING_ARCH_unaligned || _STRING_INLINE_unaligned) -# define UNALIGNED_P(p) ((uintptr_t) (p) % sizeof (u64) != 0) - if (UNALIGNED_P (buffer)) - while (len > 128) - { - sha512_process_block (memcpy (ctx->buffer, buffer, 128), 128, ctx); - buffer = (const char *) buffer + 128; - len -= 128; - } - else +#define UNALIGNED_P(p) ((uintptr_t)(p) % sizeof(u64) != 0) + if(UNALIGNED_P(buffer)) + while(len > 128) { + sha512_process_block(memcpy(ctx->buffer, buffer, 128), 128, ctx); + buffer = (const char*)buffer + 128; + len -= 128; + } + else #endif { - sha512_process_block (buffer, len & ~127, ctx); - buffer = (const char *) buffer + (len & ~127); - len &= 127; + sha512_process_block(buffer, len & ~127, ctx); + buffer = (const char*)buffer + (len & ~127); + len &= 127; } } - /* Move remaining bytes in internal buffer. */ - if (len > 0) - { - size_t left_over = ctx->buflen; + /* Move remaining bytes in internal buffer. */ + if(len > 0) { + size_t left_over = ctx->buflen; - memcpy (&((char *) ctx->buffer)[left_over], buffer, len); - left_over += len; - if (left_over >= 128) - { - sha512_process_block (ctx->buffer, 128, ctx); - left_over -= 128; - /* The regions in the following copy operation cannot overlap, + memcpy(&((char*)ctx->buffer)[left_over], buffer, len); + left_over += len; + if(left_over >= 128) { + sha512_process_block(ctx->buffer, 128, ctx); + left_over -= 128; + /* The regions in the following copy operation cannot overlap, because left_over ≤ 128. */ - memcpy (ctx->buffer, &ctx->buffer[16], left_over); + memcpy(ctx->buffer, &ctx->buffer[16], left_over); } - ctx->buflen = left_over; + ctx->buflen = left_over; } } @@ -266,202 +231,192 @@ sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx) /* SHA512 round constants */ #define K(I) sha512_round_constants[I] static u64 const sha512_round_constants[80] = { - u64init (0x428a2f98, 0xd728ae22), u64init (0x71374491, 0x23ef65cd), - u64init (0xb5c0fbcf, 0xec4d3b2f), u64init (0xe9b5dba5, 0x8189dbbc), - u64init (0x3956c25b, 0xf348b538), u64init (0x59f111f1, 0xb605d019), - u64init (0x923f82a4, 0xaf194f9b), u64init (0xab1c5ed5, 0xda6d8118), - u64init (0xd807aa98, 0xa3030242), u64init (0x12835b01, 0x45706fbe), - u64init (0x243185be, 0x4ee4b28c), u64init (0x550c7dc3, 0xd5ffb4e2), - u64init (0x72be5d74, 0xf27b896f), u64init (0x80deb1fe, 0x3b1696b1), - u64init (0x9bdc06a7, 0x25c71235), u64init (0xc19bf174, 0xcf692694), - u64init (0xe49b69c1, 0x9ef14ad2), u64init (0xefbe4786, 0x384f25e3), - u64init (0x0fc19dc6, 0x8b8cd5b5), u64init (0x240ca1cc, 0x77ac9c65), - u64init (0x2de92c6f, 0x592b0275), u64init (0x4a7484aa, 0x6ea6e483), - u64init (0x5cb0a9dc, 0xbd41fbd4), u64init (0x76f988da, 0x831153b5), - u64init (0x983e5152, 0xee66dfab), u64init (0xa831c66d, 0x2db43210), - u64init (0xb00327c8, 0x98fb213f), u64init (0xbf597fc7, 0xbeef0ee4), - u64init (0xc6e00bf3, 0x3da88fc2), u64init (0xd5a79147, 0x930aa725), - u64init (0x06ca6351, 0xe003826f), u64init (0x14292967, 0x0a0e6e70), - u64init (0x27b70a85, 0x46d22ffc), u64init (0x2e1b2138, 0x5c26c926), - u64init (0x4d2c6dfc, 0x5ac42aed), u64init (0x53380d13, 0x9d95b3df), - u64init (0x650a7354, 0x8baf63de), u64init (0x766a0abb, 0x3c77b2a8), - u64init (0x81c2c92e, 0x47edaee6), u64init (0x92722c85, 0x1482353b), - u64init (0xa2bfe8a1, 0x4cf10364), u64init (0xa81a664b, 0xbc423001), - u64init (0xc24b8b70, 0xd0f89791), u64init (0xc76c51a3, 0x0654be30), - u64init (0xd192e819, 0xd6ef5218), u64init (0xd6990624, 0x5565a910), - u64init (0xf40e3585, 0x5771202a), u64init (0x106aa070, 0x32bbd1b8), - u64init (0x19a4c116, 0xb8d2d0c8), u64init (0x1e376c08, 0x5141ab53), - u64init (0x2748774c, 0xdf8eeb99), u64init (0x34b0bcb5, 0xe19b48a8), - u64init (0x391c0cb3, 0xc5c95a63), u64init (0x4ed8aa4a, 0xe3418acb), - u64init (0x5b9cca4f, 0x7763e373), u64init (0x682e6ff3, 0xd6b2b8a3), - u64init (0x748f82ee, 0x5defb2fc), u64init (0x78a5636f, 0x43172f60), - u64init (0x84c87814, 0xa1f0ab72), u64init (0x8cc70208, 0x1a6439ec), - u64init (0x90befffa, 0x23631e28), u64init (0xa4506ceb, 0xde82bde9), - u64init (0xbef9a3f7, 0xb2c67915), u64init (0xc67178f2, 0xe372532b), - u64init (0xca273ece, 0xea26619c), u64init (0xd186b8c7, 0x21c0c207), - u64init (0xeada7dd6, 0xcde0eb1e), u64init (0xf57d4f7f, 0xee6ed178), - u64init (0x06f067aa, 0x72176fba), u64init (0x0a637dc5, 0xa2c898a6), - u64init (0x113f9804, 0xbef90dae), u64init (0x1b710b35, 0x131c471b), - u64init (0x28db77f5, 0x23047d84), u64init (0x32caab7b, 0x40c72493), - u64init (0x3c9ebe0a, 0x15c9bebc), u64init (0x431d67c4, 0x9c100d4c), - u64init (0x4cc5d4be, 0xcb3e42b6), u64init (0x597f299c, 0xfc657e2a), - u64init (0x5fcb6fab, 0x3ad6faec), u64init (0x6c44198c, 0x4a475817), + u64init(0x428a2f98, 0xd728ae22), u64init(0x71374491, 0x23ef65cd), + u64init(0xb5c0fbcf, 0xec4d3b2f), u64init(0xe9b5dba5, 0x8189dbbc), + u64init(0x3956c25b, 0xf348b538), u64init(0x59f111f1, 0xb605d019), + u64init(0x923f82a4, 0xaf194f9b), u64init(0xab1c5ed5, 0xda6d8118), + u64init(0xd807aa98, 0xa3030242), u64init(0x12835b01, 0x45706fbe), + u64init(0x243185be, 0x4ee4b28c), u64init(0x550c7dc3, 0xd5ffb4e2), + u64init(0x72be5d74, 0xf27b896f), u64init(0x80deb1fe, 0x3b1696b1), + u64init(0x9bdc06a7, 0x25c71235), u64init(0xc19bf174, 0xcf692694), + u64init(0xe49b69c1, 0x9ef14ad2), u64init(0xefbe4786, 0x384f25e3), + u64init(0x0fc19dc6, 0x8b8cd5b5), u64init(0x240ca1cc, 0x77ac9c65), + u64init(0x2de92c6f, 0x592b0275), u64init(0x4a7484aa, 0x6ea6e483), + u64init(0x5cb0a9dc, 0xbd41fbd4), u64init(0x76f988da, 0x831153b5), + u64init(0x983e5152, 0xee66dfab), u64init(0xa831c66d, 0x2db43210), + u64init(0xb00327c8, 0x98fb213f), u64init(0xbf597fc7, 0xbeef0ee4), + u64init(0xc6e00bf3, 0x3da88fc2), u64init(0xd5a79147, 0x930aa725), + u64init(0x06ca6351, 0xe003826f), u64init(0x14292967, 0x0a0e6e70), + u64init(0x27b70a85, 0x46d22ffc), u64init(0x2e1b2138, 0x5c26c926), + u64init(0x4d2c6dfc, 0x5ac42aed), u64init(0x53380d13, 0x9d95b3df), + u64init(0x650a7354, 0x8baf63de), u64init(0x766a0abb, 0x3c77b2a8), + u64init(0x81c2c92e, 0x47edaee6), u64init(0x92722c85, 0x1482353b), + u64init(0xa2bfe8a1, 0x4cf10364), u64init(0xa81a664b, 0xbc423001), + u64init(0xc24b8b70, 0xd0f89791), u64init(0xc76c51a3, 0x0654be30), + u64init(0xd192e819, 0xd6ef5218), u64init(0xd6990624, 0x5565a910), + u64init(0xf40e3585, 0x5771202a), u64init(0x106aa070, 0x32bbd1b8), + u64init(0x19a4c116, 0xb8d2d0c8), u64init(0x1e376c08, 0x5141ab53), + u64init(0x2748774c, 0xdf8eeb99), u64init(0x34b0bcb5, 0xe19b48a8), + u64init(0x391c0cb3, 0xc5c95a63), u64init(0x4ed8aa4a, 0xe3418acb), + u64init(0x5b9cca4f, 0x7763e373), u64init(0x682e6ff3, 0xd6b2b8a3), + u64init(0x748f82ee, 0x5defb2fc), u64init(0x78a5636f, 0x43172f60), + u64init(0x84c87814, 0xa1f0ab72), u64init(0x8cc70208, 0x1a6439ec), + u64init(0x90befffa, 0x23631e28), u64init(0xa4506ceb, 0xde82bde9), + u64init(0xbef9a3f7, 0xb2c67915), u64init(0xc67178f2, 0xe372532b), + u64init(0xca273ece, 0xea26619c), u64init(0xd186b8c7, 0x21c0c207), + u64init(0xeada7dd6, 0xcde0eb1e), u64init(0xf57d4f7f, 0xee6ed178), + u64init(0x06f067aa, 0x72176fba), u64init(0x0a637dc5, 0xa2c898a6), + u64init(0x113f9804, 0xbef90dae), u64init(0x1b710b35, 0x131c471b), + u64init(0x28db77f5, 0x23047d84), u64init(0x32caab7b, 0x40c72493), + u64init(0x3c9ebe0a, 0x15c9bebc), u64init(0x431d67c4, 0x9c100d4c), + u64init(0x4cc5d4be, 0xcb3e42b6), u64init(0x597f299c, 0xfc657e2a), + u64init(0x5fcb6fab, 0x3ad6faec), u64init(0x6c44198c, 0x4a475817), }; /* Round functions. */ -#define F2(A, B, C) u64or (u64and (A, B), u64and (C, u64or (A, B))) -#define F1(E, F, G) u64xor (G, u64and (E, u64xor (F, G))) +#define F2(A, B, C) u64or(u64and(A, B), u64and(C, u64or(A, B))) +#define F1(E, F, G) u64xor(G, u64and(E, u64xor(F, G))) /* Process LEN bytes of BUFFER, accumulating context into CTX. It is assumed that LEN % 128 == 0. Most of this code comes from GnuPG's cipher/sha1.c. */ -void -sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx) -{ - u64 const *words = buffer; - u64 const *endp = words + len / sizeof (u64); - u64 x[16]; - u64 a = ctx->state[0]; - u64 b = ctx->state[1]; - u64 c = ctx->state[2]; - u64 d = ctx->state[3]; - u64 e = ctx->state[4]; - u64 f = ctx->state[5]; - u64 g = ctx->state[6]; - u64 h = ctx->state[7]; - u64 lolen = u64size (len); +void sha512_process_block(const void* buffer, size_t len, struct sha512_ctx* ctx) { + u64 const* words = buffer; + u64 const* endp = words + len / sizeof(u64); + u64 x[16]; + u64 a = ctx->state[0]; + u64 b = ctx->state[1]; + u64 c = ctx->state[2]; + u64 d = ctx->state[3]; + u64 e = ctx->state[4]; + u64 f = ctx->state[5]; + u64 g = ctx->state[6]; + u64 h = ctx->state[7]; + u64 lolen = u64size(len); - /* First increment the byte count. FIPS PUB 180-2 specifies the possible + /* First increment the byte count. FIPS PUB 180-2 specifies the possible length of the file up to 2^128 bits. Here we only compute the number of bytes. Do a double word increment. */ - ctx->total[0] = u64plus (ctx->total[0], lolen); - ctx->total[1] = u64plus (ctx->total[1], - u64plus (u64size (len >> 31 >> 31 >> 2), - u64lo (u64lt (ctx->total[0], lolen)))); + ctx->total[0] = u64plus(ctx->total[0], lolen); + ctx->total[1] = u64plus( + ctx->total[1], u64plus(u64size(len >> 31 >> 31 >> 2), u64lo(u64lt(ctx->total[0], lolen)))); -#define S0(x) u64xor (u64rol(x, 63), u64xor (u64rol (x, 56), u64shr (x, 7))) -#define S1(x) u64xor (u64rol (x, 45), u64xor (u64rol (x, 3), u64shr (x, 6))) -#define SS0(x) u64xor (u64rol (x, 36), u64xor (u64rol (x, 30), u64rol (x, 25))) -#define SS1(x) u64xor (u64rol(x, 50), u64xor (u64rol (x, 46), u64rol (x, 23))) +#define S0(x) u64xor(u64rol(x, 63), u64xor(u64rol(x, 56), u64shr(x, 7))) +#define S1(x) u64xor(u64rol(x, 45), u64xor(u64rol(x, 3), u64shr(x, 6))) +#define SS0(x) u64xor(u64rol(x, 36), u64xor(u64rol(x, 30), u64rol(x, 25))) +#define SS1(x) u64xor(u64rol(x, 50), u64xor(u64rol(x, 46), u64rol(x, 23))) -#define M(I) (x[(I) & 15] \ - = u64plus (x[(I) & 15], \ - u64plus (S1 (x[((I) - 2) & 15]), \ - u64plus (x[((I) - 7) & 15], \ - S0 (x[((I) - 15) & 15]))))) +#define M(I) \ + (x[(I)&15] = u64plus( \ + x[(I)&15], \ + u64plus(S1(x[((I)-2) & 15]), u64plus(x[((I)-7) & 15], S0(x[((I)-15) & 15]))))) -#define R(A, B, C, D, E, F, G, H, K, M) \ - do \ - { \ - u64 t0 = u64plus (SS0 (A), F2 (A, B, C)); \ - u64 t1 = \ - u64plus (H, u64plus (SS1 (E), \ - u64plus (F1 (E, F, G), u64plus (K, M)))); \ - D = u64plus (D, t1); \ - H = u64plus (t0, t1); \ - } \ - while (0) +#define R(A, B, C, D, E, F, G, H, K, M) \ + do { \ + u64 t0 = u64plus(SS0(A), F2(A, B, C)); \ + u64 t1 = u64plus(H, u64plus(SS1(E), u64plus(F1(E, F, G), u64plus(K, M)))); \ + D = u64plus(D, t1); \ + H = u64plus(t0, t1); \ + } while(0) - while (words < endp) - { - int t; - /* FIXME: see sha1.c for a better implementation. */ - for (t = 0; t < 16; t++) - { - x[t] = SWAP (*words); - words++; + while(words < endp) { + int t; + /* FIXME: see sha1.c for a better implementation. */ + for(t = 0; t < 16; t++) { + x[t] = SWAP(*words); + words++; } - R( a, b, c, d, e, f, g, h, K( 0), x[ 0] ); - R( h, a, b, c, d, e, f, g, K( 1), x[ 1] ); - R( g, h, a, b, c, d, e, f, K( 2), x[ 2] ); - R( f, g, h, a, b, c, d, e, K( 3), x[ 3] ); - R( e, f, g, h, a, b, c, d, K( 4), x[ 4] ); - R( d, e, f, g, h, a, b, c, K( 5), x[ 5] ); - R( c, d, e, f, g, h, a, b, K( 6), x[ 6] ); - R( b, c, d, e, f, g, h, a, K( 7), x[ 7] ); - R( a, b, c, d, e, f, g, h, K( 8), x[ 8] ); - R( h, a, b, c, d, e, f, g, K( 9), x[ 9] ); - R( g, h, a, b, c, d, e, f, K(10), x[10] ); - R( f, g, h, a, b, c, d, e, K(11), x[11] ); - R( e, f, g, h, a, b, c, d, K(12), x[12] ); - R( d, e, f, g, h, a, b, c, K(13), x[13] ); - R( c, d, e, f, g, h, a, b, K(14), x[14] ); - R( b, c, d, e, f, g, h, a, K(15), x[15] ); - R( a, b, c, d, e, f, g, h, K(16), M(16) ); - R( h, a, b, c, d, e, f, g, K(17), M(17) ); - R( g, h, a, b, c, d, e, f, K(18), M(18) ); - R( f, g, h, a, b, c, d, e, K(19), M(19) ); - R( e, f, g, h, a, b, c, d, K(20), M(20) ); - R( d, e, f, g, h, a, b, c, K(21), M(21) ); - R( c, d, e, f, g, h, a, b, K(22), M(22) ); - R( b, c, d, e, f, g, h, a, K(23), M(23) ); - R( a, b, c, d, e, f, g, h, K(24), M(24) ); - R( h, a, b, c, d, e, f, g, K(25), M(25) ); - R( g, h, a, b, c, d, e, f, K(26), M(26) ); - R( f, g, h, a, b, c, d, e, K(27), M(27) ); - R( e, f, g, h, a, b, c, d, K(28), M(28) ); - R( d, e, f, g, h, a, b, c, K(29), M(29) ); - R( c, d, e, f, g, h, a, b, K(30), M(30) ); - R( b, c, d, e, f, g, h, a, K(31), M(31) ); - R( a, b, c, d, e, f, g, h, K(32), M(32) ); - R( h, a, b, c, d, e, f, g, K(33), M(33) ); - R( g, h, a, b, c, d, e, f, K(34), M(34) ); - R( f, g, h, a, b, c, d, e, K(35), M(35) ); - R( e, f, g, h, a, b, c, d, K(36), M(36) ); - R( d, e, f, g, h, a, b, c, K(37), M(37) ); - R( c, d, e, f, g, h, a, b, K(38), M(38) ); - R( b, c, d, e, f, g, h, a, K(39), M(39) ); - R( a, b, c, d, e, f, g, h, K(40), M(40) ); - R( h, a, b, c, d, e, f, g, K(41), M(41) ); - R( g, h, a, b, c, d, e, f, K(42), M(42) ); - R( f, g, h, a, b, c, d, e, K(43), M(43) ); - R( e, f, g, h, a, b, c, d, K(44), M(44) ); - R( d, e, f, g, h, a, b, c, K(45), M(45) ); - R( c, d, e, f, g, h, a, b, K(46), M(46) ); - R( b, c, d, e, f, g, h, a, K(47), M(47) ); - R( a, b, c, d, e, f, g, h, K(48), M(48) ); - R( h, a, b, c, d, e, f, g, K(49), M(49) ); - R( g, h, a, b, c, d, e, f, K(50), M(50) ); - R( f, g, h, a, b, c, d, e, K(51), M(51) ); - R( e, f, g, h, a, b, c, d, K(52), M(52) ); - R( d, e, f, g, h, a, b, c, K(53), M(53) ); - R( c, d, e, f, g, h, a, b, K(54), M(54) ); - R( b, c, d, e, f, g, h, a, K(55), M(55) ); - R( a, b, c, d, e, f, g, h, K(56), M(56) ); - R( h, a, b, c, d, e, f, g, K(57), M(57) ); - R( g, h, a, b, c, d, e, f, K(58), M(58) ); - R( f, g, h, a, b, c, d, e, K(59), M(59) ); - R( e, f, g, h, a, b, c, d, K(60), M(60) ); - R( d, e, f, g, h, a, b, c, K(61), M(61) ); - R( c, d, e, f, g, h, a, b, K(62), M(62) ); - R( b, c, d, e, f, g, h, a, K(63), M(63) ); - R( a, b, c, d, e, f, g, h, K(64), M(64) ); - R( h, a, b, c, d, e, f, g, K(65), M(65) ); - R( g, h, a, b, c, d, e, f, K(66), M(66) ); - R( f, g, h, a, b, c, d, e, K(67), M(67) ); - R( e, f, g, h, a, b, c, d, K(68), M(68) ); - R( d, e, f, g, h, a, b, c, K(69), M(69) ); - R( c, d, e, f, g, h, a, b, K(70), M(70) ); - R( b, c, d, e, f, g, h, a, K(71), M(71) ); - R( a, b, c, d, e, f, g, h, K(72), M(72) ); - R( h, a, b, c, d, e, f, g, K(73), M(73) ); - R( g, h, a, b, c, d, e, f, K(74), M(74) ); - R( f, g, h, a, b, c, d, e, K(75), M(75) ); - R( e, f, g, h, a, b, c, d, K(76), M(76) ); - R( d, e, f, g, h, a, b, c, K(77), M(77) ); - R( c, d, e, f, g, h, a, b, K(78), M(78) ); - R( b, c, d, e, f, g, h, a, K(79), M(79) ); + R(a, b, c, d, e, f, g, h, K(0), x[0]); + R(h, a, b, c, d, e, f, g, K(1), x[1]); + R(g, h, a, b, c, d, e, f, K(2), x[2]); + R(f, g, h, a, b, c, d, e, K(3), x[3]); + R(e, f, g, h, a, b, c, d, K(4), x[4]); + R(d, e, f, g, h, a, b, c, K(5), x[5]); + R(c, d, e, f, g, h, a, b, K(6), x[6]); + R(b, c, d, e, f, g, h, a, K(7), x[7]); + R(a, b, c, d, e, f, g, h, K(8), x[8]); + R(h, a, b, c, d, e, f, g, K(9), x[9]); + R(g, h, a, b, c, d, e, f, K(10), x[10]); + R(f, g, h, a, b, c, d, e, K(11), x[11]); + R(e, f, g, h, a, b, c, d, K(12), x[12]); + R(d, e, f, g, h, a, b, c, K(13), x[13]); + R(c, d, e, f, g, h, a, b, K(14), x[14]); + R(b, c, d, e, f, g, h, a, K(15), x[15]); + R(a, b, c, d, e, f, g, h, K(16), M(16)); + R(h, a, b, c, d, e, f, g, K(17), M(17)); + R(g, h, a, b, c, d, e, f, K(18), M(18)); + R(f, g, h, a, b, c, d, e, K(19), M(19)); + R(e, f, g, h, a, b, c, d, K(20), M(20)); + R(d, e, f, g, h, a, b, c, K(21), M(21)); + R(c, d, e, f, g, h, a, b, K(22), M(22)); + R(b, c, d, e, f, g, h, a, K(23), M(23)); + R(a, b, c, d, e, f, g, h, K(24), M(24)); + R(h, a, b, c, d, e, f, g, K(25), M(25)); + R(g, h, a, b, c, d, e, f, K(26), M(26)); + R(f, g, h, a, b, c, d, e, K(27), M(27)); + R(e, f, g, h, a, b, c, d, K(28), M(28)); + R(d, e, f, g, h, a, b, c, K(29), M(29)); + R(c, d, e, f, g, h, a, b, K(30), M(30)); + R(b, c, d, e, f, g, h, a, K(31), M(31)); + R(a, b, c, d, e, f, g, h, K(32), M(32)); + R(h, a, b, c, d, e, f, g, K(33), M(33)); + R(g, h, a, b, c, d, e, f, K(34), M(34)); + R(f, g, h, a, b, c, d, e, K(35), M(35)); + R(e, f, g, h, a, b, c, d, K(36), M(36)); + R(d, e, f, g, h, a, b, c, K(37), M(37)); + R(c, d, e, f, g, h, a, b, K(38), M(38)); + R(b, c, d, e, f, g, h, a, K(39), M(39)); + R(a, b, c, d, e, f, g, h, K(40), M(40)); + R(h, a, b, c, d, e, f, g, K(41), M(41)); + R(g, h, a, b, c, d, e, f, K(42), M(42)); + R(f, g, h, a, b, c, d, e, K(43), M(43)); + R(e, f, g, h, a, b, c, d, K(44), M(44)); + R(d, e, f, g, h, a, b, c, K(45), M(45)); + R(c, d, e, f, g, h, a, b, K(46), M(46)); + R(b, c, d, e, f, g, h, a, K(47), M(47)); + R(a, b, c, d, e, f, g, h, K(48), M(48)); + R(h, a, b, c, d, e, f, g, K(49), M(49)); + R(g, h, a, b, c, d, e, f, K(50), M(50)); + R(f, g, h, a, b, c, d, e, K(51), M(51)); + R(e, f, g, h, a, b, c, d, K(52), M(52)); + R(d, e, f, g, h, a, b, c, K(53), M(53)); + R(c, d, e, f, g, h, a, b, K(54), M(54)); + R(b, c, d, e, f, g, h, a, K(55), M(55)); + R(a, b, c, d, e, f, g, h, K(56), M(56)); + R(h, a, b, c, d, e, f, g, K(57), M(57)); + R(g, h, a, b, c, d, e, f, K(58), M(58)); + R(f, g, h, a, b, c, d, e, K(59), M(59)); + R(e, f, g, h, a, b, c, d, K(60), M(60)); + R(d, e, f, g, h, a, b, c, K(61), M(61)); + R(c, d, e, f, g, h, a, b, K(62), M(62)); + R(b, c, d, e, f, g, h, a, K(63), M(63)); + R(a, b, c, d, e, f, g, h, K(64), M(64)); + R(h, a, b, c, d, e, f, g, K(65), M(65)); + R(g, h, a, b, c, d, e, f, K(66), M(66)); + R(f, g, h, a, b, c, d, e, K(67), M(67)); + R(e, f, g, h, a, b, c, d, K(68), M(68)); + R(d, e, f, g, h, a, b, c, K(69), M(69)); + R(c, d, e, f, g, h, a, b, K(70), M(70)); + R(b, c, d, e, f, g, h, a, K(71), M(71)); + R(a, b, c, d, e, f, g, h, K(72), M(72)); + R(h, a, b, c, d, e, f, g, K(73), M(73)); + R(g, h, a, b, c, d, e, f, K(74), M(74)); + R(f, g, h, a, b, c, d, e, K(75), M(75)); + R(e, f, g, h, a, b, c, d, K(76), M(76)); + R(d, e, f, g, h, a, b, c, K(77), M(77)); + R(c, d, e, f, g, h, a, b, K(78), M(78)); + R(b, c, d, e, f, g, h, a, K(79), M(79)); - a = ctx->state[0] = u64plus (ctx->state[0], a); - b = ctx->state[1] = u64plus (ctx->state[1], b); - c = ctx->state[2] = u64plus (ctx->state[2], c); - d = ctx->state[3] = u64plus (ctx->state[3], d); - e = ctx->state[4] = u64plus (ctx->state[4], e); - f = ctx->state[5] = u64plus (ctx->state[5], f); - g = ctx->state[6] = u64plus (ctx->state[6], g); - h = ctx->state[7] = u64plus (ctx->state[7], h); + a = ctx->state[0] = u64plus(ctx->state[0], a); + b = ctx->state[1] = u64plus(ctx->state[1], b); + c = ctx->state[2] = u64plus(ctx->state[2], c); + d = ctx->state[3] = u64plus(ctx->state[3], d); + e = ctx->state[4] = u64plus(ctx->state[4], e); + f = ctx->state[5] = u64plus(ctx->state[5], f); + g = ctx->state[6] = u64plus(ctx->state[6], g); + h = ctx->state[7] = u64plus(ctx->state[7], h); } } diff --git a/applications/plugins/totp/services/hmac/sha512.h b/applications/plugins/totp/services/hmac/sha512.h index 59949471f..6489fc3cb 100644 --- a/applications/plugins/totp/services/hmac/sha512.h +++ b/applications/plugins/totp/services/hmac/sha512.h @@ -17,64 +17,60 @@ #pragma once -# include -# include "u64.h" +#include +#include "u64.h" -# if HAVE_OPENSSL_SHA512 -# ifndef OPENSSL_API_COMPAT -# define OPENSSL_API_COMPAT 0x10101000L /* FIXME: Use OpenSSL 1.1+ API. */ -# endif -# include -# endif +#if HAVE_OPENSSL_SHA512 +#ifndef OPENSSL_API_COMPAT +#define OPENSSL_API_COMPAT 0x10101000L /* FIXME: Use OpenSSL 1.1+ API. */ +#endif +#include +#endif -# ifdef __cplusplus +#ifdef __cplusplus extern "C" { -# endif +#endif enum { SHA384_DIGEST_SIZE = 384 / 8 }; enum { SHA512_DIGEST_SIZE = 512 / 8 }; -# if HAVE_OPENSSL_SHA512 -# define GL_OPENSSL_NAME 384 -# include "gl_openssl.h" -# define GL_OPENSSL_NAME 512 -# include "gl_openssl.h" -# else +#if HAVE_OPENSSL_SHA512 +#define GL_OPENSSL_NAME 384 +#include "gl_openssl.h" +#define GL_OPENSSL_NAME 512 +#include "gl_openssl.h" +#else /* Structure to save state of computation between the single steps. */ -struct sha512_ctx -{ - u64 state[8]; +struct sha512_ctx { + u64 state[8]; - u64 total[2]; - size_t buflen; /* ≥ 0, ≤ 256 */ - u64 buffer[32]; /* 256 bytes; the first buflen bytes are in use */ + u64 total[2]; + size_t buflen; /* ≥ 0, ≤ 256 */ + u64 buffer[32]; /* 256 bytes; the first buflen bytes are in use */ }; /* Initialize structure containing state of computation. */ -extern void sha512_init_ctx (struct sha512_ctx *ctx); -extern void sha384_init_ctx (struct sha512_ctx *ctx); +extern void sha512_init_ctx(struct sha512_ctx* ctx); +extern void sha384_init_ctx(struct sha512_ctx* ctx); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is necessary that LEN is a multiple of 128!!! */ -extern void sha512_process_block (const void *buffer, size_t len, - struct sha512_ctx *ctx); +extern void sha512_process_block(const void* buffer, size_t len, struct sha512_ctx* ctx); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is NOT required that LEN is a multiple of 128. */ -extern void sha512_process_bytes (const void *buffer, size_t len, - struct sha512_ctx *ctx); +extern void sha512_process_bytes(const void* buffer, size_t len, struct sha512_ctx* ctx); /* Process the remaining bytes in the buffer and put result from CTX in first 64 (48) bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha512_finish_ctx (struct sha512_ctx *ctx, void *restrict resbuf); -extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void *restrict resbuf); - +extern void* sha512_finish_ctx(struct sha512_ctx* ctx, void* restrict resbuf); +extern void* sha384_finish_ctx(struct sha512_ctx* ctx, void* restrict resbuf); /* Put result from CTX in first 64 (48) bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields @@ -82,22 +78,17 @@ extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void *restrict resbuf); IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ -extern void *sha512_read_ctx (const struct sha512_ctx *ctx, - void *restrict resbuf); -extern void *sha384_read_ctx (const struct sha512_ctx *ctx, - void *restrict resbuf); - +extern void* sha512_read_ctx(const struct sha512_ctx* ctx, void* restrict resbuf); +extern void* sha384_read_ctx(const struct sha512_ctx* ctx, void* restrict resbuf); /* Compute SHA512 (SHA384) message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha512_buffer (const char *buffer, size_t len, - void *restrict resblock); -extern void *sha384_buffer (const char *buffer, size_t len, - void *restrict resblock); +extern void* sha512_buffer(const char* buffer, size_t len, void* restrict resblock); +extern void* sha384_buffer(const char* buffer, size_t len, void* restrict resblock); -# endif +#endif /* Compute SHA512 (SHA384) message digest for bytes read from STREAM. STREAM is an open file stream. Regular files are handled more efficiently. @@ -105,13 +96,12 @@ extern void *sha384_buffer (const char *buffer, size_t len, The case that the last operation on STREAM was an 'ungetc' is not supported. The resulting message digest number will be written into the 64 (48) bytes beginning at RESBLOCK. */ -extern int sha512_stream (FILE *stream, void *resblock); -extern int sha384_stream (FILE *stream, void *resblock); +extern int sha512_stream(FILE* stream, void* resblock); +extern int sha384_stream(FILE* stream, void* resblock); - -# ifdef __cplusplus +#ifdef __cplusplus } -# endif +#endif /* * Hey Emacs! diff --git a/applications/plugins/totp/services/hmac/u64.h b/applications/plugins/totp/services/hmac/u64.h index df94d08ac..af0bb067b 100644 --- a/applications/plugins/totp/services/hmac/u64.h +++ b/applications/plugins/totp/services/hmac/u64.h @@ -22,23 +22,23 @@ #include #ifndef _GL_U64_INLINE -# define _GL_U64_INLINE _GL_INLINE +#define _GL_U64_INLINE _GL_INLINE #endif /* Return X rotated left by N bits, where 0 < N < 64. */ -#define u64rol(x, n) u64or (u64shl (x, n), u64shr (x, 64 - n)) +#define u64rol(x, n) u64or(u64shl(x, n), u64shr(x, 64 - n)) /* Native implementations are trivial. See below for comments on what these operations do. */ typedef uint64_t u64; -# define u64hilo(hi, lo) ((u64) (((u64) (hi) << 32) + (lo))) -# define u64init(hi, lo) u64hilo (hi, lo) -# define u64lo(x) ((u64) (x)) -# define u64size(x) u64lo (x) -# define u64lt(x, y) ((x) < (y)) -# define u64and(x, y) ((x) & (y)) -# define u64or(x, y) ((x) | (y)) -# define u64xor(x, y) ((x) ^ (y)) -# define u64plus(x, y) ((x) + (y)) -# define u64shl(x, n) ((x) << (n)) -# define u64shr(x, n) ((x) >> (n)) +#define u64hilo(hi, lo) ((u64)(((u64)(hi) << 32) + (lo))) +#define u64init(hi, lo) u64hilo(hi, lo) +#define u64lo(x) ((u64)(x)) +#define u64size(x) u64lo(x) +#define u64lt(x, y) ((x) < (y)) +#define u64and(x, y) ((x) & (y)) +#define u64or(x, y) ((x) | (y)) +#define u64xor(x, y) ((x) ^ (y)) +#define u64plus(x, y) ((x) + (y)) +#define u64shl(x, n) ((x) << (n)) +#define u64shr(x, n) ((x) >> (n)) diff --git a/applications/plugins/totp/services/list/list.c b/applications/plugins/totp/services/list/list.c index 08c9d9930..77df1105a 100644 --- a/applications/plugins/totp/services/list/list.c +++ b/applications/plugins/totp/services/list/list.c @@ -1,23 +1,23 @@ #include "list.h" -ListNode *list_init_head(void* data) { - ListNode *new = (ListNode *) malloc(sizeof(ListNode)); +ListNode* list_init_head(void* data) { + ListNode* new = (ListNode*)malloc(sizeof(ListNode)); new->data = data; new->next = NULL; return new; } -ListNode *list_add(ListNode *head, void* data) { - ListNode *new = (ListNode *) malloc(sizeof(ListNode)); +ListNode* list_add(ListNode* head, void* data) { + ListNode* new = (ListNode*)malloc(sizeof(ListNode)); new->data = data; new->next = NULL; - if (head == NULL) + if(head == NULL) head = new; else { - ListNode *it; + ListNode* it; - for (it = head; it->next != NULL; it = it->next) + for(it = head; it->next != NULL; it = it->next) ; it->next = new; @@ -26,33 +26,33 @@ ListNode *list_add(ListNode *head, void* data) { return head; } -ListNode *list_find(ListNode *head, void* data) { - ListNode *it; +ListNode* list_find(ListNode* head, void* data) { + ListNode* it; - for (it = head; it != NULL; it = it->next) - if (it->data == data) - break; + for(it = head; it != NULL; it = it->next) + if(it->data == data) break; return it; } -ListNode *list_element_at(ListNode *head, uint16_t index) { - ListNode *it; +ListNode* list_element_at(ListNode* head, uint16_t index) { + ListNode* it; uint16_t i; - for (it = head, i = 0; it != NULL && i < index; it = it->next, i++); + for(it = head, i = 0; it != NULL && i < index; it = it->next, i++) + ; return it; } -ListNode *list_remove(ListNode *head, ListNode *ep) { - if (head == ep) { - ListNode *new_head = head->next; +ListNode* list_remove(ListNode* head, ListNode* ep) { + if(head == ep) { + ListNode* new_head = head->next; free(head); return new_head; } - ListNode *it; + ListNode* it; - for (it = head; it->next != ep; it = it->next) + for(it = head; it->next != ep; it = it->next) ; it->next = ep->next; @@ -61,10 +61,10 @@ ListNode *list_remove(ListNode *head, ListNode *ep) { return head; } -void list_free(ListNode *head) { +void list_free(ListNode* head) { ListNode *it = head, *tmp; - while (it != NULL) { + while(it != NULL) { tmp = it; it = it->next; free(tmp); diff --git a/applications/plugins/totp/services/list/list.h b/applications/plugins/totp/services/list/list.h index ee7473704..771eac565 100644 --- a/applications/plugins/totp/services/list/list.h +++ b/applications/plugins/totp/services/list/list.h @@ -5,12 +5,20 @@ typedef struct ListNode { void* data; - struct ListNode *next; + struct ListNode* next; } ListNode; -ListNode *list_init_head(void* data); -ListNode *list_add(ListNode *head, void* data); /* adds element with specified data to the end of the list and returns new head node. */ -ListNode *list_find(ListNode *head, void* data); /* returns pointer of element with specified data in list. */ -ListNode *list_element_at(ListNode *head, uint16_t index); /* returns pointer of element with specified index in list. */ -ListNode *list_remove(ListNode *head, ListNode *ep); /* removes element from the list and returns new head node. */ -void list_free(ListNode *head); /* deletes all elements of the list. */ +ListNode* list_init_head(void* data); +ListNode* list_add( + ListNode* head, + void* data); /* adds element with specified data to the end of the list and returns new head node. */ +ListNode* list_find( + ListNode* head, + void* data); /* returns pointer of element with specified data in list. */ +ListNode* list_element_at( + ListNode* head, + uint16_t index); /* returns pointer of element with specified index in list. */ +ListNode* list_remove( + ListNode* head, + ListNode* ep); /* removes element from the list and returns new head node. */ +void list_free(ListNode* head); /* deletes all elements of the list. */ diff --git a/applications/plugins/totp/services/timezone_utils/timezone_utils.c b/applications/plugins/totp/services/timezone_utils/timezone_utils.c index 7638da89f..31df3bbba 100644 --- a/applications/plugins/totp/services/timezone_utils/timezone_utils.c +++ b/applications/plugins/totp/services/timezone_utils/timezone_utils.c @@ -6,7 +6,7 @@ int32_t timezone_offset_from_hours(float hours) { uint64_t timezone_offset_apply(uint64_t time, int32_t offset) { uint64_t for_time_adjusted; - if (offset > 0) { + if(offset > 0) { for_time_adjusted = time - offset; } else { for_time_adjusted = time + (-offset); diff --git a/applications/plugins/totp/services/totp/totp.c b/applications/plugins/totp/services/totp/totp.c index 9a1c7f234..8c51cde38 100644 --- a/applications/plugins/totp/services/totp/totp.c +++ b/applications/plugins/totp/services/totp/totp.c @@ -5,9 +5,9 @@ #include #include #include -#include "../hmac/hmac-sha1.h" -#include "../hmac/hmac-sha256.h" -#include "../hmac/hmac-sha512.h" +#include "../hmac/hmac_sha1.h" +#include "../hmac/hmac_sha256.h" +#include "../hmac/hmac_sha512.h" #include "../timezone_utils/timezone_utils.h" #define UINT64_GET_BYTE(integer, index) ((integer >> (8 * index)) & 0xFF) @@ -25,9 +25,8 @@ timeblock given for_time, using data->interval error, 0 */ -uint64_t totp_timecode(uint8_t interval, uint64_t for_time) -{ - return for_time/interval; +uint64_t totp_timecode(uint8_t interval, uint64_t for_time) { + return for_time / interval; } /* @@ -35,8 +34,7 @@ uint64_t totp_timecode(uint8_t interval, uint64_t for_time) out_bytes is the null-terminated output string already allocated */ -void otp_num_to_bytes(uint64_t integer, uint8_t* out_bytes) -{ +void otp_num_to_bytes(uint64_t integer, uint8_t* out_bytes) { out_bytes[7] = UINT64_GET_BYTE(integer, 0); out_bytes[6] = UINT64_GET_BYTE(integer, 1); out_bytes[5] = UINT64_GET_BYTE(integer, 2); @@ -57,33 +55,35 @@ void otp_num_to_bytes(uint64_t integer, uint8_t* out_bytes) OTP code if otp code was successfully generated 0 otherwise */ -uint32_t otp_generate(TOTP_ALGO algo, uint8_t digits, const uint8_t* plain_secret, uint8_t plain_secret_length, uint64_t input) -{ - uint8_t* bytes = malloc(8); +uint32_t otp_generate( + TOTP_ALGO algo, + uint8_t digits, + const uint8_t* plain_secret, + uint8_t plain_secret_length, + uint64_t input) { + uint8_t* bytes = malloc(8); memset(bytes, 0, 8); - uint8_t* hmac = malloc(64); + uint8_t* hmac = malloc(64); memset(hmac, 0, 64); otp_num_to_bytes(input, bytes); - - int hmac_len = (*(algo))(plain_secret, plain_secret_length, bytes, 8, hmac); - if (hmac_len == 0) { - free(hmac); + + int hmac_len = (*(algo))(plain_secret, plain_secret_length, bytes, 8, hmac); + if(hmac_len == 0) { + free(hmac); free(bytes); return OTP_ERROR; } - - uint64_t offset = (hmac[hmac_len-1] & 0xF); - uint64_t i_code = - ((hmac[offset] & 0x7F) << 24 | - (hmac[offset + 1] & 0xFF) << 16 | - (hmac[offset + 2] & 0xFF) << 8 | - (hmac[offset + 3] & 0xFF)); - i_code %= (uint64_t) pow(10, digits); - free(hmac); - free(bytes); - return i_code; + uint64_t offset = (hmac[hmac_len - 1] & 0xF); + uint64_t i_code = + ((hmac[offset] & 0x7F) << 24 | (hmac[offset + 1] & 0xFF) << 16 | + (hmac[offset + 2] & 0xFF) << 8 | (hmac[offset + 3] & 0xFF)); + i_code %= (uint64_t)pow(10, digits); + + free(hmac); + free(bytes); + return i_code; } /* @@ -97,25 +97,52 @@ uint32_t otp_generate(TOTP_ALGO algo, uint8_t digits, const uint8_t* plain_secre TOTP code if otp code was successfully generated 0 otherwise */ -uint32_t totp_at(TOTP_ALGO algo, uint8_t digits, const uint8_t* plain_secret, uint8_t plain_secret_length, uint64_t for_time, float timezone, uint8_t interval) -{ - uint64_t for_time_adjusted = timezone_offset_apply(for_time, timezone_offset_from_hours(timezone)); - return otp_generate(algo, digits, plain_secret, plain_secret_length, totp_timecode(interval, for_time_adjusted)); +uint32_t totp_at( + TOTP_ALGO algo, + uint8_t digits, + const uint8_t* plain_secret, + uint8_t plain_secret_length, + uint64_t for_time, + float timezone, + uint8_t interval) { + uint64_t for_time_adjusted = + timezone_offset_apply(for_time, timezone_offset_from_hours(timezone)); + return otp_generate( + algo, + digits, + plain_secret, + plain_secret_length, + totp_timecode(interval, for_time_adjusted)); } -static int totp_algo_sha1(const uint8_t* key, uint8_t key_length, const uint8_t* input, uint8_t input_length, uint8_t* output) { - hmac_sha1(key, key_length, input, input_length, output); - return HMAC_SHA1_RESULT_SIZE; +static int totp_algo_sha1( + const uint8_t* key, + uint8_t key_length, + const uint8_t* input, + uint8_t input_length, + uint8_t* output) { + hmac_sha1(key, key_length, input, input_length, output); + return HMAC_SHA1_RESULT_SIZE; } -static int totp_algo_sha256(const uint8_t* key, uint8_t key_length, const uint8_t* input, uint8_t input_length, uint8_t* output) { - hmac_sha256(key, key_length, input, input_length, output); - return HMAC_SHA256_RESULT_SIZE; +static int totp_algo_sha256( + const uint8_t* key, + uint8_t key_length, + const uint8_t* input, + uint8_t input_length, + uint8_t* output) { + hmac_sha256(key, key_length, input, input_length, output); + return HMAC_SHA256_RESULT_SIZE; } -static int totp_algo_sha512(const uint8_t* key, uint8_t key_length, const uint8_t* input, uint8_t input_length, uint8_t* output) { - hmac_sha512(key, key_length, input, input_length, output); - return HMAC_SHA512_RESULT_SIZE; +static int totp_algo_sha512( + const uint8_t* key, + uint8_t key_length, + const uint8_t* input, + uint8_t input_length, + uint8_t* output) { + hmac_sha512(key, key_length, input, input_length, output); + return HMAC_SHA512_RESULT_SIZE; } const TOTP_ALGO TOTP_ALGO_SHA1 = (TOTP_ALGO)(&totp_algo_sha1); diff --git a/applications/plugins/totp/services/totp/totp.h b/applications/plugins/totp/services/totp/totp.h index d2eb71c7e..31e70e01b 100644 --- a/applications/plugins/totp/services/totp/totp.h +++ b/applications/plugins/totp/services/totp/totp.h @@ -3,7 +3,7 @@ #include #include -#define OTP_ERROR (0) +#define OTP_ERROR (0) /* Must compute HMAC using passed arguments, @@ -15,7 +15,12 @@ Must return 0 if error, or the length in bytes of the HMAC operation. */ -typedef int (*TOTP_ALGO)(const uint8_t* key, uint8_t key_length, const uint8_t* input, uint8_t input_length, uint8_t* output); +typedef int (*TOTP_ALGO)( + const uint8_t* key, + uint8_t key_length, + const uint8_t* input, + uint8_t input_length, + uint8_t* output); /* Computes HMAC using SHA1 @@ -38,4 +43,11 @@ extern const TOTP_ALGO TOTP_ALGO_SHA512; TOTP token on success 0 otherwise */ -uint32_t totp_at(TOTP_ALGO algo, uint8_t digits, const uint8_t* plain_secret, uint8_t plain_secret_length, uint64_t for_time, float timezone, uint8_t interval); +uint32_t totp_at( + TOTP_ALGO algo, + uint8_t digits, + const uint8_t* plain_secret, + uint8_t plain_secret_length, + uint64_t for_time, + float timezone, + uint8_t interval); diff --git a/applications/plugins/totp/services/ui/icons.h b/applications/plugins/totp/services/ui/icons.h index 3bbbc52f6..a9139403f 100644 --- a/applications/plugins/totp/services/ui/icons.h +++ b/applications/plugins/totp/services/ui/icons.h @@ -4,8 +4,9 @@ #define ICON_ARROW_LEFT_8x9_WIDTH 8 #define ICON_ARROW_LEFT_8x9_HEIGHT 9 -static const uint8_t ICON_ARROW_LEFT_8x9[] = { 0x80,0xe0,0xf8,0xfe,0xff,0xfe,0xf8,0xe0,0x80 }; +static const uint8_t ICON_ARROW_LEFT_8x9[] = {0x80, 0xe0, 0xf8, 0xfe, 0xff, 0xfe, 0xf8, 0xe0, 0x80}; #define ICON_ARROW_RIGHT_8x9_WIDTH 8 #define ICON_ARROW_RIGHT_8x9_HEIGHT 9 -static const uint8_t ICON_ARROW_RIGHT_8x9[] = { 0x01,0x07,0x1f,0x7f,0xff,0x7f,0x1f,0x07,0x01 }; +static const uint8_t ICON_ARROW_RIGHT_8x9[] = + {0x01, 0x07, 0x1f, 0x7f, 0xff, 0x7f, 0x1f, 0x07, 0x01}; diff --git a/applications/plugins/totp/services/ui/ui_controls.c b/applications/plugins/totp/services/ui/ui_controls.c index b73f43fc8..269c52294 100644 --- a/applications/plugins/totp/services/ui/ui_controls.c +++ b/applications/plugins/totp/services/ui/ui_controls.c @@ -6,51 +6,109 @@ #define TEXT_BOX_MARGIN 4 void ui_control_text_box_render(Canvas* const canvas, int8_t y, char* text, bool is_selected) { - if (y < -TEXT_BOX_HEIGHT) { + if(y < -TEXT_BOX_HEIGHT) { return; } - if (is_selected) { - canvas_draw_rframe(canvas, TEXT_BOX_MARGIN, TEXT_BOX_MARGIN + y, SCREEN_WIDTH - TEXT_BOX_MARGIN - TEXT_BOX_MARGIN, TEXT_BOX_HEIGHT, 0); - canvas_draw_rframe(canvas, TEXT_BOX_MARGIN - 1, TEXT_BOX_MARGIN + y - 1, SCREEN_WIDTH - TEXT_BOX_MARGIN - TEXT_BOX_MARGIN + 2, TEXT_BOX_HEIGHT + 2, 1); + if(is_selected) { + canvas_draw_rframe( + canvas, + TEXT_BOX_MARGIN, + TEXT_BOX_MARGIN + y, + SCREEN_WIDTH - TEXT_BOX_MARGIN - TEXT_BOX_MARGIN, + TEXT_BOX_HEIGHT, + 0); + canvas_draw_rframe( + canvas, + TEXT_BOX_MARGIN - 1, + TEXT_BOX_MARGIN + y - 1, + SCREEN_WIDTH - TEXT_BOX_MARGIN - TEXT_BOX_MARGIN + 2, + TEXT_BOX_HEIGHT + 2, + 1); } else { - canvas_draw_rframe(canvas, TEXT_BOX_MARGIN, TEXT_BOX_MARGIN + y, SCREEN_WIDTH - TEXT_BOX_MARGIN - TEXT_BOX_MARGIN, TEXT_BOX_HEIGHT, 1); + canvas_draw_rframe( + canvas, + TEXT_BOX_MARGIN, + TEXT_BOX_MARGIN + y, + SCREEN_WIDTH - TEXT_BOX_MARGIN - TEXT_BOX_MARGIN, + TEXT_BOX_HEIGHT, + 1); } - canvas_draw_str_aligned(canvas, TEXT_BOX_MARGIN + 2, TEXT_BOX_MARGIN + 3 + y, AlignLeft, AlignTop, text); + canvas_draw_str_aligned( + canvas, TEXT_BOX_MARGIN + 2, TEXT_BOX_MARGIN + 3 + y, AlignLeft, AlignTop, text); } void ui_control_select_render(Canvas* const canvas, int8_t y, char* text, bool is_selected) { - if (y < -TEXT_BOX_HEIGHT) { + if(y < -TEXT_BOX_HEIGHT) { return; } - if (is_selected) { - canvas_draw_rframe(canvas, TEXT_BOX_MARGIN, TEXT_BOX_MARGIN + y, SCREEN_WIDTH - TEXT_BOX_MARGIN - TEXT_BOX_MARGIN, TEXT_BOX_HEIGHT, 0); - canvas_draw_rframe(canvas, TEXT_BOX_MARGIN - 1, TEXT_BOX_MARGIN + y - 1, SCREEN_WIDTH - TEXT_BOX_MARGIN - TEXT_BOX_MARGIN + 2, TEXT_BOX_HEIGHT + 2, 1); + if(is_selected) { + canvas_draw_rframe( + canvas, + TEXT_BOX_MARGIN, + TEXT_BOX_MARGIN + y, + SCREEN_WIDTH - TEXT_BOX_MARGIN - TEXT_BOX_MARGIN, + TEXT_BOX_HEIGHT, + 0); + canvas_draw_rframe( + canvas, + TEXT_BOX_MARGIN - 1, + TEXT_BOX_MARGIN + y - 1, + SCREEN_WIDTH - TEXT_BOX_MARGIN - TEXT_BOX_MARGIN + 2, + TEXT_BOX_HEIGHT + 2, + 1); } else { - canvas_draw_rframe(canvas, TEXT_BOX_MARGIN, TEXT_BOX_MARGIN + y, SCREEN_WIDTH - TEXT_BOX_MARGIN - TEXT_BOX_MARGIN, TEXT_BOX_HEIGHT, 1); + canvas_draw_rframe( + canvas, + TEXT_BOX_MARGIN, + TEXT_BOX_MARGIN + y, + SCREEN_WIDTH - TEXT_BOX_MARGIN - TEXT_BOX_MARGIN, + TEXT_BOX_HEIGHT, + 1); } - canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, TEXT_BOX_MARGIN + 3 + y, AlignCenter, AlignTop, text); - canvas_draw_xbm(canvas, TEXT_BOX_MARGIN + 2, TEXT_BOX_MARGIN + 2 + y, ICON_ARROW_LEFT_8x9_WIDTH, ICON_ARROW_LEFT_8x9_HEIGHT, &ICON_ARROW_LEFT_8x9[0]); - canvas_draw_xbm(canvas, SCREEN_WIDTH - TEXT_BOX_MARGIN - 10, TEXT_BOX_MARGIN + 2 + y, ICON_ARROW_RIGHT_8x9_WIDTH, ICON_ARROW_RIGHT_8x9_HEIGHT, &ICON_ARROW_RIGHT_8x9[0]); + canvas_draw_str_aligned( + canvas, SCREEN_WIDTH_CENTER, TEXT_BOX_MARGIN + 3 + y, AlignCenter, AlignTop, text); + canvas_draw_xbm( + canvas, + TEXT_BOX_MARGIN + 2, + TEXT_BOX_MARGIN + 2 + y, + ICON_ARROW_LEFT_8x9_WIDTH, + ICON_ARROW_LEFT_8x9_HEIGHT, + &ICON_ARROW_LEFT_8x9[0]); + canvas_draw_xbm( + canvas, + SCREEN_WIDTH - TEXT_BOX_MARGIN - 10, + TEXT_BOX_MARGIN + 2 + y, + ICON_ARROW_RIGHT_8x9_WIDTH, + ICON_ARROW_RIGHT_8x9_HEIGHT, + &ICON_ARROW_RIGHT_8x9[0]); } -void ui_control_button_render(Canvas* const canvas, uint8_t x, int8_t y, uint8_t width, uint8_t height, char* text, bool is_selected) { - if (y < -height) { +void ui_control_button_render( + Canvas* const canvas, + uint8_t x, + int8_t y, + uint8_t width, + uint8_t height, + char* text, + bool is_selected) { + if(y < -height) { return; } - if (is_selected) { + if(is_selected) { canvas_draw_rbox(canvas, x, y, width, height, 1); canvas_set_color(canvas, ColorWhite); } else { canvas_draw_rframe(canvas, x, y, width, height, 1); } - canvas_draw_str_aligned(canvas, x + (width >> 1), y + (height >> 1) + 1, AlignCenter, AlignCenter, text); - if (is_selected) { + canvas_draw_str_aligned( + canvas, x + (width >> 1), y + (height >> 1) + 1, AlignCenter, AlignCenter, text); + if(is_selected) { canvas_set_color(canvas, ColorBlack); } } diff --git a/applications/plugins/totp/services/ui/ui_controls.h b/applications/plugins/totp/services/ui/ui_controls.h index 3f9e7b6eb..f0c8bb6bb 100644 --- a/applications/plugins/totp/services/ui/ui_controls.h +++ b/applications/plugins/totp/services/ui/ui_controls.h @@ -4,5 +4,12 @@ #include void ui_control_text_box_render(Canvas* const canvas, int8_t y, char* text, bool is_selected); -void ui_control_button_render(Canvas* const canvas, uint8_t x, int8_t y, uint8_t width, uint8_t height, char* text, bool is_selected); +void ui_control_button_render( + Canvas* const canvas, + uint8_t x, + int8_t y, + uint8_t width, + uint8_t height, + char* text, + bool is_selected); void ui_control_select_render(Canvas* const canvas, int8_t y, char* text, bool is_selected); diff --git a/applications/plugins/totp/totp_app.c b/applications/plugins/totp/totp_app.c index 3b8539b52..7438ac810 100644 --- a/applications/plugins/totp/totp_app.c +++ b/applications/plugins/totp/totp_app.c @@ -21,7 +21,7 @@ static void render_callback(Canvas* const canvas, void* ctx) { PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25); - if (plugin_state != NULL && !plugin_state->changing_scene) { + if(plugin_state != NULL && !plugin_state->changing_scene) { totp_scene_director_render(canvas, plugin_state); } @@ -56,7 +56,7 @@ static void dispose_plugin_state(PluginState* plugin_state) { ListNode* node = plugin_state->tokens_list; ListNode* tmp; - while (node != NULL) { + while(node != NULL) { tmp = node->next; TokenInfo* tokenInfo = (TokenInfo*)node->data; token_info_free(tokenInfo); @@ -64,7 +64,7 @@ static void dispose_plugin_state(PluginState* plugin_state) { node = tmp; } - if (plugin_state->crypto_verify_data != NULL) { + if(plugin_state->crypto_verify_data != NULL) { free(plugin_state->crypto_verify_data); } free(plugin_state); @@ -95,18 +95,20 @@ int32_t totp_app() { bool processing = true; uint32_t last_user_interaction_time = furi_get_tick(); while(processing) { - if (plugin_state->changing_scene) continue; + if(plugin_state->changing_scene) continue; FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex); if(event_status == FuriStatusOk) { - if (event.type == EventTypeKey) { + if(event.type == EventTypeKey) { last_user_interaction_time = furi_get_tick(); } processing = totp_scene_director_handle_event(&event, plugin_state); - } else if (plugin_state->current_scene != TotpSceneAuthentication && furi_get_tick() - last_user_interaction_time > IDLE_TIMEOUT) { + } else if( + plugin_state->current_scene != TotpSceneAuthentication && + furi_get_tick() - last_user_interaction_time > IDLE_TIMEOUT) { totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication, NULL); } diff --git a/applications/plugins/totp/types/token_info.c b/applications/plugins/totp/types/token_info.c index 3284c522e..6596cd510 100644 --- a/applications/plugins/totp/types/token_info.c +++ b/applications/plugins/totp/types/token_info.c @@ -13,15 +13,20 @@ TokenInfo* token_info_alloc() { } void token_info_free(TokenInfo* token_info) { - if (token_info == NULL) return; + if(token_info == NULL) return; free(token_info->name); free(token_info->token); free(token_info); } -void token_info_set_secret(TokenInfo* token_info, const char* base32_token_secret, uint8_t token_secret_length, uint8_t* iv) { +void token_info_set_secret( + TokenInfo* token_info, + const char* base32_token_secret, + uint8_t token_secret_length, + uint8_t* iv) { uint8_t* plain_secret = malloc(token_secret_length); - int plain_secret_length = base32_decode((uint8_t *)base32_token_secret, plain_secret, token_secret_length); + int plain_secret_length = + base32_decode((uint8_t*)base32_token_secret, plain_secret, token_secret_length); token_info->token_length = plain_secret_length; size_t remain = token_info->token_length % 16; @@ -35,7 +40,7 @@ void token_info_set_secret(TokenInfo* token_info, const char* base32_token_secre } token_info->token = malloc(token_info->token_length); - + furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, iv); furi_hal_crypto_encrypt(plain_secret, token_info->token, token_info->token_length); furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT); @@ -45,9 +50,11 @@ void token_info_set_secret(TokenInfo* token_info, const char* base32_token_secre } uint8_t token_info_get_digits_count(TokenInfo* token_info) { - switch (token_info->digits) { - case TOTP_6_DIGITS: return 6; - case TOTP_8_DIGITS: return 8; + switch(token_info->digits) { + case TOTP_6_DIGITS: + return 6; + case TOTP_8_DIGITS: + return 8; } return 6; diff --git a/applications/plugins/totp/types/token_info.h b/applications/plugins/totp/types/token_info.h index c0c865ead..2d531ec89 100644 --- a/applications/plugins/totp/types/token_info.h +++ b/applications/plugins/totp/types/token_info.h @@ -2,16 +2,9 @@ #include -typedef enum { - SHA1, - SHA256, - SHA512 -} TokenHashAlgo; +typedef enum { SHA1, SHA256, SHA512 } TokenHashAlgo; -typedef enum { - TOTP_6_DIGITS, - TOTP_8_DIGITS -} TokenDigitsCount; +typedef enum { TOTP_6_DIGITS, TOTP_8_DIGITS } TokenDigitsCount; typedef struct { uint8_t* token; @@ -23,5 +16,9 @@ typedef struct { TokenInfo* token_info_alloc(); void token_info_free(TokenInfo* token_info); -void token_info_set_secret(TokenInfo* token_info, const char* base32_token_secret, uint8_t token_secret_length, uint8_t* iv); +void token_info_set_secret( + TokenInfo* token_info, + const char* base32_token_secret, + uint8_t token_secret_length, + uint8_t* iv); uint8_t token_info_get_digits_count(TokenInfo* token_info); diff --git a/applications/plugins/usbkeyboard/usb_hid.c b/applications/plugins/usbkeyboard/usb_hid.c index c2344565b..60acb6e32 100644 --- a/applications/plugins/usbkeyboard/usb_hid.c +++ b/applications/plugins/usbkeyboard/usb_hid.c @@ -72,8 +72,10 @@ UsbHid* usb_hid_app_alloc() { app->submenu, "Dirpad", UsbHidSubmenuIndexDirpad, usb_hid_submenu_callback, app); submenu_add_item( app->submenu, "Keyboard", UsbHidSubmenuIndexKeyboard, usb_hid_submenu_callback, app); - submenu_add_item(app->submenu, "Media", UsbHidSubmenuIndexMedia, usb_hid_submenu_callback, app); - submenu_add_item(app->submenu, "Mouse", UsbHidSubmenuIndexMouse, usb_hid_submenu_callback, app); + submenu_add_item( + app->submenu, "Media", UsbHidSubmenuIndexMedia, usb_hid_submenu_callback, app); + submenu_add_item( + app->submenu, "Mouse", UsbHidSubmenuIndexMouse, usb_hid_submenu_callback, app); view_set_previous_callback(submenu_get_view(app->submenu), usb_hid_exit); view_dispatcher_add_view( app->view_dispatcher, UsbHidViewSubmenu, submenu_get_view(app->submenu)); @@ -101,17 +103,21 @@ UsbHid* usb_hid_app_alloc() { view_set_previous_callback( usb_hid_keyboard_get_view(app->usb_hid_keyboard), usb_hid_exit_confirm_view); view_dispatcher_add_view( - app->view_dispatcher, UsbHidViewKeyboard, usb_hid_keyboard_get_view(app->usb_hid_keyboard)); + app->view_dispatcher, + UsbHidViewKeyboard, + usb_hid_keyboard_get_view(app->usb_hid_keyboard)); // Media view app->usb_hid_media = usb_hid_media_alloc(); - view_set_previous_callback(usb_hid_media_get_view(app->usb_hid_media), usb_hid_exit_confirm_view); + view_set_previous_callback( + usb_hid_media_get_view(app->usb_hid_media), usb_hid_exit_confirm_view); view_dispatcher_add_view( app->view_dispatcher, UsbHidViewMedia, usb_hid_media_get_view(app->usb_hid_media)); // Mouse view app->usb_hid_mouse = usb_hid_mouse_alloc(); - view_set_previous_callback(usb_hid_mouse_get_view(app->usb_hid_mouse), usb_hid_exit_confirm_view); + view_set_previous_callback( + usb_hid_mouse_get_view(app->usb_hid_mouse), usb_hid_exit_confirm_view); view_dispatcher_add_view( app->view_dispatcher, UsbHidViewMouse, usb_hid_mouse_get_view(app->usb_hid_mouse)); @@ -157,14 +163,14 @@ int32_t usb_hid_app(void* p) { // Switch profile to Hid UsbHid* app = usb_hid_app_alloc(); - FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); + FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); furi_hal_usb_unlock(); furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true); - view_dispatcher_run(app->view_dispatcher); - - // Change back profile - furi_hal_usb_set_config(usb_mode_prev, NULL); + view_dispatcher_run(app->view_dispatcher); + + // Change back profile + furi_hal_usb_set_config(usb_mode_prev, NULL); usb_hid_app_free(app); return 0; diff --git a/assets/resources/infrared/assets/fans.ir b/assets/resources/infrared/assets/fans.ir index 9f488cfcb..a693c0037 100644 --- a/assets/resources/infrared/assets/fans.ir +++ b/assets/resources/infrared/assets/fans.ir @@ -1,6 +1,6 @@ Filetype: IR library file Version: 1 -# Last Updated 3rd Oct, 2022 +# Last Updated 9th Oct, 2022 # name: POWER type: raw @@ -1009,4 +1009,10 @@ type: raw frequency: 38000 duty_cycle: 0.330000 data: 3583 1639 534 386 484 1208 534 386 484 386 485 386 484 387 483 386 484 386 485 386 457 394 476 394 451 419 452 419 476 1237 506 393 477 394 475 395 474 396 473 397 473 398 472 1270 472 399 471 1271 471 1270 471 399 470 401 469 1273 469 402 468 427 443 427 443 427 443 1299 443 427 443 427 444 427 444 427 444 1298 443 1299 442 427 444 427 445 426 445 425 446 425 447 424 447 399 472 398 473 1294 445 426 446 400 471 399 472 1294 446 425 447 398 473 1295 446 400 471 398 472 74544 3552 1672 472 399 471 1271 471 399 471 400 470 400 470 400 470 400 471 400 470 400 470 401 470 401 469 401 469 401 470 1273 470 400 470 401 469 401 469 401 470 401 469 401 470 1273 470 401 469 1273 470 1272 469 401 469 401 469 1274 468 401 469 401 469 401 470 402 469 1273 469 401 469 401 469 402 469 401 469 1273 469 1273 469 401 469 402 468 402 469 426 444 427 444 427 444 426 445 426 444 1274 468 402 469 426 444 427 443 1275 467 403 467 427 443 1275 467 402 468 427 443 +# OFF +name: POWER +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 1366 388 1295 387 446 1164 1368 387 1296 387 448 1164 518 1164 493 1189 517 1165 492 1189 493 1189 493 7851 1365 387 1270 388 446 1190 1365 387 1295 387 447 1192 490 1193 489 1193 489 1194 488 1194 488 1193 489 7855 1337 386 1296 386 448 1193 1338 386 1296 386 448 1193 489 1193 489 1193 489 1193 489 1193 489 1193 489 7855 1337 386 1297 386 448 1194 1337 386 1296 386 448 1194 488 1194 488 1194 488 1194 488 1194 488 1194 488 8160 1336 387 1296 387 447 1194 1337 387 1296 386 448 1194 488 1194 488 1194 488 1194 488 1194 488 1194 488 7855 1336 386 1297 387 447 1195 1336 386 1297 386 448 1195 486 1195 487 1195 487 1195 487 1196 486 1196 486 7881 1310 387 1272 397 436 1245 1286 397 1285 397 436 1246 436 1246 436 1247 435 1247 435 1248 434 1248 434 7934 1259 424 1259 424 408 1274 1258 424 1259 424 408 1274 408 1274 408 1274 408 1274 408 1274 408 1274 408 8239 1258 425 1258 424 408 1274 1258 424 1258 425 407 1273 408 1273 409 1273 408 1273 408 1274 408 1273 408 7907 1283 424 1258 424 409 1248 1283 399 1283 400 433 1247 434 1247 434 1247 434 1247 434 1247 434 1247 434 7905 1282 424 1258 425 407 1273 1257 425 1257 425 407 1273 407 1274 407 1274 407 1274 407 1275 406 1275 406 7958 1230 478 1204 478 353 1328 1204 478 1204 453 378 1327 353 1328 353 1302 379 1301 380 1301 380 1300 381 # diff --git a/assets/resources/subghz/assets/keeloq_mfcodes b/assets/resources/subghz/assets/keeloq_mfcodes index 0c0e15a62..1e6cf9a36 100644 --- a/assets/resources/subghz/assets/keeloq_mfcodes +++ b/assets/resources/subghz/assets/keeloq_mfcodes @@ -1,51 +1,52 @@ Filetype: Flipper SubGhz Keystore File Version: 0 Encryption: 1 -IV: 2A 34 F1 5A AF 6F F5 1A 83 A6 1E DA DE B7 3D F1 -06B63DF24AE073A2F2B19C55CA9E8364FBECD26E49C551990153F6513BDE5267 -6139C78C74C341EB7474085CF1D047BD6FB005F80A72AF3EF3F89D58EF5DF500 -D85F11689020ECA47FBE9C2B67EE41A81E1F06DE2A35AF958965E3ECE29EA701 -1AE9073A42FE0E439544FE6945F6B33CF15A7A4A279020B5E0B3BE33FD189A7E -E161F007854BB33E0056FA09A2E2DEE66789B5C87C8D6D3DE2C8C1BD2B48983EB9D1C5697CA6E95996918F7C47B761B0 -59AE4644DCB3D720C38B5115F230DA58E7BE0A697907F6174BB05AB7886ACDB1 -634DF0BCC185C4C1F7E1B1594B4438D051ABAE092433078963063B51D961D08C -1EBEBCB49E498B9BE977D53EC21B9A546155B627737BD0AA832D496035729346 -4DFA93E639197772D57E8ACE04512CEFC045B8CC965C175A25ED525B630CBB63 -C2D5235D1014A319B249EAE8A5EE350F18D5AB8A498EF222704BD4EB1435F388 -F66D1937160E1392197F463A52E87FCE938A92070892113443C348D7553327A5715CF615CE2F2C96284F47759E043419 -841D29E7CBE040188E2283BFBA9F26EF2F65CCB085B56C3515E8C46C3F20BD75BAA963550869435FDAF509CEEE66A2C4 -7D87E24487D307635E7A17B989B8547EE11F3BF3468D055F0B44633B631BA42C -B4916043973501B95A82B329196D6EBA69FBBC3AF8FD914583104E0E18CE82F6 -E4649F9C2A5465D2EA6F3E9724DD06CD6962FE2BAEB14F1453C14D1559232AE1 -96E15D890DF7FD348441F5E429A875754C6BF0520A787F8E9D8C5415674783CC -CB52005EDED47B57F795BC92FB0522EAB18D23EE028B8D10ED57828C250EB285BFEC6E4A4BE8DABCE0D57ECAA20D90C3 -8E5A50C7D5C374445E88752301D20F0B3D6E4988B61D90FD63779B0EDEF9C60D -49D6CB276A0E5FF134A38062503F01351F44CD6455708B50B5F07D03FC477C33 -CB45B56613DF208E79E4E10A6510F07DC1AA49210C7B94E8BBAECD2C35EC6ABC99FB10FD7C96DD6BB6A6685E9FAD93FB -0743F3CC51200F763C242F1956B4D775C092ADF1A5C19ACAE96EB60C2990CF214F8FEA8FC6749286F6BDAB67657C479A -E5608B28A058787D64A145F0362DEFD98CAE0B5A0F22C6DA7C6D278C7B5F95E3 -D4C113D43E7FB6D2EFA9E87471AA76A61B26872607B4AF5B87F9D72113835CE6 -2DC502800BFD21B76126390CA64A08C5432A2254E822F214CDE1EA11430084C5 -CA22C73010B0F1CB8009601BE2AF0B3674D83D5880E4A26C2A3FF0EA0A098CEA -E53B2B102FDB000E9BB747F957156976E5A0C0E3898AA844C13AE8A9CEE7013B -EFB27324B5661419265804ABD130C13DC9DF9CD4D2AC2011CB4FD43D56304AD1 -491D75A82ACE8CE216FBE4F0D2D0133BAC7EA8F4A5304337D5E8611AD9C72523 -BBFA2B00827E0BCC8AC5CE12C972BB58DFA2EA59DFEFF5A538398FCF970F58A7 -6BAF9C855926B683BEDC11883543B2C0E0866FF6B06C46CC09B3C4E1200E7716 -B35A4D25FF4D5CFF93B9C4C07B78FCF7E2646138DAB7C090A938C8055CCCE3D8 -71CC3C0180771E6B304CE984F5A9962EB35D1965CB78EBAE6F4DDFA44E5E02A2 -3DCF52C549FEFCCE2831DB74579AA2C157A4BEE70C43905664C9A6491A171F5D -F7E45AF200F7663DCCE54C14118D2CDFD1228ED0BFF7F70CFBCE15B6F9DF3D40 -C44E048AD5C003E68DCF0111317D109CF2B7DD79299692CDA7DA2A12EC9A295A -2B3E6778A97B251A5FEB190991B8AE8EC48F5FC6E94C2ECB8DFADFDD9D8E21FEE5DCCEDD9A1EB8C5212DEAE36FBBDF92 -1DD4756E681528CBBDBA6C7BF8833DF556D41E5EA4E4DE52CAD3544C946CD8CA -F903D388CF2016B40B492494F7475E71C50E9FDD63304558212DAF6FBC4E1BA4 -9E9F24951DB27917668CD6366795052306022F6F8BA11B08A970691C6857E6C5 -C88461104FA0EAA68001B0C2D0483D1A53D6AE04F4CB291C76CEF3A1A5C5DC10 -8345B2B9F08B018FEAC2F74D76747FF30DBF426C9B390ACD42AD48104C12042E -087269DC66C76E1D6449831A2C3B6F0006C0F8B1861062B95708C6B222C58A9C -4D31DE05DB12E552D43B1017C68AF3F52B6FE8063E4AD82CB568CDAF22950BCC26FF21EE968FB57650111B617A84DEF7 -769BAA780F84797431B6E9DD5180AF3848E03C942C67040B39CC6384E2A8F4C6 -1844AAAAD6A6AFB2623DF1452DF940715E6EB92F54C49F408872EC4B2156DDB2 -23EB39CD7F3921081199BA8B63D4C19F74365F8D8E71D486576DC900E5EFEEA3 -45958B93A16A73CA2578ADCFB1EADAA983BB7015321B0592B67CDF573B084194 +IV: 3B 23 A4 B0 BA B1 BA 2C 45 B7 3D AF AE B1 D8 53 +7C22D7C0AD9099E4DD9BE3DD97F4E5171F0502B89FF7CA7B63A218EC70EA66FC +8468A45C97CC0718E3FE756DE72584C1C7F9FEB3E2873C6DE27A753017D69883 +A5983C8C10314C8BED1258B3CF7B81A43CFDAE0CB4A7E94EBDEC6B9876709157 +7B5C74E9011244735DB27F6D57BE32DA1DB26E1F60CE7C8D1029FDDCE3B12695 +940EF169CA9FE65E7E76FC4B3C8D67DF879D7D165A02E602DAF0B31FA0426B785D0E2500288603346505251D993F28F3 +639BBF96DBBA66408ABB04775689E7C85F4CBE3B1D94B834E4D371F6A262FF75 +1B4935A15D4C019C08E215025E6C1F2C89890C307CEF2ABAD9C1A1C84745B4FB +5796A104EA1D22A0B9000DA4630248635D1772FDB620B937963D1C8454CD2927 +661EBB18ECC20A236C0AE6BB0AE21B2BF3BDE64A42BA7616D2D87C2992C157FB +804352D4445CF4E08A7C7CEEA21DCCE0E2A0E436BA148C1E24DDDDA0B8ED3A67 +92D9D6C16DECD2E320D42818CC509FB3C22B8CA096630A50344FB2969653A6696FD46940C347205946358689D80F101E +02176E6C111509AB74FC6C88FE578F1C035A2676D93FA0AD595771A8A9BC536A842141B6FC0B56EFE1601614B931064A +5210722EA559F6F8ADD0E79F99A83265C2661DFDD7D1B1EEDAC02F641027EFCE +CCF01357E399E4F7F2FB32D1E697BF777948FF875A954F55F31BF02C6790EDDC +98E7CE7D325ED70B32200D809C109718DE633A5A286A3CDC889D9A241475AA4B +A7ECDEE650749FB4A7764F459AD49EE9F8FDC54B0E83A385BDB6413DD2D5DED1 +B2303659591EE6E9BDF56C1E70AEE6FAF21B97D7FEC026A96CFD780A7C3BC1FF5A4F868DC8BD4DD9160C3C8F715C6DC0 +869316BD6BB3E641A4C2BE32EF160E1B1405B16DD53A3042464CF5E07BBB7AC0 +72D442A018CD2875143AAFAE3D7C4AD1467BCBE0BE71119D123A7941EB0A56EA +32CC4E29CB6E03ECAE66BC38046D4BB1BDA7E3D0580F3F141008077EE906FA2EE6D2329706B96F49FA4E1E63EA974490 +791E004A574CC7A934DDE0ECAA097593721D71B9EE67995197CAB8349F166E230E5BA6488527C2BB55EA3E5BFD059F44 +2229CC65C99F31E6DB19B29CB625BF4EB95B5EB4AACC60BBB8C65BB7CBB07C2C +EA04BAF7B59B8D93678544D97BB0EDF81D043C97B740435AFA9EA9F3414829D6 +300A9BD3E912C5D09EFDB50F96704B8287BFDCBA82EF5D0E9D2306A4995B13BF +0C2EB6DBCB583977789DA234BCF186A0BE3008131360E46A85C13F7EA96469BC +2417D60848938A3DEAFC63344B4F49A68DC168FD6CE9D7F1CB7A0D70B2ABE32A +DF14D34ED4B03638926F1C4FF217AD3512A2C94C2A7B518CFCEB161FE9E0860E +AF920E82A02B46F3743626DB0FCB8F7EC1B444FA82F213C19F68E6A745BA5A8D +D7A5A38C2CEDA048F9FA5F091E3F36DC564698EF9BDC2B68A31188DF6294CA09 +5358679FC5EB2BC8C85ACA2957B24ACFD966FE53B9E9003264B06CDF900417F8 +D10608BCB41260D5A74E3224C820700E4D03C1CDC379E20D7C03564B3019189B +EE8EEA79570BB81660ED133D470E051FF45B4E5E8442D5931275353F6A434D66 +019AC0D9AF968B5CE43DA3FC1A6B11770B2CA801829BC05F88BB8A68AC074EDB +44EF315DA7310A4EE926B734B8F29A2241AAF631AF605B1FA9DD6C2AB2786695 +536FBE9BDD6FDED8F29CB6DC2935781874F8408DF6DB622CE8335B1BD21AB1C7 +76245B84908ECBC102E2F09FAB668D36A68D3C8BD2AB04A4FA119EBECAF232CA80A71D8BB379E59C62B6FB92717DB2FB +9EA362345970E8CA049119E5211BA78FDBCB33F5FD4B93B4189BE7FFA690ADA9 +40228619492D62DE5D98333265B2AF50773BDD0AC2C192A7C11073A37507CD12 +F6D31A4C37F591CD1C6FD2004501662549319C1862954A10CF5970099381BECC +8F917EAB00A545F6DEBF67A5DE9C12AA87AFE3C70C832EB4CC4F377A464F43C4 +E78E7F43A40C9AB1EA9DC9F9D2D7381ED037169928F8FEA2299C98C4B0F22569 +983E86FFEE7252E47AB1E0A0FB3CEEC901FF9627DD5242C9A688186F9889BEF0 +2B477C1E5DCD318DD039810D78879185BD8F1DF8C7BB0E330316A4D85A46A7BE +645F7E9A2EC08168432B3B9D80F45D30BA27E35C1D7075D14882EF50D00C811ED37E39F87C2115B47E302D7A90B2EC4F +20713989A6FAFC8B4F43A141AED90A67CA4C49D858EEB6E9BC802EA395D5553C +AB312E5A23E5804D089224BFC62252C92BC23F712C9426DEA1B3742F2A6A3502 +AAE727A60B82B21EA9E7E8111C048581F11F770AF34C619E85932C63C8636895 +1FE3C9BD1241B49E2737B6D760040050D984E4EBF39B5F7C04D16FD84604129C diff --git a/lib/lfrfid/protocols/protocol_awid.c b/lib/lfrfid/protocols/protocol_awid.c index 88093900e..4dc991733 100644 --- a/lib/lfrfid/protocols/protocol_awid.c +++ b/lib/lfrfid/protocols/protocol_awid.c @@ -81,7 +81,7 @@ static bool protocol_awid_can_be_decoded(uint8_t* data) { // Avoid detection for invalid formats uint8_t len = bit_lib_get_bits(data, 8, 8); - if(len != 26 && len != 50 && len != 37 && len != 34) break; + if(len != 26 && len != 50 && len != 37 && len != 34 && len != 36) break; result = true; } while(false); @@ -207,7 +207,7 @@ bool protocol_awid_write_data(ProtocolAwid* protocol, void* data) { // Fix incorrect length byte if(protocol->data[0] != 26 && protocol->data[0] != 50 && protocol->data[0] != 37 && - protocol->data[0] != 34) { + protocol->data[0] != 34 && protocol->data[0] != 36) { protocol->data[0] = 26; } diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index e5f90c73a..cb4e9f963 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -494,6 +494,9 @@ static void nfc_worker_mf_classic_key_attack( uint16_t start_sector) { furi_assert(nfc_worker); + bool card_found_notified = true; + bool card_removed_notified = false; + MfClassicData* data = &nfc_worker->dev_data->mf_classic_data; uint32_t total_sectors = mf_classic_get_total_sectors_num(data->type); @@ -501,36 +504,52 @@ static void nfc_worker_mf_classic_key_attack( // Check every sector's A and B keys with the given key for(size_t i = start_sector; i < total_sectors; i++) { - uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i); - if(mf_classic_is_sector_read(data, i)) continue; - if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) { - FURI_LOG_D( - TAG, - "Trying A key for sector %d, key: %04lx%08lx", - i, - (uint32_t)(key >> 32), - (uint32_t)key); - if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) { - mf_classic_set_key_found(data, i, MfClassicKeyA, key); - FURI_LOG_D(TAG, "Key found"); - nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); + furi_hal_nfc_sleep(); + if(furi_hal_nfc_activate_nfca(200, NULL)) { + furi_hal_nfc_sleep(); + if(!card_found_notified) { + nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); + card_found_notified = true; + card_removed_notified = false; + } + uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i); + if(mf_classic_is_sector_read(data, i)) continue; + if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) { + FURI_LOG_D( + TAG, + "Trying A key for sector %d, key: %04lx%08lx", + i, + (uint32_t)(key >> 32), + (uint32_t)key); + if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) { + mf_classic_set_key_found(data, i, MfClassicKeyA, key); + FURI_LOG_D(TAG, "Key found"); + nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); + } + } + if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) { + FURI_LOG_D( + TAG, + "Trying B key for sector %d, key: %04lx%08lx", + i, + (uint32_t)(key >> 32), + (uint32_t)key); + if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) { + mf_classic_set_key_found(data, i, MfClassicKeyB, key); + FURI_LOG_D(TAG, "Key found"); + nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); + } + } + + if(mf_classic_is_sector_read(data, i)) continue; + mf_classic_read_sector(tx_rx, data, i); + } else { + if(!card_removed_notified) { + nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context); + card_removed_notified = true; + card_found_notified = false; } } - if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) { - FURI_LOG_D( - TAG, - "Trying B key for sector %d, key: %04lx%08lx", - i, - (uint32_t)(key >> 32), - (uint32_t)key); - if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) { - mf_classic_set_key_found(data, i, MfClassicKeyB, key); - FURI_LOG_D(TAG, "Key found"); - nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); - } - } - if(mf_classic_is_sector_read(data, i)) continue; - mf_classic_read_sector(tx_rx, data, i); if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; } } @@ -544,6 +563,7 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { &nfc_worker->dev_data->mf_classic_dict_attack_data; uint32_t total_sectors = mf_classic_get_total_sectors_num(data->type); uint64_t key = 0; + uint64_t prev_key = 0; FuriHalNfcTxRxContext tx_rx = {}; bool card_found_notified = true; bool card_removed_notified = false; @@ -556,6 +576,18 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { return; } + // Clear found keys if the key cache is incorrect (key set as found but sector not read) + for(uint16_t sector = 0; sector < total_sectors; sector++) { + if(mf_classic_is_key_found(data, sector, MfClassicKeyA) && + !mf_classic_is_sector_read(data, sector)) { + mf_classic_set_key_not_found(data, sector, MfClassicKeyA); + } + if(mf_classic_is_key_found(data, sector, MfClassicKeyB) && + !mf_classic_is_sector_read(data, sector)) { + mf_classic_set_key_not_found(data, sector, MfClassicKeyB); + } + } + FURI_LOG_D( TAG, "Start Dictionary attack, Key Count %ld", mf_classic_dict_get_total_keys(dict)); for(size_t i = 0; i < total_sectors; i++) { @@ -578,6 +610,7 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); card_found_notified = true; card_removed_notified = false; + nfc_worker_mf_classic_key_attack(nfc_worker, prev_key, &tx_rx, i); } FURI_LOG_D( TAG, @@ -614,6 +647,7 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { } if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; } + memcpy(&prev_key, &key, sizeof(key)); } if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; mf_classic_read_sector(&tx_rx, data, i); diff --git a/lib/nfc/protocols/mifare_classic.c b/lib/nfc/protocols/mifare_classic.c index 783202451..0e51fc42e 100644 --- a/lib/nfc/protocols/mifare_classic.c +++ b/lib/nfc/protocols/mifare_classic.c @@ -155,6 +155,16 @@ void mf_classic_set_key_found( } } +void mf_classic_set_key_not_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type) { + furi_assert(data); + + if(key_type == MfClassicKeyA) { + FURI_BIT_CLEAR(data->key_a_mask, sector_num); + } else if(key_type == MfClassicKeyB) { + FURI_BIT_CLEAR(data->key_b_mask, sector_num); + } +} + bool mf_classic_is_sector_read(MfClassicData* data, uint8_t sector_num) { furi_assert(data); diff --git a/lib/nfc/protocols/mifare_classic.h b/lib/nfc/protocols/mifare_classic.h index b9921fb1c..244641358 100644 --- a/lib/nfc/protocols/mifare_classic.h +++ b/lib/nfc/protocols/mifare_classic.h @@ -98,6 +98,8 @@ void mf_classic_set_key_found( MfClassicKey key_type, uint64_t key); +void mf_classic_set_key_not_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type); + bool mf_classic_is_block_read(MfClassicData* data, uint8_t block_num); void mf_classic_set_block_read(MfClassicData* data, uint8_t block_num, MfClassicBlock* block_data); diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index b43a60e4d..65927d7b1 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -28,6 +28,8 @@ struct SubGhzProtocolDecoderKeeloq { uint16_t header_count; SubGhzKeystore* keystore; const char* manufacture_name; + + FuriString* manufacture_from_file; }; struct SubGhzProtocolEncoderKeeloq { @@ -38,6 +40,8 @@ struct SubGhzProtocolEncoderKeeloq { SubGhzKeystore* keystore; const char* manufacture_name; + + FuriString* manufacture_from_file; }; typedef enum { @@ -113,12 +117,16 @@ void* subghz_protocol_encoder_keeloq_alloc(SubGhzEnvironment* environment) { instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; + + instance->manufacture_from_file = furi_string_alloc(); + return instance; } void subghz_protocol_encoder_keeloq_free(void* context) { furi_assert(context); SubGhzProtocolEncoderKeeloq* instance = context; + furi_string_free(instance->manufacture_from_file); free(instance->encoder.upload); free(instance); } @@ -143,6 +151,13 @@ static bool subghz_protocol_keeloq_gen_data(SubGhzProtocolEncoderKeeloq* instanc instance->manufacture_name = ""; } + // Nice Smilo, MHouse, JCM has 8bit serial - simple learning + if((strcmp(instance->manufacture_name, "NICE_Smilo") == 0) || + (strcmp(instance->manufacture_name, "NICE_MHOUSE") == 0) || + (strcmp(instance->manufacture_name, "JCM_Tech") == 0)) { + decrypt = btn << 28 | (instance->generic.serial & 0xFF) << 16 | instance->generic.cnt; + } + if(strcmp(instance->manufacture_name, "Unknown") == 0) { code_found_reverse = subghz_protocol_blocks_reverse_key( instance->generic.data, instance->generic.data_count_bit); @@ -347,6 +362,16 @@ bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* fl FURI_LOG_E(TAG, "Wrong number of bits in key"); break; } + + // Read manufacturer from file + if(flipper_format_read_string( + flipper_format, "Manufacture", instance->manufacture_from_file)) { + instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); + mfname = furi_string_get_cstr(instance->manufacture_from_file); + } else { + FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); + } + uint8_t seed_data[sizeof(uint32_t)] = {0}; for(size_t i = 0; i < sizeof(uint32_t); i++) { seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF; @@ -415,6 +440,7 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_keeloq; instance->generic.protocol_name = instance->base.protocol->name; instance->keystore = subghz_environment_get_keystore(environment); + instance->manufacture_from_file = furi_string_alloc(); return instance; } @@ -422,6 +448,7 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) { void subghz_protocol_decoder_keeloq_free(void* context) { furi_assert(context); SubGhzProtocolDecoderKeeloq* instance = context; + furi_string_free(instance->manufacture_from_file); free(instance); } @@ -950,6 +977,16 @@ bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* fl FURI_LOG_E(TAG, "Rewind error"); break; } + + // Read manufacturer from file + if(flipper_format_read_string( + flipper_format, "Manufacture", instance->manufacture_from_file)) { + instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); + mfname = furi_string_get_cstr(instance->manufacture_from_file); + } else { + FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); + } + uint8_t seed_data[sizeof(uint32_t)] = {0}; for(size_t i = 0; i < sizeof(uint32_t); i++) { seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF; diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index d6c9c0ae0..f91e9ad18 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -28,6 +28,8 @@ struct SubGhzProtocolDecoderStarLine { uint16_t header_count; SubGhzKeystore* keystore; const char* manufacture_name; + + FuriString* manufacture_from_file; }; struct SubGhzProtocolEncoderStarLine { @@ -38,6 +40,8 @@ struct SubGhzProtocolEncoderStarLine { SubGhzKeystore* keystore; const char* manufacture_name; + + FuriString* manufacture_from_file; }; typedef enum { @@ -109,16 +113,20 @@ void* subghz_protocol_encoder_star_line_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->keystore = subghz_environment_get_keystore(environment); + instance->manufacture_from_file = furi_string_alloc(); + instance->encoder.repeat = 10; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; + return instance; } void subghz_protocol_encoder_star_line_free(void* context) { furi_assert(context); SubGhzProtocolEncoderStarLine* instance = context; + furi_string_free(instance->manufacture_from_file); free(instance->encoder.upload); free(instance); } @@ -274,6 +282,15 @@ bool subghz_protocol_encoder_star_line_deserialize(void* context, FlipperFormat* break; } + // Read manufacturer from file + if(flipper_format_read_string( + flipper_format, "Manufacture", instance->manufacture_from_file)) { + instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); + mfname = furi_string_get_cstr(instance->manufacture_from_file); + } else { + FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); + } + subghz_protocol_star_line_check_remote_controller( &instance->generic, instance->keystore, &instance->manufacture_name); @@ -331,6 +348,9 @@ void* subghz_protocol_decoder_star_line_alloc(SubGhzEnvironment* environment) { SubGhzProtocolDecoderStarLine* instance = malloc(sizeof(SubGhzProtocolDecoderStarLine)); instance->base.protocol = &subghz_protocol_star_line; instance->generic.protocol_name = instance->base.protocol->name; + + instance->manufacture_from_file = furi_string_alloc(); + instance->keystore = subghz_environment_get_keystore(environment); return instance; @@ -339,6 +359,7 @@ void* subghz_protocol_decoder_star_line_alloc(SubGhzEnvironment* environment) { void subghz_protocol_decoder_star_line_free(void* context) { furi_assert(context); SubGhzProtocolDecoderStarLine* instance = context; + furi_string_free(instance->manufacture_from_file); free(instance); } @@ -705,6 +726,16 @@ bool subghz_protocol_decoder_star_line_deserialize(void* context, FlipperFormat* FURI_LOG_E(TAG, "Deserialize error"); break; } + + // Read manufacturer from file + if(flipper_format_read_string( + flipper_format, "Manufacture", instance->manufacture_from_file)) { + instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); + mfname = furi_string_get_cstr(instance->manufacture_from_file); + } else { + FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); + } + res = true; } while(false);