Ejemplo n.º 1
0
void recovery_word(const char *word)
{
	if (!awaiting_word) {
		fsm_sendFailure(FailureType_Failure_UnexpectedMessage, "Not in Recovery mode");
		layoutHome();
		return;
	}

	if (word_pos == 0) { // fake word
		if (strcmp(word, fake_word) != 0) {
			storage_reset();
			fsm_sendFailure(FailureType_Failure_SyntaxError, "Wrong word retyped");
			layoutHome();
			return;
		}
	} else { // real word
		if (enforce_wordlist) { // check if word is valid
			const char * const *wl = mnemonic_wordlist();
			bool found = false;
			while (*wl) {
				if (strcmp(word, *wl) == 0) {
					found = true;
					break;
				}
				wl++;
			}
			if (!found) {
				storage_reset();
				fsm_sendFailure(FailureType_Failure_SyntaxError, "Word not found in a wordlist");
				layoutHome();
				return;
			}
		}
		strlcpy(words[word_pos - 1], word, sizeof(words[word_pos - 1]));
	}

	if (word_index + 1 == 24) { // last one
		uint32_t i;
		strlcpy(storage.mnemonic, words[0], sizeof(storage.mnemonic));
		for (i = 1; i < word_count; i++) {
			strlcat(storage.mnemonic, " ", sizeof(storage.mnemonic));
			strlcat(storage.mnemonic, words[i], sizeof(storage.mnemonic));
		}
		if (!enforce_wordlist || mnemonic_check(storage.mnemonic)) {
			storage.has_mnemonic = true;
			storage_commit();
			fsm_sendSuccess("Device recovered");
		} else {
			storage_reset();
			fsm_sendFailure(FailureType_Failure_SyntaxError, "Invalid mnemonic, are words in correct order?");
		}
		awaiting_word = false;
		layoutHome();
	} else {
		word_index++;
		next_word();
	}
}
Ejemplo n.º 2
0
static uint8 at_sreset(char *ret_buf)
{
	struct ther_info *ti = get_ti();

	if (ti->mode != CAL_MODE)
		enter_cal_mode(ti);

	storage_reset();

	return 0;
}
Ejemplo n.º 3
0
/*
 * storage_load_device() - Load configuration data from usb message to shadow memory
 *
 * INPUT
 *     - msg: load device message
 * OUTPUT
 *     none
 */
void storage_load_device(LoadDevice *msg)
{
    storage_reset();

    shadow_config.storage.has_imported = true;
    shadow_config.storage.imported = true;

    if(msg->has_pin > 0)
    {
        storage_set_pin(msg->pin);
    }

    if(msg->has_passphrase_protection)
    {
        shadow_config.storage.has_passphrase_protection = true;
        shadow_config.storage.passphrase_protection = msg->passphrase_protection;
    }
    else
    {
        shadow_config.storage.has_passphrase_protection = false;
    }

    if(msg->has_node)
    {
        shadow_config.storage.has_node = true;
        shadow_config.storage.has_mnemonic = false;
        memcpy(&shadow_config.storage.node, &(msg->node), sizeof(HDNodeType));
        sessionRootNodeCached = false;
        memset(&sessionRootNode, 0, sizeof(sessionRootNode));
    }
    else if(msg->has_mnemonic)
    {
        shadow_config.storage.has_mnemonic = true;
        shadow_config.storage.has_node = false;
        strlcpy(shadow_config.storage.mnemonic, msg->mnemonic,
                sizeof(shadow_config.storage.mnemonic));
        sessionRootNodeCached = false;
        memset(&sessionRootNode, 0, sizeof(sessionRootNode));
    }

    if(msg->has_language)
    {
        storage_set_language(msg->language);
    }

    if(msg->has_label)
    {
        storage_set_label(msg->label);
    }
}
Ejemplo n.º 4
0
/*
 * storage_init() - Validate storage content and copy data to shadow memory
 *
 * INPUT
 *     none
 * OUTPUT
 *     none
 */
void storage_init(void)
{
    ConfigFlash *stor_config;

    /* Find storage sector with valid data and set storage_location variable */
    if(find_active_storage(&storage_location))
    {
        stor_config = (ConfigFlash *)flash_write_helper(storage_location);
    }
    else
    {
        /* Set to storage sector1 as default if no sector has been initialized */
        storage_location = STORAGE_SECT_DEFAULT;
        stor_config = (ConfigFlash *)flash_write_helper(storage_location);
    }

    /* Reset shadow configuration in RAM */
    storage_reset();

    /* Verify storage partition is initialized */
    if(memcmp((void *)stor_config->meta.magic , STORAGE_MAGIC_STR,
              STORAGE_MAGIC_LEN) == 0)
    {
        /* Clear out stor_config before finding end config node */
        memcpy(shadow_config.meta.uuid, (void *)&stor_config->meta.uuid,
               sizeof(shadow_config.meta.uuid));
        data2hex(shadow_config.meta.uuid, sizeof(shadow_config.meta.uuid),
                 shadow_config.meta.uuid_str);

        if(stor_config->storage.version)
        {
            if(stor_config->storage.version <= STORAGE_VERSION)
            {
                storage_from_flash(stor_config);
            }
        }

        /* New app with storage version changed!  update the storage space */
        if(stor_config->storage.version != STORAGE_VERSION)
        {
            storage_commit();
        }
    }
    else
    {
        /* Keep storage area cleared */
        storage_reset_uuid();
        storage_commit();
    }
}
Ejemplo n.º 5
0
void fsm_msgWipeDevice(WipeDevice *msg)
{
	(void)msg;
	layoutDialogSwipe(DIALOG_ICON_QUESTION, "Cancel", "Confirm", NULL, "Do you really want to", "wipe the device?", NULL, "All data will be lost.", NULL, NULL);
	if (!protectButton(ButtonRequestType_ButtonRequest_WipeDevice, false)) {
		fsm_sendFailure(FailureType_Failure_ActionCancelled, "Wipe cancelled");
		layoutHome();
		return;
	}
	storage_reset();
	storage_reset_uuid();
	storage_commit();
	// the following does not work on Mac anyway :-/ Linux/Windows are fine, so it is not needed
	// usbReconnect(); // force re-enumeration because of the serial number change
	fsm_sendSuccess("Device wiped");
	layoutHome();
}
Ejemplo n.º 6
0
void fsm_msgWipeDevice(WipeDevice *msg)
{
    (void)msg;

    if(!confirm(ButtonRequestType_ButtonRequest_WipeDevice, "Wipe Device",
                "Do you want to erase your private keys and settings?"))
    {
        fsm_sendFailure(FailureType_Failure_ActionCancelled, "Wipe cancelled");
        go_home();
        return;
    }

    /* Wipe device */
    storage_reset();
    storage_reset_uuid();
    storage_commit();

    fsm_sendSuccess("Device wiped");
    go_home();
}
Ejemplo n.º 7
0
void storage_init(void)
{
	storage_reset();
	// if magic is ok
	if (memcmp((void *)FLASH_STORAGE_START, "stor", 4) == 0) {
		// load uuid
		memcpy(storage_uuid, (void *)(FLASH_STORAGE_START + 4), sizeof(storage_uuid));
		data2hex(storage_uuid, sizeof(storage_uuid), storage_uuid_str);
		// load storage struct
		uint32_t version = ((Storage *)(FLASH_STORAGE_START + 4 + sizeof(storage_uuid)))->version;
		if (version && version <= STORAGE_VERSION) {
			storage_from_flash(version);
		}
		if (version != STORAGE_VERSION) {
			storage_commit();
		}
	} else {
		storage_reset_uuid();
		storage_commit();
	}
}
Ejemplo n.º 8
0
void reset_entropy(const uint8_t *ext_entropy, uint32_t len)
{
    if(!awaiting_entropy)
    {
        fsm_sendFailure(FailureType_Failure_UnexpectedMessage, "Not in Reset mode");
        return;
    }

    SHA256_CTX ctx;
    sha256_Init(&ctx);
    sha256_Update(&ctx, int_entropy, 32);
    sha256_Update(&ctx, ext_entropy, len);
    sha256_Final(int_entropy, &ctx);

    const char *temp_mnemonic = mnemonic_from_data(int_entropy, strength / 8);

    memset(int_entropy, 0, 32);
    awaiting_entropy = false;

    /*
     * Format mnemonic for user review
     */
    uint32_t word_count = 0, current_page = 0, page_count;
    char *tok;
    char tokened_mnemonic[TOKENED_MNEMONIC_BUF];
    char mnemonic_by_screen[MAX_PAGES][MNEMONIC_BY_SCREEN_BUF];
    char formatted_mnemonic[MAX_PAGES][FORMATTED_MNEMONIC_BUF];
    char mnemonic_display[FORMATTED_MNEMONIC_BUF];
    char formatted_word[MAX_WORD_LEN + ADDITIONAL_WORD_PAD];

    strlcpy(tokened_mnemonic, temp_mnemonic, TOKENED_MNEMONIC_BUF);

    tok = strtok(tokened_mnemonic, " ");

    while(tok)
    {
        snprintf(formatted_word, MAX_WORD_LEN + ADDITIONAL_WORD_PAD, "%lu.%s",
                 (unsigned long)(word_count + 1), tok);

        /* Check that we have enough room on display to show word */
        snprintf(mnemonic_display, FORMATTED_MNEMONIC_BUF, "%s   %s",
                 formatted_mnemonic[current_page], formatted_word);

        if(calc_str_line(get_body_font(), mnemonic_display, BODY_WIDTH) > 3)
        {
            page_count++;
            current_page++;

            snprintf(mnemonic_display, FORMATTED_MNEMONIC_BUF, "%s   %s",
                 formatted_mnemonic[current_page], formatted_word);
        }


        strlcpy(formatted_mnemonic[current_page], mnemonic_display,
                FORMATTED_MNEMONIC_BUF);

        /* Save mnemonic for each screen */
        if(strlen(mnemonic_by_screen[current_page]) == 0)
        {
            strlcpy(mnemonic_by_screen[current_page], tok, MNEMONIC_BY_SCREEN_BUF);
        }
        else
        {
            strlcat(mnemonic_by_screen[current_page], " ", MNEMONIC_BY_SCREEN_BUF);
            strlcat(mnemonic_by_screen[current_page], tok, MNEMONIC_BY_SCREEN_BUF);
        }

        tok = strtok(NULL, " ");
        word_count++;
    }

    /* Have user confirm mnemonic is sets of 12 words */
    for(page_count = current_page + 1, current_page = 0; current_page < page_count; current_page++)
    {
        char title[MEDIUM_STR_BUF] = "Recovery Sentence";

        /* make current screen mnemonic available via debuglink */
        strlcpy(current_words, mnemonic_by_screen[current_page], MNEMONIC_BY_SCREEN_BUF);

        if(page_count > 1)
        {
            /* snprintf: 20 + 10 (%d) + 1 (NULL) = 31 */
            snprintf(title, MEDIUM_STR_BUF, "Recovery Sentence %lu/%lu", current_page + 1, page_count);
        }

        if(!confirm(ButtonRequestType_ButtonRequest_ConfirmWord, title, "%s",
                    formatted_mnemonic[current_page]))
        {
            fsm_sendFailure(FailureType_Failure_ActionCancelled, "Reset cancelled");
            storage_reset();
            go_home();
            return;
        }
    }

    /* Save mnemonic */
    storage_set_mnemonic(temp_mnemonic);
    storage_commit();

    fsm_sendSuccess("Device reset");
    go_home();
}
Ejemplo n.º 9
0
void recovery_word(const char *word)
{
    if (!awaiting_word) 
    {
        fsm_sendFailure(FailureType_Failure_UnexpectedMessage, "Not in Recovery mode");
        go_home();
        return;
    }

    if (word_pos == 0) 
    { // fake word
        if (strcmp(word, fake_word) != 0) {
            storage_reset();
            fsm_sendFailure(FailureType_Failure_SyntaxError, "Wrong word retyped");
            go_home();
            return;
        }
    } else { // real word
        if (enforce_wordlist) 
        { // check if word is valid
            const char * const *wl = mnemonic_wordlist();
            bool found = false;
            while (*wl) 
            {
                if (strcmp(word, *wl) == 0) 
                {
                    found = true;
                    break;
                }
                wl++;
            }
            if (!found) 
            {
                storage_reset();
                fsm_sendFailure(FailureType_Failure_SyntaxError, "Word not found in a wordlist");
                go_home();
                return;
            }
        }
        strlcpy(words[word_pos - 1], word, sizeof(words[word_pos - 1]));
    }

    if (word_index + 1 == 24)
    { // last one
        storage_set_mnemonic_from_words((const char (*)[])words, word_count);

        if (!enforce_wordlist || mnemonic_check(storage_get_shadow_mnemonic()))
        {
        	storage_commit();
            fsm_sendSuccess("Device recovered");
        } else {
            storage_reset();
            fsm_sendFailure(FailureType_Failure_SyntaxError, "Invalid mnemonic, are words in correct order?");
        }
        awaiting_word = false;
        go_home();
    } else {
        word_index++;
        next_word();
    }
}
Ejemplo n.º 10
0
void reset_entropy(const uint8_t *ext_entropy, uint32_t len)
{
    if (!awaiting_entropy) {
        fsm_sendFailure(FailureType_Failure_UnexpectedMessage, "Not in Reset mode");
        return;
    }
    SHA256_CTX ctx;
    sha256_Init(&ctx);
    sha256_Update(&ctx, int_entropy, 32);
    sha256_Update(&ctx, ext_entropy, len);
    sha256_Final(int_entropy, &ctx);
    strlcpy(storage.mnemonic, mnemonic_from_data(int_entropy, strength / 8), sizeof(storage.mnemonic));
    memset(int_entropy, 0, 32);
    awaiting_entropy = false;

    int pass, word_pos, i = 0, j;

    for (pass = 0; pass < 2; pass++) {
        i = 0;
        for (word_pos = 1; word_pos <= (int)strength/32*3; word_pos++) {
            // copy current_word
            j = 0;
            while (storage.mnemonic[i] != ' ' && storage.mnemonic[i] != 0 && j + 1 < (int)sizeof(current_word)) {
                current_word[j] = storage.mnemonic[i];
                i++;
                j++;
            }
            current_word[j] = 0;
            if (storage.mnemonic[i] != 0) i++;
            char desc[] = "##th word is:";
            if (word_pos < 10) {
                desc[0] = ' ';
            } else {
                desc[0] = '0' + word_pos / 10;
            }
            desc[1] = '0' + word_pos % 10;
            if (word_pos == 1 || word_pos == 21) {
                desc[2] = 's';
                desc[3] = 't';
            } else if (word_pos == 2 || word_pos == 22) {
                desc[2] = 'n';
                desc[3] = 'd';
            } else if (word_pos == 3 || word_pos == 23) {
                desc[2] = 'r';
                desc[3] = 'd';
            }
            if (word_pos == (int)strength/32*3) { // last word
                if (pass == 1) {
                    layoutDialogSwipe(DIALOG_ICON_INFO, NULL, "Finish", NULL, "Please check the seed", NULL, (word_pos < 10 ? desc + 1 : desc), NULL, current_word, NULL);
                } else {
                    layoutDialogSwipe(DIALOG_ICON_INFO, NULL, "Again", NULL, "Write down the seed", NULL, (word_pos < 10 ? desc + 1 : desc), NULL, current_word, NULL);
                }
            } else {
                if (pass == 1) {
                    layoutDialogSwipe(DIALOG_ICON_INFO, NULL, "Next", NULL, "Please check the seed", NULL, (word_pos < 10 ? desc + 1 : desc), NULL, current_word, NULL);
                } else {
                    layoutDialogSwipe(DIALOG_ICON_INFO, NULL, "Next", NULL, "Write down the seed", NULL, (word_pos < 10 ? desc + 1 : desc), NULL, current_word, NULL);
                }
            }
            if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmWord, true)) {
                storage_reset();
                layoutHome();
                return;
            }
        }
    }

    storage.has_mnemonic = true;
    storage_commit();
    fsm_sendSuccess("Device reset");
    layoutHome();
}