diff --git a/common.h b/common.h index 9ac0a13c1c..9a40d000f7 100644 --- a/common.h +++ b/common.h @@ -23,16 +23,6 @@ #include #include "secbool.h" -#define XSTR(s) STR(s) -#define STR(s) #s - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif -#ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif - void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func); void __attribute__((noreturn)) error_shutdown(const char *line1, const char *line2, const char *line3, const char *line4); diff --git a/firmware/config.c b/firmware/config.c index 0ba7ab7816..aeda096afb 100644 --- a/firmware/config.c +++ b/firmware/config.c @@ -23,6 +23,7 @@ #include "messages.pb.h" +#include "common.h" #include "trezor.h" #include "sha2.h" #include "aes/aes.h" @@ -147,12 +148,17 @@ static bool config_set_bool(uint16_t key, bool value) } } -static bool config_get_bool(uint16_t key) +static bool config_get_bool(uint16_t key, bool *value) { - uint8_t value = 0; + uint8_t val = 0; uint16_t len = 0; - secbool ret = storage_get(key, &value, sizeof(value), &len); - return (sectrue == ret && len == 1 && value == TRUE_BYTE); + if (sectrue == storage_get(key, &val, sizeof(val), &len) && len == sizeof(TRUE_BYTE)) { + *value = (val == TRUE_BYTE); + return true; + } else { + *value = false; + return false; + } } static bool config_has_key(uint16_t key) @@ -161,7 +167,8 @@ static bool config_has_key(uint16_t key) return sectrue == storage_get(key, NULL, 0, &len); } -static bool config_get_string(uint16_t key, char *dest, uint16_t dest_size) { +static bool config_get_string(uint16_t key, char *dest, uint16_t dest_size) +{ dest[0] = '\0'; uint16_t len = 0; if (sectrue != storage_get(key, dest, dest_size - 1, &len)) { @@ -171,19 +178,14 @@ static bool config_get_string(uint16_t key, char *dest, uint16_t dest_size) { return true; } -static uint32_t config_get_uint32(uint16_t key) { - uint32_t value = 0; - uint16_t len = 0; - if (sectrue != storage_get(key, &value, sizeof(value), &len) || len != sizeof(value)) { - return 0; - } - return value; -} - -void config_show_error(void) +static bool config_get_uint32(uint16_t key, uint32_t *value) { - layoutDialog(&bmp_icon_error, NULL, NULL, NULL, _("Storage failure"), _("detected."), NULL, _("Please unplug"), _("the device."), NULL); - shutdown(); + uint16_t len = 0; + if (sectrue != storage_get(key, value, sizeof(uint32_t), &len) || len != sizeof(uint32_t)) { + *value = 0; + return false; + } + return true; } static bool config_upgrade_v10(void) @@ -494,9 +496,9 @@ void config_setPassphraseProtection(bool passphrase_protection) config_set_bool(KEY_PASSPHRASE_PROTECTION, passphrase_protection); } -bool config_hasPassphraseProtection(void) +bool config_getPassphraseProtection(bool *passphrase_protection) { - return config_get_bool(KEY_PASSPHRASE_PROTECTION); + return config_get_bool(KEY_PASSPHRASE_PROTECTION, passphrase_protection); } void config_setHomescreen(const uint8_t *data, uint32_t size) @@ -530,11 +532,13 @@ const uint8_t *config_getSeed(bool usePassphrase) return NULL; } // if storage was not imported (i.e. it was properly generated or recovered) - if (!config_get_bool(KEY_IMPORTED)) { + bool imported = false; + config_get_bool(KEY_IMPORTED, &imported); + if (!imported) { // test whether mnemonic is a valid BIP-0039 mnemonic if (!mnemonic_check(mnemonic)) { // and if not then halt the device - config_show_error(); + error_shutdown(_("Storage failure"), _("detected."), NULL, NULL); } } char oldTiny = usbTiny(1); @@ -580,7 +584,9 @@ bool config_getRootNode(HDNode *node, const char *curve, bool usePassphrase) memzero(&storageHDNode, sizeof(storageHDNode)); return false; } - if (config_hasPassphraseProtection() && sessionPassphraseCached && sessionPassphrase[0] != '\0') { + bool passphrase_protection = false; + config_getPassphraseProtection(&passphrase_protection); + if (passphrase_protection && sessionPassphraseCached && sessionPassphrase[0] != '\0') { // decrypt hd node uint8_t secret[64]; PBKDF2_HMAC_SHA512_CTX pctx; @@ -770,12 +776,14 @@ bool session_isPinCached(void) bool config_isInitialized(void) { - return config_get_bool(KEY_INITIALIZED); + bool initialized = false; + config_get_bool(KEY_INITIALIZED, &initialized); + return initialized; } -bool config_isImported(void) +bool config_getImported(bool* imported) { - return config_get_bool(KEY_IMPORTED); + return config_get_bool(KEY_IMPORTED, imported); } void config_setImported(bool imported) @@ -783,9 +791,9 @@ void config_setImported(bool imported) config_set_bool(KEY_IMPORTED, imported); } -bool config_needsBackup(void) +bool config_getNeedsBackup(bool *needs_backup) { - return config_get_bool(KEY_NEEDS_BACKUP); + return config_get_bool(KEY_NEEDS_BACKUP, needs_backup); } void config_setNeedsBackup(bool needs_backup) @@ -793,9 +801,9 @@ void config_setNeedsBackup(bool needs_backup) config_set_bool(KEY_NEEDS_BACKUP, needs_backup); } -bool config_unfinishedBackup(void) +bool config_getUnfinishedBackup(bool *unfinished_backup) { - return config_get_bool(KEY_UNFINISHED_BACKUP); + return config_get_bool(KEY_UNFINISHED_BACKUP, unfinished_backup); } void config_setUnfinishedBackup(bool unfinished_backup) @@ -803,9 +811,9 @@ void config_setUnfinishedBackup(bool unfinished_backup) config_set_bool(KEY_UNFINISHED_BACKUP, unfinished_backup); } -bool config_noBackup(void) +bool config_getNoBackup(bool *no_backup) { - return config_get_bool(KEY_NO_BACKUP); + return config_get_bool(KEY_NO_BACKUP, no_backup); } void config_setNoBackup(void) @@ -815,7 +823,8 @@ void config_setNoBackup(void) void config_applyFlags(uint32_t flags) { - uint32_t old_flags = config_get_uint32(KEY_FLAGS); + uint32_t old_flags = 0; + config_get_uint32(KEY_FLAGS, &old_flags); flags |= old_flags; if (flags == old_flags) { return; // no new flags @@ -823,9 +832,9 @@ void config_applyFlags(uint32_t flags) storage_set(KEY_FLAGS, &flags, sizeof(flags)); } -uint32_t config_getFlags(void) +bool config_getFlags(uint32_t *flags) { - return config_get_uint32(KEY_FLAGS); + return config_get_uint32(KEY_FLAGS, flags); } uint32_t config_nextU2FCounter(void) @@ -847,8 +856,11 @@ void config_setU2FCounter(uint32_t u2fcounter) uint32_t config_getAutoLockDelayMs() { const uint32_t default_delay_ms = 10 * 60 * 1000U; // 10 minutes - uint32_t delay_ms = config_get_uint32(KEY_AUTO_LOCK_DELAY_MS); - return (delay_ms != 0) ? delay_ms : default_delay_ms; + uint32_t delay_ms = 0; + if (config_get_uint32(KEY_AUTO_LOCK_DELAY_MS, &delay_ms)) { + return delay_ms; + } + return default_delay_ms; } void config_setAutoLockDelayMs(uint32_t auto_lock_delay_ms) diff --git a/firmware/config.h b/firmware/config.h index a44b6f29f3..b015ca78f9 100644 --- a/firmware/config.h +++ b/firmware/config.h @@ -102,7 +102,7 @@ bool config_getLanguage(char *dest, uint16_t dest_size); void config_setLanguage(const char *lang); void config_setPassphraseProtection(bool passphrase_protection); -bool config_hasPassphraseProtection(void); +bool config_getPassphraseProtection(bool *passphrase_protection); bool config_getHomescreen(uint8_t *dest, uint16_t dest_size); void config_setHomescreen(const uint8_t *data, uint32_t size); @@ -132,20 +132,20 @@ void config_setU2FCounter(uint32_t u2fcounter); bool config_isInitialized(void); -bool config_isImported(void); +bool config_getImported(bool *imported); void config_setImported(bool imported); -bool config_needsBackup(void); +bool config_getNeedsBackup(bool *needs_backup); void config_setNeedsBackup(bool needs_backup); -bool config_unfinishedBackup(void); +bool config_getUnfinishedBackup(bool *unfinished_backup); void config_setUnfinishedBackup(bool unfinished_backup); -bool config_noBackup(void); +bool config_getNoBackup(bool *no_backup); void config_setNoBackup(void); void config_applyFlags(uint32_t flags); -uint32_t config_getFlags(void); +bool config_getFlags(uint32_t *flags); uint32_t config_getAutoLockDelayMs(void); void config_setAutoLockDelayMs(uint32_t auto_lock_delay_ms); diff --git a/firmware/fsm_msg_common.h b/firmware/fsm_msg_common.h index 93e2d8abcd..aa906423f7 100644 --- a/firmware/fsm_msg_common.h +++ b/firmware/fsm_msg_common.h @@ -47,29 +47,23 @@ void fsm_msgGetFeatures(const GetFeatures *msg) resp->has_patch_version = true; resp->patch_version = VERSION_PATCH; resp->has_device_id = true; strlcpy(resp->device_id, config_uuid_str, sizeof(resp->device_id)); resp->has_pin_protection = true; resp->pin_protection = config_hasPin(); - resp->has_passphrase_protection = true; resp->passphrase_protection = config_hasPassphraseProtection(); + resp->has_passphrase_protection = config_getPassphraseProtection(&(resp->passphrase_protection)); #ifdef SCM_REVISION int len = sizeof(SCM_REVISION) - 1; resp->has_revision = true; memcpy(resp->revision.bytes, SCM_REVISION, len); resp->revision.size = len; #endif resp->has_bootloader_hash = true; resp->bootloader_hash.size = memory_bootloader_hash(resp->bootloader_hash.bytes); - if (config_getLanguage(resp->language, sizeof(resp->language))) { - resp->has_language = true; - } - - if (config_getLabel(resp->label, sizeof(resp->label))) { - resp->has_label = true; - } - + resp->has_language = config_getLanguage(resp->language, sizeof(resp->language)); + resp->has_label = config_getLabel(resp->label, sizeof(resp->label)); resp->has_initialized = true; resp->initialized = config_isInitialized(); - resp->has_imported = config_hasKey(KEY_IMPORTED); resp->imported = config_isImported(); + resp->has_imported = config_getImported(&(resp->imported)); resp->has_pin_cached = true; resp->pin_cached = session_isPinCached(); resp->has_passphrase_cached = true; resp->passphrase_cached = session_isPassphraseCached(); - resp->has_needs_backup = true; resp->needs_backup = config_needsBackup(); - resp->has_unfinished_backup = true; resp->unfinished_backup = config_unfinishedBackup(); - resp->has_no_backup = true; resp->no_backup = config_noBackup(); - resp->has_flags = true; resp->flags = config_getFlags(); + resp->has_needs_backup = config_getNeedsBackup(&(resp->needs_backup)); + resp->has_unfinished_backup = config_getUnfinishedBackup(&(resp->unfinished_backup)); + resp->has_no_backup = config_getNoBackup(&(resp->no_backup)); + resp->has_flags = config_getFlags(&(resp->flags)); resp->has_model = true; strlcpy(resp->model, "1", sizeof(resp->model)); msg_write(MessageType_MessageType_Features, resp); diff --git a/firmware/fsm_msg_debug.h b/firmware/fsm_msg_debug.h index 307066a3d0..0ef38279f6 100644 --- a/firmware/fsm_msg_debug.h +++ b/firmware/fsm_msg_debug.h @@ -52,18 +52,14 @@ void fsm_msgDebugLinkGetState(const DebugLinkGetState *msg) resp.has_recovery_word_pos = true; resp.recovery_word_pos = recovery_get_word_pos(); - if (config_hasMnemonic()) { - resp.has_mnemonic = true; - config_getMnemonic(resp.mnemonic, sizeof(resp.mnemonic)); - } + resp.has_mnemonic = config_getMnemonic(resp.mnemonic, sizeof(resp.mnemonic)); if (config_hasNode()) { resp.has_node = true; config_dumpNode(&(resp.node)); } - resp.has_passphrase_protection = true; - resp.passphrase_protection = config_hasPassphraseProtection(); + resp.has_passphrase_protection = config_getPassphraseProtection(&(resp.passphrase_protection)); msg_debug_write(MessageType_MessageType_DebugLinkState, &resp); } diff --git a/firmware/layout2.c b/firmware/layout2.c index 98474de615..36e02829f5 100644 --- a/firmware/layout2.c +++ b/firmware/layout2.c @@ -256,15 +256,20 @@ void layoutHome(void) oledDrawBitmap(40, 0, &bmp_logo64); } } - if (config_noBackup()) { + + bool no_backup = false; + bool unfinished_backup = false; + bool needs_backup = false; + config_getNoBackup(&no_backup); + config_getUnfinishedBackup(&unfinished_backup); + config_getNeedsBackup(&needs_backup); + if (no_backup) { oledBox(0, 0, 127, 8, false); oledDrawStringCenter(OLED_WIDTH / 2, 0, "SEEDLESS", FONT_STANDARD); - } else - if (config_unfinishedBackup()) { + } else if (unfinished_backup) { oledBox(0, 0, 127, 8, false); oledDrawStringCenter(OLED_WIDTH / 2, 0, "BACKUP FAILED!", FONT_STANDARD); - } else - if (config_needsBackup()) { + } else if (needs_backup) { oledBox(0, 0, 127, 8, false); oledDrawStringCenter(OLED_WIDTH / 2, 0, "NEEDS BACKUP!", FONT_STANDARD); } diff --git a/firmware/protect.c b/firmware/protect.c index e322c3fe6d..f048eb45a5 100644 --- a/firmware/protect.c +++ b/firmware/protect.c @@ -259,7 +259,9 @@ bool protectChangePin(bool removal) bool protectPassphrase(void) { - if (!config_hasPassphraseProtection() || session_isPassphraseCached()) { + bool passphrase_protection = false; + config_getPassphraseProtection(&passphrase_protection); + if (!passphrase_protection || session_isPassphraseCached()) { return true; } diff --git a/firmware/reset.c b/firmware/reset.c index 58479ab2ee..8fa650c443 100644 --- a/firmware/reset.c +++ b/firmware/reset.c @@ -130,12 +130,14 @@ static char current_word[10]; // separated == true if called as a separate workflow via BackupMessage void reset_backup(bool separated, const char* mnemonic) { - if (separated && !config_needsBackup()) { - fsm_sendFailure(FailureType_Failure_UnexpectedMessage, _("Seed already backed up")); - return; - } - if (separated) { + bool needs_backup = false; + config_getNeedsBackup(&needs_backup); + if (!needs_backup) { + fsm_sendFailure(FailureType_Failure_UnexpectedMessage, _("Seed already backed up")); + return; + } + config_setUnfinishedBackup(true); config_setNeedsBackup(false); } diff --git a/norcow_config.h b/norcow_config.h index ba57dfb4b2..d78f0749e5 100644 --- a/norcow_config.h +++ b/norcow_config.h @@ -29,7 +29,7 @@ /* * The length of the sector header in bytes. The header is preserved between sector erasures. */ -#define NORCOW_HEADER_LEN (0x100) +#define NORCOW_HEADER_LEN (0x000) /* * Current storage version. diff --git a/vendor/trezor-storage b/vendor/trezor-storage index 4429888b93..0497802014 160000 --- a/vendor/trezor-storage +++ b/vendor/trezor-storage @@ -1 +1 @@ -Subproject commit 4429888b9325d200b699a90f7a0e1a07d08f09c0 +Subproject commit 0497802014edf03cdcce8cb70889d5a6e0bd3361