Skip to content

Commit

Permalink
Implemented #185 (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
akopachov committed Aug 9, 2023
1 parent afe7e56 commit 86a90ab
Show file tree
Hide file tree
Showing 36 changed files with 391 additions and 1,438 deletions.
12 changes: 12 additions & 0 deletions application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,17 @@ App(
Lib(
name="fonts",
),
Lib(
name="wolfssl",
sources=[
"wolfcrypt/src/pwdbased.c",
"wolfcrypt/src/hmac.c",
"wolfcrypt/src/hash.c",
"wolfcrypt/src/sha.c",
"wolfcrypt/src/sha256.c",
"wolfcrypt/src/sha512.c"
],
cflags=["-Wno-error", "-include${FAP_SRC_DIR}/wolfssl_config.h"]
),
],
)
1 change: 1 addition & 0 deletions lib/wolfssl
Submodule wolfssl added at 3b3c17
19 changes: 10 additions & 9 deletions services/config/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ static bool totp_open_config_file(Storage* storage, FlipperFormat** file) {
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);

bool conf_file_exists = storage_common_stat(storage, CONFIG_FILE_PATH, NULL) == FSE_OK;
if(!conf_file_exists) {
if(!conf_file_exists &&
storage_common_stat(storage, EXT_PATH("authenticator"), NULL) == FSE_OK) {
FURI_LOG_I(LOGGING_TAG, "Application catalog needs to be migrated");
FS_Error migration_result =
storage_common_migrate(storage, EXT_PATH("authenticator"), CONFIG_FILE_DIRECTORY_PATH);
Expand Down Expand Up @@ -396,10 +397,10 @@ bool totp_config_file_load(PluginState* const plugin_state) {

if(!flipper_format_read_hex(
fff_data_file,
TOTP_CONFIG_KEY_BASE_IV,
&plugin_state->crypto_settings.base_iv[0],
CRYPTO_IV_LENGTH)) {
FURI_LOG_D(LOGGING_TAG, "Missing base IV");
TOTP_CONFIG_KEY_SALT,
&plugin_state->crypto_settings.salt[0],
CRYPTO_SALT_LENGTH)) {
FURI_LOG_D(LOGGING_TAG, "Missing salt");
}

if(!flipper_format_rewind(fff_data_file)) {
Expand Down Expand Up @@ -529,9 +530,9 @@ bool totp_config_file_update_crypto_signatures(const PluginState* plugin_state)

if(!flipper_format_insert_or_update_hex(
config_file,
TOTP_CONFIG_KEY_BASE_IV,
plugin_state->crypto_settings.base_iv,
CRYPTO_IV_LENGTH)) {
TOTP_CONFIG_KEY_SALT,
&plugin_state->crypto_settings.salt[0],
CRYPTO_SALT_LENGTH)) {
break;
}

Expand Down Expand Up @@ -592,7 +593,7 @@ bool totp_config_file_update_encryption(
CryptoSettings old_crypto_settings = plugin_state->crypto_settings;

memset(&plugin_state->crypto_settings.iv[0], 0, CRYPTO_IV_LENGTH);
memset(&plugin_state->crypto_settings.base_iv[0], 0, CRYPTO_IV_LENGTH);
memset(&plugin_state->crypto_settings.salt[0], 0, CRYPTO_SALT_LENGTH);
if(plugin_state->crypto_settings.crypto_verify_data != NULL) {
free(plugin_state->crypto_settings.crypto_verify_data);
plugin_state->crypto_settings.crypto_verify_data = NULL;
Expand Down
6 changes: 3 additions & 3 deletions services/config/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

#include <storage/storage.h>

#define CONFIG_FILE_DIRECTORY_PATH STORAGE_APP_DATA_PATH_PREFIX
#define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("apps_data/totp")
#define CONFIG_FILE_HEADER "Flipper TOTP plugin config file"
#define CONFIG_FILE_ACTUAL_VERSION (8)
#define CONFIG_FILE_ACTUAL_VERSION (9)

#define TOTP_CONFIG_KEY_TIMEZONE "Timezone"
#define TOTP_CONFIG_KEY_TOKEN_NAME "TokenName"
Expand All @@ -14,7 +14,7 @@
#define TOTP_CONFIG_KEY_TOKEN_DURATION "TokenDuration"
#define TOTP_CONFIG_KEY_TOKEN_AUTOMATION_FEATURES "TokenAutomationFeatures"
#define TOTP_CONFIG_KEY_CRYPTO_VERIFY "Crypto"
#define TOTP_CONFIG_KEY_BASE_IV "BaseIV"
#define TOTP_CONFIG_KEY_SALT "Salt"
#define TOTP_CONFIG_KEY_PINSET "PinIsSet"
#define TOTP_CONFIG_KEY_NOTIFICATION_METHOD "NotificationMethod"
#define TOTP_CONFIG_KEY_AUTOMATION_METHOD "AutomationMethod"
Expand Down
11 changes: 9 additions & 2 deletions services/config/migrations/common_migration.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "../../../types/automation_kb_layout.h"
#include <flipper_format/flipper_format_i.h>

#define TOTP_OLD_CONFIG_KEY_BASE_IV "BaseIV"

bool totp_config_migrate_to_latest(
FlipperFormat* fff_data_file,
FlipperFormat* fff_backup_data_file) {
Expand Down Expand Up @@ -40,8 +42,13 @@ bool totp_config_migrate_to_latest(

flipper_format_rewind(fff_backup_data_file);

if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_BASE_IV, temp_str)) {
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_BASE_IV, temp_str);
if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_SALT, temp_str)) {
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_SALT, temp_str);
} else if(
flipper_format_rewind(fff_backup_data_file) &&
flipper_format_read_string(
fff_backup_data_file, TOTP_OLD_CONFIG_KEY_BASE_IV, temp_str)) {
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_SALT, temp_str);
}

flipper_format_rewind(fff_backup_data_file);
Expand Down
4 changes: 3 additions & 1 deletion services/config/token_info_iterator.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "../../types/crypto_settings.h"

#define CONFIG_FILE_PART_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf.part"
#define STREAM_COPY_BUFFER_SIZE 128
#define STREAM_COPY_BUFFER_SIZE (128)

struct TokenInfoIteratorContext {
size_t total_count;
Expand Down Expand Up @@ -547,4 +547,6 @@ void totp_token_info_iterator_attach_to_config_file(
TokenInfoIteratorContext* context,
FlipperFormat* config_file) {
context->config_file = config_file;
Stream* stream = flipper_format_get_raw_stream(context->config_file);
stream_seek(stream, context->last_seek_offset, StreamOffsetFromStart);
}
3 changes: 2 additions & 1 deletion services/crypto/constants.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#pragma once

#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 DEFAULT_CRYPTO_KEY_SLOT ACCEPTABLE_CRYPTO_KEY_SLOT_START
#define CRYPTO_LATEST_VERSION (2)
#define CRYPTO_LATEST_VERSION (3)
19 changes: 19 additions & 0 deletions services/crypto/crypto_facade.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <furi/core/check.h>
#include "crypto_v1.h"
#include "crypto_v2.h"
#include "crypto_v3.h"
#include "constants.h"

bool totp_crypto_check_key_slot(uint8_t key_slot) {
Expand Down Expand Up @@ -31,6 +32,11 @@ uint8_t* totp_crypto_encrypt(
plain_data, plain_data_length, crypto_settings, encrypted_data_length);
}

if(crypto_settings->crypto_version == 3) {
return totp_crypto_encrypt_v3(
plain_data, plain_data_length, crypto_settings, encrypted_data_length);
}

furi_crash("Unsupported crypto version");
}

Expand All @@ -49,6 +55,11 @@ uint8_t* totp_crypto_decrypt(
encrypted_data, encrypted_data_length, crypto_settings, decrypted_data_length);
}

if(crypto_settings->crypto_version == 3) {
return totp_crypto_decrypt_v3(
encrypted_data, encrypted_data_length, crypto_settings, decrypted_data_length);
}

furi_crash("Unsupported crypto version");
}

Expand All @@ -62,6 +73,10 @@ CryptoSeedIVResult
return totp_crypto_seed_iv_v2(crypto_settings, pin, pin_length);
}

if(crypto_settings->crypto_version == 3) {
return totp_crypto_seed_iv_v3(crypto_settings, pin, pin_length);
}

furi_crash("Unsupported crypto version");
}

Expand All @@ -74,5 +89,9 @@ bool totp_crypto_verify_key(const CryptoSettings* crypto_settings) {
return totp_crypto_verify_key_v2(crypto_settings);
}

if(crypto_settings->crypto_version == 3) {
return totp_crypto_verify_key_v3(crypto_settings);
}

furi_crash("Unsupported crypto version");
}
4 changes: 2 additions & 2 deletions services/crypto/crypto_v1.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ CryptoSeedIVResult totp_crypto_seed_iv_v1(
CryptoSeedIVResult result;
if(crypto_settings->crypto_verify_data == NULL) {
FURI_LOG_I(LOGGING_TAG, "Generating new IV");
furi_hal_random_fill_buf(&crypto_settings->base_iv[0], TOTP_IV_SIZE);
furi_hal_random_fill_buf(&crypto_settings->salt[0], CRYPTO_SALT_LENGTH);
}

memcpy(&crypto_settings->iv[0], &crypto_settings->base_iv[0], TOTP_IV_SIZE);
memcpy(&crypto_settings->iv[0], &crypto_settings->salt[0], TOTP_IV_SIZE);
if(pin != NULL && pin_length > 0) {
uint8_t max_i;
if(pin_length > TOTP_IV_SIZE) {
Expand Down
21 changes: 12 additions & 9 deletions services/crypto/crypto_v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
#include <furi_hal_random.h>
#include <furi_hal_version.h>
#include "../../types/common.h"
#include "../hmac/hmac_sha512.h"
#include "../../wolfssl_config.h"
#include <wolfssl/wolfcrypt/hmac.h>
#include "memset_s.h"
#include "constants.h"

Expand Down Expand Up @@ -102,12 +103,10 @@ CryptoSeedIVResult totp_crypto_seed_iv_v2(
uint8_t pin_length) {
CryptoSeedIVResult result;
if(crypto_settings->crypto_verify_data == NULL) {
FURI_LOG_I(LOGGING_TAG, "Generating new IV");
furi_hal_random_fill_buf(&crypto_settings->base_iv[0], CRYPTO_IV_LENGTH);
FURI_LOG_I(LOGGING_TAG, "Generating new salt");
furi_hal_random_fill_buf(&crypto_settings->salt[0], CRYPTO_SALT_LENGTH);
}

memcpy(&crypto_settings->iv[0], &crypto_settings->base_iv[0], CRYPTO_IV_LENGTH);

const uint8_t* device_uid = get_device_uid();
uint8_t device_uid_length = get_device_uid_length();

Expand All @@ -125,16 +124,20 @@ CryptoSeedIVResult totp_crypto_seed_iv_v2(
memcpy(hmac_key + device_uid_length, pin, pin_length);
}

uint8_t hmac[HMAC_SHA512_RESULT_SIZE] = {0};
int hmac_result_code = hmac_sha512(
hmac_key, hmac_key_length, &crypto_settings->base_iv[0], CRYPTO_IV_LENGTH, &hmac[0]);
uint8_t hmac[WC_SHA512_DIGEST_SIZE] = {0};

Hmac hmac_context;
wc_HmacSetKey(&hmac_context, WC_SHA512, hmac_key, hmac_key_length);
wc_HmacUpdate(&hmac_context, &crypto_settings->salt[0], CRYPTO_SALT_LENGTH);
int hmac_result_code = wc_HmacFinal(&hmac_context, &hmac[0]);
wc_HmacFree(&hmac_context);

memset_s(hmac_key, hmac_key_length, 0, hmac_key_length);
free(hmac_key);

if(hmac_result_code == 0) {
uint8_t offset =
hmac[HMAC_SHA512_RESULT_SIZE - 1] % (HMAC_SHA512_RESULT_SIZE - CRYPTO_IV_LENGTH - 1);
hmac[WC_SHA512_DIGEST_SIZE - 1] % (WC_SHA512_DIGEST_SIZE - CRYPTO_IV_LENGTH - 1);
memcpy(&crypto_settings->iv[0], &hmac[offset], CRYPTO_IV_LENGTH);

result = CryptoSeedIVResultFlagSuccess;
Expand Down
Loading

0 comments on commit 86a90ab

Please sign in to comment.