From e81b7be2321352975fcef12ac69819b947fe9567 Mon Sep 17 00:00:00 2001 From: Patrizio Bekerle Date: Tue, 8 Nov 2022 09:03:57 +0100 Subject: [PATCH 01/10] Fix link to "TOTP (Authenticator) config description" --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index 9665b8c91..d5c91a137 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -135,7 +135,7 @@ Games: ## [- Configure Sub-GHz Remote App](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemotePlugin.md) -## [- TOTP (Authenticator) config description](https://github.com/akopachov/flipper-zero_authenticator/blob/master/.github/conf-file_description.md) +## [- TOTP (Authenticator) config description](https://github.com/akopachov/flipper-zero_authenticator/blob/master/docs/conf-file_description.md) ## [- Barcode Generator](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/BarcodeGenerator.md) From 9e39f829065b6de7af392d4963b93e65f4aa8c0f Mon Sep 17 00:00:00 2001 From: krolchonok_z Date: Wed, 9 Nov 2022 22:07:26 +0300 Subject: [PATCH 02/10] fix hc-sr --- applications/plugins/hc_sr04/application.fam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/plugins/hc_sr04/application.fam b/applications/plugins/hc_sr04/application.fam index 17599b5d1..ad451a102 100644 --- a/applications/plugins/hc_sr04/application.fam +++ b/applications/plugins/hc_sr04/application.fam @@ -1,6 +1,6 @@ App( appid="hc_sr04", - name="HC-SR04 Dist. Sensor", + name="[HC-SR] Dist. Sensor", apptype=FlipperAppType.EXTERNAL, entry_point="hc_sr04_app", cdefines=["APP_HC_SR04"], From 65a593c52e4a587bc6415fc8c38cf9980c7f084d Mon Sep 17 00:00:00 2001 From: krolchonok_z Date: Wed, 9 Nov 2022 22:21:25 +0300 Subject: [PATCH 03/10] Update application.fam --- applications/plugins/hc_sr04/application.fam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/plugins/hc_sr04/application.fam b/applications/plugins/hc_sr04/application.fam index ad451a102..61c028cf9 100644 --- a/applications/plugins/hc_sr04/application.fam +++ b/applications/plugins/hc_sr04/application.fam @@ -1,6 +1,6 @@ App( appid="hc_sr04", - name="[HC-SR] Dist. Sensor", + name="[HC-SR04] Dist. Sensor", apptype=FlipperAppType.EXTERNAL, entry_point="hc_sr04_app", cdefines=["APP_HC_SR04"], From c3bdbcd5cc2d51fd3db72e83a9bc6b0f0c4b8b98 Mon Sep 17 00:00:00 2001 From: krolchonok_z Date: Wed, 9 Nov 2022 22:25:23 +0300 Subject: [PATCH 04/10] fix naming hc-sr --- applications/plugins/hc_sr04/application.fam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/plugins/hc_sr04/application.fam b/applications/plugins/hc_sr04/application.fam index 61c028cf9..ad451a102 100644 --- a/applications/plugins/hc_sr04/application.fam +++ b/applications/plugins/hc_sr04/application.fam @@ -1,6 +1,6 @@ App( appid="hc_sr04", - name="[HC-SR04] Dist. Sensor", + name="[HC-SR] Dist. Sensor", apptype=FlipperAppType.EXTERNAL, entry_point="hc_sr04_app", cdefines=["APP_HC_SR04"], From 1657604eb27db14291e6ad1b813584246c4eb541 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 10 Nov 2022 07:07:35 +0300 Subject: [PATCH 05/10] remove srand calls --- applications/plugins/arkanoid/arkanoid_game.c | 2 -- applications/plugins/game15/game15.c | 1 - applications/plugins/heap_defence_game/heap_defence.c | 1 - applications/plugins/tetris_game/tetris_game.c | 2 -- 4 files changed, 6 deletions(-) diff --git a/applications/plugins/arkanoid/arkanoid_game.c b/applications/plugins/arkanoid/arkanoid_game.c index d0026e226..0b0458424 100644 --- a/applications/plugins/arkanoid/arkanoid_game.c +++ b/applications/plugins/arkanoid/arkanoid_game.c @@ -370,8 +370,6 @@ static void arkanoid_update_timer_callback(FuriMessageQueue* event_queue) { int32_t arkanoid_game_app(void* p) { UNUSED(p); int32_t return_code = 0; - // Set random seed from interrupts - srand(DWT->CYCCNT); FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(GameEvent)); diff --git a/applications/plugins/game15/game15.c b/applications/plugins/game15/game15.c index aad5f1330..d9b059466 100644 --- a/applications/plugins/game15/game15.c +++ b/applications/plugins/game15/game15.c @@ -436,7 +436,6 @@ static void game_event_handler(GameEvent const event) { } static void game_alloc() { - srand(DWT->CYCCNT); key_stack_init(); notification = furi_record_open(RECORD_NOTIFICATION); notification_message_block(notification, &sequence_display_backlight_enforce_on); diff --git a/applications/plugins/heap_defence_game/heap_defence.c b/applications/plugins/heap_defence_game/heap_defence.c index c4375bafe..e43bcf425 100644 --- a/applications/plugins/heap_defence_game/heap_defence.c +++ b/applications/plugins/heap_defence_game/heap_defence.c @@ -500,7 +500,6 @@ static void heap_defense_timer_callback(FuriMessageQueue* event_queue) { int32_t heap_defence_app(void* p) { UNUSED(p); - srand(DWT->CYCCNT); //FURI_LOG_W(TAG, "Heap defence start %d", __LINE__); FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(GameEvent)); diff --git a/applications/plugins/tetris_game/tetris_game.c b/applications/plugins/tetris_game/tetris_game.c index 949c29896..8d3b9fb7a 100644 --- a/applications/plugins/tetris_game/tetris_game.c +++ b/applications/plugins/tetris_game/tetris_game.c @@ -345,8 +345,6 @@ static void } int32_t tetris_game_app() { - srand(DWT->CYCCNT); - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(TetrisEvent)); TetrisState* tetris_state = malloc(sizeof(TetrisState)); From e90d335cdf30f81cb294016703d36da79ef9872a Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 10 Nov 2022 07:13:02 +0300 Subject: [PATCH 06/10] Add value_index to API symbols --- firmware/targets/f7/api_symbols.csv | 8 ++++++-- lib/toolbox/SConscript | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 7a851dfd0..b7fd132f0 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,8.41,, +Version,+,8.42,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -190,6 +190,7 @@ Header,+,lib/toolbox/stream/file_stream.h,, Header,+,lib/toolbox/stream/stream.h,, Header,+,lib/toolbox/stream/string_stream.h,, Header,+,lib/toolbox/tar/tar_archive.h,, +Header,+,lib/toolbox/value_index.h,, Header,+,lib/toolbox/version.h,, Header,+,lib/u8g2/u8g2.h,, Function,-,LL_ADC_CommonDeInit,ErrorStatus,ADC_Common_TypeDef* @@ -3142,6 +3143,7 @@ Function,-,toupper_l,int,"int, locale_t" Function,-,trunc,double,double Function,-,truncf,float,float Function,-,truncl,long double,long double +Function,-,tzset,void, Function,-,u8g2_AddPolygonXY,void,"u8g2_t*, int16_t, int16_t" Function,-,u8g2_ClearBuffer,void,u8g2_t* Function,-,u8g2_ClearDisplay,void,u8g2_t* @@ -4196,7 +4198,6 @@ Function,-,u8x8_upscale_byte,uint16_t,uint8_t Function,-,u8x8_utf8_init,void,u8x8_t* Function,-,u8x8_utf8_next,uint16_t,"u8x8_t*, uint8_t" Function,-,u8x8_utoa,const char*,uint16_t -Function,-,tzset,void, Function,-,uECC_compress,void,"const uint8_t*, uint8_t*, uECC_Curve" Function,+,uECC_compute_public_key,int,"const uint8_t*, uint8_t*, uECC_Curve" Function,-,uECC_curve_private_key_size,int,uECC_Curve @@ -4284,6 +4285,9 @@ Function,-,vTimerSetTimerNumber,void,"TimerHandle_t, UBaseType_t" Function,+,validator_is_file_alloc_init,ValidatorIsFile*,"const char*, const char*, const char*" Function,+,validator_is_file_callback,_Bool,"const char*, FuriString*, void*" Function,+,validator_is_file_free,void,ValidatorIsFile* +Function,+,value_index_bool,uint8_t,"const _Bool, const _Bool[], uint8_t" +Function,+,value_index_float,uint8_t,"const float, const float[], uint8_t" +Function,+,value_index_uint32,uint8_t,"const uint32_t, const uint32_t[], uint8_t" Function,+,variable_item_get_context,void*,VariableItem* Function,+,variable_item_get_current_value_index,uint8_t,VariableItem* Function,+,variable_item_list_add,VariableItem*,"VariableItemList*, const char*, uint8_t, VariableItemChangeCallback, void*" diff --git a/lib/toolbox/SConscript b/lib/toolbox/SConscript index 015a8ed18..d51e31826 100644 --- a/lib/toolbox/SConscript +++ b/lib/toolbox/SConscript @@ -8,6 +8,7 @@ env.Append( "#/lib/toolbox", ], SDK_HEADERS=[ + File("value_index.h"), File("manchester_decoder.h"), File("manchester_encoder.h"), File("path.h"), From 0a0c06222a9fa02fec63c1db0e085732a6f1df49 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 10 Nov 2022 08:05:28 +0300 Subject: [PATCH 07/10] fix links --- ReadMe.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index d5c91a137..5403cd655 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -147,7 +147,11 @@ Games: ### **Plugins that works with external hardware** -## [- How to use: Temperature Sensor Plugin - HTU21D / SI7021](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/applications/plugins/temperature_sensor/Readme.md) +## [- How to use: Temperature Sensor Plugin - HTU21D / SI7021](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/applications/plugins/htu21d_temp_sensor/Readme.md) + +## [- How to use: DHT11/22 Temp. Sensor Monitor](https://github.com/quen0n/FipperZero-DHT-Monitor#readme) + +## [- How to use: AM2320/AM2321 Temp. Sensor plugin](https://github.com/xMasterX/AM2320_Flipper_Plugin) ## [- How to use: [NMEA] GPS](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/applications/plugins/gps_nmea_uart/README.md) From 68219f0d7be0ef4b193b363287ca087a11877584 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 10 Nov 2022 08:08:51 +0300 Subject: [PATCH 08/10] update readme --- ReadMe.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index 5403cd655..12e1da026 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -81,11 +81,11 @@ Also check changelog in releases for latest updates! - MultiConverter plugin [(by theisolinearchip)](https://github.com/theisolinearchip/flipperzero_stuff) - USB Keyboard plugin [(by huuck)](https://github.com/huuck/FlipperZeroUSBKeyboard) - WAV player plugin (fixed) [(OFW: DrZlo13)](https://github.com/flipperdevices/flipperzero-firmware/tree/zlo/wav-player) -- UPC-A Barcode generator plugin [(by McAzzaMan)](https://github.com/McAzzaMan/flipperzero-firmware/tree/UPC-A_Barcode_Generator/applications/barcode_generator) +- Barcode generator plugin [(original by McAzzaMan)](https://github.com/McAzzaMan/flipperzero-firmware/tree/UPC-A_Barcode_Generator/applications/barcode_generator) - [EAN-8 and refactoring](https://github.com/DarkFlippers/unleashed-firmware/pull/154) by @msvsergey - GPIO: Sentry Safe plugin [(by H4ckd4ddy)](https://github.com/H4ckd4ddy/flipperzero-sentry-safe-plugin) - ESP32: WiFi Marauder companion plugin [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion) - NRF24: Sniffer & MouseJacker (with changes) [(by mothball187)](https://github.com/mothball187/flipperzero-nrf24/tree/main/mousejacker) -- Simple Clock (timer by GMMan / settings by kowalski7cc) [(Original by CompaqDisc)](https://gist.github.com/CompaqDisc/4e329c501bd03c1e801849b81f48ea61) +- Simple Clock (timer by GMMan / settings by kowalski7cc) [(original by CompaqDisc)](https://gist.github.com/CompaqDisc/4e329c501bd03c1e801849b81f48ea61) - UniversalRF Remix / Sub-GHz Remote [(by @darmiel & @xMasterX)](https://github.com/darmiel/flipper-playlist/tree/feat/unirf-protocols) (original by @ESurge) - Spectrum Analyzer (with changes) [(by jolcese)](https://github.com/jolcese/flipperzero-firmware/tree/spectrum/applications/spectrum_analyzer) - [Ultra Narrow mode & scan channels non-consecutively](https://github.com/theY4Kman/flipperzero-firmware/commits?author=theY4Kman) - Metronome [(by panki27)](https://github.com/panki27/Metronome) @@ -93,7 +93,7 @@ Also check changelog in releases for latest updates! - **TOTP (Authenticator)** [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) - GPS [(by ezod)](https://github.com/ezod/flipperzero-gps) works with module `NMEA 0183` via UART (13TX, 14RX, GND pins on Flipper) - i2c Tools [(by NaejEL)](https://github.com/NaejEL/flipperzero-i2ctools) - C0 -> SCL / C1 -> SDA / GND -> GND | 3v3 logic levels only! -- Temperature Sensor Plugin - HTU21D / SI7021 [(by Mywk)](https://github.com/Mywk/FlipperTemperatureSensor) - [How to Connect](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/applications/plugins/temperature_sensor/Readme.md) +- Temperature Sensor Plugin - HTU21D / SI7021 [(by Mywk)](https://github.com/Mywk/FlipperTemperatureSensor) - [How to Connect](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/applications/plugins/htu21d_temp_sensor/Readme.md) - HC-SR04 Distance sensor - Ported and modified by @xMasterX [(original by Sanqui)](https://github.com/Sanqui/flipperzero-firmware/tree/hc_sr04) - How to connect -> (5V -> VCC) / (GND -> GND) / (13|TX -> Trig) / (14|RX -> Echo) - Morse Code [(by wh00hw)](https://github.com/wh00hw/MorseCodeFAP) - AM2320/AM2321 Temp. Sensor plugin [(by xMasterX)](https://github.com/xMasterX/AM2320_Flipper_Plugin) - [How to Connect](https://github.com/xMasterX/AM2320_Flipper_Plugin) From 3420cda83a03768d4cd9d69435e30d1e704d8e35 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 10 Nov 2022 08:23:54 +0300 Subject: [PATCH 09/10] update i2c tools --- .../plugins/flipper_i2ctools/i2cscanner.c | 2 +- .../plugins/flipper_i2ctools/i2csniffer.h | 2 +- .../flipper_i2ctools/views/main_view.h | 3 +- .../flipper_i2ctools/views/scanner_view.h | 2 - .../flipper_i2ctools/views/sender_view.h | 2 - .../flipper_i2ctools/views/sniffer_view.c | 52 ++++++++++++------- .../flipper_i2ctools/views/sniffer_view.h | 2 - 7 files changed, 36 insertions(+), 29 deletions(-) diff --git a/applications/plugins/flipper_i2ctools/i2cscanner.c b/applications/plugins/flipper_i2ctools/i2cscanner.c index 0ed949621..dab618b78 100644 --- a/applications/plugins/flipper_i2ctools/i2cscanner.c +++ b/applications/plugins/flipper_i2ctools/i2cscanner.c @@ -6,7 +6,7 @@ void scan_i2c_bus(i2cScanner* i2c_scanner) { // Get the bus furi_hal_i2c_acquire(I2C_BUS); // scan - for(uint8_t addr = 0x01; addr < MAX_I2C_ADDR; addr++) { + for(uint8_t addr = 0x01; addr <= MAX_I2C_ADDR << 1; addr++) { // Check for peripherals if(furi_hal_i2c_is_device_ready(I2C_BUS, addr, I2C_TIMEOUT)) { // skip even 8-bit addr diff --git a/applications/plugins/flipper_i2ctools/i2csniffer.h b/applications/plugins/flipper_i2ctools/i2csniffer.h index d7fd0df07..908e91031 100644 --- a/applications/plugins/flipper_i2ctools/i2csniffer.h +++ b/applications/plugins/flipper_i2ctools/i2csniffer.h @@ -16,7 +16,7 @@ typedef enum { I2C_BUS_FREE, I2C_BUS_STARTED } i2cBusStates; #define MAX_MESSAGE_SIZE 128 // Nb of records -#define MAX_RECORDS 32 +#define MAX_RECORDS 128 /// @brief Struct used to store our reads typedef struct { diff --git a/applications/plugins/flipper_i2ctools/views/main_view.h b/applications/plugins/flipper_i2ctools/views/main_view.h index ee7be7f9f..57b2be2e8 100644 --- a/applications/plugins/flipper_i2ctools/views/main_view.h +++ b/applications/plugins/flipper_i2ctools/views/main_view.h @@ -2,8 +2,7 @@ #include #include #include - -#define APP_NAME "I2C Tools" +#define APP_NAME "I2C_Tools" #define SCAN_MENU_TEXT "Scan" #define SCAN_MENU_X 75 diff --git a/applications/plugins/flipper_i2ctools/views/scanner_view.h b/applications/plugins/flipper_i2ctools/views/scanner_view.h index 99ba3c29f..53aee33f2 100644 --- a/applications/plugins/flipper_i2ctools/views/scanner_view.h +++ b/applications/plugins/flipper_i2ctools/views/scanner_view.h @@ -1,9 +1,7 @@ #include #include #include - #include - #include "../i2cscanner.h" #define SCAN_MENU_TEXT "Scan" diff --git a/applications/plugins/flipper_i2ctools/views/sender_view.h b/applications/plugins/flipper_i2ctools/views/sender_view.h index 866e483aa..96cc28fbc 100644 --- a/applications/plugins/flipper_i2ctools/views/sender_view.h +++ b/applications/plugins/flipper_i2ctools/views/sender_view.h @@ -1,9 +1,7 @@ #include #include #include - #include - #include "../i2csender.h" #define SEND_MENU_TEXT "Send" diff --git a/applications/plugins/flipper_i2ctools/views/sniffer_view.c b/applications/plugins/flipper_i2ctools/views/sniffer_view.c index 8f289066c..dbed3e4c9 100644 --- a/applications/plugins/flipper_i2ctools/views/sniffer_view.c +++ b/applications/plugins/flipper_i2ctools/views/sniffer_view.c @@ -20,39 +20,53 @@ void draw_sniffer_view(Canvas* canvas, i2cSniffer* i2c_sniffer) { canvas_draw_str_aligned(canvas, 85, 51, AlignLeft, AlignTop, "Stop"); } canvas_set_color(canvas, ColorBlack); + if(i2c_sniffer->first) { + canvas_draw_str_aligned(canvas, 50, 3, AlignLeft, AlignTop, "Nothing Recorded"); + return; + } + char text_buffer[8]; + // nbFrame text + canvas_draw_str_aligned(canvas, 50, 3, AlignLeft, AlignTop, "Frame: "); + snprintf(text_buffer, sizeof(text_buffer), "%d", (int)i2c_sniffer->menu_index + 1); + canvas_draw_str_aligned(canvas, 85, 3, AlignLeft, AlignTop, text_buffer); + canvas_draw_str_aligned(canvas, 100, 3, AlignLeft, AlignTop, "/"); + snprintf(text_buffer, sizeof(text_buffer), "%d", (int)i2c_sniffer->frame_index + 1); + canvas_draw_str_aligned(canvas, 110, 3, AlignLeft, AlignTop, text_buffer); // Address text - char addr_text[8]; snprintf( - addr_text, - sizeof(addr_text), + text_buffer, + sizeof(text_buffer), "0x%02x", (int)(i2c_sniffer->frames[i2c_sniffer->menu_index].data[0] >> 1)); - canvas_draw_str_aligned(canvas, 50, 3, AlignLeft, AlignTop, "Addr: "); - canvas_draw_str_aligned(canvas, 75, 3, AlignLeft, AlignTop, addr_text); + canvas_draw_str_aligned(canvas, 50, 13, AlignLeft, AlignTop, "Addr: "); + canvas_draw_str_aligned(canvas, 75, 13, AlignLeft, AlignTop, text_buffer); // R/W if((int)(i2c_sniffer->frames[i2c_sniffer->menu_index].data[0]) % 2 == 0) { - canvas_draw_str_aligned(canvas, 105, 3, AlignLeft, AlignTop, "W"); + canvas_draw_str_aligned(canvas, 105, 13, AlignLeft, AlignTop, "W"); } else { - canvas_draw_str_aligned(canvas, 105, 3, AlignLeft, AlignTop, "R"); + canvas_draw_str_aligned(canvas, 105, 13, AlignLeft, AlignTop, "R"); } - // nbFrame text - canvas_draw_str_aligned(canvas, 50, 13, AlignLeft, AlignTop, "Frames: "); - snprintf(addr_text, sizeof(addr_text), "%d", (int)i2c_sniffer->menu_index + 1); - canvas_draw_str_aligned(canvas, 90, 13, AlignLeft, AlignTop, addr_text); - canvas_draw_str_aligned(canvas, 100, 13, AlignLeft, AlignTop, "/"); - snprintf(addr_text, sizeof(addr_text), "%d", (int)i2c_sniffer->frame_index + 1); - canvas_draw_str_aligned(canvas, 110, 13, AlignLeft, AlignTop, addr_text); // Frames content + const uint8_t x_min = 50; + const uint8_t y_min = 23; uint8_t x_pos = 0; - uint8_t y_pos = 23; + uint8_t y_pos = 0; + uint8_t row = 1; + uint8_t column = 1; for(uint8_t i = 1; i < i2c_sniffer->frames[i2c_sniffer->menu_index].data_index; i++) { snprintf( - addr_text, - sizeof(addr_text), + text_buffer, + sizeof(text_buffer), "0x%02x", (int)i2c_sniffer->frames[i2c_sniffer->menu_index].data[i]); - x_pos = 50 + (i - 1) * 35; - canvas_draw_str_aligned(canvas, x_pos, y_pos, AlignLeft, AlignTop, addr_text); + x_pos = x_min + (column - 1) * 35; + y_pos = y_min + (row - 1) * 10; + column++; + if(column > 2) { + column = 1; + row++; + } + canvas_draw_str_aligned(canvas, x_pos, y_pos, AlignLeft, AlignTop, text_buffer); if(i2c_sniffer->frames[i2c_sniffer->menu_index].ack[i]) { canvas_draw_str_aligned(canvas, x_pos + 24, y_pos, AlignLeft, AlignTop, "A"); } else { diff --git a/applications/plugins/flipper_i2ctools/views/sniffer_view.h b/applications/plugins/flipper_i2ctools/views/sniffer_view.h index 56a213895..3fe1839a1 100644 --- a/applications/plugins/flipper_i2ctools/views/sniffer_view.h +++ b/applications/plugins/flipper_i2ctools/views/sniffer_view.h @@ -1,9 +1,7 @@ #include #include #include - #include - #include "../i2csniffer.h" #define SNIFF_MENU_TEXT "Sniff" From ef72ad2462e50b17585725089931d80883bd8098 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 10 Nov 2022 08:32:21 +0300 Subject: [PATCH 10/10] update totp --- .../totp/images/totp_arrow_left_8x9.png | Bin 0 -> 149 bytes .../totp/images/totp_arrow_right_8x9.png | Bin 0 -> 149 bytes .../scenes/add_new_token/totp_input_text.c | 21 +- .../scenes/add_new_token/totp_input_text.h | 2 +- .../add_new_token/totp_scene_add_new_token.c | 301 +++++++++--------- .../add_new_token/totp_scene_add_new_token.h | 6 +- .../scenes/app_settings/totp_app_settings.c | 154 ++++----- .../scenes/app_settings/totp_app_settings.h | 10 +- .../authenticate/totp_scene_authenticate.c | 153 ++++----- .../authenticate/totp_scene_authenticate.h | 6 +- .../totp_scene_generate_token.c | 143 ++++----- .../totp_scene_generate_token.h | 10 +- .../plugins/totp/scenes/scene_director.c | 10 +- .../plugins/totp/scenes/scene_director.h | 2 +- .../scenes/token_menu/totp_scene_token_menu.c | 218 +++++++------ .../scenes/token_menu/totp_scene_token_menu.h | 8 +- applications/plugins/totp/services/cli/cli.c | 2 +- .../plugins/totp/services/cli/cli_helpers.c | 5 +- .../plugins/totp/services/cli/cli_helpers.h | 28 +- .../totp/services/cli/commands/add/add.c | 120 +++---- .../totp/services/cli/commands/list/list.c | 4 + .../plugins/totp/services/config/config.c | 45 +-- .../plugins/totp/services/config/config.h | 4 +- .../plugins/totp/services/crypto/crypto.c | 24 +- .../plugins/totp/services/crypto/crypto.h | 10 +- .../plugins/totp/services/crypto/memset_s.c | 22 ++ .../plugins/totp/services/crypto/memset_s.h | 16 + .../plugins/totp/services/hmac/sha1.c | 114 ++----- .../plugins/totp/services/hmac/sha1.h | 21 -- .../plugins/totp/services/hmac/sha256.c | 129 +------- .../plugins/totp/services/hmac/sha256.h | 33 +- .../plugins/totp/services/hmac/sha512.c | 145 +-------- .../plugins/totp/services/hmac/sha512.h | 31 +- applications/plugins/totp/services/hmac/u64.c | 20 -- applications/plugins/totp/services/hmac/u64.h | 2 +- .../plugins/totp/services/list/list.c | 11 +- .../plugins/totp/services/list/list.h | 12 +- .../plugins/totp/services/nullable/nullable.h | 17 + .../totp/services/roll_value/roll_value.c | 28 ++ .../totp/services/roll_value/roll_value.h | 17 + .../plugins/totp/services/totp/totp.c | 19 +- .../plugins/totp/services/totp/totp.h | 6 +- applications/plugins/totp/services/ui/icons.h | 13 - .../plugins/totp/services/ui/ui_controls.c | 30 +- .../plugins/totp/services/ui/ui_controls.h | 10 +- applications/plugins/totp/totp_app.c | 11 +- .../plugins/totp/types/plugin_state.h | 4 +- applications/plugins/totp/types/token_info.c | 15 +- applications/plugins/totp/types/token_info.h | 8 +- 49 files changed, 921 insertions(+), 1099 deletions(-) create mode 100644 applications/plugins/totp/images/totp_arrow_left_8x9.png create mode 100644 applications/plugins/totp/images/totp_arrow_right_8x9.png create mode 100644 applications/plugins/totp/services/crypto/memset_s.c create mode 100644 applications/plugins/totp/services/crypto/memset_s.h delete mode 100644 applications/plugins/totp/services/hmac/u64.c create mode 100644 applications/plugins/totp/services/nullable/nullable.h create mode 100644 applications/plugins/totp/services/roll_value/roll_value.c create mode 100644 applications/plugins/totp/services/roll_value/roll_value.h delete mode 100644 applications/plugins/totp/services/ui/icons.h diff --git a/applications/plugins/totp/images/totp_arrow_left_8x9.png b/applications/plugins/totp/images/totp_arrow_left_8x9.png new file mode 100644 index 0000000000000000000000000000000000000000..3bf9121c0b3eb1d3a7e05bc069f9b23827adb381 GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^96-#;$P6S+=l;(HQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`*#dk*T>t<74`hZOx?BgOI14-?iy0XB4ude`@%$AjKtTyl7sn8Z%gG5T o3F#BkSET>oKk|v^4Nnh)$W|twRlcWOfod2$UHx3vIVCg!0A-gcZvX%Q literal 0 HcmV?d00001 diff --git a/applications/plugins/totp/images/totp_arrow_right_8x9.png b/applications/plugins/totp/images/totp_arrow_right_8x9.png new file mode 100644 index 0000000000000000000000000000000000000000..8c6a8bfeb91385715c668ae573f6e609cf43ad72 GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^96-#;$P6S+=l;(HQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`*#dk*T!Hle|NocXoPQU{;w #include "../../types/common.h" +size_t strnlen(const char* s, size_t maxlen) { + size_t len; + + for(len = 0; len < maxlen; len++, s++) { + if(!*s) break; + } + + return len; +} + void view_draw(View* view, Canvas* canvas) { furi_assert(view); if(view->draw_callback) { @@ -32,16 +42,23 @@ static void commit_text_input_callback(void* context) { 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); + furi_check(result != NULL); + result->user_input_length = + strnlen(text_input_state->text_input_buffer, INPUT_BUFFER_SIZE); result->user_input = malloc(result->user_input_length + 1); + furi_check(result->user_input != NULL); result->callback_data = text_input_state->callback_data; - strcpy(result->user_input, text_input_state->text_input_buffer); + strlcpy( + result->user_input, + text_input_state->text_input_buffer, + result->user_input_length + 1); text_input_state->callback(result); } } InputTextSceneState* totp_input_text_activate(InputTextSceneContext* context) { InputTextSceneState* text_input_state = malloc(sizeof(InputTextSceneState)); + furi_check(text_input_state != NULL); text_input_state->text_input = text_input_alloc(); text_input_state->text_input_view = text_input_get_view(text_input_state->text_input); text_input_state->callback = context->callback; diff --git a/applications/plugins/totp/scenes/add_new_token/totp_input_text.h b/applications/plugins/totp/scenes/add_new_token/totp_input_text.h index a73a227b5..dda0dc301 100644 --- a/applications/plugins/totp/scenes/add_new_token/totp_input_text.h +++ b/applications/plugins/totp/scenes/add_new_token/totp_input_text.h @@ -10,7 +10,7 @@ typedef struct { char* user_input; - uint8_t user_input_length; + size_t user_input_length; void* callback_data; } InputTextSceneCallbackResult; 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 04b73595b..97b642f5c 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 @@ -8,6 +8,8 @@ #include "../../services/base32/base32.h" #include "../../services/config/config.h" #include "../../services/ui/ui_controls.h" +#include "../../services/roll_value/roll_value.h" +#include "../../services/nullable/nullable.h" #include "../generate_token/totp_scene_generate_token.h" #define TOKEN_ALGO_LIST_LENGTH 3 @@ -25,22 +27,22 @@ typedef enum { typedef struct { char* token_name; - uint8_t token_name_length; + size_t token_name_length; char* token_secret; - uint8_t token_secret_length; + size_t token_secret_length; bool saved; Control selected_control; InputTextSceneContext* token_name_input_context; InputTextSceneContext* token_secret_input_context; InputTextSceneState* input_state; uint32_t input_started_at; - int16_t current_token_index; - int32_t screen_y_offset; + TotpNullable_uint16_t current_token_index; + int16_t screen_y_offset; TokenHashAlgo algo; TokenDigitsCount digits_count; } SceneState; -void totp_scene_add_new_token_init(PluginState* plugin_state) { +void totp_scene_add_new_token_init(const PluginState* plugin_state) { UNUSED(plugin_state); } @@ -66,6 +68,7 @@ void totp_scene_add_new_token_activate( PluginState* plugin_state, const TokenAddEditSceneContext* context) { SceneState* scene_state = malloc(sizeof(SceneState)); + furi_check(scene_state != NULL); plugin_state->current_scene_state = scene_state; scene_state->token_name = "Name"; scene_state->token_name_length = strlen(scene_state->token_name); @@ -73,11 +76,13 @@ void totp_scene_add_new_token_activate( scene_state->token_secret_length = strlen(scene_state->token_secret); scene_state->token_name_input_context = malloc(sizeof(InputTextSceneContext)); + furi_check(scene_state->token_name_input_context != NULL); scene_state->token_name_input_context->header_text = "Enter token name"; scene_state->token_name_input_context->callback_data = scene_state; scene_state->token_name_input_context->callback = on_token_name_user_comitted; scene_state->token_secret_input_context = malloc(sizeof(InputTextSceneContext)); + furi_check(scene_state->token_secret_input_context != NULL); scene_state->token_secret_input_context->header_text = "Enter token secret"; scene_state->token_secret_input_context->callback_data = scene_state; scene_state->token_secret_input_context->callback = on_token_secret_user_comitted; @@ -87,9 +92,9 @@ void totp_scene_add_new_token_activate( scene_state->input_state = NULL; if(context == NULL) { - scene_state->current_token_index = -1; + TOTP_NULLABLE_NULL(scene_state->current_token_index); } else { - scene_state->current_token_index = context->current_token_index; + TOTP_NULLABLE_VALUE(scene_state->current_token_index, context->current_token_index); } } @@ -150,143 +155,151 @@ 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) { - return totp_input_text_handle_event(event, scene_state->input_state); - } - - 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(); - bool token_secret_set = token_info_set_secret( - tokenInfo, - scene_state->token_secret, - scene_state->token_secret_length, - &plugin_state->iv[0]); - - if(token_secret_set) { - tokenInfo->name = malloc(scene_state->token_name_length + 1); - strcpy(tokenInfo->name, scene_state->token_name); - 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++; - - totp_config_file_save_new_token(tokenInfo); - - GenerateTokenSceneContext generate_scene_context = { - .current_token_index = plugin_state->tokens_count - 1}; - totp_scene_director_activate_scene( - plugin_state, TotpSceneGenerateToken, &generate_scene_context); - } else { - token_info_free(tokenInfo); - DialogMessage* message = dialog_message_alloc(); - dialog_message_set_buttons(message, "Back", NULL, NULL); - dialog_message_set_text( - message, - "Token secret is invalid", - SCREEN_WIDTH_CENTER, - SCREEN_HEIGHT_CENTER, - AlignCenter, - AlignCenter); - dialog_message_show(plugin_state->dialogs, message); - dialog_message_free(message); - scene_state->selected_control = TokenSecretTextBox; - update_screen_y_offset(scene_state); - } - 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; - default: - break; - } - } + if(event->type != EventTypeKey) { + return true; } + + 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) { + return false; + } + + if(event->input.type != InputTypePress) { + return true; + } + + switch(event->input.key) { + case InputKeyUp: + totp_roll_value_uint8_t( + &scene_state->selected_control, + -1, + TokenNameTextBox, + ConfirmButton, + RollOverflowBehaviorStop); + update_screen_y_offset(scene_state); + break; + case InputKeyDown: + totp_roll_value_uint8_t( + &scene_state->selected_control, + 1, + TokenNameTextBox, + ConfirmButton, + RollOverflowBehaviorStop); + update_screen_y_offset(scene_state); + break; + case InputKeyRight: + if(scene_state->selected_control == TokenAlgoSelect) { + totp_roll_value_uint8_t(&scene_state->algo, 1, SHA1, SHA512, RollOverflowBehaviorRoll); + } else if(scene_state->selected_control == TokenLengthSelect) { + totp_roll_value_uint8_t( + &scene_state->digits_count, + 1, + TOTP_6_DIGITS, + TOTP_8_DIGITS, + RollOverflowBehaviorRoll); + } + break; + case InputKeyLeft: + if(scene_state->selected_control == TokenAlgoSelect) { + totp_roll_value_uint8_t( + &scene_state->algo, -1, SHA1, SHA512, RollOverflowBehaviorRoll); + } else if(scene_state->selected_control == TokenLengthSelect) { + totp_roll_value_uint8_t( + &scene_state->digits_count, + -1, + TOTP_6_DIGITS, + TOTP_8_DIGITS, + RollOverflowBehaviorRoll); + } + 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(); + bool token_secret_set = token_info_set_secret( + tokenInfo, + scene_state->token_secret, + scene_state->token_secret_length, + &plugin_state->iv[0]); + + if(token_secret_set) { + tokenInfo->name = malloc(scene_state->token_name_length + 1); + furi_check(tokenInfo->name != NULL); + strlcpy( + tokenInfo->name, scene_state->token_name, scene_state->token_name_length + 1); + tokenInfo->algo = scene_state->algo; + tokenInfo->digits = scene_state->digits_count; + + TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, tokenInfo, furi_check); + plugin_state->tokens_count++; + + totp_config_file_save_new_token(tokenInfo); + + GenerateTokenSceneContext generate_scene_context = { + .current_token_index = plugin_state->tokens_count - 1}; + totp_scene_director_activate_scene( + plugin_state, TotpSceneGenerateToken, &generate_scene_context); + } else { + token_info_free(tokenInfo); + DialogMessage* message = dialog_message_alloc(); + dialog_message_set_buttons(message, "Back", NULL, NULL); + dialog_message_set_text( + message, + "Token secret is invalid", + SCREEN_WIDTH_CENTER, + SCREEN_HEIGHT_CENTER, + AlignCenter, + AlignCenter); + dialog_message_show(plugin_state->dialogs, message); + dialog_message_free(message); + scene_state->selected_control = TokenSecretTextBox; + update_screen_y_offset(scene_state); + } + break; + } + default: + break; + } + break; + case InputKeyBack: + if(!scene_state->current_token_index.is_null) { + GenerateTokenSceneContext generate_scene_context = { + .current_token_index = scene_state->current_token_index.value}; + totp_scene_director_activate_scene( + plugin_state, TotpSceneGenerateToken, &generate_scene_context); + } else { + totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL); + } + break; + default: + break; + } + return true; } @@ -310,6 +323,6 @@ void totp_scene_add_new_token_deactivate(PluginState* plugin_state) { plugin_state->current_scene_state = NULL; } -void totp_scene_add_new_token_free(PluginState* plugin_state) { +void totp_scene_add_new_token_free(const PluginState* plugin_state) { UNUSED(plugin_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 b65c567a2..9f53fe799 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 @@ -7,14 +7,14 @@ #include "../../types/plugin_event.h" typedef struct { - uint8_t current_token_index; + uint16_t current_token_index; } TokenAddEditSceneContext; -void totp_scene_add_new_token_init(PluginState* plugin_state); +void totp_scene_add_new_token_init(const PluginState* plugin_state); 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); -void totp_scene_add_new_token_free(PluginState* plugin_state); +void totp_scene_add_new_token_free(const PluginState* plugin_state); diff --git a/applications/plugins/totp/scenes/app_settings/totp_app_settings.c b/applications/plugins/totp/scenes/app_settings/totp_app_settings.c index b3e6ab847..63db2e46b 100644 --- a/applications/plugins/totp/scenes/app_settings/totp_app_settings.c +++ b/applications/plugins/totp/scenes/app_settings/totp_app_settings.c @@ -4,6 +4,8 @@ #include "../token_menu/totp_scene_token_menu.h" #include "../../services/ui/constants.h" #include "../../services/config/config.h" +#include "../../services/roll_value/roll_value.h" +#include "../../services/nullable/nullable.h" #define DIGIT_TO_CHAR(digit) ((digit) + '0') @@ -12,11 +14,11 @@ typedef enum { HoursInput, MinutesInput, ConfirmButton } Control; typedef struct { int8_t tz_offset_hours; uint8_t tz_offset_minutes; - int16_t current_token_index; + TotpNullable_uint16_t current_token_index; Control selected_control; } SceneState; -void totp_scene_app_settings_init(PluginState* plugin_state) { +void totp_scene_app_settings_init(const PluginState* plugin_state) { UNUSED(plugin_state); } @@ -24,11 +26,12 @@ void totp_scene_app_settings_activate( PluginState* plugin_state, const AppSettingsSceneContext* context) { SceneState* scene_state = malloc(sizeof(SceneState)); + furi_check(scene_state != NULL); plugin_state->current_scene_state = scene_state; if(context != NULL) { - scene_state->current_token_index = context->current_token_index; + TOTP_NULLABLE_VALUE(scene_state->current_token_index, context->current_token_index); } else { - scene_state->current_token_index = -1; + TOTP_NULLABLE_NULL(scene_state->current_token_index); } float off_int; @@ -53,7 +56,7 @@ static void two_digit_to_str(int8_t num, char* str) { } void totp_scene_app_settings_render(Canvas* const canvas, PluginState* plugin_state) { - SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; + const SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; canvas_set_font(canvas, FontPrimary); canvas_draw_str_aligned(canvas, 0, 0, AlignLeft, AlignTop, "Timezone offset"); @@ -90,79 +93,80 @@ void totp_scene_app_settings_render(Canvas* const canvas, PluginState* plugin_st scene_state->selected_control == ConfirmButton); } -bool totp_scene_app_settings_handle_event(PluginEvent* const event, PluginState* plugin_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 > HoursInput) { - scene_state->selected_control--; - } - break; - case InputKeyDown: - if(scene_state->selected_control < ConfirmButton) { - scene_state->selected_control++; - } - break; - case InputKeyRight: - if(scene_state->selected_control == HoursInput) { - if(scene_state->tz_offset_hours < 12) { - scene_state->tz_offset_hours++; - } - } else if(scene_state->selected_control == MinutesInput) { - if(scene_state->tz_offset_minutes < 45) { - scene_state->tz_offset_minutes += 15; - } else { - scene_state->tz_offset_minutes = 0; - } - } - break; - case InputKeyLeft: - if(scene_state->selected_control == HoursInput) { - if(scene_state->tz_offset_hours > -12) { - scene_state->tz_offset_hours--; - } - } else if(scene_state->selected_control == MinutesInput) { - if(scene_state->tz_offset_minutes >= 15) { - scene_state->tz_offset_minutes -= 15; - } else { - scene_state->tz_offset_minutes = 45; - } - } - break; - case InputKeyOk: - if(scene_state->selected_control == ConfirmButton) { - plugin_state->timezone_offset = (float)scene_state->tz_offset_hours + - (float)scene_state->tz_offset_minutes / 60.0f; - totp_config_file_update_timezone_offset(plugin_state->timezone_offset); +bool totp_scene_app_settings_handle_event( + const PluginEvent* const event, + PluginState* plugin_state) { + if(event->type != EventTypeKey) { + return true; + } - if(scene_state->current_token_index >= 0) { - TokenMenuSceneContext generate_scene_context = { - .current_token_index = scene_state->current_token_index}; - totp_scene_director_activate_scene( - plugin_state, TotpSceneTokenMenu, &generate_scene_context); - } else { - totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu, NULL); - } - } - break; - case InputKeyBack: { - if(scene_state->current_token_index >= 0) { - TokenMenuSceneContext generate_scene_context = { - .current_token_index = scene_state->current_token_index}; - totp_scene_director_activate_scene( - plugin_state, TotpSceneTokenMenu, &generate_scene_context); - } else { - totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu, NULL); - } - break; - } - default: - break; + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; + if(event->input.type != InputTypePress) { + return true; + } + + switch(event->input.key) { + case InputKeyUp: + totp_roll_value_uint8_t( + &scene_state->selected_control, + -1, + HoursInput, + ConfirmButton, + RollOverflowBehaviorStop); + break; + case InputKeyDown: + totp_roll_value_uint8_t( + &scene_state->selected_control, 1, HoursInput, ConfirmButton, RollOverflowBehaviorStop); + break; + case InputKeyRight: + if(scene_state->selected_control == HoursInput) { + totp_roll_value_int8_t( + &scene_state->tz_offset_hours, 1, -12, 12, RollOverflowBehaviorStop); + } else if(scene_state->selected_control == MinutesInput) { + totp_roll_value_uint8_t( + &scene_state->tz_offset_minutes, 15, 0, 45, RollOverflowBehaviorRoll); + } + break; + case InputKeyLeft: + if(scene_state->selected_control == HoursInput) { + totp_roll_value_int8_t( + &scene_state->tz_offset_hours, -1, -12, 12, RollOverflowBehaviorStop); + } else if(scene_state->selected_control == MinutesInput) { + totp_roll_value_uint8_t( + &scene_state->tz_offset_minutes, -15, 0, 45, RollOverflowBehaviorRoll); + } + break; + case InputKeyOk: + if(scene_state->selected_control == ConfirmButton) { + plugin_state->timezone_offset = (float)scene_state->tz_offset_hours + + (float)scene_state->tz_offset_minutes / 60.0f; + totp_config_file_update_timezone_offset(plugin_state->timezone_offset); + + if(!scene_state->current_token_index.is_null) { + TokenMenuSceneContext generate_scene_context = { + .current_token_index = scene_state->current_token_index.value}; + totp_scene_director_activate_scene( + plugin_state, TotpSceneTokenMenu, &generate_scene_context); + } else { + totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu, NULL); } } + break; + case InputKeyBack: { + if(!scene_state->current_token_index.is_null) { + TokenMenuSceneContext generate_scene_context = { + .current_token_index = scene_state->current_token_index.value}; + totp_scene_director_activate_scene( + plugin_state, TotpSceneTokenMenu, &generate_scene_context); + } else { + totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu, NULL); + } + break; } + default: + break; + } + return true; } @@ -173,6 +177,6 @@ void totp_scene_app_settings_deactivate(PluginState* plugin_state) { plugin_state->current_scene_state = NULL; } -void totp_scene_app_settings_free(PluginState* plugin_state) { +void totp_scene_app_settings_free(const PluginState* plugin_state) { UNUSED(plugin_state); } \ No newline at end of file diff --git a/applications/plugins/totp/scenes/app_settings/totp_app_settings.h b/applications/plugins/totp/scenes/app_settings/totp_app_settings.h index b97de3390..bcf930839 100644 --- a/applications/plugins/totp/scenes/app_settings/totp_app_settings.h +++ b/applications/plugins/totp/scenes/app_settings/totp_app_settings.h @@ -7,14 +7,16 @@ #include "../../types/plugin_event.h" typedef struct { - uint8_t current_token_index; + uint16_t current_token_index; } AppSettingsSceneContext; -void totp_scene_app_settings_init(PluginState* plugin_state); +void totp_scene_app_settings_init(const PluginState* plugin_state); void totp_scene_app_settings_activate( PluginState* plugin_state, const AppSettingsSceneContext* context); void totp_scene_app_settings_render(Canvas* const canvas, PluginState* plugin_state); -bool totp_scene_app_settings_handle_event(PluginEvent* const event, PluginState* plugin_state); +bool totp_scene_app_settings_handle_event( + const PluginEvent* const event, + PluginState* plugin_state); void totp_scene_app_settings_deactivate(PluginState* plugin_state); -void totp_scene_app_settings_free(PluginState* plugin_state); \ No newline at end of file +void totp_scene_app_settings_free(const PluginState* plugin_state); \ No newline at end of file diff --git a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c b/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c index cdb77f5e2..627f6a10d 100644 --- a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c +++ b/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c @@ -1,7 +1,7 @@ #include "totp_scene_authenticate.h" #include +#include #include "../../types/common.h" -#include "../../services/ui/icons.h" #include "../../services/ui/constants.h" #include "../../services/config/config.h" #include "../scene_director.h" @@ -9,6 +9,10 @@ #include "../../services/crypto/crypto.h" #define MAX_CODE_LENGTH TOTP_IV_SIZE +#define ARROW_UP_CODE 2 +#define ARROW_RIGHT_CODE 8 +#define ARROW_DOWN_CODE 11 +#define ARROW_LEFT_CODE 5 typedef struct { uint8_t code_input[MAX_CODE_LENGTH]; @@ -21,6 +25,7 @@ void totp_scene_authenticate_init(PluginState* plugin_state) { void totp_scene_authenticate_activate(PluginState* plugin_state) { SceneState* scene_state = malloc(sizeof(SceneState)); + furi_check(scene_state != NULL); scene_state->code_length = 0; memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH); plugin_state->current_scene_state = scene_state; @@ -28,7 +33,7 @@ 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; + const SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; int v_shift = 0; if(scene_state->code_length > 0) { @@ -62,7 +67,7 @@ void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_st const uint8_t PIN_ASTERISK_RADIUS = 3; const uint8_t PIN_ASTERISK_STEP = (PIN_ASTERISK_RADIUS << 1) + 2; if(scene_state->code_length > 0) { - uint8_t left_start_x = (scene_state->code_length - 1) * PIN_ASTERISK_STEP >> 1; + 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++) { canvas_draw_disc( canvas, @@ -73,80 +78,82 @@ 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) { - return false; - } else if(event->input.type == InputTypePress) { - SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; +bool totp_scene_authenticate_handle_event( + const PluginEvent* const event, + PluginState* plugin_state) { + if(event->type != EventTypeKey) { + return true; + } - const uint8_t ARROW_UP_CODE = 2; - const uint8_t ARROW_RIGHT_CODE = 8; - const uint8_t ARROW_DOWN_CODE = 11; - const uint8_t ARROW_LEFT_CODE = 5; + if(event->input.type == InputTypeLong && event->input.key == InputKeyBack) { + return false; + } - 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: - totp_crypto_seed_iv( - plugin_state, &scene_state->code_input[0], scene_state->code_length); + if(event->input.type != InputTypePress) { + return true; + } - if(totp_crypto_verify_key(plugin_state)) { - 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; + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; - 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; - default: - break; - } + 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: + totp_crypto_seed_iv(plugin_state, &scene_state->code_input[0], scene_state->code_length); + + if(totp_crypto_verify_key(plugin_state)) { + 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; + default: + break; } return true; @@ -158,6 +165,6 @@ void totp_scene_authenticate_deactivate(PluginState* plugin_state) { plugin_state->current_scene_state = NULL; } -void totp_scene_authenticate_free(PluginState* plugin_state) { +void totp_scene_authenticate_free(const PluginState* plugin_state) { UNUSED(plugin_state); } diff --git a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.h b/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.h index f1199a425..c54152f62 100644 --- a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.h +++ b/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.h @@ -9,6 +9,8 @@ void totp_scene_authenticate_init(PluginState* plugin_state); void totp_scene_authenticate_activate(PluginState* plugin_state); void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_state); -bool totp_scene_authenticate_handle_event(PluginEvent* const event, PluginState* plugin_state); +bool totp_scene_authenticate_handle_event( + const PluginEvent* const event, + PluginState* plugin_state); void totp_scene_authenticate_deactivate(PluginState* plugin_state); -void totp_scene_authenticate_free(PluginState* plugin_state); +void totp_scene_authenticate_free(const PluginState* plugin_state); 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 c9547a1ab..f0366243a 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 @@ -1,14 +1,16 @@ #include #include #include +#include #include "totp_scene_generate_token.h" #include "../../types/token_info.h" #include "../../types/common.h" -#include "../../services/ui/icons.h" #include "../../services/ui/constants.h" #include "../../services/totp/totp.h" #include "../../services/config/config.h" #include "../../services/crypto/crypto.h" +#include "../../services/crypto/memset_s.h" +#include "../../services/roll_value/roll_value.h" #include "../scene_director.h" #include "../token_menu/totp_scene_token_menu.h" @@ -16,7 +18,7 @@ #define DIGIT_TO_CHAR(digit) ((digit) + '0') typedef struct { - uint8_t current_token_index; + uint16_t current_token_index; char last_code[9]; char* last_code_name; bool need_token_update; @@ -35,24 +37,17 @@ static const NotificationSequence sequence_short_vibro_and_sound = { }; static void i_token_to_str(uint32_t i_token_code, char* str, TokenDigitsCount len) { + uint8_t str_token_length = 0; if(len == TOTP_8_DIGITS) { str[8] = '\0'; + str_token_length = 8; } else if(len == TOTP_6_DIGITS) { str[6] = '\0'; + str_token_length = 6; } - if(i_token_code == 0) { - if(len > TOTP_6_DIGITS) { - str[7] = '-'; - str[6] = '-'; - } - - str[5] = '-'; - str[4] = '-'; - str[3] = '-'; - str[2] = '-'; - str[1] = '-'; - str[0] = '-'; + if(i_token_code == OTP_ERROR) { + memset(&str[0], '-', str_token_length); } else { if(len == TOTP_8_DIGITS) { str[7] = DIGIT_TO_CHAR(i_token_code % 10); @@ -78,6 +73,8 @@ TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) { return TOTP_ALGO_SHA256; case SHA512: return TOTP_ALGO_SHA512; + default: + break; } return NULL; @@ -95,7 +92,7 @@ void update_totp_params(PluginState* const plugin_state) { } } -void totp_scene_generate_token_init(PluginState* plugin_state) { +void totp_scene_generate_token_init(const PluginState* plugin_state) { UNUSED(plugin_state); } @@ -130,6 +127,7 @@ void totp_scene_generate_token_activate( } } SceneState* scene_state = malloc(sizeof(SceneState)); + furi_check(scene_state != NULL); if(context == NULL || context->current_token_index > plugin_state->tokens_count) { scene_state->current_token_index = 0; } else { @@ -180,7 +178,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ ->data); if(tokenInfo->token != NULL && tokenInfo->token_length > 0) { - uint8_t key_length; + size_t key_length; uint8_t* key = totp_crypto_decrypt( tokenInfo->token, tokenInfo->token_length, &plugin_state->iv[0], &key_length); @@ -195,7 +193,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ TOKEN_LIFETIME), scene_state->last_code, tokenInfo->digits); - memset(key, 0, key_length); + memset_s(key, key_length, 0, key_length); free(key); } else { i_token_to_str(0, scene_state->last_code, tokenInfo->digits); @@ -248,65 +246,63 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ 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]); + canvas_draw_icon(canvas, 0, SCREEN_HEIGHT_CENTER - 24, &I_totp_arrow_left_8x9); + canvas_draw_icon( + canvas, SCREEN_WIDTH - 9, SCREEN_HEIGHT_CENTER - 24, &I_totp_arrow_right_8x9); } } -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) { - return false; - } else if(event->input.type == InputTypePress) { - 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, TotpSceneTokenMenu, 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; - default: - break; - } +bool totp_scene_generate_token_handle_event( + const PluginEvent* const event, + PluginState* plugin_state) { + if(event->type != EventTypeKey) { + return true; + } + + if(event->input.type == InputTypeLong && event->input.key == InputKeyBack) { + return false; + } + + if(event->input.type != InputTypePress) { + return true; + } + + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; + switch(event->input.key) { + case InputKeyUp: + break; + case InputKeyDown: + break; + case InputKeyRight: + totp_roll_value_uint16_t( + &scene_state->current_token_index, + 1, + 0, + plugin_state->tokens_count - 1, + RollOverflowBehaviorRoll); + update_totp_params(plugin_state); + break; + case InputKeyLeft: + totp_roll_value_uint16_t( + &scene_state->current_token_index, + -1, + 0, + plugin_state->tokens_count - 1, + RollOverflowBehaviorRoll); + update_totp_params(plugin_state); + break; + case InputKeyOk: + if(plugin_state->tokens_count == 0) { + totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu, 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; + default: + break; } return true; @@ -316,11 +312,10 @@ 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; - free(scene_state->last_code); free(scene_state); plugin_state->current_scene_state = NULL; } -void totp_scene_generate_token_free(PluginState* plugin_state) { +void totp_scene_generate_token_free(const PluginState* plugin_state) { UNUSED(plugin_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 1284c7b41..65f9b84e0 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 @@ -7,14 +7,16 @@ #include "../../types/plugin_event.h" typedef struct { - uint8_t current_token_index; + uint16_t current_token_index; } GenerateTokenSceneContext; -void totp_scene_generate_token_init(PluginState* plugin_state); +void totp_scene_generate_token_init(const PluginState* plugin_state); 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); +bool totp_scene_generate_token_handle_event( + const PluginEvent* const event, + PluginState* plugin_state); void totp_scene_generate_token_deactivate(PluginState* plugin_state); -void totp_scene_generate_token_free(PluginState* plugin_state); +void totp_scene_generate_token_free(const PluginState* plugin_state); diff --git a/applications/plugins/totp/scenes/scene_director.c b/applications/plugins/totp/scenes/scene_director.c index d4ddd1768..a518dcfc8 100644 --- a/applications/plugins/totp/scenes/scene_director.c +++ b/applications/plugins/totp/scenes/scene_director.c @@ -30,6 +30,8 @@ void totp_scene_director_activate_scene( break; case TotpSceneNone: break; + default: + break; } plugin_state->current_scene = scene; @@ -55,6 +57,8 @@ void totp_scene_director_deactivate_active_scene(PluginState* const plugin_state break; case TotpSceneNone: break; + default: + break; } } @@ -85,10 +89,12 @@ void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_ break; case TotpSceneNone: break; + default: + break; } } -void totp_scene_director_dispose(PluginState* const plugin_state) { +void totp_scene_director_dispose(const PluginState* const plugin_state) { totp_scene_generate_token_free(plugin_state); totp_scene_authenticate_free(plugin_state); totp_scene_add_new_token_free(plugin_state); @@ -116,6 +122,8 @@ bool totp_scene_director_handle_event(PluginEvent* const event, PluginState* con break; case TotpSceneNone: break; + default: + break; } return processing; diff --git a/applications/plugins/totp/scenes/scene_director.h b/applications/plugins/totp/scenes/scene_director.h index 3c25afff6..cc06029d3 100644 --- a/applications/plugins/totp/scenes/scene_director.h +++ b/applications/plugins/totp/scenes/scene_director.h @@ -12,5 +12,5 @@ void totp_scene_director_activate_scene( 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); -void totp_scene_director_dispose(PluginState* const plugin_state); +void totp_scene_director_dispose(const PluginState* const plugin_state); bool totp_scene_director_handle_event(PluginEvent* const event, 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 717cb64bc..d936bf95f 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,6 +10,8 @@ #include "../generate_token/totp_scene_generate_token.h" #include "../add_new_token/totp_scene_add_new_token.h" #include "../app_settings/totp_app_settings.h" +#include "../../services/nullable/nullable.h" +#include "../../services/roll_value/roll_value.h" #define SCREEN_HEIGHT_THIRD (SCREEN_HEIGHT / 3) #define SCREEN_HEIGHT_THIRD_CENTER (SCREEN_HEIGHT_THIRD >> 1) @@ -18,10 +20,10 @@ typedef enum { AddNewToken, DeleteToken, AppSettings } Control; typedef struct { Control selected_control; - int16_t current_token_index; + TotpNullable_uint16_t current_token_index; } SceneState; -void totp_scene_token_menu_init(PluginState* plugin_state) { +void totp_scene_token_menu_init(const PluginState* plugin_state) { UNUSED(plugin_state); } @@ -29,17 +31,18 @@ void totp_scene_token_menu_activate( PluginState* plugin_state, const TokenMenuSceneContext* context) { SceneState* scene_state = malloc(sizeof(SceneState)); + furi_check(scene_state != NULL); plugin_state->current_scene_state = scene_state; if(context != NULL) { - scene_state->current_token_index = context->current_token_index; + TOTP_NULLABLE_VALUE(scene_state->current_token_index, context->current_token_index); } else { - scene_state->current_token_index = -1; + TOTP_NULLABLE_NULL(scene_state->current_token_index); } } void totp_scene_token_menu_render(Canvas* const canvas, PluginState* plugin_state) { - SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; - if(scene_state->current_token_index < 0) { + const SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; + if(scene_state->current_token_index.is_null) { ui_control_button_render( canvas, SCREEN_WIDTH_CENTER - 36, @@ -84,106 +87,109 @@ void totp_scene_token_menu_render(Canvas* const canvas, PluginState* plugin_stat } } -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->input.type == InputTypePress) { - switch(event->input.key) { - case InputKeyUp: - if(scene_state->selected_control > AddNewToken) { - scene_state->selected_control--; - if(scene_state->selected_control == DeleteToken && - scene_state->current_token_index < 0) { - scene_state->selected_control--; - } - } else { - scene_state->selected_control = AppSettings; - } - break; - case InputKeyDown: - if(scene_state->selected_control < AppSettings) { - scene_state->selected_control++; - if(scene_state->selected_control == DeleteToken && - scene_state->current_token_index < 0) { - scene_state->selected_control++; - } - } else { - scene_state->selected_control = AddNewToken; - } - 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) { - ListNode* list_node = list_element_at( - plugin_state->tokens_list, scene_state->current_token_index); - - 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; - } - case AppSettings: { - if(scene_state->current_token_index >= 0) { - AppSettingsSceneContext app_settings_context = { - .current_token_index = scene_state->current_token_index}; - totp_scene_director_activate_scene( - plugin_state, TotpSceneAppSettings, &app_settings_context); - } else { - totp_scene_director_activate_scene( - plugin_state, TotpSceneAppSettings, NULL); - } - 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; - } - default: - break; - } - } +bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginState* plugin_state) { + if(event->type != EventTypeKey) { + return true; } + + SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; + if(event->input.type != InputTypePress) { + return true; + } + + switch(event->input.key) { + case InputKeyUp: + totp_roll_value_uint8_t( + &scene_state->selected_control, -1, AddNewToken, AppSettings, RollOverflowBehaviorRoll); + if(scene_state->selected_control == DeleteToken && + scene_state->current_token_index.is_null) { + scene_state->selected_control--; + } + break; + case InputKeyDown: + totp_roll_value_uint8_t( + &scene_state->selected_control, 1, AddNewToken, AppSettings, RollOverflowBehaviorRoll); + if(scene_state->selected_control == DeleteToken && + scene_state->current_token_index.is_null) { + scene_state->selected_control++; + } + break; + case InputKeyRight: + break; + case InputKeyLeft: + break; + case InputKeyOk: + switch(scene_state->selected_control) { + case AddNewToken: { + if(scene_state->current_token_index.is_null) { + totp_scene_director_activate_scene(plugin_state, TotpSceneAddNewToken, NULL); + } else { + TokenAddEditSceneContext add_new_token_scene_context = { + .current_token_index = scene_state->current_token_index.value}; + 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 && + !scene_state->current_token_index.is_null) { + ListNode* list_node = list_element_at( + plugin_state->tokens_list, scene_state->current_token_index.value); + + 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; + } + case AppSettings: { + if(!scene_state->current_token_index.is_null) { + AppSettingsSceneContext app_settings_context = { + .current_token_index = scene_state->current_token_index.value}; + totp_scene_director_activate_scene( + plugin_state, TotpSceneAppSettings, &app_settings_context); + } else { + totp_scene_director_activate_scene(plugin_state, TotpSceneAppSettings, NULL); + } + break; + } + default: + break; + } + break; + case InputKeyBack: { + if(!scene_state->current_token_index.is_null) { + GenerateTokenSceneContext generate_scene_context = { + .current_token_index = scene_state->current_token_index.value}; + totp_scene_director_activate_scene( + plugin_state, TotpSceneGenerateToken, &generate_scene_context); + } else { + totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL); + } + break; + } + default: + break; + } + return true; } @@ -194,6 +200,6 @@ void totp_scene_token_menu_deactivate(PluginState* plugin_state) { plugin_state->current_scene_state = NULL; } -void totp_scene_token_menu_free(PluginState* plugin_state) { +void totp_scene_token_menu_free(const PluginState* plugin_state) { UNUSED(plugin_state); } 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 0b117cb25..acb499be8 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 @@ -7,14 +7,14 @@ #include "../../types/plugin_event.h" typedef struct { - uint8_t current_token_index; + uint16_t current_token_index; } TokenMenuSceneContext; -void totp_scene_token_menu_init(PluginState* plugin_state); +void totp_scene_token_menu_init(const PluginState* plugin_state); 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); +bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginState* plugin_state); void totp_scene_token_menu_deactivate(PluginState* plugin_state); -void totp_scene_token_menu_free(PluginState* plugin_state); +void totp_scene_token_menu_free(const PluginState* plugin_state); diff --git a/applications/plugins/totp/services/cli/cli.c b/applications/plugins/totp/services/cli/cli.c index 3a7afdd96..76e58a02d 100644 --- a/applications/plugins/totp/services/cli/cli.c +++ b/applications/plugins/totp/services/cli/cli.c @@ -9,7 +9,7 @@ #include "commands/timezone/timezone.h" #include "commands/help/help.h" -static void totp_cli_print_unknown_command(FuriString* unknown_command) { +static void totp_cli_print_unknown_command(const FuriString* unknown_command) { TOTP_CLI_PRINTF( "Command \"%s\" is unknown. Use \"" TOTP_CLI_COMMAND_HELP "\" command to get list of available commands.", diff --git a/applications/plugins/totp/services/cli/cli_helpers.c b/applications/plugins/totp/services/cli/cli_helpers.c index 81a1e4b77..0bea6fd90 100644 --- a/applications/plugins/totp/services/cli/cli_helpers.c +++ b/applications/plugins/totp/services/cli/cli_helpers.c @@ -1,7 +1,7 @@ #include "cli_helpers.h" #include -bool totp_cli_ensure_authenticated(PluginState* plugin_state, Cli* cli) { +bool totp_cli_ensure_authenticated(const PluginState* plugin_state, Cli* cli) { if(plugin_state->current_scene == TotpSceneAuthentication) { TOTP_CLI_PRINTF("Pleases enter PIN on your flipper device\r\n"); @@ -11,9 +11,8 @@ bool totp_cli_ensure_authenticated(PluginState* plugin_state, Cli* cli) { } TOTP_CLI_DELETE_LAST_LINE(); - fflush(stdout); - if(plugin_state->current_scene == TotpSceneAuthentication) { + if(plugin_state->current_scene == TotpSceneAuthentication) { //-V547 return false; } } diff --git a/applications/plugins/totp/services/cli/cli_helpers.h b/applications/plugins/totp/services/cli/cli_helpers.h index 216925e50..9b19f926b 100644 --- a/applications/plugins/totp/services/cli/cli_helpers.h +++ b/applications/plugins/totp/services/cli/cli_helpers.h @@ -13,16 +13,28 @@ #define DOCOPT_OPTIONS "[options]" #define DOCOPT_DEFAULT(val) "[default: " val "]" -#define TOTP_CLI_PRINTF(format, ...) \ - _Pragma(STRINGIFY(GCC diagnostic push)); \ - _Pragma(STRINGIFY(GCC diagnostic ignored "-Wdouble-promotion")); \ - printf(format, ##__VA_ARGS__); \ - _Pragma(STRINGIFY(GCC diagnostic pop)); +#define TOTP_CLI_PRINTF(format, ...) \ + do { \ + _Pragma(STRINGIFY(GCC diagnostic push)) \ + _Pragma(STRINGIFY(GCC diagnostic ignored "-Wdouble-promotion")) \ + printf(format, ##__VA_ARGS__); \ + _Pragma(STRINGIFY(GCC diagnostic pop)) \ + } while(false) + +#define TOTP_CLI_DELETE_LAST_LINE() \ + TOTP_CLI_PRINTF("\033[A\33[2K\r"); \ + fflush(stdout) + +#define TOTP_CLI_DELETE_CURRENT_LINE() \ + TOTP_CLI_PRINTF("\33[2K\r"); \ + fflush(stdout) + +#define TOTP_CLI_DELETE_LAST_CHAR() \ + TOTP_CLI_PRINTF("\b \b"); \ + fflush(stdout) -#define TOTP_CLI_DELETE_LAST_LINE() TOTP_CLI_PRINTF("\033[A\33[2K\r") -#define TOTP_CLI_DELETE_CURRENT_LINE() TOTP_CLI_PRINTF("\33[2K\r") #define TOTP_CLI_PRINT_INVALID_ARGUMENTS() \ TOTP_CLI_PRINTF( \ "Invalid command arguments. use \"help\" command to get list of available commands") -bool totp_cli_ensure_authenticated(PluginState* plugin_state, Cli* cli); +bool totp_cli_ensure_authenticated(const PluginState* plugin_state, Cli* cli); diff --git a/applications/plugins/totp/services/cli/commands/add/add.c b/applications/plugins/totp/services/cli/commands/add/add.c index 41ff5b860..2e8f22547 100644 --- a/applications/plugins/totp/services/cli/commands/add/add.c +++ b/applications/plugins/totp/services/cli/commands/add/add.c @@ -14,7 +14,7 @@ #define TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "-d" #define TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX "-u" -static bool token_info_set_digits_from_str(TokenInfo* token_info, FuriString* str) { +static bool token_info_set_digits_from_str(TokenInfo* token_info, const FuriString* str) { switch(furi_string_get_char(str, 0)) { case '6': token_info->digits = TOTP_6_DIGITS; @@ -22,12 +22,14 @@ static bool token_info_set_digits_from_str(TokenInfo* token_info, FuriString* st case '8': token_info->digits = TOTP_8_DIGITS; return true; + default: + break; } return false; } -static bool token_info_set_algo_from_str(TokenInfo* token_info, FuriString* str) { +static bool token_info_set_algo_from_str(TokenInfo* token_info, const FuriString* str) { if(furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME) == 0) { token_info->algo = SHA1; return true; @@ -79,10 +81,53 @@ void totp_cli_command_add_docopt_options() { TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX) " Show console user input as-is without masking\r\n"); } +static void furi_string_secure_free(FuriString* str) { + for(long i = furi_string_size(str) - 1; i >= 0; i--) { + furi_string_set_char(str, i, '\0'); + } + + furi_string_free(str); +} + +static bool totp_cli_read_secret(Cli* cli, FuriString* out_str, bool mask_user_input) { + uint8_t c; + while(cli_read(cli, &c, 1) == 1) { + if(c == CliSymbolAsciiEsc) { + // Some keys generating escape-sequences + // We need to ignore them as we case about alpha-numerics only + uint8_t c2; + cli_read_timeout(cli, &c2, 1, 0); + cli_read_timeout(cli, &c2, 1, 0); + } else if(c == CliSymbolAsciiETX) { + TOTP_CLI_DELETE_CURRENT_LINE(); + TOTP_CLI_PRINTF("Cancelled by user\r\n"); + return false; + } else if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { + if(mask_user_input) { + putc('*', stdout); + } else { + putc(c, stdout); + } + fflush(stdout); + furi_string_push_back(out_str, c); + } else if(c == CliSymbolAsciiBackspace || c == CliSymbolAsciiDel) { + size_t out_str_size = furi_string_size(out_str); + if(out_str_size > 0) { + TOTP_CLI_DELETE_LAST_CHAR(); + furi_string_left(out_str, out_str_size - 1); + } + } else if(c == CliSymbolAsciiCR) { + cli_nl(); + break; + } + } + + TOTP_CLI_DELETE_LAST_LINE(); + return true; +} + void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cli* cli) { FuriString* temp_str = furi_string_alloc(); - const char* temp_cstr; - TokenInfo* token_info = token_info_alloc(); // Reading token name @@ -93,9 +138,10 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl return; } - temp_cstr = furi_string_get_cstr(temp_str); - token_info->name = malloc(strlen(temp_cstr) + 1); - strcpy(token_info->name, temp_cstr); + size_t temp_cstr_len = furi_string_size(temp_str); + token_info->name = malloc(temp_cstr_len + 1); + furi_check(token_info->name != NULL); + strlcpy(token_info->name, furi_string_get_cstr(temp_str), temp_cstr_len + 1); // Read optional arguments bool mask_user_input = true; @@ -142,59 +188,25 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl // Reading token secret furi_string_reset(temp_str); TOTP_CLI_PRINTF("Enter token secret and confirm with [ENTER]\r\n"); - - uint8_t c; - while(cli_read(cli, &c, 1) == 1) { - if(c == CliSymbolAsciiEsc) { - uint8_t c2; - cli_read_timeout(cli, &c2, 1, 0); - cli_read_timeout(cli, &c2, 1, 0); - } else if(c == CliSymbolAsciiETX) { - TOTP_CLI_DELETE_CURRENT_LINE(); - TOTP_CLI_PRINTF("Cancelled by user"); - furi_string_free(temp_str); - token_info_free(token_info); - return; - } else if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { - if(mask_user_input) { - putc('*', stdout); - } else { - putc(c, stdout); - } - fflush(stdout); - furi_string_push_back(temp_str, c); - } else if(c == CliSymbolAsciiBackspace || c == CliSymbolAsciiDel) { - size_t temp_str_size = furi_string_size(temp_str); - if(temp_str_size > 0) { - TOTP_CLI_PRINTF("\b \b"); - fflush(stdout); - furi_string_left(temp_str, temp_str_size - 1); - } - } else if(c == CliSymbolAsciiCR) { - cli_nl(); - break; - } - } - - temp_cstr = furi_string_get_cstr(temp_str); - - TOTP_CLI_DELETE_LAST_LINE(); - - if(!totp_cli_ensure_authenticated(plugin_state, cli)) { - furi_string_free(temp_str); + if(!totp_cli_read_secret(cli, temp_str, mask_user_input) || + !totp_cli_ensure_authenticated(plugin_state, cli)) { + furi_string_secure_free(temp_str); token_info_free(token_info); return; } - if(!token_info_set_secret(token_info, temp_cstr, strlen(temp_cstr), plugin_state->iv)) { + if(!token_info_set_secret( + token_info, + furi_string_get_cstr(temp_str), + furi_string_size(temp_str), + plugin_state->iv)) { TOTP_CLI_PRINTF("Token secret seems to be invalid and can not be parsed\r\n"); - furi_string_free(temp_str); + furi_string_secure_free(temp_str); token_info_free(token_info); return; } - furi_string_reset(temp_str); - furi_string_free(temp_str); + furi_string_secure_free(temp_str); bool load_generate_token_scene = false; if(plugin_state->current_scene == TotpSceneGenerateToken) { @@ -202,11 +214,7 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl load_generate_token_scene = true; } - if(plugin_state->tokens_list == NULL) { - plugin_state->tokens_list = list_init_head(token_info); - } else { - list_add(plugin_state->tokens_list, token_info); - } + TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, token_info, furi_check); plugin_state->tokens_count++; totp_config_file_save_new_token(token_info); diff --git a/applications/plugins/totp/services/cli/commands/list/list.c b/applications/plugins/totp/services/cli/commands/list/list.c index 61791084d..9f6bf2d0f 100644 --- a/applications/plugins/totp/services/cli/commands/list/list.c +++ b/applications/plugins/totp/services/cli/commands/list/list.c @@ -13,6 +13,8 @@ static char* get_algo_as_cstr(TokenHashAlgo algo) { return TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME; case SHA512: return TOTP_CONFIG_TOKEN_ALGO_SHA512_NAME; + default: + break; } return "UNKNOWN"; @@ -24,6 +26,8 @@ static uint8_t get_digits_as_int(TokenDigitsCount digits) { return 6; case TOTP_8_DIGITS: return 8; + default: + break; } return 6; diff --git a/applications/plugins/totp/services/config/config.c b/applications/plugins/totp/services/config/config.c index 0854d79ad..765b9c20e 100644 --- a/applications/plugins/totp/services/config/config.c +++ b/applications/plugins/totp/services/config/config.c @@ -10,12 +10,14 @@ #define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf" #define CONFIG_FILE_BACKUP_PATH CONFIG_FILE_PATH ".backup" -static uint8_t token_info_get_digits_as_int(TokenInfo* token_info) { +static uint8_t token_info_get_digits_as_int(const TokenInfo* token_info) { switch(token_info->digits) { case TOTP_6_DIGITS: return 6; case TOTP_8_DIGITS: return 8; + default: + break; } return 6; @@ -29,10 +31,12 @@ static void token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits case 8: token_info->digits = TOTP_8_DIGITS; break; + default: + break; } } -static char* token_info_get_algo_as_cstr(TokenInfo* token_info) { +static char* token_info_get_algo_as_cstr(const TokenInfo* token_info) { switch(token_info->algo) { case SHA1: return TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME; @@ -40,12 +44,14 @@ static char* token_info_get_algo_as_cstr(TokenInfo* token_info) { return TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME; case SHA512: return TOTP_CONFIG_TOKEN_ALGO_SHA512_NAME; + default: + break; } return NULL; } -static void token_info_set_algo_from_str(TokenInfo* token_info, FuriString* str) { +static void token_info_set_algo_from_str(TokenInfo* token_info, const FuriString* str) { 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) == 0) { @@ -152,7 +158,7 @@ FlipperFormat* totp_open_config_file(Storage* storage) { return fff_data_file; } -void totp_config_file_save_new_token_i(FlipperFormat* file, TokenInfo* token_info) { +void totp_config_file_save_new_token_i(FlipperFormat* file, const TokenInfo* token_info) { flipper_format_seek_to_end(file); flipper_format_write_string_cstr(file, TOTP_CONFIG_KEY_TOKEN_NAME, token_info->name); bool token_is_valid = token_info->token != NULL && token_info->token_length > 0; @@ -170,7 +176,7 @@ void totp_config_file_save_new_token_i(FlipperFormat* file, TokenInfo* token_inf flipper_format_write_uint32(file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &digits_count_as_uint32, 1); } -void totp_config_file_save_new_token(TokenInfo* token_info) { +void totp_config_file_save_new_token(const TokenInfo* token_info) { Storage* cfg_storage = totp_open_storage(); FlipperFormat* file = totp_open_config_file(cfg_storage); @@ -190,7 +196,7 @@ void totp_config_file_update_timezone_offset(float new_timezone_offset) { totp_close_storage(); } -void totp_full_save_config_file(PluginState* const plugin_state) { +void totp_full_save_config_file(const PluginState* const plugin_state) { Storage* storage = totp_open_storage(); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); @@ -209,7 +215,7 @@ void totp_full_save_config_file(PluginState* const plugin_state) { flipper_format_write_bool(fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1); ListNode* node = plugin_state->tokens_list; while(node != NULL) { - TokenInfo* token_info = node->data; + const TokenInfo* token_info = node->data; totp_config_file_save_new_token_i(fff_data_file, token_info); node = node->next; } @@ -283,6 +289,7 @@ void totp_config_file_load_base(PluginState* const plugin_state) { if(flipper_format_get_value_count(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, &crypto_size) && crypto_size > 0) { plugin_state->crypto_verify_data = malloc(sizeof(uint8_t) * crypto_size); + furi_check(plugin_state->crypto_verify_data != NULL); plugin_state->crypto_verify_data_length = crypto_size; if(!flipper_format_read_hex( fff_data_file, @@ -333,7 +340,7 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state) } TokenLoadingResult result = TokenLoadingResultSuccess; - uint8_t index = 0; + uint16_t index = 0; bool has_any_plain_secret = false; while(true) { @@ -343,9 +350,10 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state) TokenInfo* tokenInfo = token_info_alloc(); - const char* temp_cstr = furi_string_get_cstr(temp_str); - tokenInfo->name = (char*)malloc(strlen(temp_cstr) + 1); - strcpy(tokenInfo->name, temp_cstr); + size_t temp_cstr_len = furi_string_size(temp_str); + tokenInfo->name = malloc(temp_cstr_len + 1); + furi_check(tokenInfo->name != NULL); + strlcpy(tokenInfo->name, furi_string_get_cstr(temp_str), temp_cstr_len + 1); uint32_t secret_bytes_count; if(!flipper_format_get_value_count( @@ -355,9 +363,11 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state) if(secret_bytes_count == 1) { // Plain secret key if(flipper_format_read_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_SECRET, temp_str)) { - temp_cstr = furi_string_get_cstr(temp_str); if(token_info_set_secret( - tokenInfo, temp_cstr, strlen(temp_cstr), &plugin_state->iv[0])) { + tokenInfo, + furi_string_get_cstr(temp_str), + furi_string_size(temp_str), + &plugin_state->iv[0])) { FURI_LOG_W(LOGGING_TAG, "Token \"%s\" has plain secret", tokenInfo->name); } else { tokenInfo->token = NULL; @@ -376,6 +386,7 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state) tokenInfo->token_length = secret_bytes_count; if(secret_bytes_count > 0) { tokenInfo->token = malloc(tokenInfo->token_length); + furi_check(tokenInfo->token != NULL); if(!flipper_format_read_hex( fff_data_file, TOTP_CONFIG_KEY_TOKEN_SECRET, @@ -407,11 +418,7 @@ TokenLoadingResult 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) { - plugin_state->tokens_list = list_init_head(tokenInfo); - } else { - list_add(plugin_state->tokens_list, tokenInfo); - } + TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, tokenInfo, furi_check); index++; } @@ -419,7 +426,7 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state) plugin_state->tokens_count = index; plugin_state->token_list_loaded = true; - FURI_LOG_D(LOGGING_TAG, "Found %" PRIu8 " tokens", index); + FURI_LOG_D(LOGGING_TAG, "Found %" PRIu16 " tokens", index); furi_string_free(temp_str); totp_close_config_file(fff_data_file); diff --git a/applications/plugins/totp/services/config/config.h b/applications/plugins/totp/services/config/config.h index 76cb40b2c..d452ad4b3 100644 --- a/applications/plugins/totp/services/config/config.h +++ b/applications/plugins/totp/services/config/config.h @@ -16,8 +16,8 @@ Storage* totp_open_storage(); void totp_close_storage(); FlipperFormat* totp_open_config_file(Storage* storage); void totp_close_config_file(FlipperFormat* file); -void totp_full_save_config_file(PluginState* const plugin_state); +void totp_full_save_config_file(const PluginState* const plugin_state); void totp_config_file_load_base(PluginState* const plugin_state); TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state); -void totp_config_file_save_new_token(TokenInfo* token_info); +void totp_config_file_save_new_token(const TokenInfo* token_info); void totp_config_file_update_timezone_offset(float new_timezone_offset); diff --git a/applications/plugins/totp/services/crypto/crypto.c b/applications/plugins/totp/services/crypto/crypto.c index ade2f9f49..794d0b0be 100644 --- a/applications/plugins/totp/services/crypto/crypto.c +++ b/applications/plugins/totp/services/crypto/crypto.c @@ -3,6 +3,7 @@ #include #include "../config/config.h" #include "../../types/common.h" +#include "memset_s.h" #define CRYPTO_KEY_SLOT 2 #define CRYPTO_VERIFY_KEY "FFF_Crypto_pass" @@ -11,28 +12,31 @@ uint8_t* totp_crypto_encrypt( const uint8_t* plain_data, - const uint8_t plain_data_length, + const size_t plain_data_length, const uint8_t* iv, - uint8_t* encrypted_data_length) { + size_t* encrypted_data_length) { uint8_t* encrypted_data; size_t remain = plain_data_length % CRYPTO_ALIGNMENT_FACTOR; if(remain) { - uint8_t plain_data_aligned_length = plain_data_length - remain + CRYPTO_ALIGNMENT_FACTOR; + size_t plain_data_aligned_length = plain_data_length - remain + CRYPTO_ALIGNMENT_FACTOR; uint8_t* plain_data_aligned = malloc(plain_data_aligned_length); + furi_check(plain_data_aligned != NULL); memset(plain_data_aligned, 0, plain_data_aligned_length); memcpy(plain_data_aligned, plain_data, plain_data_length); encrypted_data = malloc(plain_data_aligned_length); + furi_check(encrypted_data != NULL); *encrypted_data_length = plain_data_aligned_length; furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, iv); furi_hal_crypto_encrypt(plain_data_aligned, encrypted_data, plain_data_aligned_length); furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT); - memset(plain_data_aligned, 0, plain_data_aligned_length); + memset_s(plain_data_aligned, plain_data_aligned_length, 0, plain_data_aligned_length); free(plain_data_aligned); } else { encrypted_data = malloc(plain_data_length); + furi_check(encrypted_data != NULL); *encrypted_data_length = plain_data_length; furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, iv); @@ -45,18 +49,19 @@ uint8_t* totp_crypto_encrypt( uint8_t* totp_crypto_decrypt( const uint8_t* encrypted_data, - const uint8_t encrypted_data_length, + const size_t encrypted_data_length, const uint8_t* iv, - uint8_t* decrypted_data_length) { + size_t* decrypted_data_length) { *decrypted_data_length = encrypted_data_length; uint8_t* decrypted_data = malloc(*decrypted_data_length); + furi_check(decrypted_data != NULL); furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, iv); furi_hal_crypto_decrypt(encrypted_data, decrypted_data, encrypted_data_length); furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT); return decrypted_data; } -void totp_crypto_seed_iv(PluginState* plugin_state, uint8_t* pin, uint8_t pin_length) { +void totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t pin_length) { 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); @@ -92,6 +97,7 @@ void totp_crypto_seed_iv(PluginState* plugin_state, uint8_t* pin, uint8_t pin_le 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); + furi_check(plugin_state->crypto_verify_data != NULL); plugin_state->crypto_verify_data_length = CRYPTO_VERIFY_KEY_LENGTH; Storage* storage = totp_open_storage(); FlipperFormat* config_file = totp_open_config_file(storage); @@ -118,8 +124,8 @@ void totp_crypto_seed_iv(PluginState* plugin_state, uint8_t* pin, uint8_t pin_le } bool totp_crypto_verify_key(const PluginState* plugin_state) { - uint8_t decrypted_key_length; - uint8_t* decrypted_key = totp_crypto_decrypt( + size_t decrypted_key_length; + const uint8_t* decrypted_key = totp_crypto_decrypt( plugin_state->crypto_verify_data, plugin_state->crypto_verify_data_length, &plugin_state->iv[0], diff --git a/applications/plugins/totp/services/crypto/crypto.h b/applications/plugins/totp/services/crypto/crypto.h index 9fc319659..f0a28f798 100644 --- a/applications/plugins/totp/services/crypto/crypto.h +++ b/applications/plugins/totp/services/crypto/crypto.h @@ -4,13 +4,13 @@ uint8_t* totp_crypto_encrypt( const uint8_t* plain_data, - const uint8_t plain_data_length, + const size_t plain_data_length, const uint8_t* iv, - uint8_t* encrypted_data_length); + size_t* encrypted_data_length); uint8_t* totp_crypto_decrypt( const uint8_t* encrypted_data, - const uint8_t encrypted_data_length, + const size_t encrypted_data_length, const uint8_t* iv, - uint8_t* decrypted_data_length); -void totp_crypto_seed_iv(PluginState* plugin_state, uint8_t* pin, uint8_t pin_length); + size_t* decrypted_data_length); +void totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t pin_length); bool totp_crypto_verify_key(const PluginState* plugin_state); \ No newline at end of file diff --git a/applications/plugins/totp/services/crypto/memset_s.c b/applications/plugins/totp/services/crypto/memset_s.c new file mode 100644 index 000000000..81c285c0d --- /dev/null +++ b/applications/plugins/totp/services/crypto/memset_s.c @@ -0,0 +1,22 @@ +#include "memset_s.h" + +#define RSIZE_MAX 0x7fffffffffffffffUL + +errno_t memset_s(void* s, rsize_t smax, int c, rsize_t n) { + if(!s || smax > RSIZE_MAX) { + return EINVAL; + } + + errno_t violation_present = 0; + if(n > smax) { + n = smax; + violation_present = EINVAL; + } + + volatile unsigned char* v = s; + for(rsize_t i = 0u; i < n; ++i) { + *v++ = (unsigned char)c; + } + + return violation_present; +} \ No newline at end of file diff --git a/applications/plugins/totp/services/crypto/memset_s.h b/applications/plugins/totp/services/crypto/memset_s.h new file mode 100644 index 000000000..060c6642b --- /dev/null +++ b/applications/plugins/totp/services/crypto/memset_s.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include + +#ifndef _RSIZE_T_DECLARED +typedef uint64_t rsize_t; +#define _RSIZE_T_DECLARED +#endif +#ifndef _ERRNOT_DECLARED +typedef int16_t errno_t; //-V677 +#define _ERRNOT_DECLARED +#endif + +errno_t memset_s(void* s, rsize_t smax, int c, rsize_t n); \ No newline at end of file diff --git a/applications/plugins/totp/services/hmac/sha1.c b/applications/plugins/totp/services/hmac/sha1.c index 5679e489d..243a6dde8 100644 --- a/applications/plugins/totp/services/hmac/sha1.c +++ b/applications/plugins/totp/services/hmac/sha1.c @@ -22,9 +22,6 @@ */ /* Specification. */ -#if HAVE_OPENSSL_SHA1 -#define GL_OPENSSL_INLINE _GL_EXTERN_INLINE -#endif #include "sha1.h" #include @@ -37,8 +34,6 @@ #define SWAP(n) swap_uint32(n) #endif -#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, ... */}; @@ -146,7 +141,7 @@ void sha1_process_bytes(const void* buffer, size_t len, struct sha1_ctx* ctx) { #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); + sha1_process_block(memcpy(ctx->buffer, buffer, 64), 64, ctx); //-V1086 buffer = (const char*)buffer + 64; len -= 64; } @@ -232,86 +227,31 @@ void sha1_process_block(const void* buffer, size_t len, struct sha1_ctx* ctx) { 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)); + for(int i = 0; i < 80; i++) { + uint32_t xx = i < 16 ? x[i] : M(i); + uint32_t ki = i / 20; + switch(ki) { + case 0: + R(a, b, c, d, e, F1, K1, xx); + break; + case 1: + R(a, b, c, d, e, F2, K2, xx); + break; + case 2: + R(a, b, c, d, e, F3, K3, xx); + break; + default: + R(a, b, c, d, e, F4, K4, xx); + break; + } + + uint32_t tt = a; + a = e; + e = d; + d = c; + c = b; + b = tt; + } a = ctx->A += a; b = ctx->B += b; @@ -321,8 +261,6 @@ void sha1_process_block(const void* buffer, size_t len, struct sha1_ctx* ctx) { } } -#endif - /* * Hey Emacs! * Local Variables: diff --git a/applications/plugins/totp/services/hmac/sha1.h b/applications/plugins/totp/services/hmac/sha1.h index d602d26fd..e9eb7712a 100644 --- a/applications/plugins/totp/services/hmac/sha1.h +++ b/applications/plugins/totp/services/hmac/sha1.h @@ -21,23 +21,12 @@ #include #include -#if HAVE_OPENSSL_SHA1 -#ifndef OPENSSL_API_COMPAT -#define OPENSSL_API_COMPAT 0x10101000L /* FIXME: Use OpenSSL 1.1+ API. */ -#endif -#include -#endif - #ifdef __cplusplus extern "C" { #endif #define SHA1_DIGEST_SIZE 20 -#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; @@ -83,16 +72,6 @@ extern void* sha1_read_ctx(const struct sha1_ctx* ctx, void* restrict resbuf); digest. */ extern void* sha1_buffer(const char* buffer, size_t len, void* restrict resblock); -#endif - -/* Compute SHA1 message digest for bytes read from STREAM. - STREAM is an open file stream. Regular files are handled more efficiently. - The contents of STREAM from its current position to its end will be read. - 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); - #ifdef __cplusplus } #endif diff --git a/applications/plugins/totp/services/hmac/sha256.c b/applications/plugins/totp/services/hmac/sha256.c index 2ea63dd37..89ca67c2b 100644 --- a/applications/plugins/totp/services/hmac/sha256.c +++ b/applications/plugins/totp/services/hmac/sha256.c @@ -1,4 +1,4 @@ -/* sha256.c - Functions to compute SHA256 and SHA224 message digest of files or +/* sha256.c - Functions to compute SHA256 message digest of files or memory blocks according to the NIST specification FIPS-180-2. Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc. @@ -21,9 +21,6 @@ */ /* Specification. */ -#if HAVE_OPENSSL_SHA256 -#define GL_OPENSSL_INLINE _GL_EXTERN_INLINE -#endif #include "sha256.h" #include @@ -36,8 +33,6 @@ #define SWAP(n) swap_uint32(n) #endif -#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, ... */}; @@ -61,20 +56,6 @@ void sha256_init_ctx(struct sha256_ctx* ctx) { 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; - - 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 */ @@ -93,15 +74,6 @@ void* sha256_read_ctx(const struct sha256_ctx* ctx, void* resbuf) { return 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])); - - 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) { @@ -130,11 +102,6 @@ void* sha256_finish_ctx(struct sha256_ctx* ctx, void* resbuf) { 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); -} - /* 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 @@ -152,19 +119,6 @@ void* sha256_buffer(const char* buffer, size_t len, void* resblock) { return sha256_finish_ctx(&ctx, resblock); } -void* sha224_buffer(const char* buffer, size_t len, void* resblock) { - struct sha256_ctx ctx; - - /* Initialize the computation context. */ - sha224_init_ctx(&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); -} - 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. */ @@ -194,7 +148,7 @@ void sha256_process_bytes(const void* buffer, size_t len, struct sha256_ctx* ctx #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); + sha256_process_block(memcpy(ctx->buffer, buffer, 64), 64, ctx); //-V1086 buffer = (const char*)buffer + 64; len -= 64; } @@ -299,70 +253,19 @@ void sha256_process_block(const void* buffer, size_t len, struct sha256_ctx* ctx 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)); + for(int i = 0; i < 64; i++) { + uint32_t xx = i < 16 ? x[i] : M(i); + R(a, b, c, d, e, f, g, h, K(i), xx); + uint32_t tt = a; + a = h; + h = g; + g = f; + f = e; + e = d; + d = c; + c = b; + b = tt; + } a = ctx->state[0] += a; b = ctx->state[1] += b; @@ -375,8 +278,6 @@ void sha256_process_block(const void* buffer, size_t len, struct sha256_ctx* ctx } } -#endif - /* * Hey Emacs! * Local Variables: diff --git a/applications/plugins/totp/services/hmac/sha256.h b/applications/plugins/totp/services/hmac/sha256.h index 2f99d1428..964f2eb97 100644 --- a/applications/plugins/totp/services/hmac/sha256.h +++ b/applications/plugins/totp/services/hmac/sha256.h @@ -1,4 +1,4 @@ -/* Declarations of functions and data types used for SHA256 and SHA224 sum +/* Declarations of functions and data types used for SHA256 sum library functions. Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc. @@ -20,26 +20,12 @@ #include #include -#if HAVE_OPENSSL_SHA256 -#ifndef OPENSSL_API_COMPAT -#define OPENSSL_API_COMPAT 0x10101000L /* FIXME: Use OpenSSL 1.1+ API. */ -#endif -#include -#endif - #ifdef __cplusplus extern "C" { #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 /* Structure to save state of computation between the single steps. */ struct sha256_ctx { uint32_t state[8]; @@ -51,7 +37,6 @@ struct sha256_ctx { /* Initialize structure containing state of computation. */ 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 @@ -70,31 +55,17 @@ extern void sha256_process_bytes(const void* buffer, size_t len, struct sha256_c 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); /* 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); -/* Compute SHA256 (SHA224) message digest for LEN bytes beginning at BUFFER. +/* 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. */ 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 - -/* Compute SHA256 (SHA224) message digest for bytes read from STREAM. - STREAM is an open file stream. Regular files are handled more efficiently. - The contents of STREAM from its current position to its end will be read. - 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); #ifdef __cplusplus } diff --git a/applications/plugins/totp/services/hmac/sha512.c b/applications/plugins/totp/services/hmac/sha512.c index 53d3bad2e..f04c4d593 100644 --- a/applications/plugins/totp/services/hmac/sha512.c +++ b/applications/plugins/totp/services/hmac/sha512.c @@ -1,4 +1,4 @@ -/* sha512.c - Functions to compute SHA512 and SHA384 message digest of files or +/* sha512.c - Functions to compute SHA512 message digest of files or memory blocks according to the NIST specification FIPS-180-2. Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc. @@ -21,9 +21,6 @@ */ /* Specification. */ -#if HAVE_OPENSSL_SHA512 -#define GL_OPENSSL_INLINE _GL_EXTERN_INLINE -#endif #include "sha512.h" #include @@ -36,8 +33,6 @@ #define SWAP(n) swap_uint64(n) #endif -#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, ... */}; @@ -61,20 +56,6 @@ void sha512_init_ctx(struct sha512_ctx* ctx) { 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); - - 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 */ @@ -93,15 +74,6 @@ void* sha512_read_ctx(const struct sha512_ctx* ctx, void* resbuf) { return 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])); - - 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) { @@ -132,11 +104,6 @@ void* sha512_finish_ctx(struct sha512_ctx* ctx, void* resbuf) { 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); -} - /* 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 @@ -154,19 +121,6 @@ void* sha512_buffer(const char* buffer, size_t len, void* resblock) { return sha512_finish_ctx(&ctx, resblock); } -void* sha384_buffer(const char* buffer, size_t len, void* resblock) { - struct sha512_ctx ctx; - - /* Initialize the computation context. */ - sha384_init_ctx(&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); -} - 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. */ @@ -196,7 +150,7 @@ void sha512_process_bytes(const void* buffer, size_t len, struct sha512_ctx* ctx #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); + sha512_process_block(memcpy(ctx->buffer, buffer, 128), 128, ctx); //-V1086 buffer = (const char*)buffer + 128; len -= 128; } @@ -328,86 +282,19 @@ void sha512_process_block(const void* buffer, size_t len, struct sha512_ctx* ctx 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)); + for(int i = 0; i < 80; i++) { + u64 xx = i < 16 ? x[i] : M(i); + R(a, b, c, d, e, f, g, h, K(i), xx); + u64 tt = a; + a = h; + h = g; + g = f; + f = e; + e = d; + d = c; + c = b; + b = tt; + } a = ctx->state[0] = u64plus(ctx->state[0], a); b = ctx->state[1] = u64plus(ctx->state[1], b); @@ -420,8 +307,6 @@ void sha512_process_block(const void* buffer, size_t len, struct sha512_ctx* ctx } } -#endif - /* * Hey Emacs! * Local Variables: diff --git a/applications/plugins/totp/services/hmac/sha512.h b/applications/plugins/totp/services/hmac/sha512.h index 6489fc3cb..38590829e 100644 --- a/applications/plugins/totp/services/hmac/sha512.h +++ b/applications/plugins/totp/services/hmac/sha512.h @@ -20,26 +20,12 @@ #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 - #ifdef __cplusplus extern "C" { #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 /* Structure to save state of computation between the single steps. */ struct sha512_ctx { u64 state[8]; @@ -51,7 +37,6 @@ struct sha512_ctx { /* Initialize structure containing state of computation. */ 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 @@ -70,7 +55,6 @@ extern void sha512_process_bytes(const void* buffer, size_t len, struct sha512_c 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); /* 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 @@ -79,25 +63,12 @@ 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); -/* Compute SHA512 (SHA384) message digest for LEN bytes beginning at BUFFER. +/* 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. */ 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 - -/* Compute SHA512 (SHA384) message digest for bytes read from STREAM. - STREAM is an open file stream. Regular files are handled more efficiently. - The contents of STREAM from its current position to its end will be read. - 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); #ifdef __cplusplus } diff --git a/applications/plugins/totp/services/hmac/u64.c b/applications/plugins/totp/services/hmac/u64.c deleted file mode 100644 index de6257ba0..000000000 --- a/applications/plugins/totp/services/hmac/u64.c +++ /dev/null @@ -1,20 +0,0 @@ -/* uint64_t-like operations that work even on hosts lacking uint64_t - - Copyright (C) 2012-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 . */ - -#define _GL_U64_INLINE _GL_EXTERN_INLINE -#include "u64.h" -typedef int dummy; diff --git a/applications/plugins/totp/services/hmac/u64.h b/applications/plugins/totp/services/hmac/u64.h index af0bb067b..91e42e6c9 100644 --- a/applications/plugins/totp/services/hmac/u64.h +++ b/applications/plugins/totp/services/hmac/u64.h @@ -26,7 +26,7 @@ #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. */ diff --git a/applications/plugins/totp/services/list/list.c b/applications/plugins/totp/services/list/list.c index 3a3317980..bc7307fdb 100644 --- a/applications/plugins/totp/services/list/list.c +++ b/applications/plugins/totp/services/list/list.c @@ -1,14 +1,16 @@ #include "list.h" ListNode* list_init_head(void* data) { - ListNode* new = (ListNode*)malloc(sizeof(ListNode)); + ListNode* new = malloc(sizeof(ListNode)); + if(new == NULL) return NULL; new->data = data; new->next = NULL; return new; } ListNode* list_add(ListNode* head, void* data) { - ListNode* new = (ListNode*)malloc(sizeof(ListNode)); + ListNode* new = malloc(sizeof(ListNode)); + if(new == NULL) return NULL; new->data = data; new->next = NULL; @@ -26,7 +28,7 @@ ListNode* list_add(ListNode* head, void* data) { return head; } -ListNode* list_find(ListNode* head, void* data) { +ListNode* list_find(ListNode* head, const void* data) { ListNode* it; for(it = head; it != NULL; it = it->next) @@ -66,7 +68,8 @@ ListNode* list_remove(ListNode* head, ListNode* ep) { } void list_free(ListNode* head) { - ListNode *it = head, *tmp; + ListNode* it = head; + ListNode* tmp; while(it != NULL) { tmp = it; diff --git a/applications/plugins/totp/services/list/list.h b/applications/plugins/totp/services/list/list.h index 771eac565..7721b2522 100644 --- a/applications/plugins/totp/services/list/list.h +++ b/applications/plugins/totp/services/list/list.h @@ -14,7 +14,7 @@ ListNode* list_add( 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. */ + const 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. */ @@ -22,3 +22,13 @@ 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. */ + +#define TOTP_LIST_INIT_OR_ADD(head, item, assert) \ + do { \ + if(head == NULL) { \ + head = list_init_head(item); \ + assert(head != NULL); \ + } else { \ + assert(list_add(head, item) != NULL); \ + } \ + } while(false) diff --git a/applications/plugins/totp/services/nullable/nullable.h b/applications/plugins/totp/services/nullable/nullable.h new file mode 100644 index 000000000..4f9b7bc01 --- /dev/null +++ b/applications/plugins/totp/services/nullable/nullable.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +#define TOTP_NULLABLE_STRUCT(value_type) \ + typedef struct TotpNullable_##value_type { \ + bool is_null; \ + value_type value; \ + } TotpNullable_##value_type + +#define TOTP_NULLABLE_NULL(s) s.is_null = true +#define TOTP_NULLABLE_VALUE(s, v) \ + s.is_null = false; \ + s.value = v + +TOTP_NULLABLE_STRUCT(uint16_t); diff --git a/applications/plugins/totp/services/roll_value/roll_value.c b/applications/plugins/totp/services/roll_value/roll_value.c new file mode 100644 index 000000000..b8f30e078 --- /dev/null +++ b/applications/plugins/totp/services/roll_value/roll_value.c @@ -0,0 +1,28 @@ +#include "roll_value.h" + +#define TOTP_ROLL_VALUE_FN(type, step_type) \ + TOTP_ROLL_VALUE_FN_HEADER(type, step_type) { \ + type v = *value; \ + if(step > 0 && v > max - step) { \ + if(overflow_behavior == RollOverflowBehaviorRoll) { \ + v = min; \ + } else if(overflow_behavior == RollOverflowBehaviorStop) { \ + v = max; \ + } \ + } else if(step < 0 && v < min - step) { \ + if(overflow_behavior == RollOverflowBehaviorRoll) { \ + v = max; \ + } else if(overflow_behavior == RollOverflowBehaviorStop) { \ + v = min; \ + } \ + } else { \ + v += step; \ + } \ + *value = v; \ + } + +TOTP_ROLL_VALUE_FN(int8_t, int8_t) + +TOTP_ROLL_VALUE_FN(uint8_t, int8_t) + +TOTP_ROLL_VALUE_FN(uint16_t, int16_t); \ No newline at end of file diff --git a/applications/plugins/totp/services/roll_value/roll_value.h b/applications/plugins/totp/services/roll_value/roll_value.h new file mode 100644 index 000000000..87337597f --- /dev/null +++ b/applications/plugins/totp/services/roll_value/roll_value.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +typedef enum { RollOverflowBehaviorStop, RollOverflowBehaviorRoll } TotpRollValueOverflowBehavior; + +#define TOTP_ROLL_VALUE_FN_HEADER(type, step_type) \ + void totp_roll_value_##type( \ + type* value, \ + step_type step, \ + type min, \ + type max, \ + TotpRollValueOverflowBehavior overflow_behavior) + +TOTP_ROLL_VALUE_FN_HEADER(int8_t, int8_t); +TOTP_ROLL_VALUE_FN_HEADER(uint8_t, int8_t); +TOTP_ROLL_VALUE_FN_HEADER(uint16_t, int16_t); \ No newline at end of file diff --git a/applications/plugins/totp/services/totp/totp.c b/applications/plugins/totp/services/totp/totp.c index 90e49367d..9e0672ea9 100644 --- a/applications/plugins/totp/services/totp/totp.c +++ b/applications/plugins/totp/services/totp/totp.c @@ -42,14 +42,15 @@ uint32_t otp_generate( TOTP_ALGO algo, uint8_t digits, const uint8_t* plain_secret, - uint8_t plain_secret_length, + size_t plain_secret_length, uint64_t input) { uint8_t* hmac = malloc(64); + if(hmac == NULL) return OTP_ERROR; memset(hmac, 0, 64); uint64_t input_swapped = swap_uint64(input); - int hmac_len = (*(algo))(plain_secret, plain_secret_length, (uint8_t*)&input_swapped, 8, hmac); + int hmac_len = (*algo)(plain_secret, plain_secret_length, (uint8_t*)&input_swapped, 8, hmac); if(hmac_len == 0) { free(hmac); return OTP_ERROR; @@ -80,7 +81,7 @@ uint32_t totp_at( TOTP_ALGO algo, uint8_t digits, const uint8_t* plain_secret, - uint8_t plain_secret_length, + size_t plain_secret_length, uint64_t for_time, float timezone, uint8_t interval) { @@ -96,9 +97,9 @@ uint32_t totp_at( static int totp_algo_sha1( const uint8_t* key, - uint8_t key_length, + size_t key_length, const uint8_t* input, - uint8_t input_length, + size_t input_length, uint8_t* output) { hmac_sha1(key, key_length, input, input_length, output); return HMAC_SHA1_RESULT_SIZE; @@ -106,9 +107,9 @@ static int totp_algo_sha1( static int totp_algo_sha256( const uint8_t* key, - uint8_t key_length, + size_t key_length, const uint8_t* input, - uint8_t input_length, + size_t input_length, uint8_t* output) { hmac_sha256(key, key_length, input, input_length, output); return HMAC_SHA256_RESULT_SIZE; @@ -116,9 +117,9 @@ static int totp_algo_sha256( static int totp_algo_sha512( const uint8_t* key, - uint8_t key_length, + size_t key_length, const uint8_t* input, - uint8_t input_length, + size_t input_length, uint8_t* output) { hmac_sha512(key, key_length, input, input_length, output); return HMAC_SHA512_RESULT_SIZE; diff --git a/applications/plugins/totp/services/totp/totp.h b/applications/plugins/totp/services/totp/totp.h index 31e70e01b..431ca11aa 100644 --- a/applications/plugins/totp/services/totp/totp.h +++ b/applications/plugins/totp/services/totp/totp.h @@ -17,9 +17,9 @@ */ typedef int (*TOTP_ALGO)( const uint8_t* key, - uint8_t key_length, + size_t key_length, const uint8_t* input, - uint8_t input_length, + size_t input_length, uint8_t* output); /* @@ -47,7 +47,7 @@ uint32_t totp_at( TOTP_ALGO algo, uint8_t digits, const uint8_t* plain_secret, - uint8_t plain_secret_length, + size_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 deleted file mode 100644 index 2ce25a898..000000000 --- a/applications/plugins/totp/services/ui/icons.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include -#include - -#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}; - -#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}; diff --git a/applications/plugins/totp/services/ui/ui_controls.c b/applications/plugins/totp/services/ui/ui_controls.c index 7f6a4dd4d..af029dd9f 100644 --- a/applications/plugins/totp/services/ui/ui_controls.c +++ b/applications/plugins/totp/services/ui/ui_controls.c @@ -1,11 +1,15 @@ #include "ui_controls.h" +#include #include "constants.h" -#include "icons.h" #define TEXT_BOX_HEIGHT 13 #define TEXT_BOX_MARGIN 4 -void ui_control_text_box_render(Canvas* const canvas, int8_t y, char* text, bool is_selected) { +void ui_control_text_box_render( + Canvas* const canvas, + int16_t y, + const char* text, + bool is_selected) { if(y < -TEXT_BOX_HEIGHT) { return; } @@ -44,7 +48,7 @@ void ui_control_select_render( int16_t x, int16_t y, uint8_t width, - char* text, + const char* text, bool is_selected) { if(y < -TEXT_BOX_HEIGHT) { return; @@ -77,20 +81,10 @@ void ui_control_select_render( canvas_draw_str_aligned( canvas, x + (width >> 1), TEXT_BOX_MARGIN + 3 + y, AlignCenter, AlignTop, text); - canvas_draw_xbm( - canvas, - x + 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, - x + 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_icon( + canvas, x + TEXT_BOX_MARGIN + 2, TEXT_BOX_MARGIN + 2 + y, &I_totp_arrow_left_8x9); + canvas_draw_icon( + canvas, x + width - TEXT_BOX_MARGIN - 10, TEXT_BOX_MARGIN + 2 + y, &I_totp_arrow_right_8x9); } void ui_control_button_render( @@ -99,7 +93,7 @@ void ui_control_button_render( int16_t y, uint8_t width, uint8_t height, - char* text, + const char* text, bool is_selected) { if(y < -height) { return; diff --git a/applications/plugins/totp/services/ui/ui_controls.h b/applications/plugins/totp/services/ui/ui_controls.h index e86b3e5d9..ef3af5f55 100644 --- a/applications/plugins/totp/services/ui/ui_controls.h +++ b/applications/plugins/totp/services/ui/ui_controls.h @@ -3,19 +3,23 @@ #include #include -void ui_control_text_box_render(Canvas* const canvas, int8_t y, char* text, bool is_selected); +void ui_control_text_box_render( + Canvas* const canvas, + int16_t y, + const char* text, + bool is_selected); void ui_control_button_render( Canvas* const canvas, int16_t x, int16_t y, uint8_t width, uint8_t height, - char* text, + const char* text, bool is_selected); void ui_control_select_render( Canvas* const canvas, int16_t x, int16_t y, uint8_t width, - char* text, + const char* text, bool is_selected); diff --git a/applications/plugins/totp/totp_app.c b/applications/plugins/totp/totp_app.c index ede8416b6..aece31197 100644 --- a/applications/plugins/totp/totp_app.c +++ b/applications/plugins/totp/totp_app.c @@ -125,6 +125,7 @@ static void totp_plugin_state_free(PluginState* plugin_state) { int32_t totp_app() { FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); PluginState* plugin_state = malloc(sizeof(PluginState)); + furi_check(plugin_state != NULL); if(!totp_plugin_state_init(plugin_state)) { FURI_LOG_E(LOGGING_TAG, "App state initialization failed\r\n"); @@ -154,22 +155,22 @@ int32_t totp_app() { if(plugin_state->changing_scene) continue; FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - PluginState* plugin_state = acquire_mutex_block(&state_mutex); + PluginState* plugin_state_m = acquire_mutex_block(&state_mutex); if(event_status == FuriStatusOk) { if(event.type == EventTypeKey) { last_user_interaction_time = furi_get_tick(); } - processing = totp_scene_director_handle_event(&event, plugin_state); + processing = totp_scene_director_handle_event(&event, plugin_state_m); } else if( - plugin_state->pin_set && plugin_state->current_scene != TotpSceneAuthentication && + plugin_state_m->pin_set && plugin_state_m->current_scene != TotpSceneAuthentication && furi_get_tick() - last_user_interaction_time > IDLE_TIMEOUT) { - totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication, NULL); + totp_scene_director_activate_scene(plugin_state_m, TotpSceneAuthentication, NULL); } view_port_update(view_port); - release_mutex(&state_mutex, plugin_state); + release_mutex(&state_mutex, plugin_state_m); } view_port_enabled_set(view_port, false); diff --git a/applications/plugins/totp/types/plugin_state.h b/applications/plugins/totp/types/plugin_state.h index 98afe53cf..9b16d7d57 100644 --- a/applications/plugins/totp/types/plugin_state.h +++ b/applications/plugins/totp/types/plugin_state.h @@ -19,10 +19,10 @@ typedef struct { float timezone_offset; ListNode* tokens_list; bool token_list_loaded; - uint8_t tokens_count; + uint16_t tokens_count; uint8_t* crypto_verify_data; - uint8_t crypto_verify_data_length; + size_t crypto_verify_data_length; bool pin_set; uint8_t iv[TOTP_IV_SIZE]; uint8_t base_iv[TOTP_IV_SIZE]; diff --git a/applications/plugins/totp/types/token_info.c b/applications/plugins/totp/types/token_info.c index 09ad1230a..66e32f5a4 100644 --- a/applications/plugins/totp/types/token_info.c +++ b/applications/plugins/totp/types/token_info.c @@ -5,9 +5,11 @@ #include "common.h" #include "../services/base32/base32.h" #include "../services/crypto/crypto.h" +#include "../services/crypto/memset_s.h" TokenInfo* token_info_alloc() { TokenInfo* tokenInfo = malloc(sizeof(TokenInfo)); + furi_check(tokenInfo != NULL); tokenInfo->algo = SHA1; tokenInfo->digits = TOTP_6_DIGITS; return tokenInfo; @@ -23,11 +25,12 @@ void token_info_free(TokenInfo* token_info) { bool token_info_set_secret( TokenInfo* token_info, const char* base32_token_secret, - uint8_t token_secret_length, - uint8_t* iv) { + size_t token_secret_length, + const uint8_t* iv) { uint8_t* plain_secret = malloc(token_secret_length); + furi_check(plain_secret != NULL); int plain_secret_length = - base32_decode((uint8_t*)base32_token_secret, plain_secret, token_secret_length); + base32_decode((const uint8_t*)base32_token_secret, plain_secret, token_secret_length); bool result; if(plain_secret_length >= 0) { token_info->token = @@ -37,17 +40,19 @@ bool token_info_set_secret( result = false; } - memset(plain_secret, 0, token_secret_length); + memset_s(plain_secret, token_secret_length, 0, token_secret_length); free(plain_secret); return result; } -uint8_t token_info_get_digits_count(TokenInfo* token_info) { +uint8_t token_info_get_digits_count(const TokenInfo* token_info) { switch(token_info->digits) { case TOTP_6_DIGITS: return 6; case TOTP_8_DIGITS: return 8; + default: + break; } return 6; diff --git a/applications/plugins/totp/types/token_info.h b/applications/plugins/totp/types/token_info.h index e40c6e9bf..4f1223367 100644 --- a/applications/plugins/totp/types/token_info.h +++ b/applications/plugins/totp/types/token_info.h @@ -8,7 +8,7 @@ typedef enum { TOTP_6_DIGITS, TOTP_8_DIGITS } TokenDigitsCount; typedef struct { uint8_t* token; - uint8_t token_length; + size_t token_length; char* name; TokenHashAlgo algo; TokenDigitsCount digits; @@ -19,6 +19,6 @@ void token_info_free(TokenInfo* token_info); bool 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); + size_t token_secret_length, + const uint8_t* iv); +uint8_t token_info_get_digits_count(const TokenInfo* token_info);