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:
parent
b5d6aaf77c
commit
48fe192103
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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"));
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user