From 48fe19210351e2ac702fd5de92a99e0d4df96fbb Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Mon, 20 Jan 2020 14:00:07 +0000 Subject: [PATCH] legacy: clear up passphrase usage --- legacy/firmware/config.c | 81 +++++--------------------------- legacy/firmware/config.h | 4 +- legacy/firmware/fsm.c | 2 +- legacy/firmware/fsm_msg_common.h | 8 ++-- legacy/firmware/protect.c | 9 ++-- legacy/firmware/protect.h | 2 +- legacy/firmware/stellar.c | 2 +- 7 files changed, 26 insertions(+), 82 deletions(-) diff --git a/legacy/firmware/config.c b/legacy/firmware/config.c index a5173137b3..45900beb5f 100644 --- a/legacy/firmware/config.c +++ b/legacy/firmware/config.c @@ -119,15 +119,12 @@ be added to the storage u2f_counter to get the real counter value. * storage.u2f_counter + config_u2f_offset. * This corresponds to the number of cleared bits in the U2FAREA. */ -static secbool sessionSeedCached, sessionSeedUsesPassphrase; +static secbool sessionSeedCached; static uint8_t CONFIDENTIAL sessionSeed[64]; static secbool sessionIdCached; static uint8_t sessionId[32]; -static secbool sessionPassphraseCached = secfalse; -static char CONFIDENTIAL sessionPassphrase[51]; - #define autoLockDelayMsDefault (10 * 60 * 1000U) // 10 minutes static secbool autoLockDelayMsCached = secfalse; static uint32_t autoLockDelayMs = autoLockDelayMsDefault; @@ -410,8 +407,6 @@ void config_init(void) { void session_clear(bool lock) { sessionSeedCached = secfalse; memzero(&sessionSeed, sizeof(sessionSeed)); - sessionPassphraseCached = secfalse; - memzero(&sessionPassphrase, sizeof(sessionPassphrase)); sessionIdCached = secfalse; memzero(&sessionId, sizeof(sessionId)); if (lock) { @@ -553,19 +548,19 @@ static void get_root_node_callback(uint32_t iter, uint32_t total) { layoutProgress(_("Waking up"), 1000 * iter / total); } -const uint8_t *config_getSeed(bool usePassphrase) { +const uint8_t *config_getSeed(void) { // root node is properly cached - // TODO: investigate - if (usePassphrase == (sectrue == sessionSeedUsesPassphrase) && - sectrue == sessionSeedCached) { + if (sectrue == sessionSeedCached) { return sessionSeed; } // if storage has mnemonic, convert it to node and use it char mnemonic[MAX_MNEMONIC_LEN + 1] = {0}; if (config_getMnemonic(mnemonic, sizeof(mnemonic))) { - if (usePassphrase && !protectPassphrase()) { + char passphrase[51]; + if (!protectPassphrase(passphrase)) { memzero(mnemonic, sizeof(mnemonic)); + memzero(passphrase, sizeof(passphrase)); return NULL; } // if storage was not imported (i.e. it was properly generated or recovered) @@ -579,12 +574,12 @@ const uint8_t *config_getSeed(bool usePassphrase) { } } char oldTiny = usbTiny(1); - mnemonic_to_seed(mnemonic, usePassphrase ? sessionPassphrase : "", - sessionSeed, get_root_node_callback); // BIP-0039 + mnemonic_to_seed(mnemonic, passphrase, sessionSeed, + get_root_node_callback); // BIP-0039 memzero(mnemonic, sizeof(mnemonic)); + memzero(passphrase, sizeof(passphrase)); usbTiny(oldTiny); sessionSeedCached = sectrue; - sessionSeedUsesPassphrase = usePassphrase ? sectrue : secfalse; return sessionSeed; } @@ -610,53 +605,8 @@ bool config_getU2FRoot(HDNode *node) { return ret; } -bool config_getRootNode(HDNode *node, const char *curve, bool usePassphrase) { - // if storage has node, decrypt and use it - StorageHDNode storageHDNode = {0}; - uint16_t len = 0; - if (strcmp(curve, SECP256K1_NAME) == 0 && - sectrue == - storage_get(KEY_NODE, &storageHDNode, sizeof(storageHDNode), &len) && - len == sizeof(StorageHDNode)) { - if (!protectPassphrase()) { - memzero(&storageHDNode, sizeof(storageHDNode)); - return false; - } - if (!config_loadNode(&storageHDNode, curve, node)) { - memzero(&storageHDNode, sizeof(storageHDNode)); - return false; - } - bool passphrase_protection = false; - config_getPassphraseProtection(&passphrase_protection); - if (passphrase_protection && sectrue == sessionPassphraseCached && - sessionPassphrase[0] != '\0') { - // decrypt hd node - uint8_t secret[64] = {0}; - PBKDF2_HMAC_SHA512_CTX pctx = {0}; - char oldTiny = usbTiny(1); - pbkdf2_hmac_sha512_Init(&pctx, (const uint8_t *)sessionPassphrase, - strlen(sessionPassphrase), - (const uint8_t *)"TREZORHD", 8, 1); - get_root_node_callback(0, BIP39_PBKDF2_ROUNDS); - for (int i = 0; i < 8; i++) { - pbkdf2_hmac_sha512_Update(&pctx, BIP39_PBKDF2_ROUNDS / 8); - get_root_node_callback((i + 1) * BIP39_PBKDF2_ROUNDS / 8, - BIP39_PBKDF2_ROUNDS); - } - pbkdf2_hmac_sha512_Final(&pctx, secret); - usbTiny(oldTiny); - aes_decrypt_ctx ctx = {0}; - aes_decrypt_key256(secret, &ctx); - aes_cbc_decrypt(node->chain_code, node->chain_code, 32, secret + 32, - &ctx); - aes_cbc_decrypt(node->private_key, node->private_key, 32, secret + 32, - &ctx); - } - return true; - } - memzero(&storageHDNode, sizeof(storageHDNode)); - - const uint8_t *seed = config_getSeed(usePassphrase); +bool config_getRootNode(HDNode *node, const char *curve) { + const uint8_t *seed = config_getSeed(); if (seed == NULL) { return false; } @@ -815,15 +765,6 @@ bool config_changeWipeCode(const char *pin, const char *wipe_code) { return sectrue == ret; } -void session_cachePassphrase(const char *passphrase) { - strlcpy(sessionPassphrase, passphrase, sizeof(sessionPassphrase)); - sessionPassphraseCached = sectrue; -} - -bool session_isPassphraseCached(void) { - return sectrue == sessionPassphraseCached; -} - const uint8_t *session_getSessionId(void) { if (!sessionIdCached) { random_buffer(sessionId, 32); diff --git a/legacy/firmware/config.h b/legacy/firmware/config.h index b16fce71dc..c43e7c1540 100644 --- a/legacy/firmware/config.h +++ b/legacy/firmware/config.h @@ -91,10 +91,10 @@ void session_clear(bool lock); void config_loadDevice(const LoadDevice *msg); -const uint8_t *config_getSeed(bool usePassphrase); +const uint8_t *config_getSeed(void); bool config_getU2FRoot(HDNode *node); -bool config_getRootNode(HDNode *node, const char *curve, bool usePassphrase); +bool config_getRootNode(HDNode *node, const char *curve); bool config_getLabel(char *dest, uint16_t dest_size); void config_setLabel(const char *label); diff --git a/legacy/firmware/fsm.c b/legacy/firmware/fsm.c index 4c82442b3b..0d12c31f7e 100644 --- a/legacy/firmware/fsm.c +++ b/legacy/firmware/fsm.c @@ -212,7 +212,7 @@ static HDNode *fsm_getDerivedNode(const char *curve, const uint32_t *address_n, if (fingerprint) { *fingerprint = 0; } - if (!config_getRootNode(&node, curve, true)) { + if (!config_getRootNode(&node, curve)) { fsm_sendFailure(FailureType_Failure_NotInitialized, _("Device not initialized or passphrase request cancelled " "or unsupported curve")); diff --git a/legacy/firmware/fsm_msg_common.h b/legacy/firmware/fsm_msg_common.h index 25667ea57b..f9d8bba219 100644 --- a/legacy/firmware/fsm_msg_common.h +++ b/legacy/firmware/fsm_msg_common.h @@ -73,8 +73,8 @@ void fsm_msgGetFeatures(const GetFeatures *msg) { resp->has_imported = config_getImported(&(resp->imported)); resp->has_pin_cached = true; resp->pin_cached = session_isUnlocked() && config_hasPin(); - resp->has_passphrase_cached = true; - resp->passphrase_cached = session_isPassphraseCached(); + // resp->has_passphrase_cached = true; + // resp->passphrase_cached = session_isPassphraseCached(); resp->has_needs_backup = true; config_getNeedsBackup(&(resp->needs_backup)); resp->has_unfinished_backup = true; @@ -127,10 +127,12 @@ void fsm_msgPing(const Ping *msg) { } if (msg->has_passphrase_protection && msg->passphrase_protection) { - if (!protectPassphrase()) { + char dummy[51]; + if (!protectPassphrase(dummy)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); return; } + memzero(&dummy, sizeof(dummy)); } if (msg->has_message) { diff --git a/legacy/firmware/protect.c b/legacy/firmware/protect.c index 810d931be2..fdd8fb9c01 100644 --- a/legacy/firmware/protect.c +++ b/legacy/firmware/protect.c @@ -350,11 +350,11 @@ bool protectChangeWipeCode(bool removal) { return ret; } -bool protectPassphrase(void) { +bool protectPassphrase(char *passphrase) { bool passphrase_protection = false; config_getPassphraseProtection(&passphrase_protection); - if (!passphrase_protection || session_isPassphraseCached()) { - session_cachePassphrase(""); + if (!passphrase_protection) { + passphrase[0] = '\0'; return true; } @@ -387,7 +387,8 @@ bool protectPassphrase(void) { result = false; break; } - session_cachePassphrase(ppa->passphrase); + // TODO: ask - why ppa->passphrase.size is not working? because of tiny? + strlcpy(passphrase, ppa->passphrase, sizeof(ppa->passphrase)); result = true; break; } diff --git a/legacy/firmware/protect.h b/legacy/firmware/protect.h index 4d9af7c6e6..d53d3ae09c 100644 --- a/legacy/firmware/protect.h +++ b/legacy/firmware/protect.h @@ -30,7 +30,7 @@ secbool protectPinUiCallback(uint32_t wait, uint32_t progress, bool protectPin(bool use_cached); bool protectChangePin(bool removal); bool protectChangeWipeCode(bool removal); -bool protectPassphrase(void); +bool protectPassphrase(char* passphrase); extern bool protectAbortedByCancel; extern bool protectAbortedByInitialize; diff --git a/legacy/firmware/stellar.c b/legacy/firmware/stellar.c index ae74982046..e7b081ea4b 100644 --- a/legacy/firmware/stellar.c +++ b/legacy/firmware/stellar.c @@ -1460,7 +1460,7 @@ const HDNode *stellar_deriveNode(const uint32_t *address_n, const char *curve = "ed25519"; // Device not initialized, passphrase request cancelled, or unsupported curve - if (!config_getRootNode(&node, curve, true)) { + if (!config_getRootNode(&node, curve)) { return 0; } // Failed to derive private key