mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-23 21:13:16 +00:00
parent
4f7ca617cc
commit
04d67ca8ae
10 changed files with 234 additions and 77 deletions
|
@ -6,10 +6,9 @@
|
||||||
#include "../../services/config/config.h"
|
#include "../../services/config/config.h"
|
||||||
#include "../scene_director.h"
|
#include "../scene_director.h"
|
||||||
#include "../totp_scenes_enum.h"
|
#include "../totp_scenes_enum.h"
|
||||||
|
#include "../../services/crypto/crypto.h"
|
||||||
|
|
||||||
#define MAX_CODE_LENGTH TOTP_IV_SIZE
|
#define MAX_CODE_LENGTH TOTP_IV_SIZE
|
||||||
#define CRYPTO_VERIFY_KEY "FFF_Crypto_pass"
|
|
||||||
#define CRYPTO_VERIFY_KEY_LENGTH 16
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t code_input[MAX_CODE_LENGTH];
|
uint8_t code_input[MAX_CODE_LENGTH];
|
||||||
|
@ -111,52 +110,10 @@ bool totp_scene_authenticate_handle_event(PluginEvent* const event, PluginState*
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InputKeyOk:
|
case InputKeyOk:
|
||||||
if(plugin_state->crypto_verify_data == NULL) {
|
totp_crypto_seed_iv(
|
||||||
FURI_LOG_D(LOGGING_TAG, "Generating new IV");
|
plugin_state, &scene_state->code_input[0], scene_state->code_length);
|
||||||
furi_hal_random_fill_buf(&plugin_state->base_iv[0], TOTP_IV_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&plugin_state->iv[0], &plugin_state->base_iv[0], TOTP_IV_SIZE);
|
if(totp_crypto_verify_key(plugin_state)) {
|
||||||
for(uint8_t i = 0; i < scene_state->code_length; i++) {
|
|
||||||
plugin_state->iv[i] = plugin_state->iv[i] ^
|
|
||||||
(uint8_t)(scene_state->code_input[i] * (i + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(plugin_state->crypto_verify_data == NULL) {
|
|
||||||
FURI_LOG_D(LOGGING_TAG, "Generating crypto verify data");
|
|
||||||
plugin_state->crypto_verify_data = malloc(CRYPTO_VERIFY_KEY_LENGTH);
|
|
||||||
plugin_state->crypto_verify_data_length = CRYPTO_VERIFY_KEY_LENGTH;
|
|
||||||
Storage* storage = totp_open_storage();
|
|
||||||
FlipperFormat* config_file = totp_open_config_file(storage);
|
|
||||||
furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, &plugin_state->iv[0]);
|
|
||||||
furi_hal_crypto_encrypt(
|
|
||||||
(uint8_t*)CRYPTO_VERIFY_KEY,
|
|
||||||
plugin_state->crypto_verify_data,
|
|
||||||
CRYPTO_VERIFY_KEY_LENGTH);
|
|
||||||
furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
|
|
||||||
flipper_format_insert_or_update_hex(
|
|
||||||
config_file, TOTP_CONFIG_KEY_BASE_IV, plugin_state->base_iv, TOTP_IV_SIZE);
|
|
||||||
flipper_format_insert_or_update_hex(
|
|
||||||
config_file,
|
|
||||||
TOTP_CONFIG_KEY_CRYPTO_VERIFY,
|
|
||||||
plugin_state->crypto_verify_data,
|
|
||||||
CRYPTO_VERIFY_KEY_LENGTH);
|
|
||||||
totp_close_config_file(config_file);
|
|
||||||
totp_close_storage();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t decrypted_key[CRYPTO_VERIFY_KEY_LENGTH];
|
|
||||||
furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, &plugin_state->iv[0]);
|
|
||||||
furi_hal_crypto_decrypt(
|
|
||||||
plugin_state->crypto_verify_data, &decrypted_key[0], CRYPTO_VERIFY_KEY_LENGTH);
|
|
||||||
furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
|
|
||||||
|
|
||||||
bool key_valid = true;
|
|
||||||
for(uint8_t i = 0; i < CRYPTO_VERIFY_KEY_LENGTH && key_valid; i++) {
|
|
||||||
if(decrypted_key[i] != CRYPTO_VERIFY_KEY[i]) key_valid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(key_valid) {
|
|
||||||
FURI_LOG_D(LOGGING_TAG, "PIN is valid");
|
FURI_LOG_D(LOGGING_TAG, "PIN is valid");
|
||||||
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
|
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "../../services/ui/constants.h"
|
#include "../../services/ui/constants.h"
|
||||||
#include "../../services/totp/totp.h"
|
#include "../../services/totp/totp.h"
|
||||||
#include "../../services/config/config.h"
|
#include "../../services/config/config.h"
|
||||||
|
#include "../../services/crypto/crypto.h"
|
||||||
#include "../scene_director.h"
|
#include "../scene_director.h"
|
||||||
#include "../token_menu/totp_scene_token_menu.h"
|
#include "../token_menu/totp_scene_token_menu.h"
|
||||||
|
|
||||||
|
@ -156,24 +157,22 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
||||||
plugin_state->tokens_list, scene_state->current_token_index)
|
plugin_state->tokens_list, scene_state->current_token_index)
|
||||||
->data);
|
->data);
|
||||||
|
|
||||||
uint8_t* key = malloc(tokenInfo->token_length);
|
uint8_t key_length;
|
||||||
|
uint8_t* key = totp_crypto_decrypt(
|
||||||
furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, &plugin_state->iv[0]);
|
tokenInfo->token, tokenInfo->token_length, &plugin_state->iv[0], &key_length);
|
||||||
furi_hal_crypto_decrypt(tokenInfo->token, key, tokenInfo->token_length);
|
|
||||||
furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
|
|
||||||
|
|
||||||
i_token_to_str(
|
i_token_to_str(
|
||||||
totp_at(
|
totp_at(
|
||||||
get_totp_algo_impl(tokenInfo->algo),
|
get_totp_algo_impl(tokenInfo->algo),
|
||||||
token_info_get_digits_count(tokenInfo),
|
token_info_get_digits_count(tokenInfo),
|
||||||
key,
|
key,
|
||||||
tokenInfo->token_length,
|
key_length,
|
||||||
curr_ts,
|
curr_ts,
|
||||||
plugin_state->timezone_offset,
|
plugin_state->timezone_offset,
|
||||||
TOKEN_LIFETIME),
|
TOKEN_LIFETIME),
|
||||||
scene_state->last_code,
|
scene_state->last_code,
|
||||||
tokenInfo->digits);
|
tokenInfo->digits);
|
||||||
memset(key, 0, tokenInfo->token_length);
|
memset(key, 0, key_length);
|
||||||
free(key);
|
free(key);
|
||||||
|
|
||||||
if(is_new_token_time) {
|
if(is_new_token_time) {
|
||||||
|
|
|
@ -199,6 +199,7 @@ void totp_full_save_config_file(PluginState* const plugin_state) {
|
||||||
plugin_state->crypto_verify_data_length);
|
plugin_state->crypto_verify_data_length);
|
||||||
flipper_format_write_float(
|
flipper_format_write_float(
|
||||||
fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1);
|
fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1);
|
||||||
|
flipper_format_write_bool(fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1);
|
||||||
ListNode* node = plugin_state->tokens_list;
|
ListNode* node = plugin_state->tokens_list;
|
||||||
while(node != NULL) {
|
while(node != NULL) {
|
||||||
TokenInfo* token_info = node->data;
|
TokenInfo* token_info = node->data;
|
||||||
|
@ -272,7 +273,8 @@ void totp_config_file_load_base(PluginState* const plugin_state) {
|
||||||
flipper_format_rewind(fff_data_file);
|
flipper_format_rewind(fff_data_file);
|
||||||
|
|
||||||
uint32_t crypto_size;
|
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 = malloc(sizeof(uint8_t) * crypto_size);
|
||||||
plugin_state->crypto_verify_data_length = crypto_size;
|
plugin_state->crypto_verify_data_length = crypto_size;
|
||||||
if(!flipper_format_read_hex(
|
if(!flipper_format_read_hex(
|
||||||
|
@ -283,7 +285,11 @@ void totp_config_file_load_base(PluginState* const plugin_state) {
|
||||||
FURI_LOG_D(LOGGING_TAG, "Missing crypto verify token");
|
FURI_LOG_D(LOGGING_TAG, "Missing crypto verify token");
|
||||||
free(plugin_state->crypto_verify_data);
|
free(plugin_state->crypto_verify_data);
|
||||||
plugin_state->crypto_verify_data = NULL;
|
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);
|
flipper_format_rewind(fff_data_file);
|
||||||
|
@ -294,6 +300,13 @@ void totp_config_file_load_base(PluginState* const plugin_state) {
|
||||||
FURI_LOG_D(LOGGING_TAG, "Missing timezone offset information, defaulting to 0");
|
FURI_LOG_D(LOGGING_TAG, "Missing timezone offset information, defaulting to 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flipper_format_rewind(fff_data_file);
|
||||||
|
|
||||||
|
if(!flipper_format_read_bool(
|
||||||
|
fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1)) {
|
||||||
|
plugin_state->pin_set = true;
|
||||||
|
}
|
||||||
|
|
||||||
furi_string_free(temp_str);
|
furi_string_free(temp_str);
|
||||||
totp_close_config_file(fff_data_file);
|
totp_close_config_file(fff_data_file);
|
||||||
totp_close_storage();
|
totp_close_storage();
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#define TOTP_CONFIG_KEY_TOKEN_DIGITS "TokenDigits"
|
#define TOTP_CONFIG_KEY_TOKEN_DIGITS "TokenDigits"
|
||||||
#define TOTP_CONFIG_KEY_CRYPTO_VERIFY "Crypto"
|
#define TOTP_CONFIG_KEY_CRYPTO_VERIFY "Crypto"
|
||||||
#define TOTP_CONFIG_KEY_BASE_IV "BaseIV"
|
#define TOTP_CONFIG_KEY_BASE_IV "BaseIV"
|
||||||
|
#define TOTP_CONFIG_KEY_PINSET "PinIsSet"
|
||||||
|
|
||||||
#define TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME "sha1"
|
#define TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME "sha1"
|
||||||
#define TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME "sha256"
|
#define TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME "sha256"
|
||||||
|
|
134
applications/plugins/totp/services/crypto/crypto.c
Normal file
134
applications/plugins/totp/services/crypto/crypto.c
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
#include "crypto.h"
|
||||||
|
#include <furi.h>
|
||||||
|
#include <furi_hal.h>
|
||||||
|
#include "../config/config.h"
|
||||||
|
#include "../../types/common.h"
|
||||||
|
|
||||||
|
#define CRYPTO_KEY_SLOT 2
|
||||||
|
#define CRYPTO_VERIFY_KEY "FFF_Crypto_pass"
|
||||||
|
#define CRYPTO_VERIFY_KEY_LENGTH 16
|
||||||
|
#define CRYPTO_ALIGNMENT_FACTOR 16
|
||||||
|
|
||||||
|
uint8_t* totp_crypto_encrypt(
|
||||||
|
const uint8_t* plain_data,
|
||||||
|
const uint8_t plain_data_length,
|
||||||
|
const uint8_t* iv,
|
||||||
|
uint8_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;
|
||||||
|
uint8_t* plain_data_aligned = malloc(plain_data_aligned_length);
|
||||||
|
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);
|
||||||
|
*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);
|
||||||
|
free(plain_data_aligned);
|
||||||
|
} else {
|
||||||
|
encrypted_data = malloc(plain_data_length);
|
||||||
|
*encrypted_data_length = plain_data_length;
|
||||||
|
|
||||||
|
furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, iv);
|
||||||
|
furi_hal_crypto_encrypt(plain_data, encrypted_data, plain_data_length);
|
||||||
|
furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return encrypted_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* totp_crypto_decrypt(
|
||||||
|
const uint8_t* encrypted_data,
|
||||||
|
const uint8_t encrypted_data_length,
|
||||||
|
const uint8_t* iv,
|
||||||
|
uint8_t* decrypted_data_length) {
|
||||||
|
*decrypted_data_length = encrypted_data_length;
|
||||||
|
uint8_t* decrypted_data = malloc(*decrypted_data_length);
|
||||||
|
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) {
|
||||||
|
if(plugin_state->crypto_verify_data == NULL) {
|
||||||
|
FURI_LOG_D(LOGGING_TAG, "Generating new IV");
|
||||||
|
furi_hal_random_fill_buf(&plugin_state->base_iv[0], TOTP_IV_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&plugin_state->iv[0], &plugin_state->base_iv[0], TOTP_IV_SIZE);
|
||||||
|
if(pin != NULL && pin_length > 0) {
|
||||||
|
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) {
|
||||||
|
FURI_LOG_D(LOGGING_TAG, "Generating crypto verify data");
|
||||||
|
plugin_state->crypto_verify_data = malloc(CRYPTO_VERIFY_KEY_LENGTH);
|
||||||
|
plugin_state->crypto_verify_data_length = CRYPTO_VERIFY_KEY_LENGTH;
|
||||||
|
Storage* storage = totp_open_storage();
|
||||||
|
FlipperFormat* config_file = totp_open_config_file(storage);
|
||||||
|
|
||||||
|
plugin_state->crypto_verify_data = totp_crypto_encrypt(
|
||||||
|
(uint8_t*)CRYPTO_VERIFY_KEY,
|
||||||
|
CRYPTO_VERIFY_KEY_LENGTH,
|
||||||
|
&plugin_state->iv[0],
|
||||||
|
&plugin_state->crypto_verify_data_length);
|
||||||
|
|
||||||
|
flipper_format_insert_or_update_hex(
|
||||||
|
config_file, TOTP_CONFIG_KEY_BASE_IV, plugin_state->base_iv, TOTP_IV_SIZE);
|
||||||
|
flipper_format_insert_or_update_hex(
|
||||||
|
config_file,
|
||||||
|
TOTP_CONFIG_KEY_CRYPTO_VERIFY,
|
||||||
|
plugin_state->crypto_verify_data,
|
||||||
|
CRYPTO_VERIFY_KEY_LENGTH);
|
||||||
|
plugin_state->pin_set = pin != NULL && pin_length > 0;
|
||||||
|
flipper_format_insert_or_update_bool(
|
||||||
|
config_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1);
|
||||||
|
totp_close_config_file(config_file);
|
||||||
|
totp_close_storage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool totp_crypto_verify_key(const PluginState* plugin_state) {
|
||||||
|
uint8_t decrypted_key_length;
|
||||||
|
uint8_t* decrypted_key = totp_crypto_decrypt(
|
||||||
|
plugin_state->crypto_verify_data,
|
||||||
|
plugin_state->crypto_verify_data_length,
|
||||||
|
&plugin_state->iv[0],
|
||||||
|
&decrypted_key_length);
|
||||||
|
|
||||||
|
bool key_valid = true;
|
||||||
|
for(uint8_t i = 0; i < CRYPTO_VERIFY_KEY_LENGTH && key_valid; i++) {
|
||||||
|
if(decrypted_key[i] != CRYPTO_VERIFY_KEY[i]) key_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return key_valid;
|
||||||
|
}
|
16
applications/plugins/totp/services/crypto/crypto.h
Normal file
16
applications/plugins/totp/services/crypto/crypto.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../../types/plugin_state.h"
|
||||||
|
|
||||||
|
uint8_t* totp_crypto_encrypt(
|
||||||
|
const uint8_t* plain_data,
|
||||||
|
const uint8_t plain_data_length,
|
||||||
|
const uint8_t* iv,
|
||||||
|
uint8_t* encrypted_data_length);
|
||||||
|
uint8_t* totp_crypto_decrypt(
|
||||||
|
const uint8_t* encrypted_data,
|
||||||
|
const uint8_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);
|
||||||
|
bool totp_crypto_verify_key(const PluginState* plugin_state);
|
|
@ -16,6 +16,8 @@
|
||||||
#include "types/event_type.h"
|
#include "types/event_type.h"
|
||||||
#include "types/common.h"
|
#include "types/common.h"
|
||||||
#include "scenes/scene_director.h"
|
#include "scenes/scene_director.h"
|
||||||
|
#include "services/ui/constants.h"
|
||||||
|
#include "services/crypto/crypto.h"
|
||||||
|
|
||||||
#define IDLE_TIMEOUT 60000
|
#define IDLE_TIMEOUT 60000
|
||||||
|
|
||||||
|
@ -35,14 +37,58 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu
|
||||||
furi_message_queue_put(event_queue, &event, FuriWaitForever);
|
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->gui = furi_record_open(RECORD_GUI);
|
||||||
plugin_state->notification = furi_record_open(RECORD_NOTIFICATION);
|
plugin_state->notification = furi_record_open(RECORD_NOTIFICATION);
|
||||||
plugin_state->dialogs = furi_record_open(RECORD_DIALOGS);
|
plugin_state->dialogs = furi_record_open(RECORD_DIALOGS);
|
||||||
totp_config_file_load_base(plugin_state);
|
totp_config_file_load_base(plugin_state);
|
||||||
|
|
||||||
totp_scene_director_init_scenes(plugin_state);
|
totp_scene_director_init_scenes(plugin_state);
|
||||||
|
|
||||||
|
if(plugin_state->crypto_verify_data == NULL) {
|
||||||
|
DialogMessage* message = dialog_message_alloc();
|
||||||
|
dialog_message_set_buttons(message, "No", NULL, "Yes");
|
||||||
|
dialog_message_set_text(
|
||||||
|
message,
|
||||||
|
"Would you like to setup PIN?",
|
||||||
|
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) {
|
||||||
totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication, NULL);
|
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);
|
||||||
|
}
|
||||||
|
} else if(plugin_state->pin_set) {
|
||||||
|
totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication, NULL);
|
||||||
|
} else {
|
||||||
|
totp_crypto_seed_iv(plugin_state, NULL, 0);
|
||||||
|
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) {
|
static void dispose_plugin_state(PluginState* plugin_state) {
|
||||||
|
@ -74,7 +120,11 @@ int32_t totp_app() {
|
||||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
|
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
|
||||||
PluginState* plugin_state = malloc(sizeof(PluginState));
|
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;
|
ValueMutex state_mutex;
|
||||||
if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) {
|
if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) {
|
||||||
|
@ -107,7 +157,7 @@ int32_t totp_app() {
|
||||||
|
|
||||||
processing = totp_scene_director_handle_event(&event, plugin_state);
|
processing = totp_scene_director_handle_event(&event, plugin_state);
|
||||||
} else if(
|
} else if(
|
||||||
plugin_state->current_scene != TotpSceneAuthentication &&
|
plugin_state->pin_set && plugin_state->current_scene != TotpSceneAuthentication &&
|
||||||
furi_get_tick() - last_user_interaction_time > IDLE_TIMEOUT) {
|
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, TotpSceneAuthentication, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define LOGGING_TAG "TOTP APP"
|
#define LOGGING_TAG "TOTP APP"
|
||||||
#define CRYPTO_KEY_SLOT 2
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ typedef struct {
|
||||||
|
|
||||||
uint8_t* crypto_verify_data;
|
uint8_t* crypto_verify_data;
|
||||||
uint8_t crypto_verify_data_length;
|
uint8_t crypto_verify_data_length;
|
||||||
|
bool pin_set;
|
||||||
uint8_t iv[TOTP_IV_SIZE];
|
uint8_t iv[TOTP_IV_SIZE];
|
||||||
uint8_t base_iv[TOTP_IV_SIZE];
|
uint8_t base_iv[TOTP_IV_SIZE];
|
||||||
} PluginState;
|
} PluginState;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "../services/base32/base32.h"
|
#include "../services/base32/base32.h"
|
||||||
|
#include "../services/crypto/crypto.h"
|
||||||
|
|
||||||
TokenInfo* token_info_alloc() {
|
TokenInfo* token_info_alloc() {
|
||||||
TokenInfo* tokenInfo = malloc(sizeof(TokenInfo));
|
TokenInfo* tokenInfo = malloc(sizeof(TokenInfo));
|
||||||
|
@ -27,25 +28,11 @@ void token_info_set_secret(
|
||||||
uint8_t* plain_secret = malloc(token_secret_length);
|
uint8_t* plain_secret = malloc(token_secret_length);
|
||||||
int plain_secret_length =
|
int plain_secret_length =
|
||||||
base32_decode((uint8_t*)base32_token_secret, plain_secret, token_secret_length);
|
base32_decode((uint8_t*)base32_token_secret, plain_secret, token_secret_length);
|
||||||
token_info->token_length = plain_secret_length;
|
|
||||||
|
|
||||||
size_t remain = token_info->token_length % 16;
|
token_info->token =
|
||||||
if(remain) {
|
totp_crypto_encrypt(plain_secret, plain_secret_length, iv, &token_info->token_length);
|
||||||
token_info->token_length = token_info->token_length - remain + 16;
|
|
||||||
uint8_t* plain_secret_aligned = malloc(token_info->token_length);
|
|
||||||
memcpy(plain_secret_aligned, plain_secret, plain_secret_length);
|
|
||||||
memset(plain_secret, 0, plain_secret_length);
|
|
||||||
free(plain_secret);
|
|
||||||
plain_secret = plain_secret_aligned;
|
|
||||||
}
|
|
||||||
|
|
||||||
token_info->token = malloc(token_info->token_length);
|
memset(plain_secret, 0, token_secret_length);
|
||||||
|
|
||||||
furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, iv);
|
|
||||||
furi_hal_crypto_encrypt(plain_secret, token_info->token, token_info->token_length);
|
|
||||||
furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
|
|
||||||
|
|
||||||
memset(plain_secret, 0, token_info->token_length);
|
|
||||||
free(plain_secret);
|
free(plain_secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue