1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-03 12:00:59 +00:00

Reorder storage keys in config.c to correspond with trezor-core and add KEY_INITIALIZED. Add CHECK_PIN to fsm_msgApplyFlags() and to other fsm_msg functions in order to unlock storage. Improve error handling in reset.c and recovery.c.

This commit is contained in:
andrew 2019-02-05 20:40:58 +01:00 committed by Pavol Rusnak
parent 247337c63d
commit e49e84ea5a
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
6 changed files with 77 additions and 41 deletions

View File

@ -53,20 +53,21 @@ static const uint32_t CONFIG_MAGIC_V10 = 0x726f7473; // 'stor' as uint32_t
static const uint16_t KEY_UUID = 0 | APP | FLAG_PUBLIC; // bytes(12) static const uint16_t KEY_UUID = 0 | APP | FLAG_PUBLIC; // bytes(12)
static const uint16_t KEY_VERSION = 1 | APP; // uint32 static const uint16_t KEY_VERSION = 1 | APP; // uint32
static const uint16_t KEY_NODE = 2 | APP; // node static const uint16_t KEY_MNEMONIC = 2 | APP; // string(241)
static const uint16_t KEY_MNEMONIC = 3 | APP; // string(241) static const uint16_t KEY_LANGUAGE = 3 | APP | FLAG_PUBLIC; // string(17)
static const uint16_t KEY_PASSPHRASE_PROTECTION = 4 | APP; // bool static const uint16_t KEY_LABEL = 4 | APP | FLAG_PUBLIC; // string(33)
static const uint16_t KEY_LANGUAGE = 5 | APP | FLAG_PUBLIC; // string(17) static const uint16_t KEY_PASSPHRASE_PROTECTION = 5 | APP; // bool
static const uint16_t KEY_LABEL = 6 | APP | FLAG_PUBLIC; // string(33) static const uint16_t KEY_HOMESCREEN = 6 | APP | FLAG_PUBLIC; // bytes(1024)
static const uint16_t KEY_IMPORTED = 7 | APP; // bool static const uint16_t KEY_NEEDS_BACKUP = 7 | APP; // bool
static const uint16_t KEY_HOMESCREEN = 8 | APP | FLAG_PUBLIC; // bytes(1024) static const uint16_t KEY_FLAGS = 8 | APP; // uint32
static const uint16_t KEY_U2F_COUNTER = 9 | APP | FLAG_PUBLIC; // uint32 static const uint16_t KEY_U2F_COUNTER = 9 | APP | FLAG_PUBLIC; // uint32
static const uint16_t KEY_NEEDS_BACKUP = 10 | APP; // bool static const uint16_t KEY_UNFINISHED_BACKUP = 11 | APP; // bool
static const uint16_t KEY_FLAGS = 11 | APP; // uint32 static const uint16_t KEY_AUTO_LOCK_DELAY_MS = 12 | APP; // uint32
static const uint16_t KEY_U2F_ROOT = 12 | APP; // node static const uint16_t KEY_NO_BACKUP = 13 | APP; // bool
static const uint16_t KEY_UNFINISHED_BACKUP = 13 | APP; // bool static const uint16_t KEY_INITIALIZED = 14 | APP | FLAG_PUBLIC; // uint32
static const uint16_t KEY_AUTO_LOCK_DELAY_MS = 14 | APP; // uint32 static const uint16_t KEY_NODE = 15 | APP; // node
static const uint16_t KEY_NO_BACKUP = 15 | APP; // bool static const uint16_t KEY_IMPORTED = 16 | APP; // bool
static const uint16_t KEY_U2F_ROOT = 17 | APP | FLAG_PUBLIC; // node
// The PIN value corresponding to an empty PIN. // The PIN value corresponding to an empty PIN.
static const uint32_t PIN_EMPTY = 1; static const uint32_t PIN_EMPTY = 1;
@ -290,7 +291,9 @@ static bool config_upgrade_v10(void)
storage_set(KEY_UUID, config_uuid, sizeof(config_uuid)); storage_set(KEY_UUID, config_uuid, sizeof(config_uuid));
storage_set(KEY_VERSION, &CONFIG_VERSION, sizeof(CONFIG_VERSION)); storage_set(KEY_VERSION, &CONFIG_VERSION, sizeof(CONFIG_VERSION));
if (config.has_node) { if (config.has_node) {
storage_set(KEY_NODE, &config.node, sizeof(config.node)); if (sectrue == storage_set(KEY_NODE, &config.node, sizeof(config.node))) {
config_set_bool(KEY_INITIALIZED, true);
}
} }
if (config.has_mnemonic) { if (config.has_mnemonic) {
config_setMnemonic(config.mnemonic); config_setMnemonic(config.mnemonic);
@ -402,7 +405,9 @@ static void config_setNode(const HDNodeType *node) {
storageHDNode.private_key.size = 32; storageHDNode.private_key.size = 32;
memcpy(storageHDNode.private_key.bytes, node->private_key.bytes, 32); memcpy(storageHDNode.private_key.bytes, node->private_key.bytes, 32);
} }
storage_set(KEY_NODE, &storageHDNode, sizeof(storageHDNode)); if (sectrue == storage_set(KEY_NODE, &storageHDNode, sizeof(storageHDNode))) {
config_set_bool(KEY_INITIALIZED, true);
}
} }
#if DEBUG_LINK #if DEBUG_LINK
@ -628,21 +633,33 @@ bool config_getHomescreen(uint8_t *dest, uint16_t dest_size)
return true; return true;
} }
void config_setMnemonic(const char *mnemonic) bool config_setMnemonic(const char *mnemonic)
{ {
if (mnemonic == NULL) { if (mnemonic == NULL) {
return; return false;
} }
if (sectrue != storage_set(KEY_MNEMONIC, mnemonic, strnlen(mnemonic, MAX_MNEMONIC_LEN))) { if (sectrue != storage_set(KEY_MNEMONIC, mnemonic, strnlen(mnemonic, MAX_MNEMONIC_LEN))) {
return; return false;
}
if (sectrue != config_set_bool(KEY_INITIALIZED, true)) {
storage_delete(KEY_MNEMONIC);
return false;
} }
StorageHDNode u2fNode; StorageHDNode u2fNode;
memzero(&u2fNode, sizeof(u2fNode)); memzero(&u2fNode, sizeof(u2fNode));
config_compute_u2froot(mnemonic, &u2fNode); config_compute_u2froot(mnemonic, &u2fNode);
storage_set(KEY_U2F_ROOT, &u2fNode, sizeof(u2fNode)); secbool ret = storage_set(KEY_U2F_ROOT, &u2fNode, sizeof(u2fNode));
memzero(&u2fNode, sizeof(u2fNode)); memzero(&u2fNode, sizeof(u2fNode));
if (sectrue != ret) {
storage_delete(KEY_MNEMONIC);
storage_delete(KEY_INITIALIZED);
return false;
}
return true;
} }
bool config_hasNode(void) bool config_hasNode(void)
@ -756,7 +773,7 @@ bool session_isPinCached(void)
bool config_isInitialized(void) bool config_isInitialized(void)
{ {
return config_has_key(KEY_NODE) || config_has_key(KEY_MNEMONIC); return config_get_bool(KEY_INITIALIZED);
} }
bool config_isImported(void) bool config_isImported(void)

View File

@ -111,7 +111,7 @@ void session_cachePassphrase(const char *passphrase);
bool session_isPassphraseCached(void); bool session_isPassphraseCached(void);
bool session_getState(const uint8_t *salt, uint8_t *state, const char *passphrase); bool session_getState(const uint8_t *salt, uint8_t *state, const char *passphrase);
void config_setMnemonic(const char *mnemonic); bool config_setMnemonic(const char *mnemonic);
bool config_containsMnemonic(const char *mnemonic); bool config_containsMnemonic(const char *mnemonic);
bool config_hasMnemonic(void); bool config_hasMnemonic(void);
bool config_getMnemonic(char *dest, uint16_t dest_size); bool config_getMnemonic(char *dest, uint16_t dest_size);

View File

@ -63,7 +63,7 @@ void fsm_msgGetFeatures(const GetFeatures *msg)
} }
resp->has_initialized = true; resp->initialized = config_isInitialized(); resp->has_initialized = true; resp->initialized = config_isInitialized();
resp->has_imported = true; resp->imported = config_isImported(); resp->has_imported = config_hasKey(KEY_IMPORTED); resp->imported = config_isImported();
resp->has_pin_cached = true; resp->pin_cached = session_isPinCached(); resp->has_pin_cached = true; resp->pin_cached = session_isPinCached();
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; resp->needs_backup = config_needsBackup(); resp->has_needs_backup = true; resp->needs_backup = config_needsBackup();
@ -180,6 +180,8 @@ void fsm_msgGetEntropy(const GetEntropy *msg)
void fsm_msgLoadDevice(const LoadDevice *msg) void fsm_msgLoadDevice(const LoadDevice *msg)
{ {
CHECK_PIN
CHECK_NOT_INITIALIZED CHECK_NOT_INITIALIZED
layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("I take the risk"), NULL, _("Loading private seed"), _("is not recommended."), _("Continue only if you"), _("know what you are"), _("doing!"), NULL); layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("I take the risk"), NULL, _("Loading private seed"), _("is not recommended."), _("Continue only if you"), _("know what you are"), _("doing!"), NULL);
@ -204,6 +206,8 @@ void fsm_msgLoadDevice(const LoadDevice *msg)
void fsm_msgResetDevice(const ResetDevice *msg) void fsm_msgResetDevice(const ResetDevice *msg)
{ {
CHECK_PIN
CHECK_NOT_INITIALIZED CHECK_NOT_INITIALIZED
CHECK_PARAM(!msg->has_strength || msg->strength == 128 || msg->strength == 192 || msg->strength == 256, _("Invalid seed strength")); CHECK_PARAM(!msg->has_strength || msg->strength == 128 || msg->strength == 192 || msg->strength == 256, _("Invalid seed strength"));
@ -331,6 +335,8 @@ void fsm_msgApplySettings(const ApplySettings *msg)
void fsm_msgApplyFlags(const ApplyFlags *msg) void fsm_msgApplyFlags(const ApplyFlags *msg)
{ {
CHECK_PIN
if (msg->has_flags) { if (msg->has_flags) {
config_applyFlags(msg->flags); config_applyFlags(msg->flags);
} }
@ -339,10 +345,10 @@ void fsm_msgApplyFlags(const ApplyFlags *msg)
void fsm_msgRecoveryDevice(const RecoveryDevice *msg) void fsm_msgRecoveryDevice(const RecoveryDevice *msg)
{ {
CHECK_PIN
const bool dry_run = msg->has_dry_run ? msg->dry_run : false; const bool dry_run = msg->has_dry_run ? msg->dry_run : false;
if (dry_run) { if (!dry_run) {
CHECK_PIN
} else {
CHECK_NOT_INITIALIZED CHECK_NOT_INITIALIZED
} }

View File

@ -180,17 +180,20 @@ void protectPinUiCallback(uint32_t wait, uint32_t progress)
bool protectPin(bool use_cached) bool protectPin(bool use_cached)
{ {
if (!config_hasPin() || (use_cached && session_isPinCached())) { if (use_cached && session_isPinCached()) {
return true; return true;
} }
// TODO If maximum number of PIN attempts: // TODO If maximum number of PIN attempts:
// error_shutdown("Too many wrong PIN", "attempts. Storage has", "been wiped.", NULL, "Please unplug", "the device."); // error_shutdown("Too many wrong PIN", "attempts. Storage has", "been wiped.", NULL, "Please unplug", "the device.");
const char *pin = requestPin(PinMatrixRequestType_PinMatrixRequestType_Current, _("Please enter current PIN:")); const char *pin = "";
if (!pin) { if (config_hasPin()) {
fsm_sendFailure(FailureType_Failure_PinCancelled, NULL); pin = requestPin(PinMatrixRequestType_PinMatrixRequestType_Current, _("Please enter current PIN:"));
return false; if (!pin) {
fsm_sendFailure(FailureType_Failure_PinCancelled, NULL);
return false;
}
} }
usbTiny(1); usbTiny(1);

View File

@ -164,13 +164,16 @@ static void recovery_done(void) {
// New mnemonic is valid. // New mnemonic is valid.
if (!dry_run) { if (!dry_run) {
// Update mnemonic on config. // Update mnemonic on config.
config_setMnemonic(new_mnemonic); if (config_setMnemonic(new_mnemonic)) {
memzero(new_mnemonic, sizeof(new_mnemonic)); if (!enforce_wordlist) {
if (!enforce_wordlist) { // not enforcing => mark config as imported
// not enforcing => mark config as imported config_setImported(true);
config_setImported(true); }
fsm_sendSuccess(_("Device recovered"));
} else {
fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to store mnemonic"));
} }
fsm_sendSuccess(_("Device recovered")); memzero(new_mnemonic, sizeof(new_mnemonic));
} else { } else {
// Inform the user about new mnemonic correctness (as well as whether it is the same as the current one). // Inform the user about new mnemonic correctness (as well as whether it is the same as the current one).
bool match = (config_isInitialized() && config_containsMnemonic(new_mnemonic)); bool match = (config_isInitialized() && config_containsMnemonic(new_mnemonic));

View File

@ -97,6 +97,8 @@ void reset_entropy(const uint8_t *ext_entropy, uint32_t len)
fsm_sendFailure(FailureType_Failure_UnexpectedMessage, _("Not in Reset mode")); fsm_sendFailure(FailureType_Failure_UnexpectedMessage, _("Not in Reset mode"));
return; return;
} }
awaiting_entropy = false;
SHA256_CTX ctx; SHA256_CTX ctx;
sha256_Init(&ctx); sha256_Init(&ctx);
sha256_Update(&ctx, int_entropy, 32); sha256_Update(&ctx, int_entropy, 32);
@ -104,7 +106,6 @@ void reset_entropy(const uint8_t *ext_entropy, uint32_t len)
sha256_Final(&ctx, int_entropy); sha256_Final(&ctx, int_entropy);
const char* mnemonic = mnemonic_from_data(int_entropy, strength / 8); const char* mnemonic = mnemonic_from_data(int_entropy, strength / 8);
memzero(int_entropy, 32); memzero(int_entropy, 32);
awaiting_entropy = false;
if (skip_backup || no_backup) { if (skip_backup || no_backup) {
if (no_backup) { if (no_backup) {
@ -112,8 +113,11 @@ void reset_entropy(const uint8_t *ext_entropy, uint32_t len)
} else { } else {
config_setNeedsBackup(true); config_setNeedsBackup(true);
} }
config_setMnemonic(mnemonic); if (config_setMnemonic(mnemonic)) {
fsm_sendSuccess(_("Device successfully initialized")); fsm_sendSuccess(_("Device successfully initialized"));
} else {
fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to store mnemonic"));
}
layoutHome(); layoutHome();
} else { } else {
reset_backup(false, mnemonic); reset_backup(false, mnemonic);
@ -169,8 +173,11 @@ void reset_backup(bool separated, const char* mnemonic)
fsm_sendSuccess(_("Seed successfully backed up")); fsm_sendSuccess(_("Seed successfully backed up"));
} else { } else {
config_setNeedsBackup(false); config_setNeedsBackup(false);
config_setMnemonic(mnemonic); if (config_setMnemonic(mnemonic)) {
fsm_sendSuccess(_("Device successfully initialized")); fsm_sendSuccess(_("Device successfully initialized"));
} else {
fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to store mnemonic"));
}
} }
layoutHome(); layoutHome();
} }