mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-24 07:18:09 +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.
|
||||
* 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);
|
||||
|
@ -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);
|
||||
|
@ -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"));
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user