Просмотр исходного кода

* Fixed "Add new token" scene.

* Added UID as IV modifier if user is not using PIN
alex.kopachov 3 лет назад
Родитель
Сommit
ad814f4686
7 измененных файлов с 56 добавлено и 9 удалено
  1. 2 0
      .gitmodules
  2. 2 2
      README.md
  3. 5 0
      fbt.ps1
  4. 5 1
      totp/services/config/config.c
  5. 21 1
      totp/services/crypto/crypto.c
  6. 20 4
      totp/totp_app.c
  7. 1 1
      totp/types/token_info.c

+ 2 - 0
.gitmodules

@@ -2,7 +2,9 @@
 	path = flipperzero-firmware_official
 	url = https://github.com/flipperdevices/flipperzero-firmware.git
 	branch = dev
+	ignore = all
 [submodule "flipperzero-firmware_unleashed"]
 	path = flipperzero-firmware_unleashed
 	url = https://github.com/Eng1n33r/flipperzero-firmware.git
 	branch = dev
+	ignore = all

+ 2 - 2
README.md

@@ -30,9 +30,9 @@ Detailed description of file format can be found [here](.github/conf-file_descri
 
 ## Is it secure?
 
-Flipper Authenticator stores token secrets in config file in encrypted form. Encryption is done using standard Flipper Zero API, which states that it is using AES encryption with built-in into flipper secret key and initialization vector (IV) generated by the app at initial setup XOR-ed by user's PIN.
+Flipper Authenticator stores token secrets in config file in encrypted form. Encryption is done using standard Flipper Zero API, which states that it is using AES encryption with built-in into flipper secret key and initialization vector (IV) generated by the app at initial setup XOR-ed by user's PIN (or Flipper UID, if PIN not setup by user).
 
-So in theory to get plain token secret it is necessary to have original Flipper Zero device where config file was generated and know user's PIN.
+So in theory to get plain token secret it is necessary to have original Flipper Zero device where config file was generated and know user's PIN (if user setup PIN).
 
 If user provides plain token secret manually straight to a config file, once app will be launched it will detect plain token, will encrypt it and will replace plain token secret with encrypted copy.
 

+ 5 - 0
fbt.ps1

@@ -25,6 +25,11 @@ if ((Test-Path -Path "$firmware_path\applications_user\totp") -ne $True) {
     }    
 }
 
+$builtin_totp_path = "$firmware_path\applications\plugins\totp"
+if ((Test-Path -Path $builtin_totp_path) -eq $True) {
+    Remove-Item $builtin_totp_path -Recurse
+}
+
 Push-Location $firmware_path
 
 ./fbt $args[1..($args.Length - 1)]

+ 5 - 1
totp/services/config/config.c

@@ -231,14 +231,18 @@ void totp_config_file_load_base(PluginState* const plugin_state) {
     flipper_format_rewind(fff_data_file);
 
     uint32_t crypto_size;
-    if (flipper_format_get_value_count(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, &crypto_size)) {
+    if (flipper_format_get_value_count(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, &crypto_size) && crypto_size > 0) {
         plugin_state->crypto_verify_data = malloc(sizeof(uint8_t) * crypto_size);
         plugin_state->crypto_verify_data_length = crypto_size;
         if (!flipper_format_read_hex(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, plugin_state->crypto_verify_data, crypto_size)) {
             FURI_LOG_D(LOGGING_TAG, "Missing crypto verify token");
             free(plugin_state->crypto_verify_data);
             plugin_state->crypto_verify_data = NULL;
+            plugin_state->crypto_verify_data_length = 0;
         }
+    } else {
+        plugin_state->crypto_verify_data = NULL;
+        plugin_state->crypto_verify_data_length = 0;
     }
 
     flipper_format_rewind(fff_data_file);

+ 21 - 1
totp/services/crypto/crypto.c

@@ -56,9 +56,29 @@ void totp_crypto_seed_iv(PluginState* plugin_state, uint8_t* pin, uint8_t pin_le
 
     memcpy(&plugin_state->iv[0], &plugin_state->base_iv[0], TOTP_IV_SIZE);
     if (pin != NULL && pin_length > 0) {
-        for (uint8_t i = 0; i < pin_length; i++) {
+        uint8_t max_i; 
+        if (pin_length > TOTP_IV_SIZE) {
+            max_i = TOTP_IV_SIZE;
+        } else {
+            max_i = pin_length;
+        }
+
+        for (uint8_t i = 0; i < max_i; i++) {
             plugin_state->iv[i] = plugin_state->iv[i] ^ (uint8_t)(pin[i] * (i + 1));
         }
+    } else {
+        uint8_t max_i;
+        size_t uid_size = furi_hal_version_uid_size();
+        if (uid_size > TOTP_IV_SIZE) {
+            max_i = TOTP_IV_SIZE;
+        } else {
+            max_i = uid_size;
+        }
+
+        const uint8_t* uid = furi_hal_version_uid();
+        for(uint8_t i = 0; i < max_i; i++) {
+            plugin_state->iv[i] = plugin_state->iv[i] ^ uid[i];
+        }
     }
 
     if (plugin_state->crypto_verify_data == NULL) {

+ 20 - 4
totp/totp_app.c

@@ -37,7 +37,7 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu
     furi_message_queue_put(event_queue, &event, FuriWaitForever);
 }
 
-static void totp_state_init(PluginState* const plugin_state) {
+static bool totp_state_init(PluginState* const plugin_state) {
     plugin_state->gui = furi_record_open(RECORD_GUI);
     plugin_state->notification = furi_record_open(RECORD_NOTIFICATION);
     plugin_state->dialogs = furi_record_open(RECORD_DIALOGS);
@@ -61,8 +61,20 @@ static void totp_state_init(PluginState* const plugin_state) {
         totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication, NULL);
     } else {
         totp_crypto_seed_iv(plugin_state, NULL, 0);
-        totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
+        if (totp_crypto_verify_key(plugin_state)) {
+            totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
+        } else {
+            FURI_LOG_E(LOGGING_TAG, "Digital signature verification failed. Looks like conf file was created on another flipper and can't be used on any other");
+            DialogMessage* message = dialog_message_alloc();
+            dialog_message_set_buttons(message, "Exit", NULL, NULL);
+            dialog_message_set_text(message, "Digital signature verification failed", SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER, AlignCenter, AlignCenter);
+            dialog_message_show(plugin_state->dialogs, message);
+            dialog_message_free(message);
+            return false;
+        }
     }
+
+    return true;
 }
 
 static void dispose_plugin_state(PluginState* plugin_state) {
@@ -94,7 +106,11 @@ int32_t totp_app() {
     FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
     PluginState* plugin_state = malloc(sizeof(PluginState));
 
-    totp_state_init(plugin_state);
+    if (!totp_state_init(plugin_state)) {
+        FURI_LOG_E(LOGGING_TAG, "App state initialization failed\r\n");
+        dispose_plugin_state(plugin_state);
+        return 254;
+    }
 
     ValueMutex state_mutex;
     if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) {
@@ -126,7 +142,7 @@ int32_t totp_app() {
             }
 
             processing = totp_scene_director_handle_event(&event, plugin_state);
-        } else if (plugin_state->current_scene != TotpSceneAuthentication && furi_get_tick() - last_user_interaction_time > IDLE_TIMEOUT) {
+        } else if (plugin_state->pin_set && plugin_state->current_scene != TotpSceneAuthentication && furi_get_tick() - last_user_interaction_time > IDLE_TIMEOUT) {
             totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication, NULL);
         }
 

+ 1 - 1
totp/types/token_info.c

@@ -26,7 +26,7 @@ void token_info_set_secret(TokenInfo* token_info, const char* base32_token_secre
 
     token_info->token = totp_crypto_encrypt(plain_secret, plain_secret_length, iv, &token_info->token_length);
 
-    memset(plain_secret, 0, token_info->token_length);
+    memset(plain_secret, 0, token_secret_length);
     free(plain_secret);
 }