diff --git a/legacy/ble.c b/legacy/ble.c index c7e06106c..4965152a0 100644 --- a/legacy/ble.c +++ b/legacy/ble.c @@ -19,7 +19,7 @@ static bool passkey_state = false; static int ble_request_state = -1; static uint8_t ble_response_buf[64]; static char ble_name[BLE_NAME_LEN + 1] = {0}; -static char ble_ver[6] = {0}; +static char ble_ver[16] = {0}; static char ble_build_id[8] = {0}; static uint8_t ble_hash[32] = {0}; static HW_VER_t ble_hw_ver = HW_VER_INVALID; @@ -296,8 +296,8 @@ void ble_uart_poll(uint8_t *buf) { battery_cap = ble_usart_msg.cmd_vale[0]; break; case BLE_CMD_VER: - if (ble_usart_msg.cmd_len == 5) { - memcpy(ble_ver, ble_usart_msg.cmd_vale, 5); + if (ble_usart_msg.cmd_len < sizeof(ble_ver) - 1) { + memcpy(ble_ver, ble_usart_msg.cmd_vale, ble_usart_msg.cmd_len); get_ble_ver = true; } break; @@ -342,7 +342,10 @@ void ble_uart_poll(uint8_t *buf) { case BLE_CMD_HW_VER: if (ble_usart_msg.cmd_len == 2) { ble_hw_ver = ble_usart_msg.cmd_vale[1] << 8 | ble_usart_msg.cmd_vale[0]; - get_ble_hw_ver = true; + if (ble_hw_ver == HW_VER_V_1_X || ble_hw_ver == HW_VER_V_2_0 || + ble_hw_ver == HW_VER_V_PURE) { + get_ble_hw_ver = true; + } } break; default: diff --git a/legacy/firmware/fido2/ctap.c b/legacy/firmware/fido2/ctap.c index bc514f067..f52377bb8 100644 --- a/legacy/firmware/fido2/ctap.c +++ b/legacy/firmware/fido2/ctap.c @@ -676,7 +676,9 @@ static int ctap_make_auth_data(CTAP_makeCredential mc, uint32_t counter, authData->head.flags = AUTH_DATA_FLAG_UP | AUTH_DATA_FLAG_UV | AUTH_DATA_FLAG_AT; - authData->head.signCount = counter; + authData->head.signCount = + ((counter & 0xFF) << 24) | ((counter & 0xFF00) << 8) | + ((counter & 0xFF0000) >> 8) | ((counter & 0xFF000000) >> 24); memcpy(authData->attest.aaguid, CTAP_AAGUID, sizeof(CTAP_AAGUID) - 1); authData->attest.credLenL = cred_id_len & 0x00FF; @@ -1013,10 +1015,34 @@ uint8_t ctap_make_credential(CborEncoder *encoder, uint8_t *request, char *account_name = get_account_name(&MC.credInfo.user); - layoutDialogAdapterEx(_(FIDO_INFO_CONFIRMATION_TITLE), NULL, NULL, - &bmp_bottom_right_confirm, NULL, NULL, + int position_history[10] = {0}; + int history_index = 0; + + bool is_end; + int truncate_pos = 0; + char account_name_buf[64] = {0}; + int current_position = 0; + +refresh: + truncate_pos = + get_truncate_position(account_name + current_position, &is_end); + strncpy(account_name_buf, account_name + current_position, truncate_pos); + account_name_buf[truncate_pos] = '\0'; + + layoutDialogAdapterEx(_(FIDO_INFO_CONFIRMATION_TITLE), &bmp_bottom_left_close, + NULL, &bmp_bottom_right_confirm, NULL, NULL, _(GLOBAL_APP_NAME), MC.rp.id, _(GLOBAL_ACCOUNT), - account_name); + account_name_buf); + + if (!is_end) { + oledDrawBitmap(3 * OLED_WIDTH / 4, OLED_HEIGHT - 8, + &bmp_bottom_middle_arrow_down); + } + if (history_index > 0) { + oledDrawBitmap(OLED_WIDTH / 4 - 8, OLED_HEIGHT - 8, + &bmp_bottom_middle_arrow_up); + } + oledRefresh(); uint32_t start_time = svc_timer_ms(); bool yes_up = false; @@ -1028,6 +1054,20 @@ uint8_t ctap_make_credential(CborEncoder *encoder, uint8_t *request, break; } else if (button.NoUp) { break; + } else if (button.UpUp) { + if (history_index > 0) { + history_index--; + current_position -= position_history[history_index]; + goto refresh; + } + } else if (button.DownUp) { + if (!is_end) { + if (history_index < 10 - 1) { + position_history[history_index++] = truncate_pos; + } + current_position += truncate_pos; + goto refresh; + } } loop_callback_handler(); if (svc_timer_ms() - start_time > USER_PRESENCE_TIMEOUT) { @@ -1108,10 +1148,10 @@ uint8_t ctap_make_credential(CborEncoder *encoder, uint8_t *request, if (!resident_credential_store(rp_id_hash, MC.credInfo.user.id, cred_id_buf, cred_id_len)) { layoutDialogCenterAdapterV2(_(FIDO_ADD_KEY_LIMIT_REACHED_TITLE), NULL, - NULL, &bmp_bottom_right_arrow, NULL, NULL, + NULL, &bmp_bottom_right_confirm, NULL, NULL, NULL, _(FIDO_ADD_KEY_LIMIT_REACHED_DESC), NULL, NULL, NULL); - protectWaitKey(timer1s * 2, 0); + waitKey(timer1s * 5, 0); return CTAP2_ERR_KEY_STORE_FULL; } } @@ -1811,18 +1851,45 @@ uint8_t ctap_get_assertion(CborEncoder *encoder, uint8_t *request, int length) { if (GA.up || GA.uv) { const char *appname = NULL; uint8_t rp_id_hash[32]; + + int position_history[10] = {0}; + int history_index = 0; + + bool is_end; + int truncate_pos = 0; + char account_name_buf[64] = {0}; + int current_position = 0; + char *account_name = NULL; + + if (cred->type == PUB_KEY_CRED_PUB_KEY) { + account_name = get_account_name(&cred->credential.user); + } + + refresh: if (cred->type == PUB_KEY_CRED_CTAP1) { sha256_Raw((uint8_t *)GA.rp.id, GA.rp.size, rp_id_hash); getReadableAppId(rp_id_hash, &appname); - layoutDialogAdapterEx(_(T__U2F_AUTHENTICATE), NULL, NULL, - &bmp_bottom_right_confirm, NULL, NULL, + layoutDialogAdapterEx(_(T__U2F_AUTHENTICATE), &bmp_bottom_left_close, + NULL, &bmp_bottom_right_confirm, NULL, NULL, _(I__APP_NAME_COLON), appname, NULL, NULL); } else { - char *account_name = get_account_name(&cred->credential.user); - layoutDialogAdapterEx(_(FIDO_2_AUTHENTICATE), NULL, NULL, - &bmp_bottom_right_confirm, NULL, NULL, + truncate_pos = + get_truncate_position(account_name + current_position, &is_end); + strncpy(account_name_buf, account_name + current_position, truncate_pos); + account_name_buf[truncate_pos] = '\0'; + layoutDialogAdapterEx(_(FIDO_2_AUTHENTICATE), &bmp_bottom_left_close, + NULL, &bmp_bottom_right_confirm, NULL, NULL, _(GLOBAL_APP_NAME), cred->credential.rp.id, - _(GLOBAL_ACCOUNT), account_name); + _(GLOBAL_ACCOUNT), account_name_buf); + if (!is_end) { + oledDrawBitmap(3 * OLED_WIDTH / 4, OLED_HEIGHT - 8, + &bmp_bottom_middle_arrow_down); + } + if (history_index > 0) { + oledDrawBitmap(OLED_WIDTH / 4 - 8, OLED_HEIGHT - 8, + &bmp_bottom_middle_arrow_up); + } + oledRefresh(); } uint32_t start_time = svc_timer_ms(); bool yes_up = false; @@ -1835,6 +1902,20 @@ uint8_t ctap_get_assertion(CborEncoder *encoder, uint8_t *request, int length) { break; } else if (button.NoUp) { break; + } else if (button.UpUp) { + if (history_index > 0) { + history_index--; + current_position -= position_history[history_index]; + goto refresh; + } + } else if (button.DownUp) { + if (!is_end) { + if (history_index < 10 - 1) { + position_history[history_index++] = truncate_pos; + } + current_position += truncate_pos; + goto refresh; + } } loop_callback_handler(); if (svc_timer_ms() - start_time > USER_PRESENCE_TIMEOUT) { diff --git a/legacy/firmware/fido2/ctap_trans.c b/legacy/firmware/fido2/ctap_trans.c index 1d07540de..e814c38d1 100644 --- a/legacy/firmware/fido2/ctap_trans.c +++ b/legacy/firmware/fido2/ctap_trans.c @@ -100,6 +100,7 @@ bool u2f_init_command = false; static bool next_page = false; static bool se_seed_cached = false; static volatile bool usb_hid_tiny = false; +extern bool protectAbortedByFIDO; typedef enum { TRANSPORT_NULL = 0, @@ -288,6 +289,8 @@ void u2fhid_read_start(const U2FHID_FRAME *f) { ctap_printf("ctap usb cmd\n"); + protectAbortedByFIDO = true; + // We have all the data switch (reader->cmd) { case 0: @@ -1707,6 +1710,8 @@ void ctap_ble_cmd(void) { return; } + protectAbortedByFIDO = true; + ctap_printf("ctap_ble_cmd cmd: %d\n", cmd); dump_hex1(NULL, data_ptr, data_len); diff --git a/legacy/firmware/layout2.c b/legacy/firmware/layout2.c index 744cc8a29..af265e716 100644 --- a/legacy/firmware/layout2.c +++ b/legacy/firmware/layout2.c @@ -193,6 +193,21 @@ void short_line_message(const char *msg, char *buf) { } } +int get_truncate_position(const char *msg, bool *is_end) { + int width = 0; + int index = 0; + while (msg[index] != '\0' && width <= OLED_WIDTH) { + width += oledCharWidthEx(msg[index], FONT_STANDARD); + if (width > OLED_WIDTH) { + *is_end = false; + return index; + } + index++; + } + *is_end = (msg[index] == '\0'); + return index; // Return the position where the string fits in one line +} + static int countlines(char *text) { int lines = 0, steps = 0; while (*text) { @@ -5656,8 +5671,8 @@ bool layoutSignSchnorrHash(const char *chain_name, const char *signer, void layout_fido2_resident_credential(int index, int count, const char *app_name, const char *user_name) { - char app_name_buf[32] = {0}; - char user_name_buf[32] = {0}; + char app_name_buf[64] = {0}; + char user_name_buf[64] = {0}; short_line_message(app_name, app_name_buf); short_line_message(user_name, user_name_buf); diff --git a/legacy/firmware/layout2.h b/legacy/firmware/layout2.h index 5bb359bcd..0641a3356 100644 --- a/legacy/firmware/layout2.h +++ b/legacy/firmware/layout2.h @@ -38,6 +38,8 @@ extern void *layoutLast; +int get_truncate_position(const char *msg, bool *is_end); + void layoutDialogSwipe(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, diff --git a/legacy/firmware/menu_core.c b/legacy/firmware/menu_core.c index d86fcc7f3..fcae5203a 100644 --- a/legacy/firmware/menu_core.c +++ b/legacy/firmware/menu_core.c @@ -14,6 +14,7 @@ void menu_refresh(void) { refresh_menu = true; } void menu_init(struct menu *menu) { currentMenu = menu; currentMenu->current = currentMenu->start; + refresh_menu = true; } static const char *_gettext(char *en_str) { diff --git a/legacy/firmware/menu_list.c b/legacy/firmware/menu_list.c index 161a000bb..cb750eaa1 100644 --- a/legacy/firmware/menu_list.c +++ b/legacy/firmware/menu_list.c @@ -19,6 +19,7 @@ #include "fido2/resident_credential.h" static struct menu settings_menu, main_menu, security_set_menu, about_menu; +static bool resident_credential_refresh = true; void menu_erase_device(int index) { (void)index; @@ -346,6 +347,8 @@ void menu_check_all_words(int index) { } } +void menu_fido2_resident_credential(int index); + static CTAP_UserInfo user_info[FIDO2_RESIDENT_CREDENTIALS_COUNT] __attribute__((section(".secMessageSection"))) = {0}; @@ -407,7 +410,10 @@ void menu_fido2_resident_credential_display(int index) { } menu_refresh(); } else { - fido_resident_credential_menu_items[0].go_prev = true; + fido_resident_credential_menu.counts = 0; + resident_credential_refresh = false; + menu_fido2_resident_credential(0); + // fido_resident_credential_menu_items[0].go_prev = true; } } return; @@ -424,7 +430,15 @@ void menu_fido2_resident_credential(int index) { (void)index; uint8_t indexs[FIDO2_RESIDENT_CREDENTIALS_COUNT] = {0}; - uint8_t count = resident_credential_info(indexs, 30); + uint8_t count = 0; + if (resident_credential_refresh) { + count = resident_credential_info(indexs, 30); + } else { + resident_credential_refresh = true; + count = fido_resident_credential_menu.counts; + menu_init(&security_set_menu); + } + if (count == 0) { layoutDialogCenterAdapterV2(NULL, NULL, &bmp_bottom_left_arrow, &bmp_bottom_right_arrow, NULL, NULL, NULL, NULL, diff --git a/legacy/firmware/protect.c b/legacy/firmware/protect.c index cc8a25f3f..b70fc460c 100644 --- a/legacy/firmware/protect.c +++ b/legacy/firmware/protect.c @@ -51,6 +51,7 @@ bool protectAbortedByInitializeOnboarding = false; bool protectAbortedByInitialize = false; bool protectAbortedByTimeout = false; bool exitBlindSignByInitialize = false; +bool protectAbortedByFIDO = false; extern bool msg_command_inprogress; static uint8_t device_sleep_state = SLEEP_NONE; @@ -811,6 +812,11 @@ uint8_t protectWaitKey(uint32_t time_out, uint8_t mode) { } } + if (protectAbortedByFIDO && layoutLast == layoutHome) { + protectAbortedByFIDO = false; + break; + } + loop_callback_handler(); key = keyScan(); diff --git a/legacy/firmware/trezor.c b/legacy/firmware/trezor.c index edecb2add..e3b4ef076 100644 --- a/legacy/firmware/trezor.c +++ b/legacy/firmware/trezor.c @@ -196,7 +196,7 @@ static void verify_ble_firmware(void) { #endif if (!flash_otp_is_locked(FLASH_OTP_BLOCK_BLE_PUBLIC_KEY1) || !flash_otp_is_locked(FLASH_OTP_BLOCK_BLE_PUBLIC_KEY2)) { - if (memcmp(ble_ver, "1.5.1", 5) < 0) { + if (compare_str_version(ble_ver, "1.5.1") < 0) { layoutDialogCenterAdapterEx(NULL, NULL, NULL, NULL, NULL, "Please update BLE", NULL, NULL); while (1) { @@ -258,7 +258,12 @@ int main(void) { #if !EMULATOR verify_ble_firmware(); HW_VER_t ble_hw_ver; - ensure(ble_get_hw_version(&ble_hw_ver) ? sectrue : secfalse, NULL); + char *ble_ver = NULL; + ble_get_version(&ble_ver); + if (compare_str_version(ble_ver, "1.5.3") >= 0) { + ensure(ble_get_hw_version(&ble_hw_ver) ? sectrue : secfalse, NULL); + } + #endif if (!is_mode_unprivileged()) { cpu_mode = PRIVILEGED;