1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-29 19:08:12 +00:00

legacy: clear up passphrase usage

This commit is contained in:
Tomas Susanka 2020-01-20 14:00:07 +00:00 committed by Pavol Rusnak
parent b5d6aaf77c
commit 48fe192103
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
7 changed files with 26 additions and 82 deletions

View File

@ -119,15 +119,12 @@ be added to the storage u2f_counter to get the real counter value.
* storage.u2f_counter + config_u2f_offset. * storage.u2f_counter + config_u2f_offset.
* This corresponds to the number of cleared bits in the U2FAREA. * 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 uint8_t CONFIDENTIAL sessionSeed[64];
static secbool sessionIdCached; static secbool sessionIdCached;
static uint8_t sessionId[32]; static uint8_t sessionId[32];
static secbool sessionPassphraseCached = secfalse;
static char CONFIDENTIAL sessionPassphrase[51];
#define autoLockDelayMsDefault (10 * 60 * 1000U) // 10 minutes #define autoLockDelayMsDefault (10 * 60 * 1000U) // 10 minutes
static secbool autoLockDelayMsCached = secfalse; static secbool autoLockDelayMsCached = secfalse;
static uint32_t autoLockDelayMs = autoLockDelayMsDefault; static uint32_t autoLockDelayMs = autoLockDelayMsDefault;
@ -410,8 +407,6 @@ void config_init(void) {
void session_clear(bool lock) { void session_clear(bool lock) {
sessionSeedCached = secfalse; sessionSeedCached = secfalse;
memzero(&sessionSeed, sizeof(sessionSeed)); memzero(&sessionSeed, sizeof(sessionSeed));
sessionPassphraseCached = secfalse;
memzero(&sessionPassphrase, sizeof(sessionPassphrase));
sessionIdCached = secfalse; sessionIdCached = secfalse;
memzero(&sessionId, sizeof(sessionId)); memzero(&sessionId, sizeof(sessionId));
if (lock) { if (lock) {
@ -553,19 +548,19 @@ static void get_root_node_callback(uint32_t iter, uint32_t total) {
layoutProgress(_("Waking up"), 1000 * iter / 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 // root node is properly cached
// TODO: investigate if (sectrue == sessionSeedCached) {
if (usePassphrase == (sectrue == sessionSeedUsesPassphrase) &&
sectrue == sessionSeedCached) {
return sessionSeed; return sessionSeed;
} }
// if storage has mnemonic, convert it to node and use it // if storage has mnemonic, convert it to node and use it
char mnemonic[MAX_MNEMONIC_LEN + 1] = {0}; char mnemonic[MAX_MNEMONIC_LEN + 1] = {0};
if (config_getMnemonic(mnemonic, sizeof(mnemonic))) { if (config_getMnemonic(mnemonic, sizeof(mnemonic))) {
if (usePassphrase && !protectPassphrase()) { char passphrase[51];
if (!protectPassphrase(passphrase)) {
memzero(mnemonic, sizeof(mnemonic)); memzero(mnemonic, sizeof(mnemonic));
memzero(passphrase, sizeof(passphrase));
return NULL; return NULL;
} }
// if storage was not imported (i.e. it was properly generated or recovered) // 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); char oldTiny = usbTiny(1);
mnemonic_to_seed(mnemonic, usePassphrase ? sessionPassphrase : "", mnemonic_to_seed(mnemonic, passphrase, sessionSeed,
sessionSeed, get_root_node_callback); // BIP-0039 get_root_node_callback); // BIP-0039
memzero(mnemonic, sizeof(mnemonic)); memzero(mnemonic, sizeof(mnemonic));
memzero(passphrase, sizeof(passphrase));
usbTiny(oldTiny); usbTiny(oldTiny);
sessionSeedCached = sectrue; sessionSeedCached = sectrue;
sessionSeedUsesPassphrase = usePassphrase ? sectrue : secfalse;
return sessionSeed; return sessionSeed;
} }
@ -610,53 +605,8 @@ bool config_getU2FRoot(HDNode *node) {
return ret; return ret;
} }
bool config_getRootNode(HDNode *node, const char *curve, bool usePassphrase) { bool config_getRootNode(HDNode *node, const char *curve) {
// if storage has node, decrypt and use it const uint8_t *seed = config_getSeed();
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);
if (seed == NULL) { if (seed == NULL) {
return false; return false;
} }
@ -815,15 +765,6 @@ bool config_changeWipeCode(const char *pin, const char *wipe_code) {
return sectrue == ret; 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) { const uint8_t *session_getSessionId(void) {
if (!sessionIdCached) { if (!sessionIdCached) {
random_buffer(sessionId, 32); random_buffer(sessionId, 32);

View File

@ -91,10 +91,10 @@ void session_clear(bool lock);
void config_loadDevice(const LoadDevice *msg); 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_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); bool config_getLabel(char *dest, uint16_t dest_size);
void config_setLabel(const char *label); void config_setLabel(const char *label);

View File

@ -212,7 +212,7 @@ static HDNode *fsm_getDerivedNode(const char *curve, const uint32_t *address_n,
if (fingerprint) { if (fingerprint) {
*fingerprint = 0; *fingerprint = 0;
} }
if (!config_getRootNode(&node, curve, true)) { if (!config_getRootNode(&node, curve)) {
fsm_sendFailure(FailureType_Failure_NotInitialized, fsm_sendFailure(FailureType_Failure_NotInitialized,
_("Device not initialized or passphrase request cancelled " _("Device not initialized or passphrase request cancelled "
"or unsupported curve")); "or unsupported curve"));

View File

@ -73,8 +73,8 @@ void fsm_msgGetFeatures(const GetFeatures *msg) {
resp->has_imported = config_getImported(&(resp->imported)); resp->has_imported = config_getImported(&(resp->imported));
resp->has_pin_cached = true; resp->has_pin_cached = true;
resp->pin_cached = session_isUnlocked() && config_hasPin(); resp->pin_cached = session_isUnlocked() && config_hasPin();
resp->has_passphrase_cached = true; // resp->has_passphrase_cached = true;
resp->passphrase_cached = session_isPassphraseCached(); // resp->passphrase_cached = session_isPassphraseCached();
resp->has_needs_backup = true; resp->has_needs_backup = true;
config_getNeedsBackup(&(resp->needs_backup)); config_getNeedsBackup(&(resp->needs_backup));
resp->has_unfinished_backup = true; resp->has_unfinished_backup = true;
@ -127,10 +127,12 @@ void fsm_msgPing(const Ping *msg) {
} }
if (msg->has_passphrase_protection && msg->passphrase_protection) { if (msg->has_passphrase_protection && msg->passphrase_protection) {
if (!protectPassphrase()) { char dummy[51];
if (!protectPassphrase(dummy)) {
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
return; return;
} }
memzero(&dummy, sizeof(dummy));
} }
if (msg->has_message) { if (msg->has_message) {

View File

@ -350,11 +350,11 @@ bool protectChangeWipeCode(bool removal) {
return ret; return ret;
} }
bool protectPassphrase(void) { bool protectPassphrase(char *passphrase) {
bool passphrase_protection = false; bool passphrase_protection = false;
config_getPassphraseProtection(&passphrase_protection); config_getPassphraseProtection(&passphrase_protection);
if (!passphrase_protection || session_isPassphraseCached()) { if (!passphrase_protection) {
session_cachePassphrase(""); passphrase[0] = '\0';
return true; return true;
} }
@ -387,7 +387,8 @@ bool protectPassphrase(void) {
result = false; result = false;
break; 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; result = true;
break; break;
} }

View File

@ -30,7 +30,7 @@ secbool protectPinUiCallback(uint32_t wait, uint32_t progress,
bool protectPin(bool use_cached); bool protectPin(bool use_cached);
bool protectChangePin(bool removal); bool protectChangePin(bool removal);
bool protectChangeWipeCode(bool removal); bool protectChangeWipeCode(bool removal);
bool protectPassphrase(void); bool protectPassphrase(char* passphrase);
extern bool protectAbortedByCancel; extern bool protectAbortedByCancel;
extern bool protectAbortedByInitialize; extern bool protectAbortedByInitialize;

View File

@ -1460,7 +1460,7 @@ const HDNode *stellar_deriveNode(const uint32_t *address_n,
const char *curve = "ed25519"; const char *curve = "ed25519";
// Device not initialized, passphrase request cancelled, or unsupported curve // Device not initialized, passphrase request cancelled, or unsupported curve
if (!config_getRootNode(&node, curve, true)) { if (!config_getRootNode(&node, curve)) {
return 0; return 0;
} }
// Failed to derive private key // Failed to derive private key