Пример #1
0
/*
 * layout_cipher() - Draws recover cipher
 *
 * INPUT
 *     - current_word: current word that is being typed in at this point in recovery
 *     - cipher: randomized cipher
 * OUTPUT
 *     none
 */
void layout_cipher(const char *current_word, const char *cipher)
{
    DrawableParams sp;
    const Font *title_font = get_body_font();
    Canvas *canvas = layout_get_canvas();

    call_leaving_handler();
    layout_clear();

    /* Draw prompt */
    sp.y = 11;
    sp.x = 4;
    sp.color = BODY_COLOR;
    draw_string(canvas, title_font, "Recovery Cipher:", &sp, 58, font_height(title_font) + 3);

    /* Draw current word */
    sp.y = 46;
    sp.x = 4;
    sp.color = BODY_COLOR;
    draw_string(canvas, title_font, current_word, &sp, 68, font_height(title_font));
    display_refresh();

    /* Animate cipher */
    layout_add_animation(&layout_animate_cipher, (void *)cipher,
                         CIPHER_ANIMATION_FREQUENCY_MS * 30);
}
Пример #2
0
/*
 * layout_transaction_notification() - Display transaction notification
 *
 * INPUT
 *     - amount: amount of transaction
 *     - address: destination address
 *     - type: notification type
 * OUTPUT
 *     none
 */
void layout_transaction_notification(const char *amount, const char *address,
                                     NotificationType type)
{
    call_leaving_handler();
    layout_clear();

    Canvas *canvas = layout_get_canvas();
    DrawableParams sp;
    const Font *amount_font = get_title_font();
    const Font *address_font = get_title_font();

    /* Unbold fonts if address becomes too long */
    if(calc_str_width(address_font, address) > TRANSACTION_WIDTH)
    {
        amount_font = get_body_font();
        address_font = get_body_font();
    }

    /* Determine vertical alignment and body width */
    sp.y =  TOP_MARGIN_FOR_ONE_LINE;

    /* Format amount line */
    char title[BODY_CHAR_MAX];
    snprintf(title, BODY_CHAR_MAX, "Send %s to", amount);

    /* Draw amount */
    sp.x = LEFT_MARGIN;
    sp.color = TITLE_COLOR;
    draw_string(canvas, amount_font, title, &sp, TRANSACTION_WIDTH, font_height(amount_font));

    /* Draw address */
    sp.y += font_height(address_font) + TRANSACTION_TOP_MARGIN;
    sp.x = LEFT_MARGIN;
    sp.color = BODY_COLOR;
    draw_string(canvas, address_font, address, &sp, TRANSACTION_WIDTH,
                font_height(address_font) + BODY_FONT_LINE_PADDING);

    layout_notification_icon(type, &sp);
}
Пример #3
0
/*
 * layout_pin() - Draws pin matrix
 *
 * INPUT
 *     - str: string prompt to display next to pin matrix
 *     - pin: randomized pin matric
 * OUTPUT
 *     none
 */
void layout_pin(const char *str, char pin[])
{
    DrawableParams sp;
    Canvas *canvas = layout_get_canvas();

    call_leaving_handler();
    layout_clear();

    /* Draw prompt */
    const Font *font = get_body_font();
    sp.y = 29;
    sp.x = (140 - calc_str_width(font, str)) / 2;
    sp.color = BODY_COLOR;
    draw_string(canvas, font, str, &sp, TITLE_WIDTH, font_height(font));
    display_refresh();

    /* Animate pin scrambling */
    layout_add_animation(&layout_animate_pin, (void *)pin, PIN_MAX_ANIMATION_MS);
}
Пример #4
0
/*
 * layout_address_notification() - Display address notification
 *
 * INPUT
 *     - desc: description of address being shown (normal or multisig)
 *     - address: address to display both as string and QR
 *     - type: notification type
 * OUTPUT
 *      none
 */
void layout_address_notification(const char *desc, const char *address,
                                 NotificationType type)
{
    call_leaving_handler();
    layout_clear();

    Canvas *canvas = layout_get_canvas();
    DrawableParams sp;
    const Font *address_font = get_title_font();

    /* Unbold fonts if address becomes too long */
    if(calc_str_width(address_font, address) > TRANSACTION_WIDTH)
    {
        address_font = get_body_font();
    }

    /* Determine vertical alignment and body width */
    sp.y =  TOP_MARGIN_FOR_ONE_LINE;

    /* Draw address */
    sp.y += font_height(address_font) + ADDRESS_TOP_MARGIN;
    sp.x = LEFT_MARGIN;
    sp.color = BODY_COLOR;
    draw_string(canvas, address_font, address, &sp, TRANSACTION_WIDTH,
                font_height(address_font) + BODY_FONT_LINE_PADDING);

    /* Draw description */
    if(strcmp(desc, "") != 0)
    {
        sp.y = TOP_MARGIN_FOR_ONE_LINE;
        sp.x = MULTISIG_LEFT_MARGIN;
        sp.color = BODY_COLOR;
        draw_string(canvas, address_font, desc, &sp, TRANSACTION_WIDTH,
                    font_height(address_font) + BODY_FONT_LINE_PADDING);
    }

    layout_address(address);
    layout_notification_icon(type, &sp);
}
Пример #5
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();
}
Пример #6
0
/*
 * layout_animate_cipher() - Animate recovery cipher
 *
 * INPUT
 *     - data: pointer to pin array
 *     - duration: duration of the pin scramble animation
 *     - elapsed: how long we have been animating
 * OUTPUT
 *     none
 */
static void layout_animate_cipher(void *data, uint32_t duration, uint32_t elapsed)
{
    (void)duration;
    Canvas *canvas = layout_get_canvas();
    int row, letter, x_padding, cur_pos_elapsed, adj_pos, adj_x, adj_y, cur_index;
    char *cipher = (char *)data;
    char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
    char *current_letter = alphabet;

    DrawableParams sp;
    const Font *title_font = get_title_font();
    const Font *cipher_font = get_body_font();

    /* Clear area behind cipher */
    draw_box_simple(canvas, CIPHER_MASK_COLOR, CIPHER_START_X, 0,
                    KEEPKEY_DISPLAY_WIDTH - CIPHER_START_X, KEEPKEY_DISPLAY_HEIGHT);

    /* Draw grid */
    sp.y = CIPHER_START_Y;
    sp.x = CIPHER_START_X;

    for(row = 0; row < CIPHER_ROWS; row++)
    {
        for(letter = 0; letter < CIPHER_LETTER_BY_ROW; letter++)
        {
            cur_index = (row * CIPHER_LETTER_BY_ROW) + letter;
            cur_pos_elapsed = elapsed - cur_index * CIPHER_ANIMATION_FREQUENCY_MS;
            sp.x = CIPHER_START_X + (letter * (CIPHER_GRID_SIZE + CIPHER_GRID_SPACING));
            x_padding = 0;

            /* Draw grid */
            draw_box_simple(canvas, CIPHER_STEP_1, sp.x - 4, sp.y + CIPHER_GRID_SIZE,
                            CIPHER_GRID_SIZE, CIPHER_GRID_SIZE);

            x_padding = 0;

            if(*current_letter == 'i' || *current_letter == 'l')
            {
                x_padding = 2;
            }
            else if(*current_letter == 'm' || *current_letter == 'w')
            {
                x_padding = -1;
            }

            /* Draw map */
            draw_char_simple(canvas, title_font, *current_letter++, CIPHER_MAP_FONT_COLOR,
                             sp.x + x_padding, sp.y);

            x_padding = 0;

            if(*cipher == 'i' || *cipher == 'l')
            {
                x_padding = 2;
            }
            else if(*cipher == 'k' || *cipher == 'j' ||
                    *cipher == 'r' || *cipher == 'f')
            {
                x_padding = 1;
            }
            else if(*cipher == 'm' || *cipher == 'w')
            {
                x_padding = -1;
            }

            /* Draw cipher */
            if(cur_pos_elapsed > 0)
            {
                adj_pos = cur_pos_elapsed / CIPHER_ANIMATION_FREQUENCY_MS;

                adj_x = 0;
                adj_y = 0;

                if(adj_pos < 5)
                {
                    if(cur_index % 4 == 0)
                    {
                        adj_y = -(5 - adj_pos);
                    }
                    else if(cur_index % 4 == 1)
                    {
                        adj_x = 5 - adj_pos;
                    }
                    else if(cur_index % 4 == 2)
                    {
                        adj_y = 5 - adj_pos;
                    }
                    else
                    {
                        adj_x = -(5 - adj_pos);
                    }
                }

                draw_char_simple(canvas, cipher_font, *cipher, CIPHER_FONT_COLOR,
                                 sp.x + x_padding + adj_x, sp.y + (CIPHER_GRID_SIZE + CIPHER_GRID_SPACING) + adj_y);
            }

            /* Draw grid mask between boxes */
            draw_box_simple(canvas, CIPHER_MASK_COLOR, sp.x - 5, sp.y + CIPHER_GRID_SIZE, 1,
                            CIPHER_GRID_SIZE);

            cipher++;
        }

        sp.x = CIPHER_START_X;
        sp.y += 31;
    }

    /* Draw mask */
    draw_box_simple(canvas, CIPHER_MASK_COLOR, CIPHER_START_X - 4, 14,
                    CIPHER_HORIZONTAL_MASK_WIDTH,
                    CIPHER_HORIZONTAL_MASK_HEIGHT_2);
    draw_box_simple(canvas, CIPHER_MASK_COLOR, CIPHER_START_X - 4, 45,
                    CIPHER_HORIZONTAL_MASK_WIDTH,
                    CIPHER_HORIZONTAL_MASK_HEIGHT_2);
    draw_box_simple(canvas, CIPHER_MASK_COLOR, CIPHER_START_X - 4, 29,
                    CIPHER_HORIZONTAL_MASK_WIDTH,
                    CIPHER_HORIZONTAL_MASK_HEIGHT_3);
    draw_box_simple(canvas, CIPHER_MASK_COLOR, CIPHER_START_X - 4, 59,
                    CIPHER_HORIZONTAL_MASK_WIDTH,
                    CIPHER_HORIZONTAL_MASK_HEIGHT_4);
    draw_box_simple(canvas, CIPHER_MASK_COLOR,
                    KEEPKEY_DISPLAY_WIDTH - CIPHER_HORIZONTAL_MASK_WIDTH_3, 0,
                    CIPHER_HORIZONTAL_MASK_WIDTH_3, KEEPKEY_DISPLAY_HEIGHT);
}