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:
parent
247337c63d
commit
e49e84ea5a
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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));
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user