diff --git a/CHANGELOG.md b/CHANGELOG.md index dee0f84d..5ca5632e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Change log +## [1.8.0] - 2024-05-06 +### Added +- Add Stax layouts for generating SSKR shares + +### Changed +- Use stable cx_crc32 instead of cx_crc32_hw + +### Fixed +- Fix build with SDK master for LNS + ## [1.7.2] - 2024-05-06 ### Added - @@ -10,7 +20,6 @@ ### Fixed - Using Ledger SDK `cx_crc32()` function rather than buggy `cx_crc32_hw()`. - ## [1.7.1] - 2024-03-06 ### Added - @@ -109,8 +118,8 @@ ## [1.5.0] - 2023-10-20 ### Added -- Added option to generate BIP39 mnemonics from SSKR shares even if shares do not validate against seed on device - - A user may have lost or damaged original device and now needs to generate the recovery phrase from another secure device +- Added option to recover BIP39 mnemonics from SSKR shares even if shares do not validate against seed on device + - A user may have lost or damaged original device and now needs to recover the BIP39 phrase from another secure device ### Changed - @@ -194,7 +203,7 @@ ## [1.1.0] - 2023-04-04 ### Added -- Generate BIP39 mnemonic phrases from SSKR shares +- Recover BIP39 mnemonic phrases from SSKR shares - Add 'SSKR Check' menu option - Add flow to the 'SSKR Check' menu - Write SSKR to BIP39 functionality diff --git a/Makefile b/Makefile index 7a6b5f2d..8952f72d 100755 --- a/Makefile +++ b/Makefile @@ -27,8 +27,8 @@ all: default APPNAME = "Seed Tool" APPVERSION_M = 1 -APPVERSION_N = 7 -APPVERSION_P = 2 +APPVERSION_N = 8 +APPVERSION_P = 0 APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" APP_LOAD_PARAMS = --appFlags 0x10 $(COMMON_LOAD_PARAMS) --curve secp256k1 --path "" diff --git a/README.md b/README.md index 62d7867c..c5926ed5 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ --- -Use the utilities provided by this Ledger application to check a backed up seed or generate [Shamir's Secret Sharing (SSS)](https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing) for a seed. +Use the utilities provided by this Ledger application to check a backed up BIP-39 seed, generate [Shamir's Secret Sharing (SSS)](https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing) for a seed or recover a BIP-39 phrase from a Shamir's Secret Sharing backup. Not all Ledger devices are equal. The older, less capable devices do not have the capacity to provide a full range of seed utilities. The following table lists the seed utilities provided by each devices type:
@@ -28,7 +28,7 @@ Not all Ledger devices are equal. The older, less capable devices do not have th |[Check BIP39](#check-bip39)|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{green}✓}$$| |[Check Shamir's secret shares](#check-shamirs-secret-shares)|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{orange}✓}$$| |[Generate Shamir's secret sharing](#generate-shamirs-secret-sharing)|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{orange}✓}$$| -|[Generate BIP39](#generate-bip39)|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{orange}✓}$$| +|[Recover BIP39](#recover-bip39)|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{orange}✓}$$| |[Generate BIP85](#generate-bip85)|$${\color{red}✗}$$|$${\color{orange}✓}$$|$${\color{orange}✓}$$|$${\color{orange}✓}$$|
@@ -59,8 +59,8 @@ For more information about SSKR, see [SSKR for Users](https://github.com/Blockch ## Check Shamir's secret shares The Ledger application also provides an option to confirm the onboarded seed against SSKR shares. -## Generate BIP39 -When the Shamir's secret shares have been validated the user can generate the BIP39 recovery phrase derived from those shares. This option takes advantage of SSKR's ability to perform a BIP39 <-> SSKR round trip. If a user has lost or damaged their original Ledger device they may need to generate the BIP39 recovery phrase on another secure device. A BIP39 recovery phrase may still be generated even if the SSKR phrases do not match the onboarded seed of a device but are still valid SSKR shares. +## Recover BIP39 +When the Shamir's secret shares have been validated the user can recover the BIP39 phrase derived from those shares. This option takes advantage of SSKR's ability to perform a BIP39 <-> SSKR round trip. If a user has lost or damaged their original Ledger device they may need to recover their BIP39 phrase on another secure device. A BIP39 phrase may still be recovered even if the SSKR phrases do not match the onboarded seed of a device but are still valid SSKR shares. ## Generate [BIP85](https://github.com/bitcoin/bips/blob/master/bip-0085.mediawiki) Coming soon!!!! @@ -90,9 +90,9 @@ flowchart LR 2.1[Check SSKR] --> 2.2[Enter SSKR Shares] --> 2.3{Validate SSKR Shares} 2.3 --> |Valid SSKR| 2.4 2.3 --> |Invalid SSKR| 2.3.1[Quit] - subgraph 2.4[Generate BIP39 Phrases] + subgraph 2.4[Recover BIP39 Phrases] direction TB - 2.4.1[Generate BIP39 Phrases] --> 2.4.2[Display BIP39 Phrases] --> 2.4.3[Quit] + 2.4.1[Recover BIP39 Phrases] --> 2.4.2[Display BIP39 Phrases] --> 2.4.3[Quit] end end subgraph 3[Version] diff --git a/TODO.md b/TODO.md index b78b4030..2098470f 100755 --- a/TODO.md +++ b/TODO.md @@ -21,15 +21,15 @@ - [x] Save memory by setting the SSKR word buffer (G_bolos_ux_context.sskr_words_buffer) to a sensible size - [x] Add unit tests - [x] Add code coverage to GitHub actions -- [x] Add option to generate BIP39 mnemonics from SSKR shares even if shares do not validate against seed on device - - A user may have lost or damaged original device and now needs to generate the recovery phrase from another secure device +- [x] Add option to recover BIP39 mnemonics from SSKR shares even if shares do not validate against seed on device + - A user may have lost or damaged original device and now needs to recover the BIP39 phrase from another secure device - [x] Fix warnings about deprecated functions during build - [x] Remove duplicated nano code - [x] Simplified flow code - [x] Add flow to set SSKR threshold values - [x] Add automated tests - [x] Fix issue with using 'cx_crc32_hw()' function in 'onboarding_seed_sskr.c' when testing with Speculos -- [x] Generate BIP39 mnemonic phrases from SSKR shares +- [x] Recover BIP39 mnemonic phrases from SSKR shares - [x] Add SSKR Check menu option - [x] Add flow to the Check SSKR menu - [x] Write SSKR to BIP39 functionality diff --git a/src/nano/nanos_enter_phrase.c b/src/nano/nanos_enter_phrase.c index 1d3c3ba1..ef7316d3 100644 --- a/src/nano/nanos_enter_phrase.c +++ b/src/nano/nanos_enter_phrase.c @@ -132,13 +132,13 @@ UX_STEP_VALID(ux_bip39_match_step_1, clean_exit(0), {&C_icon_validate_14, "BIP39 Phrase", "is correct"}); UX_STEP_CB(ux_bip39_match_step_2, pb, clean_exit(0), {&C_icon_dashboard_x, "Quit"}); -UX_STEP_CB(ux_bip39_generate_step_1, pbb, set_sskr_descriptor_values(); +UX_STEP_CB(ux_bip39_recover_step_1, pbb, set_sskr_descriptor_values(); , {&SSKR_ICON, "Generate", "SSKR phrases"}); UX_FLOW(ux_bip39_match_flow, &ux_bip39_match_step_1, &ux_bip39_match_step_2, - &ux_bip39_generate_step_1); + &ux_bip39_recover_step_1); UX_STEP_CB(ux_sskr_invalid_step_1, pbb, screen_onboarding_sskr_restore_init(); , {&C_icon_warning, "SSKR Recovery", "phrase invalid"}); @@ -158,14 +158,14 @@ UX_FLOW(ux_sskr_nomatch_flow, &ux_sskr_nomatch_step_1, &ux_sskr_nomatch_step_2, &ux_sskr_nomatch_step_3, - &ux_bip39_generate_step_1); + &ux_bip39_recover_step_1); UX_STEP_VALID(ux_sskr_match_step_1, pbb, clean_exit(0), {&C_icon_validate_14, "SSKR Phrase", "is correct"}); UX_STEP_CB(ux_sskr_match_step_2, pb, clean_exit(0), {&C_icon_dashboard_x, "Quit"}); -UX_STEP_CB(ux_sskr_match_step_3, pbb, generate_bip39();, {&BIP39_ICON, "Generate", "BIP39 phrase"}); +UX_STEP_CB(ux_sskr_match_step_3, pbb, recover_bip39();, {&BIP39_ICON, "Recover", "BIP39 phrase"}); UX_FLOW(ux_sskr_match_flow, &ux_sskr_match_step_1, &ux_sskr_match_step_2, &ux_sskr_match_step_3); diff --git a/src/nano/nanox_enter_phrase.c b/src/nano/nanox_enter_phrase.c index 987e0ebf..db44f8dc 100644 --- a/src/nano/nanox_enter_phrase.c +++ b/src/nano/nanox_enter_phrase.c @@ -192,14 +192,14 @@ UX_STEP_NOCB(ux_sskr_nomatch_step_2, "order and spelling", }); UX_STEP_VALID(ux_sskr_nomatch_step_3, pb, ui_idle_init(), {&C_icon_back_x, "Return to menu"}); -UX_STEP_CB(ux_bip39_generate_step_1, pbb, generate_bip39(); - , {&BIP39_ICON, "Generate", "BIP39 phrases"}); +UX_STEP_CB(ux_bip39_recover_step_1, pbb, recover_bip39(); + , {&BIP39_ICON, "Recover", "BIP39 phrases"}); UX_FLOW(ux_sskr_nomatch_flow, &ux_sskr_nomatch_step_1, &ux_sskr_nomatch_step_2, &ux_sskr_nomatch_step_3, - &ux_bip39_generate_step_1); + &ux_bip39_recover_step_1); UX_STEP_VALID(ux_sskr_match_step_1, pbb, @@ -210,7 +210,7 @@ UX_STEP_CB(ux_sskr_match_step_2, pb, clean_exit(0), {&C_icon_dashboard_x, "Quit" UX_FLOW(ux_sskr_match_flow, &ux_sskr_match_step_1, &ux_sskr_match_step_2, - &ux_bip39_generate_step_1); + &ux_bip39_recover_step_1); unsigned int screen_onboarding_restore_word_select_button(unsigned int button_mask, unsigned int button_mask_counter); diff --git a/src/nano/ux_nano.h b/src/nano/ux_nano.h index dd209ee4..1714a2bb 100644 --- a/src/nano/ux_nano.h +++ b/src/nano/ux_nano.h @@ -109,7 +109,7 @@ void screen_common_keyboard_init(unsigned int stack_slot, keyboard_callback_t callback); void set_sskr_descriptor_values(void); -void generate_bip39(void); +void recover_bip39(void); #include "ux_common/common_bip39.h" #include "ux_common/common_sskr.h" diff --git a/src/nano/ux_nano_bip39.c b/src/nano/ux_nano_bip39.c index f595c791..a98e0996 100644 --- a/src/nano/ux_nano_bip39.c +++ b/src/nano/ux_nano_bip39.c @@ -29,7 +29,7 @@ UX_STEP_CB(step_bip39_clean_exit, pb, clean_exit(0), {&C_icon_dashboard_x, "Quit UX_FLOW(display_bip39_flow, &step_display_bip39, &step_bip39_clean_exit, FLOW_LOOP); -void generate_bip39(void) { +void recover_bip39(void) { // BIP39 phrase should already be in G_bolos_ux_context.words_buffer so just need to display it ux_flow_init(0, display_bip39_flow, NULL); } diff --git a/src/stax/ui_stax.c b/src/stax/ui_stax.c index cee37723..b7541180 100644 --- a/src/stax/ui_stax.c +++ b/src/stax/ui_stax.c @@ -26,10 +26,10 @@ static char headerText[HEADER_SIZE] = {0}; static nbgl_layout_t *layout = 0; static void display_home_page(void); -static void display_select_bip39_passphrase_length_page(void); +static void display_bip39_select_phrase_length_page(void); static void display_bip39_keyboard_page(void); static void display_result_page(const bool result); -static void display_numshares_keypad_page(void); +static void display_sskr_select_numshares_page(void); enum bip39_check { BACK_BUTTON_TOKEN = FIRST_USER_TOKEN, @@ -57,7 +57,7 @@ static void on_quit(void) { * About menu */ static const char *const infoTypes[] = {"Version", "Seed Tool"}; -static const char *const infoContents[] = {APPVERSION, "(c) 2023 Ledger"}; +static const char *const infoContents[] = {APPVERSION, "(c) 2024 Ledger"}; static bool on_infos(uint8_t page, nbgl_pageContent_t *content) { if (page == 0) { @@ -94,7 +94,7 @@ static void select_check_type_callback(nbgl_obj_t *obj, nbgl_touchType_t eventTy io_seproxyhal_play_tune(TUNE_TAP_CASUAL); if (obj == screenChildren[SELECT_CHECK_TYPE_BIP39_INDEX]) { nbgl_layoutRelease(layout); - display_select_bip39_passphrase_length_page(); + display_bip39_select_phrase_length_page(); } else if (obj == screenChildren[SELECT_CHECK_TYPE_SSKR_INDEX]) { nbgl_layoutRelease(layout); display_home_page(); @@ -117,7 +117,7 @@ static void display_select_check_type_page(void) { screenChildren[SELECT_CHECK_TYPE_TEXT_INDEX] = (nbgl_obj_t *) generic_screen_set_title(screenChildren[SELECT_CHECK_TYPE_ICON_INDEX]); ((nbgl_text_area_t *) screenChildren[SELECT_CHECK_TYPE_TEXT_INDEX])->text = - "Select type of\nRecovery you wish\nto check"; + "\nSelect type of\nRecovery you wish\nto check"; // create nb words buttons nbgl_objPoolGetArray(BUTTON, SELECT_CHECK_TYPE_NB_BUTTONS, @@ -168,7 +168,7 @@ static void select_generate_type_callback(nbgl_obj_t *obj, nbgl_touchType_t even display_home_page(); } else if (obj == screenChildren[SELECT_GENERATE_TYPE_SSKR_INDEX]) { nbgl_layoutRelease(layout); - display_numshares_keypad_page(); + display_sskr_select_numshares_page(); } else if (obj == screenChildren[SELECT_GENERATE_TYPE_BACK_BUTTON_INDEX]) { nbgl_layoutRelease(layout); display_home_page(); @@ -214,33 +214,33 @@ static void display_select_generate_type_page(void) { /* * Select mnemonic size page */ -enum select_bip_passphrase_length { - SELECT_BIP39_PASSPHRASE_LENGTH_ICON_INDEX = 0, - SELECT_BIP39_PASSPHRASE_LENGTH_TEXT_INDEX, - SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_12_INDEX, - SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_18_INDEX, - SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_24_INDEX, - SELECT_BIP39_PASSPHRASE_LENGTH_BACK_BUTTON_INDEX, - SELECT_BIP39_PASSPHRASE_LENGTH_KBD_TEXT_TOKEN, - SELECT_BIP39_PASSPHRASE_LENGTH_NB_CHILDREN +enum select_bip39_phrase_length { + SELECT_BIP39_PHRASE_LENGTH_ICON_INDEX = 0, + SELECT_BIP39_PHRASE_LENGTH_TEXT_INDEX, + SELECT_BIP39_PHRASE_LENGTH_BUTTON_12_INDEX, + SELECT_BIP39_PHRASE_LENGTH_BUTTON_18_INDEX, + SELECT_BIP39_PHRASE_LENGTH_BUTTON_24_INDEX, + SELECT_BIP39_PHRASE_LENGTH_BACK_BUTTON_INDEX, + SELECT_BIP39_PHRASE_LENGTH_KBD_TEXT_TOKEN, + SELECT_BIP39_PHRASE_LENGTH_NB_CHILDREN }; -#define SELECT_BIP39_PASSPHRASE_LENGTH_NB_BUTTONS 3 +#define SELECT_BIP39_PHRASE_LENGTH_NB_BUTTONS 3 static const char *bip39_passphraseLength[] = {"12 words", "18 words", "24 words"}; -static void select_bip39_passphrase_length_callback(nbgl_obj_t *obj, nbgl_touchType_t eventType) { +static void select_bip39_phrase_length_callback(nbgl_obj_t *obj, nbgl_touchType_t eventType) { nbgl_obj_t **screenChildren = nbgl_screenGetElements(0); if (eventType != TOUCHED) { return; } io_seproxyhal_play_tune(TUNE_TAP_CASUAL); - if (obj == screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_12_INDEX]) { + if (obj == screenChildren[SELECT_BIP39_PHRASE_LENGTH_BUTTON_12_INDEX]) { set_mnemonic_final_size(MNEMONIC_SIZE_12); - } else if (obj == screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_18_INDEX]) { + } else if (obj == screenChildren[SELECT_BIP39_PHRASE_LENGTH_BUTTON_18_INDEX]) { set_mnemonic_final_size(MNEMONIC_SIZE_18); - } else if (obj == screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_24_INDEX]) { + } else if (obj == screenChildren[SELECT_BIP39_PHRASE_LENGTH_BUTTON_24_INDEX]) { set_mnemonic_final_size(MNEMONIC_SIZE_24); - } else if (obj == screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_BACK_BUTTON_INDEX]) { + } else if (obj == screenChildren[SELECT_BIP39_PHRASE_LENGTH_BACK_BUTTON_INDEX]) { nbgl_layoutRelease(layout); display_select_check_type_page(); return; @@ -249,47 +249,47 @@ static void select_bip39_passphrase_length_callback(nbgl_obj_t *obj, nbgl_touchT display_bip39_keyboard_page(); } -static void display_select_bip39_passphrase_length_page(void) { +static void display_bip39_select_phrase_length_page(void) { nbgl_obj_t **screenChildren; // 3 buttons + icon + text + subText nbgl_screenSet(&screenChildren, 6, NULL, - (nbgl_touchCallback_t) &select_bip39_passphrase_length_callback); + (nbgl_touchCallback_t) &select_bip39_phrase_length_callback); - screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_ICON_INDEX] = + screenChildren[SELECT_BIP39_PHRASE_LENGTH_ICON_INDEX] = (nbgl_obj_t *) generic_screen_set_icon(&C_bip39_stax_64px); - screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_TEXT_INDEX] = + screenChildren[SELECT_BIP39_PHRASE_LENGTH_TEXT_INDEX] = (nbgl_obj_t *) generic_screen_set_title( - screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_ICON_INDEX]); - ((nbgl_text_area_t *) screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_TEXT_INDEX])->text = - "How long is your\nBIP39 Recovery\nPhrase?"; + screenChildren[SELECT_BIP39_PHRASE_LENGTH_ICON_INDEX]); + ((nbgl_text_area_t *) screenChildren[SELECT_BIP39_PHRASE_LENGTH_TEXT_INDEX])->text = + "\nHow long is your\nBIP39 Recovery\nPhrase?"; // create nb words buttons nbgl_objPoolGetArray( BUTTON, - SELECT_BIP39_PASSPHRASE_LENGTH_NB_BUTTONS, + SELECT_BIP39_PHRASE_LENGTH_NB_BUTTONS, 0, - (nbgl_obj_t **) &screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_12_INDEX]); + (nbgl_obj_t **) &screenChildren[SELECT_BIP39_PHRASE_LENGTH_BUTTON_12_INDEX]); generic_screen_configure_buttons( - (nbgl_button_t **) &screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_12_INDEX], - SELECT_BIP39_PASSPHRASE_LENGTH_NB_BUTTONS); - ((nbgl_button_t *) screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_12_INDEX])->text = + (nbgl_button_t **) &screenChildren[SELECT_BIP39_PHRASE_LENGTH_BUTTON_12_INDEX], + SELECT_BIP39_PHRASE_LENGTH_NB_BUTTONS); + ((nbgl_button_t *) screenChildren[SELECT_BIP39_PHRASE_LENGTH_BUTTON_12_INDEX])->text = bip39_passphraseLength[0]; - ((nbgl_button_t *) screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_18_INDEX])->text = + ((nbgl_button_t *) screenChildren[SELECT_BIP39_PHRASE_LENGTH_BUTTON_18_INDEX])->text = bip39_passphraseLength[1]; - ((nbgl_button_t *) screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_24_INDEX])->text = + ((nbgl_button_t *) screenChildren[SELECT_BIP39_PHRASE_LENGTH_BUTTON_24_INDEX])->text = bip39_passphraseLength[2]; - ((nbgl_button_t *) screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_24_INDEX]) + ((nbgl_button_t *) screenChildren[SELECT_BIP39_PHRASE_LENGTH_BUTTON_24_INDEX]) ->borderColor = BLACK; - ((nbgl_button_t *) screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_24_INDEX])->innerColor = + ((nbgl_button_t *) screenChildren[SELECT_BIP39_PHRASE_LENGTH_BUTTON_24_INDEX])->innerColor = BLACK; - ((nbgl_button_t *) screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_BUTTON_24_INDEX]) + ((nbgl_button_t *) screenChildren[SELECT_BIP39_PHRASE_LENGTH_BUTTON_24_INDEX]) ->foregroundColor = WHITE; // create back button - screenChildren[SELECT_BIP39_PASSPHRASE_LENGTH_BACK_BUTTON_INDEX] = + screenChildren[SELECT_BIP39_PHRASE_LENGTH_BACK_BUTTON_INDEX] = (nbgl_obj_t *) generic_screen_set_back_button(); nbgl_screenRedraw(); @@ -312,7 +312,7 @@ static void keyboard_dispatcher(const int token, uint8_t index __attribute__((un if (remove_word_from_mnemonic()) { display_bip39_keyboard_page(); } else { - display_select_bip39_passphrase_length_page(); + display_bip39_select_phrase_length_page(); } } else if (token >= FIRST_SUGGESTION_TOKEN) { nbgl_layoutRelease(layout); @@ -402,7 +402,7 @@ static void display_bip39_keyboard_page() { textToEnter, // text to display false, // not grayed-out BUTTON_VMARGIN, // vertical margin from the buttons - SELECT_BIP39_PASSPHRASE_LENGTH_KBD_TEXT_TOKEN); + SELECT_BIP39_PHRASE_LENGTH_KBD_TEXT_TOKEN); nbgl_layoutDraw(layout); } @@ -476,53 +476,28 @@ enum sskr_gen { SSKR_GEN_RESULT_TOKEN, }; -static char numToEnter[MAX_NUMBER_LENGTH + 1] = {0}; -static int keypadIndex = 0; - -static void keypad_dispatcher(const int token, uint8_t index __attribute__((unused))) { +static void sskr_sharenum_validate(const uint8_t *sharenumentry, uint8_t length) { + // Code to validate the entered shares number +} + +static void sskr_sharenum_entry_cb(int token, uint8_t index) { + UNUSED(index); + // Callback for the key navigation (back key mainly) if (token == SSKR_GEN_BACK_BUTTON_TOKEN) { - nbgl_layoutRelease(layout); display_select_generate_type_page(); - } else if (token >= FIRST_SUGGESTION_TOKEN) { - nbgl_layoutRelease(layout); - PRINTF("Selected number is '%d'\n", buttonTexts[token - FIRST_SUGGESTION_TOKEN]); } } - -// function called when a key of keypad is touched -static void keypad_press_callback(const char touchedKey __attribute__((unused))) { - // Function currently a placeholder, remove unused attribute tag -} - -static void display_numshares_keypad_page() { - nbgl_layoutDescription_t layoutDescription = {.modal = false, - .onActionCallback = &keypad_dispatcher}; - nbgl_layoutCenteredInfo_t centeredInfo = {.text1 = NULL, - .text2 = headerText, // to use as "header" - .text3 = NULL, - .style = LARGE_CASE_INFO, - .icon = NULL, - .offsetY = 0, - .onTop = true}; - numToEnter[0] = '\0'; - layout = nbgl_layoutGet(&layoutDescription); - snprintf(headerText, HEADER_SIZE, "Enter number of SSKR shares\nto generate (1 - 16)"); - nbgl_layoutAddProgressIndicator(layout, - 0, - 0, - true, - SSKR_GEN_BACK_BUTTON_TOKEN, - TUNE_TAP_CASUAL); - nbgl_layoutAddCenteredInfo(layout, ¢eredInfo); - keypadIndex = nbgl_layoutAddKeypad(layout, &keypad_press_callback, false); - textIndex = nbgl_layoutAddEnteredText(layout, - false, // numbered - 0, // number to use - numToEnter, // num to display - false, // not grayed-out - BUTTON_VMARGIN, // vertical margin from the buttons - SSKR_GEN_SELECT_THRESHOLD_TOKEN); - nbgl_layoutDraw(layout); + +void display_sskr_select_numshares_page() { + // Draw the keypad + nbgl_useCaseKeypadDigits("Enter number of SSKR shares\nto generate (1 - 16)", + 1, + MAX_NUMBER_LENGTH, + SSKR_GEN_BACK_BUTTON_TOKEN, + false, + TUNE_TAP_CASUAL, + sskr_sharenum_validate, + sskr_sharenum_entry_cb); } /* diff --git a/src/ux_common/onboarding_seed_sskr.c b/src/ux_common/onboarding_seed_sskr.c index b4c8af0a..9ee1ed9d 100644 --- a/src/ux_common/onboarding_seed_sskr.c +++ b/src/ux_common/onboarding_seed_sskr.c @@ -3,7 +3,6 @@ #include #include #include -#include // until cx_crc32 is properly define in lib_cxng/include/lcx_crc.h #include "onboarding_seed_rom_variables.h" #include "common_bip39.h" diff --git a/tests/functional/test_sskr_128bit.py b/tests/functional/test_sskr_128bit.py index d3768c74..bbf61ebb 100755 --- a/tests/functional/test_sskr_128bit.py +++ b/tests/functional/test_sskr_128bit.py @@ -789,7 +789,7 @@ def nanos_sskr_128bit(backend, navigator): navigator.navigate([NavInsID.RIGHT_CLICK], screen_change_before_first_instruction=False) backend.wait_for_text_on_screen("Quit", 1) navigator.navigate([NavInsID.RIGHT_CLICK], screen_change_before_first_instruction=False) - backend.wait_for_text_on_screen("Generate", 1) + backend.wait_for_text_on_screen("Recover", 1) backend.wait_for_text_on_screen("BIP39 phrase", 1) navigator.navigate([NavInsID.BOTH_CLICK], screen_change_before_first_instruction=False) backend.wait_for_text_on_screen("BIP39 Phrase", 1) diff --git a/tests/functional/test_sskr_256bit.py b/tests/functional/test_sskr_256bit.py index ee6c3bf6..3de2b270 100755 --- a/tests/functional/test_sskr_256bit.py +++ b/tests/functional/test_sskr_256bit.py @@ -1189,7 +1189,7 @@ def nanos_sskr_256bit(backend, navigator): navigator.navigate([NavInsID.RIGHT_CLICK], screen_change_before_first_instruction=False) backend.wait_for_text_on_screen("Quit", 1) navigator.navigate([NavInsID.RIGHT_CLICK], screen_change_before_first_instruction=False) - backend.wait_for_text_on_screen("Generate", 1) + backend.wait_for_text_on_screen("Recover", 1) backend.wait_for_text_on_screen("BIP39 phrase", 1) navigator.navigate([NavInsID.BOTH_CLICK], screen_change_before_first_instruction=False) backend.wait_for_text_on_screen("BIP39 Phrase", 1) diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index c9811155..4814aeba 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -6,7 +6,7 @@ endif() # project information project(unit_tests - VERSION 1.7.0 + VERSION 1.8.0 DESCRIPTION "Unit tests for app-seed-tool Ledger Application" LANGUAGES C) @@ -112,7 +112,7 @@ FetchContent_MakeAvailable(cmocka) add_compile_definitions(TEST DEBUG=0 SKIP_FOR_CMOCKA) add_compile_definitions(TARGET_NANOS HAVE_HASH HAVE_HMAC HAVE_SHA224 HAVE_SHA256 HAVE_SHA512 HAVE_PBKDF2 HAVE_ECC HAVE_CRC HAVE_RNG IO_HID_EP_LENGTH=64) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib $ENV{LEDGER_SECURE_SDK}/include $ENV{LEDGER_SECURE_SDK} $ENV{LEDGER_SECURE_SDK}/lib_cxng/src $ENV{LEDGER_SECURE_SDK}/lib_cxng/include $ENV{LEDGER_SECURE_SDK}/lib_ux/include $ENV{LEDGER_SECURE_SDK}/lib_bagl/include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib $ENV{LEDGER_SECURE_SDK}/include $ENV{LEDGER_SECURE_SDK}/lib_cxng/src $ENV{LEDGER_SECURE_SDK}/lib_cxng/include $ENV{LEDGER_SECURE_SDK}/lib_ux/include $ENV{LEDGER_SECURE_SDK}/lib_bagl/include) # add src install_apk_packages(linux-headers)