From 57bbcc754adde3ca5d01741e97a8f33d652ef5c2 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Tue, 22 Aug 2017 09:17:05 +0200 Subject: [PATCH] storage: make storage accessible only via functions add calls also for debug build and use them in fsm --- firmware/fsm.c | 28 ++++++++++++------------ firmware/protect.c | 4 ++-- firmware/recovery.c | 11 ++++------ firmware/reset.c | 25 ++++++++++----------- firmware/storage.c | 53 +++++++++++++++++++++++++++++++++++++++++++++ firmware/storage.h | 14 ++++++++++-- 6 files changed, 96 insertions(+), 39 deletions(-) diff --git a/firmware/fsm.c b/firmware/fsm.c index e1c6b84c37..b8b183f1f9 100644 --- a/firmware/fsm.c +++ b/firmware/fsm.c @@ -217,20 +217,20 @@ void fsm_msgGetFeatures(GetFeatures *msg) resp->has_minor_version = true; resp->minor_version = VERSION_MINOR; resp->has_patch_version = true; resp->patch_version = VERSION_PATCH; resp->has_device_id = true; strlcpy(resp->device_id, storage_uuid_str, sizeof(resp->device_id)); - resp->has_pin_protection = true; resp->pin_protection = storage.has_pin; - resp->has_passphrase_protection = true; resp->passphrase_protection = storage.has_passphrase_protection && storage.passphrase_protection; + resp->has_pin_protection = true; resp->pin_protection = storage_hasPin(); + resp->has_passphrase_protection = true; resp->passphrase_protection = storage_hasPassphraseProtection(); #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 (storage.has_language) { + if (storage_getLanguage()) { resp->has_language = true; - strlcpy(resp->language, storage.language, sizeof(resp->language)); + strlcpy(resp->language, storage_getLanguage(), sizeof(resp->language)); } - if (storage.has_label) { + if (storage_getLabel()) { resp->has_label = true; - strlcpy(resp->label, storage.label, sizeof(resp->label)); + strlcpy(resp->label, storage_getLabel(), sizeof(resp->label)); } _Static_assert(pb_arraysize(Features, coins) >= COINS_COUNT, "Features.coins max_count not large enough"); @@ -262,7 +262,7 @@ void fsm_msgGetFeatures(GetFeatures *msg) resp->coins[i].force_bip143 = coins[i].force_bip143; } resp->has_initialized = true; resp->initialized = storage_isInitialized(); - resp->has_imported = true; resp->imported = storage.has_imported && storage.imported; + resp->has_imported = true; resp->imported = storage_isImported(); 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 = storage_needsBackup(); @@ -1520,9 +1520,9 @@ void fsm_msgDebugLinkGetState(DebugLinkGetState *msg) resp.layout.size = OLED_BUFSIZE; memcpy(resp.layout.bytes, oledGetBuffer(), OLED_BUFSIZE); - if (storage.has_pin) { + if (storage_hasPin()) { resp.has_pin = true; - strlcpy(resp.pin, storage.pin, sizeof(resp.pin)); + strlcpy(resp.pin, storage_getPin(), sizeof(resp.pin)); } resp.has_matrix = true; @@ -1540,18 +1540,18 @@ void fsm_msgDebugLinkGetState(DebugLinkGetState *msg) resp.has_recovery_word_pos = true; resp.recovery_word_pos = recovery_get_word_pos(); - if (storage.has_mnemonic) { + if (storage_hasMnemonic()) { resp.has_mnemonic = true; - strlcpy(resp.mnemonic, storage.mnemonic, sizeof(resp.mnemonic)); + strlcpy(resp.mnemonic, storage_getMnemonic(), sizeof(resp.mnemonic)); } - if (storage.has_node) { + if (storage_hasNode()) { resp.has_node = true; - memcpy(&(resp.node), &(storage.node), sizeof(HDNode)); + memcpy(&(resp.node), storage_getNode(), sizeof(HDNode)); } resp.has_passphrase_protection = true; - resp.passphrase_protection = storage.has_passphrase_protection && storage.passphrase_protection; + resp.passphrase_protection = storage_hasPassphraseProtection(); msg_debug_write(MessageType_MessageType_DebugLinkState, &resp); } diff --git a/firmware/protect.c b/firmware/protect.c index f270d08351..74f5468363 100644 --- a/firmware/protect.c +++ b/firmware/protect.c @@ -155,7 +155,7 @@ static void protectCheckMaxTry(uint32_t wait) { bool protectPin(bool use_cached) { - if (!storage.has_pin || storage.pin[0] == 0 || (use_cached && session_isPinCached())) { + if (!storage_hasPin() || (use_cached && session_isPinCached())) { return true; } uint32_t *fails = storage_getPinFailsPtr(); @@ -237,7 +237,7 @@ bool protectChangePin(void) bool protectPassphrase(void) { - if (!storage.has_passphrase_protection || !storage.passphrase_protection || session_isPassphraseCached()) { + if (!storage_hasPassphraseProtection() || session_isPassphraseCached()) { return true; } diff --git a/firmware/recovery.c b/firmware/recovery.c index bdc1485dea..9d3c955488 100644 --- a/firmware/recovery.c +++ b/firmware/recovery.c @@ -130,7 +130,7 @@ static void recovery_request(void) { * Check mnemonic and send success/failure. */ static void recovery_done(void) { - char new_mnemonic[sizeof(storage.mnemonic)] = {0}; + char new_mnemonic[241] = {0}; // TODO: remove constant strlcpy(new_mnemonic, words[0], sizeof(new_mnemonic)); for (uint32_t i = 1; i < word_count; i++) { @@ -141,13 +141,11 @@ static void recovery_done(void) { // New mnemonic is valid. if (!dry_run) { // Update mnemonic on storage. - storage.has_mnemonic = true; - strlcpy(storage.mnemonic, new_mnemonic, sizeof(new_mnemonic)); + storage_setMnemonic(new_mnemonic); memset(new_mnemonic, 0, sizeof(new_mnemonic)); if (!enforce_wordlist) { // not enforcing => mark storage as imported - storage.has_imported = true; - storage.imported = true; + storage_setImported(true); } storage_commit(); fsm_sendSuccess(_("Device recovered")); @@ -421,8 +419,7 @@ void recovery_init(uint32_t _word_count, bool passphrase_protection, bool pin_pr return; } - storage.has_passphrase_protection = true; - storage.passphrase_protection = passphrase_protection; + storage_setPassphraseProtection(passphrase_protection); storage_setLanguage(language); storage_setLabel(label); storage_setU2FCounter(u2f_counter); diff --git a/firmware/reset.c b/firmware/reset.c index d4a1570d68..52934772aa 100644 --- a/firmware/reset.c +++ b/firmware/reset.c @@ -65,8 +65,7 @@ void reset_init(bool display_random, uint32_t _strength, bool passphrase_protect return; } - storage.has_passphrase_protection = true; - storage.passphrase_protection = passphrase_protection; + storage_setPassphraseProtection(passphrase_protection); storage_setLanguage(language); storage_setLabel(label); storage_setU2FCounter(u2f_counter); @@ -88,14 +87,11 @@ void reset_entropy(const uint8_t *ext_entropy, uint32_t len) sha256_Update(&ctx, int_entropy, 32); sha256_Update(&ctx, ext_entropy, len); sha256_Final(&ctx, int_entropy); - strlcpy(storage.mnemonic, mnemonic_from_data(int_entropy, strength / 8), sizeof(storage.mnemonic)); + storage_setNeedsBackup(true); + storage_setMnemonic(mnemonic_from_data(int_entropy, strength / 8)); memset(int_entropy, 0, 32); awaiting_entropy = false; - storage.has_mnemonic = true; - storage.has_needs_backup = true; - storage.needs_backup = true; - if (skip_backup) { storage_commit(); fsm_sendSuccess(_("Device successfully initialized")); @@ -116,27 +112,28 @@ void reset_backup(bool separated) return; } - storage.has_needs_backup = true; - storage.needs_backup = false; + storage_setNeedsBackup(false); if (separated) { storage_commit(); } + const char *mnemonic = storage_getMnemonic(); + for (int pass = 0; pass < 2; pass++) { int i = 0, word_pos = 1; - while (storage.mnemonic[i] != 0) { + while (mnemonic[i] != 0) { // copy current_word int j = 0; - while (storage.mnemonic[i] != ' ' && storage.mnemonic[i] != 0 && j + 1 < (int)sizeof(current_word)) { - current_word[j] = storage.mnemonic[i]; + while (mnemonic[i] != ' ' && mnemonic[i] != 0 && j + 1 < (int)sizeof(current_word)) { + current_word[j] = mnemonic[i]; i++; j++; } current_word[j] = 0; - if (storage.mnemonic[i] != 0) { + if (mnemonic[i] != 0) { i++; } - layoutResetWord(current_word, pass, word_pos, storage.mnemonic[i] == 0); + layoutResetWord(current_word, pass, word_pos, mnemonic[i] == 0); if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmWord, true)) { if (!separated) { storage_reset(); diff --git a/firmware/storage.c b/firmware/storage.c index c8f264d4a2..45d704638a 100644 --- a/firmware/storage.c +++ b/firmware/storage.c @@ -343,6 +343,11 @@ void storage_setPassphraseProtection(bool passphrase_protection) storage.passphrase_protection = passphrase_protection; } +bool storage_hasPassphraseProtection(void) +{ + return storage.has_passphrase_protection && storage.passphrase_protection; +} + void storage_setHomescreen(const uint8_t *data, uint32_t size) { if (data && size == 1024) { @@ -446,6 +451,32 @@ const uint8_t *storage_getHomescreen(void) return (storage.has_homescreen && storage.homescreen.size == 1024) ? storage.homescreen.bytes : 0; } +void storage_setMnemonic(const char *mnemonic) +{ + storage.has_mnemonic = true; + strlcpy(storage.mnemonic, mnemonic, sizeof(storage.mnemonic)); +} + +bool storage_hasNode(void) +{ + return storageRom->has_node; +} + +const HDNode *storage_getNode(void) +{ + return storageRom->has_node ? (const HDNode *)&storageRom->node : 0; +} + +bool storage_hasMnemonic(void) +{ + return storageRom->has_mnemonic; +} + +const char *storage_getMnemonic(void) +{ + return storage.has_mnemonic ? storage.mnemonic : 0; +} + /* Check whether mnemonic matches storage. The mnemonic must be * a null-terminated string. */ @@ -498,6 +529,11 @@ void storage_setPin(const char *pin) sessionPinCached = false; } +const char *storage_getPin(void) +{ + return storageRom->has_pin ? storageRom->pin : 0; +} + void session_cachePassphrase(const char *passphrase) { strlcpy(sessionPassphrase, passphrase, sizeof(sessionPassphrase)); @@ -599,11 +635,28 @@ bool storage_isInitialized(void) return storage.has_node || storage.has_mnemonic; } +bool storage_isImported(void) +{ + return storage.has_imported && storage.imported; +} + +void storage_setImported(bool imported) +{ + storage.has_imported = true; + storage.imported = imported; +} + bool storage_needsBackup(void) { return storage.has_needs_backup && storage.needs_backup; } +void storage_setNeedsBackup(bool needs_backup) +{ + storage.has_needs_backup = true; + storage.needs_backup = needs_backup; +} + void storage_applyFlags(uint32_t flags) { if ((storage.flags | flags) == storage.flags) { diff --git a/firmware/storage.h b/firmware/storage.h index 37235a0af3..e6e3a103af 100644 --- a/firmware/storage.h +++ b/firmware/storage.h @@ -44,6 +44,7 @@ const char *storage_getLanguage(void); void storage_setLanguage(const char *lang); void storage_setPassphraseProtection(bool passphrase_protection); +bool storage_hasPassphraseProtection(void); const uint8_t *storage_getHomescreen(void); void storage_setHomescreen(const uint8_t *data, uint32_t size); @@ -51,10 +52,17 @@ void storage_setHomescreen(const uint8_t *data, uint32_t size); void session_cachePassphrase(const char *passphrase); bool session_isPassphraseCached(void); +void storage_setMnemonic(const char *mnemonic); bool storage_containsMnemonic(const char *mnemonic); +bool storage_hasMnemonic(void); +const char *storage_getMnemonic(void); + +bool storage_hasNode(void); +const HDNode *storage_getNode(void); bool storage_containsPin(const char *pin); bool storage_hasPin(void); +const char *storage_getPin(void); void storage_setPin(const char *pin); void session_cachePin(void); bool session_isPinCached(void); @@ -68,15 +76,17 @@ void storage_setU2FCounter(uint32_t u2fcounter); bool storage_isInitialized(void); +bool storage_isImported(void); +void storage_setImported(bool imported); + bool storage_needsBackup(void); +void storage_setNeedsBackup(bool needs_backup); void storage_applyFlags(uint32_t flags); uint32_t storage_getFlags(void); void storage_wipe(void); -extern Storage storage; - extern char storage_uuid_str[25]; #endif