소스 검색

Implemented #188 (#189)

Alexander Kopachov 2 년 전
부모
커밋
cd5cd642c0
50개의 변경된 파일242개의 추가작업 그리고 68개의 파일을 삭제
  1. 3 1
      application.fam
  2. 2 0
      cli/commands/add/add.c
  3. 4 1
      cli/commands/add/add.h
  4. 2 0
      cli/commands/automation/automation.c
  5. 4 1
      cli/commands/automation/automation.h
  6. 2 0
      cli/commands/delete/delete.c
  7. 4 1
      cli/commands/delete/delete.h
  8. 2 0
      cli/commands/details/details.c
  9. 3 0
      cli/commands/details/details.h
  10. 7 0
      cli/commands/help/help.c
  11. 4 1
      cli/commands/help/help.h
  12. 2 0
      cli/commands/list/list.c
  13. 3 0
      cli/commands/list/list.h
  14. 2 0
      cli/commands/move/move.c
  15. 4 1
      cli/commands/move/move.h
  16. 2 0
      cli/commands/notification/notification.c
  17. 4 1
      cli/commands/notification/notification.h
  18. 2 0
      cli/commands/pin/pin.c
  19. 4 1
      cli/commands/pin/pin.h
  20. 2 0
      cli/commands/reset/reset.c
  21. 4 1
      cli/commands/reset/reset.h
  22. 2 0
      cli/commands/timezone/timezone.c
  23. 4 1
      cli/commands/timezone/timezone.h
  24. 2 0
      cli/commands/update/update.c
  25. 4 1
      cli/commands/update/update.h
  26. 23 1
      config/app/config.h
  27. 0 0
      config/wolfssl/config.h
  28. 2 2
      services/config/config.c
  29. 4 2
      services/crypto/constants.h
  30. 24 3
      services/crypto/crypto_facade.c
  31. 10 7
      services/crypto/crypto_v1.c
  32. 4 1
      services/crypto/crypto_v1.h
  33. 15 12
      services/crypto/crypto_v2.c
  34. 4 1
      services/crypto/crypto_v2.h
  35. 14 13
      services/crypto/crypto_v3.c
  36. 14 0
      services/crypto/polyfills.h
  37. 1 1
      services/totp/totp.c
  38. 1 1
      totp_app.c
  39. 1 1
      types/automation_method.h
  40. 1 1
      types/plugin_state.h
  41. 11 0
      ui/scene_director.c
  42. 2 0
      ui/scenes/add_new_token/totp_input_text.c
  43. 3 0
      ui/scenes/add_new_token/totp_input_text.h
  44. 2 1
      ui/scenes/add_new_token/totp_scene_add_new_token.c
  45. 3 0
      ui/scenes/add_new_token/totp_scene_add_new_token.h
  46. 1 2
      ui/scenes/app_settings/totp_app_settings.c
  47. 3 4
      ui/scenes/generate_token/totp_scene_generate_token.c
  48. 16 3
      ui/scenes/token_menu/totp_scene_token_menu.c
  49. 4 0
      ui/totp_scenes_enum.h
  50. 1 1
      workers/bt_type_code/bt_type_code.c

+ 3 - 1
application.fam

@@ -51,7 +51,9 @@ App(
                 "wolfcrypt/src/sha256.c",
                 "wolfcrypt/src/sha512.c"
             ],
-            cflags=["-Wno-error", "-include${FAP_SRC_DIR}/wolfssl_config.h"]
+            cflags=["-Wno-error"],
+            cdefines=["HAVE_CONFIG_H"],
+            cincludes=["config/wolfssl"]
         ),
     ],
 )

+ 2 - 0
cli/commands/add/add.c

@@ -79,6 +79,7 @@ static TotpIteratorUpdateTokenResult
     return TotpIteratorUpdateTokenResultSuccess;
 }
 
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_add_docopt_commands() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_ADD ", " TOTP_CLI_COMMAND_ADD_ALT
                     ", " TOTP_CLI_COMMAND_ADD_ALT2 "     Add new token\r\n");
@@ -155,6 +156,7 @@ void totp_cli_command_add_docopt_options() {
     TOTP_CLI_PRINTF("                 # " TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME
                     " - Type slower\r\n");
 }
+#endif
 
 void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
     if(!totp_cli_ensure_authenticated(plugin_state, cli)) {

+ 4 - 1
cli/commands/add/add.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include <cli/cli.h>
+#include "../../../config/app/config.h"
 #include "../../../types/plugin_state.h"
 
 #define TOTP_CLI_COMMAND_ADD "add"
@@ -8,7 +9,9 @@
 #define TOTP_CLI_COMMAND_ADD_ALT2 "new"
 
 void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_add_docopt_commands();
 void totp_cli_command_add_docopt_usage();
 void totp_cli_command_add_docopt_arguments();
-void totp_cli_command_add_docopt_options();
+void totp_cli_command_add_docopt_options();
+#endif

+ 2 - 0
cli/commands/automation/automation.c

@@ -15,6 +15,7 @@
 #define TOTP_CLI_COMMAND_AUTOMATION_ARG_KB_LAYOUT_PREFIX "-k"
 #define TOTP_CLI_COMMAND_AUTOMATION_ARG_KB_LAYOUT "layout"
 
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_automation_docopt_commands() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_AUTOMATION "       Get or set automation settings\r\n");
 }
@@ -45,6 +46,7 @@ void totp_cli_command_automation_docopt_options() {
                                                         ", " TOTP_CLI_COMMAND_AUTOMATION_LAYOUT_AZERTY
                                                         "\r\n");
 }
+#endif
 
 static void print_method(AutomationMethod method, const char* color) {
 #ifdef TOTP_BADBT_AUTOMATION_ENABLED

+ 4 - 1
cli/commands/automation/automation.h

@@ -2,11 +2,14 @@
 
 #include <cli/cli.h>
 #include "../../../types/plugin_state.h"
+#include "../../../config/app/config.h"
 
 #define TOTP_CLI_COMMAND_AUTOMATION "automation"
 
 void totp_cli_command_automation_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_automation_docopt_commands();
 void totp_cli_command_automation_docopt_usage();
 void totp_cli_command_automation_docopt_arguments();
-void totp_cli_command_automation_docopt_options();
+void totp_cli_command_automation_docopt_options();
+#endif

+ 2 - 0
cli/commands/delete/delete.c

@@ -10,6 +10,7 @@
 
 #define TOTP_CLI_COMMAND_DELETE_ARG_FORCE_PREFIX "-f"
 
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_delete_docopt_commands() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_DELETE ", " TOTP_CLI_COMMAND_DELETE_ALT
                     "       Delete existing token\r\n");
@@ -30,6 +31,7 @@ void totp_cli_command_delete_docopt_options() {
     TOTP_CLI_PRINTF("  " DOCOPT_SWITCH(
         TOTP_CLI_COMMAND_DELETE_ARG_FORCE_PREFIX) "             Force command to do not ask user for interactive confirmation\r\n");
 }
+#endif
 
 void totp_cli_command_delete_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
     if(!totp_cli_ensure_authenticated(plugin_state, cli)) {

+ 4 - 1
cli/commands/delete/delete.h

@@ -2,12 +2,15 @@
 
 #include <cli/cli.h>
 #include "../../../types/plugin_state.h"
+#include "../../../config/app/config.h"
 
 #define TOTP_CLI_COMMAND_DELETE "delete"
 #define TOTP_CLI_COMMAND_DELETE_ALT "rm"
 
 void totp_cli_command_delete_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_delete_docopt_commands();
 void totp_cli_command_delete_docopt_usage();
 void totp_cli_command_delete_docopt_arguments();
-void totp_cli_command_delete_docopt_options();
+void totp_cli_command_delete_docopt_options();
+#endif

+ 2 - 0
cli/commands/details/details.c

@@ -37,6 +37,7 @@ static void print_automation_features(const TokenInfo* token_info) {
     }
 }
 
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_details_docopt_commands() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_DETAILS ", " TOTP_CLI_COMMAND_DETAILS_ALT
                     "      Displays token details\r\n");
@@ -47,6 +48,7 @@ void totp_cli_command_details_docopt_usage() {
         TOTP_CLI_COMMAND_DETAILS
         " | " TOTP_CLI_COMMAND_DETAILS_ALT) " " DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_INDEX) "\r\n");
 }
+#endif
 
 void totp_cli_command_details_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
     if(!totp_cli_ensure_authenticated(plugin_state, cli)) {

+ 3 - 0
cli/commands/details/details.h

@@ -2,10 +2,13 @@
 
 #include <cli/cli.h>
 #include "../../../types/plugin_state.h"
+#include "../../../config/app/config.h"
 
 #define TOTP_CLI_COMMAND_DETAILS "lsattr"
 #define TOTP_CLI_COMMAND_DETAILS_ALT "cat"
 
 void totp_cli_command_details_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_details_docopt_commands();
 void totp_cli_command_details_docopt_usage();
+#endif

+ 7 - 0
cli/commands/help/help.c

@@ -12,6 +12,7 @@
 #include "../automation/automation.h"
 #include "../details/details.h"
 
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_help_docopt_commands() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_HELP ", " TOTP_CLI_COMMAND_HELP_ALT
                     ", " TOTP_CLI_COMMAND_HELP_ALT2 "       Show command usage help\r\n");
@@ -22,8 +23,10 @@ void totp_cli_command_help_docopt_usage() {
         TOTP_CLI_COMMAND_HELP " | " TOTP_CLI_COMMAND_HELP_ALT
                               " | " TOTP_CLI_COMMAND_HELP_ALT2) "\r\n");
 }
+#endif
 
 void totp_cli_command_help_handle() {
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
     TOTP_CLI_PRINTF("Usage:\r\n");
     totp_cli_command_help_docopt_usage();
     totp_cli_command_list_docopt_usage();
@@ -66,4 +69,8 @@ void totp_cli_command_help_handle() {
     totp_cli_command_delete_docopt_options();
     totp_cli_command_pin_docopt_options();
     totp_cli_command_automation_docopt_options();
+#else
+    TOTP_CLI_PRINTF(
+        "All the TOTP CLI commands, their arguments, options and usage can be found here https://t.ly/_6pJG");
+#endif
 }

+ 4 - 1
cli/commands/help/help.h

@@ -1,5 +1,6 @@
 #pragma once
 
+#include "../../../config/app/config.h"
 #include <cli/cli.h>
 
 #define TOTP_CLI_COMMAND_HELP "help"
@@ -7,5 +8,7 @@
 #define TOTP_CLI_COMMAND_HELP_ALT2 "?"
 
 void totp_cli_command_help_handle();
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_help_docopt_commands();
-void totp_cli_command_help_docopt_usage();
+void totp_cli_command_help_docopt_usage();
+#endif

+ 2 - 0
cli/commands/list/list.c

@@ -6,6 +6,7 @@
 #include "../../../ui/scene_director.h"
 #include "../../cli_helpers.h"
 
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_list_docopt_commands() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_LIST ", " TOTP_CLI_COMMAND_LIST_ALT
                     "         List all available tokens\r\n");
@@ -15,6 +16,7 @@ void totp_cli_command_list_docopt_usage() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_NAME " " DOCOPT_REQUIRED(
         TOTP_CLI_COMMAND_LIST " | " TOTP_CLI_COMMAND_LIST_ALT) "\r\n");
 }
+#endif
 
 void totp_cli_command_list_handle(PluginState* plugin_state, Cli* cli) {
     if(!totp_cli_ensure_authenticated(plugin_state, cli)) {

+ 3 - 0
cli/commands/list/list.h

@@ -2,10 +2,13 @@
 
 #include <cli/cli.h>
 #include "../../../types/plugin_state.h"
+#include "../../../config/app/config.h"
 
 #define TOTP_CLI_COMMAND_LIST "list"
 #define TOTP_CLI_COMMAND_LIST_ALT "ls"
 
 void totp_cli_command_list_handle(PluginState* plugin_state, Cli* cli);
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_list_docopt_commands();
 void totp_cli_command_list_docopt_usage();
+#endif

+ 2 - 0
cli/commands/move/move.c

@@ -10,6 +10,7 @@
 
 #define TOTP_CLI_COMMAND_MOVE_ARG_NEW_INDEX "new_index"
 
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_move_docopt_commands() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_MOVE ", " TOTP_CLI_COMMAND_MOVE_ALT
                     "         Move token\r\n");
@@ -26,6 +27,7 @@ void totp_cli_command_move_docopt_arguments() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_MOVE_ARG_NEW_INDEX
                     "     New token index in the list\r\n");
 }
+#endif
 
 void totp_cli_command_move_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
     if(!totp_cli_ensure_authenticated(plugin_state, cli)) {

+ 4 - 1
cli/commands/move/move.h

@@ -2,11 +2,14 @@
 
 #include <cli/cli.h>
 #include "../../../types/plugin_state.h"
+#include "../../../config/app/config.h"
 
 #define TOTP_CLI_COMMAND_MOVE "move"
 #define TOTP_CLI_COMMAND_MOVE_ALT "mv"
 
 void totp_cli_command_move_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_move_docopt_commands();
 void totp_cli_command_move_docopt_usage();
-void totp_cli_command_move_docopt_arguments();
+void totp_cli_command_move_docopt_arguments();
+#endif

+ 2 - 0
cli/commands/notification/notification.c

@@ -9,6 +9,7 @@
 #define TOTP_CLI_COMMAND_NOTIFICATION_METHOD_SOUND "sound"
 #define TOTP_CLI_COMMAND_NOTIFICATION_METHOD_VIBRO "vibro"
 
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_notification_docopt_commands() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_NOTIFICATION
                     "           Get or set notification method\r\n");
@@ -27,6 +28,7 @@ void totp_cli_command_notification_docopt_arguments() {
         ", " TOTP_CLI_COMMAND_NOTIFICATION_METHOD_SOUND
         ", " TOTP_CLI_COMMAND_NOTIFICATION_METHOD_VIBRO "\r\n");
 }
+#endif
 
 static void
     totp_cli_command_notification_print_method(NotificationMethod method, const char* color) {

+ 4 - 1
cli/commands/notification/notification.h

@@ -2,10 +2,13 @@
 
 #include <cli/cli.h>
 #include "../../../types/plugin_state.h"
+#include "../../../config/app/config.h"
 
 #define TOTP_CLI_COMMAND_NOTIFICATION "notify"
 
 void totp_cli_command_notification_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_notification_docopt_commands();
 void totp_cli_command_notification_docopt_usage();
-void totp_cli_command_notification_docopt_arguments();
+void totp_cli_command_notification_docopt_arguments();
+#endif

+ 2 - 0
cli/commands/pin/pin.c

@@ -15,6 +15,7 @@
 #define TOTP_CLI_COMMAND_PIN_ARG_NEW_CRYPTO_KEY_SLOT_PREFIX "-c"
 #define TOTP_CLI_COMMAND_PIN_ARG_NEW_CRYPTO_KEY_SLOT "slot"
 
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_pin_docopt_commands() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_PIN "              Set\\change\\remove PIN\r\n");
 }
@@ -37,6 +38,7 @@ void totp_cli_command_pin_docopt_options() {
         ACCEPTABLE_CRYPTO_KEY_SLOT_START,
         ACCEPTABLE_CRYPTO_KEY_SLOT_END);
 }
+#endif
 
 static inline uint8_t totp_cli_key_to_pin_code(uint8_t key) {
     uint8_t code = 0;

+ 4 - 1
cli/commands/pin/pin.h

@@ -2,10 +2,13 @@
 
 #include <cli/cli.h>
 #include "../../../types/plugin_state.h"
+#include "../../../config/app/config.h"
 
 #define TOTP_CLI_COMMAND_PIN "pin"
 
 void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_pin_docopt_commands();
 void totp_cli_command_pin_docopt_usage();
-void totp_cli_command_pin_docopt_options();
+void totp_cli_command_pin_docopt_options();
+#endif

+ 2 - 0
cli/commands/reset/reset.c

@@ -8,6 +8,7 @@
 
 #define TOTP_CLI_RESET_CONFIRMATION_KEYWORD "YES"
 
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_reset_docopt_commands() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_RESET
                     "            Reset application to default settings\r\n");
@@ -16,6 +17,7 @@ void totp_cli_command_reset_docopt_commands() {
 void totp_cli_command_reset_docopt_usage() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_NAME " " TOTP_CLI_COMMAND_RESET "\r\n");
 }
+#endif
 
 void totp_cli_command_reset_handle(PluginState* plugin_state, Cli* cli) {
     TOTP_CLI_LOCK_UI(plugin_state);

+ 4 - 1
cli/commands/reset/reset.h

@@ -2,9 +2,12 @@
 
 #include <cli/cli.h>
 #include "../../../types/plugin_state.h"
+#include "../../../config/app/config.h"
 
 #define TOTP_CLI_COMMAND_RESET "reset"
 
 void totp_cli_command_reset_handle(PluginState* plugin_state, Cli* cli);
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_reset_docopt_commands();
-void totp_cli_command_reset_docopt_usage();
+void totp_cli_command_reset_docopt_usage();
+#endif

+ 2 - 0
cli/commands/timezone/timezone.c

@@ -6,6 +6,7 @@
 
 #define TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE "timezone"
 
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_timezone_docopt_commands() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_TIMEZONE ", " TOTP_CLI_COMMAND_TIMEZONE_ALT
                     "     Get or set current timezone\r\n");
@@ -22,6 +23,7 @@ void totp_cli_command_timezone_docopt_arguments() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE
                     "      Timezone offset in hours to be set\r\n");
 }
+#endif
 
 void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
     if(!totp_cli_ensure_authenticated(plugin_state, cli)) {

+ 4 - 1
cli/commands/timezone/timezone.h

@@ -2,11 +2,14 @@
 
 #include <cli/cli.h>
 #include "../../../types/plugin_state.h"
+#include "../../../config/app/config.h"
 
 #define TOTP_CLI_COMMAND_TIMEZONE "timezone"
 #define TOTP_CLI_COMMAND_TIMEZONE_ALT "tz"
 
 void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_timezone_docopt_commands();
 void totp_cli_command_timezone_docopt_usage();
-void totp_cli_command_timezone_docopt_arguments();
+void totp_cli_command_timezone_docopt_arguments();
+#endif

+ 2 - 0
cli/commands/update/update.c

@@ -107,6 +107,7 @@ static TotpIteratorUpdateTokenResult
     return TotpIteratorUpdateTokenResultSuccess;
 }
 
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_update_docopt_commands() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_UPDATE "           Update existing token\r\n");
 }
@@ -129,6 +130,7 @@ void totp_cli_command_update_docopt_options() {
     TOTP_CLI_PRINTF("  " DOCOPT_SWITCH(
         TOTP_CLI_COMMAND_UPDATE_ARG_SECRET_PREFIX) "             Update token secret\r\n");
 }
+#endif
 
 void totp_cli_command_update_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
     if(!totp_cli_ensure_authenticated(plugin_state, cli)) {

+ 4 - 1
cli/commands/update/update.h

@@ -2,10 +2,13 @@
 
 #include <cli/cli.h>
 #include "../../../types/plugin_state.h"
+#include "../../../config/app/config.h"
 
 #define TOTP_CLI_COMMAND_UPDATE "update"
 
 void totp_cli_command_update_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
+#ifdef TOTP_CLI_RICH_HELP_ENABLED
 void totp_cli_command_update_docopt_commands();
 void totp_cli_command_update_docopt_usage();
-void totp_cli_command_update_docopt_options();
+void totp_cli_command_update_docopt_options();
+#endif

+ 23 - 1
features_config.h → config/app/config.h

@@ -3,11 +3,33 @@
 #define TOTP_AUTO_LOCK_IDLE_TIMEOUT_SEC (60)
 #endif
 
-// Include Bluetooth token input automation
+// Enables\disables Bluetooth token input automation
 #ifndef TOTP_NO_BADBT_AUTOMATION
 #define TOTP_BADBT_AUTOMATION_ENABLED
 #endif
 
+// Enables\disables backward compatibility with crypto algorithms v1
+#ifndef TOTP_NO_OBSOLETE_CRYPTO_V1_COMPATIBILITY
+#define TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
+#endif
+
+// Enables\disables backward compatibility with crypto algorithms v2
+#ifndef TOTP_NO_OBSOLETE_CRYPTO_V2_COMPATIBILITY
+#define TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
+#endif
+
+// Enables\disables userfriendly TOTP CLI help text
+// If disabled, it will print a link to a wiki page
+#ifndef TOTP_CLI_NO_RICH_HELP
+#define TOTP_CLI_RICH_HELP_ENABLED
+#endif
+
+// Enables\disables "Add new token" UI
+// If disabled it will print a link to wiki page
+#ifndef TOTP_UI_NO_ADD_NEW_TOKEN
+#define TOTP_UI_ADD_NEW_TOKEN_ENABLED
+#endif
+
 // List of compatible firmwares
 #define TOTP_FIRMWARE_OFFICIAL_STABLE (1)
 #define TOTP_FIRMWARE_OFFICIAL_DEV (2)

+ 0 - 0
wolfssl_config.h → config/wolfssl/config.h


+ 2 - 2
services/config/config.c

@@ -8,7 +8,7 @@
 #include <memset_s.h>
 #include "../../types/common.h"
 #include "../../types/token_info.h"
-#include "../../features_config.h"
+#include "../../config/app/config.h"
 #include "../crypto/crypto_facade.h"
 #include "../crypto/constants.h"
 #include "migrations/common_migration.h"
@@ -149,7 +149,7 @@ static bool totp_open_config_file(Storage* storage, FlipperFormat** file) {
 
         flipper_format_write_comment_cstr(
             fff_data_file,
-            "Config file format specification can be found here: https://github.com/akopachov/flipper-zero_authenticator/blob/master/docs/conf-file_description.md");
+            "Config file format specification can be found here: https://t.ly/zwQjE");
 
         float tmp_tz = 0;
         flipper_format_write_float(fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &tmp_tz, 1);

+ 4 - 2
services/crypto/constants.h

@@ -1,12 +1,14 @@
 #pragma once
 
+#include "polyfills.h"
+
 #define CRYPTO_IV_LENGTH (16)
 #define CRYPTO_SALT_LENGTH (16)
 
 // According to this explanation: https://github.com/flipperdevices/flipperzero-firmware/issues/2885#issuecomment-1646664666
 // disabling usage of any key which is "the same across all devices"
-#define ACCEPTABLE_CRYPTO_KEY_SLOT_START (12)
-#define ACCEPTABLE_CRYPTO_KEY_SLOT_END (100)
+#define ACCEPTABLE_CRYPTO_KEY_SLOT_START FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_START
+#define ACCEPTABLE_CRYPTO_KEY_SLOT_END FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_END
 
 #define DEFAULT_CRYPTO_KEY_SLOT ACCEPTABLE_CRYPTO_KEY_SLOT_START
 #define CRYPTO_LATEST_VERSION (3)

+ 24 - 3
services/crypto/crypto_facade.c

@@ -1,8 +1,13 @@
 #include "crypto_facade.h"
+#include "../../config/app/config.h"
 #include <furi_hal_crypto.h>
 #include <furi/core/check.h>
+#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
 #include "crypto_v1.h"
+#endif
+#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
 #include "crypto_v2.h"
+#endif
 #include "crypto_v3.h"
 #include "constants.h"
 
@@ -12,9 +17,9 @@ bool totp_crypto_check_key_slot(uint8_t key_slot) {
         return false;
     }
 
-    return furi_hal_crypto_verify_key(key_slot) &&
-           furi_hal_crypto_store_load_key(key_slot, empty_iv) &&
-           furi_hal_crypto_store_unload_key(key_slot);
+    return furi_hal_crypto_enclave_ensure_key(key_slot) &&
+           furi_hal_crypto_enclave_load_key(key_slot, empty_iv) &&
+           furi_hal_crypto_enclave_unload_key(key_slot);
 }
 
 uint8_t* totp_crypto_encrypt(
@@ -22,15 +27,19 @@ uint8_t* totp_crypto_encrypt(
     const size_t plain_data_length,
     const CryptoSettings* crypto_settings,
     size_t* encrypted_data_length) {
+#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
     if(crypto_settings->crypto_version == 1) {
         return totp_crypto_encrypt_v1(
             plain_data, plain_data_length, crypto_settings, encrypted_data_length);
     }
+#endif
 
+#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
     if(crypto_settings->crypto_version == 2) {
         return totp_crypto_encrypt_v2(
             plain_data, plain_data_length, crypto_settings, encrypted_data_length);
     }
+#endif
 
     if(crypto_settings->crypto_version == 3) {
         return totp_crypto_encrypt_v3(
@@ -45,15 +54,19 @@ uint8_t* totp_crypto_decrypt(
     const size_t encrypted_data_length,
     const CryptoSettings* crypto_settings,
     size_t* decrypted_data_length) {
+#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
     if(crypto_settings->crypto_version == 1) {
         return totp_crypto_decrypt_v1(
             encrypted_data, encrypted_data_length, crypto_settings, decrypted_data_length);
     }
+#endif
 
+#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
     if(crypto_settings->crypto_version == 2) {
         return totp_crypto_decrypt_v2(
             encrypted_data, encrypted_data_length, crypto_settings, decrypted_data_length);
     }
+#endif
 
     if(crypto_settings->crypto_version == 3) {
         return totp_crypto_decrypt_v3(
@@ -65,13 +78,17 @@ uint8_t* totp_crypto_decrypt(
 
 CryptoSeedIVResult
     totp_crypto_seed_iv(CryptoSettings* crypto_settings, const uint8_t* pin, uint8_t pin_length) {
+#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
     if(crypto_settings->crypto_version == 1) {
         return totp_crypto_seed_iv_v1(crypto_settings, pin, pin_length);
     }
+#endif
 
+#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
     if(crypto_settings->crypto_version == 2) {
         return totp_crypto_seed_iv_v2(crypto_settings, pin, pin_length);
     }
+#endif
 
     if(crypto_settings->crypto_version == 3) {
         return totp_crypto_seed_iv_v3(crypto_settings, pin, pin_length);
@@ -81,13 +98,17 @@ CryptoSeedIVResult
 }
 
 bool totp_crypto_verify_key(const CryptoSettings* crypto_settings) {
+#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
     if(crypto_settings->crypto_version == 1) {
         return totp_crypto_verify_key_v1(crypto_settings);
     }
+#endif
 
+#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
     if(crypto_settings->crypto_version == 2) {
         return totp_crypto_verify_key_v2(crypto_settings);
     }
+#endif
 
     if(crypto_settings->crypto_version == 3) {
         return totp_crypto_verify_key_v3(crypto_settings);

+ 10 - 7
services/crypto/crypto_v1.c

@@ -1,4 +1,5 @@
 #include "crypto_v1.h"
+#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
 #include <stdlib.h>
 #include <furi.h>
 #include <furi_hal_crypto.h>
@@ -6,6 +7,7 @@
 #include <furi_hal_version.h>
 #include "../../types/common.h"
 #include "memset_s.h"
+#include "polyfills.h"
 
 #define CRYPTO_KEY_SLOT (2)
 #define CRYPTO_VERIFY_KEY_LENGTH (16)
@@ -32,9 +34,9 @@ uint8_t* totp_crypto_encrypt_v1(
         furi_check(encrypted_data != NULL);
         *encrypted_data_length = plain_data_aligned_length;
 
-        furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, crypto_settings->iv);
+        furi_hal_crypto_enclave_load_key(CRYPTO_KEY_SLOT, crypto_settings->iv);
         furi_hal_crypto_encrypt(plain_data_aligned, encrypted_data, plain_data_aligned_length);
-        furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
+        furi_hal_crypto_enclave_unload_key(CRYPTO_KEY_SLOT);
 
         memset_s(plain_data_aligned, plain_data_aligned_length, 0, plain_data_aligned_length);
         free(plain_data_aligned);
@@ -43,9 +45,9 @@ uint8_t* totp_crypto_encrypt_v1(
         furi_check(encrypted_data != NULL);
         *encrypted_data_length = plain_data_length;
 
-        furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, crypto_settings->iv);
+        furi_hal_crypto_enclave_load_key(CRYPTO_KEY_SLOT, crypto_settings->iv);
         furi_hal_crypto_encrypt(plain_data, encrypted_data, plain_data_length);
-        furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
+        furi_hal_crypto_enclave_unload_key(CRYPTO_KEY_SLOT);
     }
 
     return encrypted_data;
@@ -59,9 +61,9 @@ uint8_t* totp_crypto_decrypt_v1(
     *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, crypto_settings->iv);
+    furi_hal_crypto_enclave_load_key(CRYPTO_KEY_SLOT, crypto_settings->iv);
     furi_hal_crypto_decrypt(encrypted_data, decrypted_data, encrypted_data_length);
-    furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
+    furi_hal_crypto_enclave_unload_key(CRYPTO_KEY_SLOT);
     return decrypted_data;
 }
 
@@ -139,4 +141,5 @@ bool totp_crypto_verify_key_v1(const CryptoSettings* crypto_settings) {
     free(decrypted_key);
 
     return key_valid;
-}
+}
+#endif

+ 4 - 1
services/crypto/crypto_v1.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include "../../config/app/config.h"
+#ifdef TOTP_OBSOLETE_CRYPTO_V1_COMPATIBILITY_ENABLED
 #include <stdint.h>
 #include <stdbool.h>
 #include <stddef.h>
@@ -49,4 +51,5 @@ CryptoSeedIVResult
  * @param crypto_settings crypto settings
  * @return \c true if cryptographic information is valid; \c false otherwise
  */
-bool totp_crypto_verify_key_v1(const CryptoSettings* crypto_settings);
+bool totp_crypto_verify_key_v1(const CryptoSettings* crypto_settings);
+#endif

+ 15 - 12
services/crypto/crypto_v2.c

@@ -1,14 +1,16 @@
 #include "crypto_v2.h"
+#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
 #include <stdlib.h>
 #include <furi.h>
 #include <furi_hal_crypto.h>
 #include <furi_hal_random.h>
 #include <furi_hal_version.h>
 #include "../../types/common.h"
-#include "../../wolfssl_config.h"
+#include "../../config/wolfssl/config.h"
 #include <wolfssl/wolfcrypt/hmac.h>
 #include "memset_s.h"
 #include "constants.h"
+#include "polyfills.h"
 
 #define CRYPTO_ALIGNMENT_FACTOR (16)
 
@@ -47,14 +49,14 @@ uint8_t* totp_crypto_encrypt_v2(
         *encrypted_data_length = plain_data_aligned_length;
 
         furi_check(
-            furi_hal_crypto_store_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
-            "Encryption failed: store_load_key");
+            furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
+            "Encryption failed: enclave_load_key");
         furi_check(
             furi_hal_crypto_encrypt(plain_data_aligned, encrypted_data, plain_data_aligned_length),
             "Encryption failed: encrypt");
         furi_check(
-            furi_hal_crypto_store_unload_key(crypto_settings->crypto_key_slot),
-            "Encryption failed: store_unload_key");
+            furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
+            "Encryption failed: enclave_unload_key");
 
         memset_s(plain_data_aligned, plain_data_aligned_length, 0, plain_data_aligned_length);
         free(plain_data_aligned);
@@ -64,13 +66,13 @@ uint8_t* totp_crypto_encrypt_v2(
         *encrypted_data_length = plain_data_length;
 
         furi_check(
-            furi_hal_crypto_store_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
+            furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
             "Encryption failed: store_load_key");
         furi_check(
             furi_hal_crypto_encrypt(plain_data, encrypted_data, plain_data_length),
             "Encryption failed: encrypt");
         furi_check(
-            furi_hal_crypto_store_unload_key(crypto_settings->crypto_key_slot),
+            furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
             "Encryption failed: store_unload_key");
     }
 
@@ -86,14 +88,14 @@ uint8_t* totp_crypto_decrypt_v2(
     uint8_t* decrypted_data = malloc(*decrypted_data_length);
     furi_check(decrypted_data != NULL);
     furi_check(
-        furi_hal_crypto_store_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
-        "Decryption failed: store_load_key");
+        furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
+        "Decryption failed: enclave_load_key");
     furi_check(
         furi_hal_crypto_decrypt(encrypted_data, decrypted_data, encrypted_data_length),
         "Decryption failed: decrypt");
     furi_check(
-        furi_hal_crypto_store_unload_key(crypto_settings->crypto_key_slot),
-        "Decryption failed: store_unload_key");
+        furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
+        "Decryption failed: enclave_unload_key");
     return decrypted_data;
 }
 
@@ -184,4 +186,5 @@ bool totp_crypto_verify_key_v2(const CryptoSettings* crypto_settings) {
     free(decrypted_key);
 
     return key_valid;
-}
+}
+#endif

+ 4 - 1
services/crypto/crypto_v2.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include "../../config/app/config.h"
+#ifdef TOTP_OBSOLETE_CRYPTO_V2_COMPATIBILITY_ENABLED
 #include <stdint.h>
 #include <stdbool.h>
 #include <stddef.h>
@@ -49,4 +51,5 @@ CryptoSeedIVResult
  * @param crypto_settings crypto settings
  * @return \c true if cryptographic information is valid; \c false otherwise
  */
-bool totp_crypto_verify_key_v2(const CryptoSettings* crypto_settings);
+bool totp_crypto_verify_key_v2(const CryptoSettings* crypto_settings);
+#endif

+ 14 - 13
services/crypto/crypto_v3.c

@@ -5,11 +5,12 @@
 #include <furi_hal_random.h>
 #include <furi_hal_version.h>
 #include "../../types/common.h"
-#include "../../wolfssl_config.h"
+#include "../../config/wolfssl/config.h"
 #include <wolfssl/wolfcrypt/hmac.h>
 #include <wolfssl/wolfcrypt/pwdbased.h>
 #include "memset_s.h"
 #include "constants.h"
+#include "polyfills.h"
 
 #define CRYPTO_ALIGNMENT_FACTOR (16)
 #define PBKDF2_ITERATIONS_COUNT (200)
@@ -49,14 +50,14 @@ uint8_t* totp_crypto_encrypt_v3(
         *encrypted_data_length = plain_data_aligned_length;
 
         furi_check(
-            furi_hal_crypto_store_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
-            "Encryption failed: store_load_key");
+            furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
+            "Encryption failed: enclave_load_key");
         furi_check(
             furi_hal_crypto_encrypt(plain_data_aligned, encrypted_data, plain_data_aligned_length),
             "Encryption failed: encrypt");
         furi_check(
-            furi_hal_crypto_store_unload_key(crypto_settings->crypto_key_slot),
-            "Encryption failed: store_unload_key");
+            furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
+            "Encryption failed: enclave_unload_key");
 
         memset_s(plain_data_aligned, plain_data_aligned_length, 0, plain_data_aligned_length);
         free(plain_data_aligned);
@@ -66,14 +67,14 @@ uint8_t* totp_crypto_encrypt_v3(
         *encrypted_data_length = plain_data_length;
 
         furi_check(
-            furi_hal_crypto_store_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
-            "Encryption failed: store_load_key");
+            furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
+            "Encryption failed: enclave_load_key");
         furi_check(
             furi_hal_crypto_encrypt(plain_data, encrypted_data, plain_data_length),
             "Encryption failed: encrypt");
         furi_check(
-            furi_hal_crypto_store_unload_key(crypto_settings->crypto_key_slot),
-            "Encryption failed: store_unload_key");
+            furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
+            "Encryption failed: enclave_unload_key");
     }
 
     return encrypted_data;
@@ -88,14 +89,14 @@ uint8_t* totp_crypto_decrypt_v3(
     uint8_t* decrypted_data = malloc(*decrypted_data_length);
     furi_check(decrypted_data != NULL);
     furi_check(
-        furi_hal_crypto_store_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
-        "Decryption failed: store_load_key");
+        furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
+        "Decryption failed: enclave_load_key");
     furi_check(
         furi_hal_crypto_decrypt(encrypted_data, decrypted_data, encrypted_data_length),
         "Decryption failed: decrypt");
     furi_check(
-        furi_hal_crypto_store_unload_key(crypto_settings->crypto_key_slot),
-        "Decryption failed: store_unload_key");
+        furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
+        "Decryption failed: enclave_unload_key");
     return decrypted_data;
 }
 

+ 14 - 0
services/crypto/polyfills.h

@@ -0,0 +1,14 @@
+#pragma once
+
+#include <furi_hal_crypto.h>
+
+#ifndef FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_START
+
+// FW Crypto API is outdated, let's polyfill it
+#define FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_START (12u)
+#define FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_END (100u)
+#define furi_hal_crypto_enclave_ensure_key furi_hal_crypto_verify_key
+#define furi_hal_crypto_enclave_load_key furi_hal_crypto_store_load_key
+#define furi_hal_crypto_enclave_unload_key furi_hal_crypto_store_unload_key
+
+#endif

+ 1 - 1
services/totp/totp.c

@@ -4,7 +4,7 @@
 #include <stdint.h>
 #include <math.h>
 #include <timezone_utils.h>
-#include "../../wolfssl_config.h"
+#include "../../config/wolfssl/config.h"
 #include <wolfssl/wolfcrypt/hmac.h>
 
 #define HMAC_MAX_RESULT_SIZE WC_SHA512_DIGEST_SIZE

+ 1 - 1
totp_app.c

@@ -5,7 +5,7 @@
 #include <notification/notification.h>
 #include <notification/notification_messages.h>
 #include <dolphin/dolphin.h>
-#include "features_config.h"
+#include "config/app/config.h"
 #include "services/config/config.h"
 #include "types/plugin_state.h"
 #include "types/token_info.h"

+ 1 - 1
types/automation_method.h

@@ -1,6 +1,6 @@
 #pragma once
 
-#include "../features_config.h"
+#include "../config/app/config.h"
 
 typedef uint8_t AutomationMethod;
 

+ 1 - 1
types/plugin_state.h

@@ -3,7 +3,7 @@
 #include <notification/notification.h>
 #include <gui/gui.h>
 #include <dialogs/dialogs.h>
-#include "../features_config.h"
+#include "../config/app/config.h"
 #include "../ui/totp_scenes_enum.h"
 #include "../services/config/config_file_context.h"
 #include "../services/idle_timeout/idle_timeout.h"

+ 11 - 0
ui/scene_director.c

@@ -1,8 +1,11 @@
 #include "../types/common.h"
+#include "../config/app/config.h"
 #include "scene_director.h"
 #include "scenes/authenticate/totp_scene_authenticate.h"
 #include "scenes/generate_token/totp_scene_generate_token.h"
+#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
 #include "scenes/add_new_token/totp_scene_add_new_token.h"
+#endif
 #include "scenes/token_menu/totp_scene_token_menu.h"
 #include "scenes/app_settings/totp_app_settings.h"
 #include "scenes/standby/standby.h"
@@ -16,9 +19,11 @@ void totp_scene_director_activate_scene(PluginState* const plugin_state, Scene s
     case TotpSceneAuthentication:
         totp_scene_authenticate_activate(plugin_state);
         break;
+#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
     case TotpSceneAddNewToken:
         totp_scene_add_new_token_activate(plugin_state);
         break;
+#endif
     case TotpSceneTokenMenu:
         totp_scene_token_menu_activate(plugin_state);
         break;
@@ -45,9 +50,11 @@ void totp_scene_director_deactivate_active_scene(PluginState* const plugin_state
     case TotpSceneAuthentication:
         totp_scene_authenticate_deactivate(plugin_state);
         break;
+#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
     case TotpSceneAddNewToken:
         totp_scene_add_new_token_deactivate(plugin_state);
         break;
+#endif
     case TotpSceneTokenMenu:
         totp_scene_token_menu_deactivate(plugin_state);
         break;
@@ -70,9 +77,11 @@ void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_
     case TotpSceneAuthentication:
         totp_scene_authenticate_render(canvas, plugin_state);
         break;
+#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
     case TotpSceneAddNewToken:
         totp_scene_add_new_token_render(canvas, plugin_state);
         break;
+#endif
     case TotpSceneTokenMenu:
         totp_scene_token_menu_render(canvas, plugin_state);
         break;
@@ -98,9 +107,11 @@ bool totp_scene_director_handle_event(PluginEvent* const event, PluginState* con
     case TotpSceneAuthentication:
         processing = totp_scene_authenticate_handle_event(event, plugin_state);
         break;
+#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
     case TotpSceneAddNewToken:
         processing = totp_scene_add_new_token_handle_event(event, plugin_state);
         break;
+#endif
     case TotpSceneTokenMenu:
         processing = totp_scene_token_menu_handle_event(event, plugin_state);
         break;

+ 2 - 0
ui/scenes/add_new_token/totp_input_text.c

@@ -1,5 +1,6 @@
 #include "totp_input_text.h"
 
+#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
 #include <gui/view_dispatcher.h>
 #include <gui/modules/text_input.h>
 
@@ -50,3 +51,4 @@ void totp_input_text(Gui* gui, const char* header_text, InputTextResult* result)
     view_dispatcher_free(view_dispatcher);
     text_input_free(text_input);
 }
+#endif

+ 3 - 0
ui/scenes/add_new_token/totp_input_text.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include "../../../config/app/config.h"
+#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
 #include <gui/gui.h>
 
 #define INPUT_BUFFER_SIZE (255)
@@ -11,3 +13,4 @@ typedef struct {
 } InputTextResult;
 
 void totp_input_text(Gui* gui, const char* header_text, InputTextResult* result);
+#endif

+ 2 - 1
ui/scenes/add_new_token/totp_scene_add_new_token.c

@@ -1,4 +1,5 @@
 #include "totp_scene_add_new_token.h"
+#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
 #include "../../../types/common.h"
 #include "../../constants.h"
 #include "../../scene_director.h"
@@ -8,7 +9,6 @@
 #include "../../ui_controls.h"
 #include "../../common_dialogs.h"
 #include <roll_value.h>
-#include "../generate_token/totp_scene_generate_token.h"
 
 char* TOKEN_ALGO_LIST[] = {"SHA1", "SHA256", "SHA512", "Steam"};
 char* TOKEN_DIGITS_TEXT_LIST[] = {"5 digits", "6 digits", "8 digits"};
@@ -318,3 +318,4 @@ void totp_scene_add_new_token_deactivate(PluginState* plugin_state) {
     free(plugin_state->current_scene_state);
     plugin_state->current_scene_state = NULL;
 }
+#endif

+ 3 - 0
ui/scenes/add_new_token/totp_scene_add_new_token.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include "../../../config/app/config.h"
+#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
 #include <gui/gui.h>
 #include "../../../types/plugin_state.h"
 #include "../../../types/plugin_event.h"
@@ -10,3 +12,4 @@ bool totp_scene_add_new_token_handle_event(
     const PluginEvent* const event,
     PluginState* plugin_state);
 void totp_scene_add_new_token_deactivate(PluginState* plugin_state);
+#endif

+ 1 - 2
ui/scenes/app_settings/totp_app_settings.c

@@ -6,12 +6,11 @@
 #include "../../ui_controls.h"
 #include "../../common_dialogs.h"
 #include "../../scene_director.h"
-#include "../token_menu/totp_scene_token_menu.h"
 #include "../../constants.h"
 #include "../../../services/config/config.h"
 #include "../../../services/convert/convert.h"
 #include <roll_value.h>
-#include "../../../features_config.h"
+#include "../../../config/app/config.h"
 #ifdef TOTP_BADBT_AUTOMATION_ENABLED
 #include "../../../workers/bt_type_code/bt_type_code.h"
 #endif

+ 3 - 4
ui/scenes/generate_token/totp_scene_generate_token.c

@@ -1,18 +1,17 @@
+#include "totp_scene_generate_token.h"
 #include <gui/gui.h>
 #include <notification/notification.h>
 #include <notification/notification_messages.h>
 #include <totp_icons.h>
 #include <roll_value.h>
 #include <available_fonts.h>
-#include "totp_scene_generate_token.h"
 #include "../../canvas_extensions.h"
 #include "../../../types/token_info.h"
 #include "../../../types/common.h"
 #include "../../constants.h"
 #include "../../../services/config/config.h"
 #include "../../scene_director.h"
-#include "../token_menu/totp_scene_token_menu.h"
-#include "../../../features_config.h"
+#include "../../../config/app/config.h"
 #include "../../../workers/generate_totp_code/generate_totp_code.h"
 #include "../../../workers/usb_type_code/usb_type_code.h"
 #ifdef TOTP_BADBT_AUTOMATION_ENABLED
@@ -246,7 +245,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
             SCREEN_HEIGHT_CENTER + 10,
             AlignCenter,
             AlignCenter,
-            "Press OK button to add");
+            "Press OK button to access menu");
         return;
     }
 

+ 16 - 3
ui/scenes/token_menu/totp_scene_token_menu.c

@@ -7,9 +7,7 @@
 #include "../../scene_director.h"
 #include "../../../services/config/config.h"
 #include "../../../types/token_info.h"
-#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 "../../../config/app/config.h"
 #include <roll_value.h>
 
 #define SCREEN_HEIGHT_THIRD (SCREEN_HEIGHT / 3)
@@ -130,7 +128,22 @@ bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginSt
     } else if(event->input.type == InputTypeRelease && event->input.key == InputKeyOk) {
         switch(scene_state->selected_control) {
         case AddNewToken: {
+#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
             totp_scene_director_activate_scene(plugin_state, TotpSceneAddNewToken);
+#else
+            DialogMessage* message = dialog_message_alloc();
+            dialog_message_set_buttons(message, "Back", NULL, NULL);
+            dialog_message_set_header(message, "Information", 0, 0, AlignLeft, AlignTop);
+            dialog_message_set_text(
+                message,
+                "Read here\nhttps://t.ly/8ZOtj\n how to add new token",
+                SCREEN_WIDTH_CENTER,
+                SCREEN_HEIGHT_CENTER,
+                AlignCenter,
+                AlignCenter);
+            dialog_message_show(plugin_state->dialogs_app, message);
+            dialog_message_free(message);
+#endif
             break;
         }
         case DeleteToken: {

+ 4 - 0
ui/totp_scenes_enum.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include "../config/app/config.h"
+
 typedef uint8_t Scene;
 
 /**
@@ -21,10 +23,12 @@ enum Scenes {
      */
     TotpSceneGenerateToken,
 
+#ifdef TOTP_UI_ADD_NEW_TOKEN_ENABLED
     /**
      * @brief Scene where user can add new token 
      */
     TotpSceneAddNewToken,
+#endif
 
     /**
      * @brief Scene with a menu for given token, allowing user to do multiple actions

+ 1 - 1
workers/bt_type_code/bt_type_code.c

@@ -11,7 +11,7 @@
 #include "../../types/common.h"
 #include "../../types/token_info.h"
 #include "../type_code_common.h"
-#include "../../features_config.h"
+#include "../../config/app/config.h"
 #include "../../services/config/constants.h"
 
 #if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL