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.

pull/25/head
andrew 5 years ago committed by Pavol Rusnak
parent 247337c63d
commit e49e84ea5a
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

@ -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_VERSION = 1 | APP; // uint32
static const uint16_t KEY_NODE = 2 | APP; // node
static const uint16_t KEY_MNEMONIC = 3 | APP; // string(241)
static const uint16_t KEY_PASSPHRASE_PROTECTION = 4 | APP; // bool
static const uint16_t KEY_LANGUAGE = 5 | APP | FLAG_PUBLIC; // string(17)
static const uint16_t KEY_LABEL = 6 | APP | FLAG_PUBLIC; // string(33)
static const uint16_t KEY_IMPORTED = 7 | APP; // bool
static const uint16_t KEY_HOMESCREEN = 8 | APP | FLAG_PUBLIC; // bytes(1024)
static const uint16_t KEY_MNEMONIC = 2 | APP; // string(241)
static const uint16_t KEY_LANGUAGE = 3 | APP | FLAG_PUBLIC; // string(17)
static const uint16_t KEY_LABEL = 4 | APP | FLAG_PUBLIC; // string(33)
static const uint16_t KEY_PASSPHRASE_PROTECTION = 5 | APP; // bool
static const uint16_t KEY_HOMESCREEN = 6 | APP | FLAG_PUBLIC; // bytes(1024)
static const uint16_t KEY_NEEDS_BACKUP = 7 | APP; // bool
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_NEEDS_BACKUP = 10 | APP; // bool
static const uint16_t KEY_FLAGS = 11 | APP; // uint32
static const uint16_t KEY_U2F_ROOT = 12 | APP; // node
static const uint16_t KEY_UNFINISHED_BACKUP = 13 | APP; // bool
static const uint16_t KEY_AUTO_LOCK_DELAY_MS = 14 | APP; // uint32
static const uint16_t KEY_NO_BACKUP = 15 | APP; // bool
static const uint16_t KEY_UNFINISHED_BACKUP = 11 | APP; // bool
static const uint16_t KEY_AUTO_LOCK_DELAY_MS = 12 | APP; // uint32
static const uint16_t KEY_NO_BACKUP = 13 | APP; // bool
static const uint16_t KEY_INITIALIZED = 14 | APP | FLAG_PUBLIC; // uint32
static const uint16_t KEY_NODE = 15 | APP; // node
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.
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_VERSION, &CONFIG_VERSION, sizeof(CONFIG_VERSION));
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) {
config_setMnemonic(config.mnemonic);
@ -402,7 +405,9 @@ static void config_setNode(const HDNodeType *node) {
storageHDNode.private_key.size = 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
@ -628,21 +633,33 @@ bool config_getHomescreen(uint8_t *dest, uint16_t dest_size)
return true;
}
void config_setMnemonic(const char *mnemonic)
bool config_setMnemonic(const char *mnemonic)
{
if (mnemonic == NULL) {
return;
return false;
}
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;
memzero(&u2fNode, sizeof(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));
if (sectrue != ret) {
storage_delete(KEY_MNEMONIC);
storage_delete(KEY_INITIALIZED);
return false;
}
return true;
}
bool config_hasNode(void)
@ -756,7 +773,7 @@ bool session_isPinCached(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)

@ -111,7 +111,7 @@ void session_cachePassphrase(const char *passphrase);
bool session_isPassphraseCached(void);
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_hasMnemonic(void);
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_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_passphrase_cached = true; resp->passphrase_cached = session_isPassphraseCached();
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)
{
CHECK_PIN
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);
@ -204,6 +206,8 @@ void fsm_msgLoadDevice(const LoadDevice *msg)
void fsm_msgResetDevice(const ResetDevice *msg)
{
CHECK_PIN
CHECK_NOT_INITIALIZED
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)
{
CHECK_PIN
if (msg->has_flags) {
config_applyFlags(msg->flags);
}
@ -339,10 +345,10 @@ void fsm_msgApplyFlags(const ApplyFlags *msg)
void fsm_msgRecoveryDevice(const RecoveryDevice *msg)
{
CHECK_PIN
const bool dry_run = msg->has_dry_run ? msg->dry_run : false;
if (dry_run) {
CHECK_PIN
} else {
if (!dry_run) {
CHECK_NOT_INITIALIZED
}

@ -180,17 +180,20 @@ void protectPinUiCallback(uint32_t wait, uint32_t progress)
bool protectPin(bool use_cached)
{
if (!config_hasPin() || (use_cached && session_isPinCached())) {
if (use_cached && session_isPinCached()) {
return true;
}
// TODO If maximum number of PIN attempts:
// 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:"));
if (!pin) {
fsm_sendFailure(FailureType_Failure_PinCancelled, NULL);
return false;
const char *pin = "";
if (config_hasPin()) {
pin = requestPin(PinMatrixRequestType_PinMatrixRequestType_Current, _("Please enter current PIN:"));
if (!pin) {
fsm_sendFailure(FailureType_Failure_PinCancelled, NULL);
return false;
}
}
usbTiny(1);

@ -164,13 +164,16 @@ static void recovery_done(void) {
// New mnemonic is valid.
if (!dry_run) {
// Update mnemonic on config.
config_setMnemonic(new_mnemonic);
memzero(new_mnemonic, sizeof(new_mnemonic));
if (!enforce_wordlist) {
// not enforcing => mark config as imported
config_setImported(true);
if (config_setMnemonic(new_mnemonic)) {
if (!enforce_wordlist) {
// not enforcing => mark config as imported
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 {
// 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));

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

Loading…
Cancel
Save