Skip to content

Commit

Permalink
Merge pull request #19 from LedgerHQ/europa
Browse files Browse the repository at this point in the history
Flex porting
  • Loading branch information
lpascal-ledger committed Jul 26, 2024
2 parents ef798e7 + d30a264 commit 7608c38
Show file tree
Hide file tree
Showing 90 changed files with 744 additions and 412 deletions.
8 changes: 0 additions & 8 deletions .github/PULL_REQUEST_TEMPLATE.md

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/build_tests_and_analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_ragger_tests.yml@v1
with:
download_app_binaries_artifact: compiled_app_binaries
run_for_devices: '["stax"]'
run_for_devices: '["stax", "flex"]'

unittesting:
name: C unit testing
Expand All @@ -33,7 +33,7 @@ jobs:
- name: Install cmocka
run: |
sudo apt update
sudo apt install libcmocka-dev lcov
sudo apt install libcmocka-dev lcov libsodium-dev
- name: Compile the tests
run: |
cd tests/unit/
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ jobs:
with:
builtin: clear,rare
check_filenames: true
ignore_words_list: ontop
ignore_words_list: ontop,onl
113 changes: 22 additions & 91 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,127 +18,58 @@
ifeq ($(BOLOS_SDK),)
$(error Environment variable BOLOS_SDK is not set)
endif

include $(BOLOS_SDK)/Makefile.defines

all: default

# Main app configuration

APPNAME = "Recovery Check"
APPVERSION_M = 1
APPVERSION_N = 2
APPVERSION_P = 3
APPVERSION_N = 4
APPVERSION_P = 0
APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)"

APP_LOAD_PARAMS = --appFlags 0x10 $(COMMON_LOAD_PARAMS) --curve secp256k1 --path ""
VARIANT_PARAM = NONE
VARIANT_VALUES = recovery_check

ifeq ($(TARGET_NAME), TARGET_NANOS)
ICONNAME=icons/nanos_app_recovery_check.gif
else ifeq ($(TARGET_NAME), TARGET_STAX)
ICONNAME=icons/stax_recovery_check_32px.gif
else
ICONNAME=icons/nanox_app_recovery_check.gif
endif
CURVE_APP_LOAD_PARAMS = secp256k1
PATH_APP_LOAD_PARAMS = ""
HAVE_APPLICATION_FLAG_DERIVE_MASTER = 1

# Build configuration
ICON_NANOS = icons/nanos_recovery_check.gif
ICON_NANOSP = icons/nanox_recovery_check.gif
ICON_NANOX = icons/nanox_recovery_check.gif
ICON_STAX = icons/stax_recovery_check.gif
ICON_FLEX = icons/flex_recovery_check.gif

DEFINES += APPVERSION=\"$(APPVERSION)\"
DEFINES += LEDGER_MAJOR_VERSION=$(APPVERSION_M)
DEFINES += LEDGER_MINOR_VERSION=$(APPVERSION_N)
DEFINES += LEDGER_PATCH_VERSION=$(APPVERSION_P)
DEFINES += OS_IO_SEPROXYHAL
DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=0 WEBUSB_URL=""

DEFINES += BOLOS_APP_ICON_SIZE_B=\(9+32\)
#DEFINES += HAVE_ELECTRUM
DEFINES += IO_USB_MAX_ENDPOINTS=4 IO_HID_EP_LENGTH=64
DEFINES += HAVE_SPRINTF

ifneq ($(TARGET_NAME), TARGET_STAX)
ifneq ($(TARGET_NAME), $(filter $(TARGET_NAME), TARGET_STAX TARGET_FLEX))
$(info Using BAGL)
DEFINES += HAVE_BAGL HAVE_UX_FLOW
else
$(info Using NBGL)
DEFINES += NBGL_KEYBOARD
endif

ifeq ($(TARGET_NAME), TARGET_NANOS)
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128
else
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
ifneq ($(TARGET_NAME), TARGET_STAX)
DEFINES += HAVE_BAGL
ifneq ($(TARGET_NAME), TARGET_NANOS)
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
DEFINES += HAVE_GLO096
DEFINES += BAGL_WIDTH=128 BAGL_HEIGHT=64
DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX
DEFINES += HAVE_KEYBOARD_UX
endif
endif

DEBUG = 0

ifneq ($(DEBUG), 0)
$(info DEBUG enabled)
DEFINES += HAVE_IO_USB HAVE_USB_APDU
SDK_SOURCE_PATH += lib_stusb lib_stusb_impl
DEFINES += HAVE_PRINTF
ifeq ($(TARGET_NAME), TARGET_NANOS)
DEFINES += PRINTF=screen_printf
else
DEFINES += PRINTF=mcu_usb_printf
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128
endif
else
DEFINES += PRINTF\(...\)=
endif

##############
# Compiler #
##############
ifneq ($(BOLOS_ENV),)
$(info BOLOS_ENV=$(BOLOS_ENV))
CLANGPATH := $(BOLOS_ENV)/clang-arm-fropi/bin/
GCCPATH := $(BOLOS_ENV)/gcc-arm-none-eabi-5_3-2016q1/bin/
else
$(info BOLOS_ENV is not set: falling back to CLANGPATH and GCCPATH)
endif
ifeq ($(CLANGPATH),)
$(info CLANGPATH is not set: clang will be used from PATH)
endif
ifeq ($(GCCPATH),)
$(info GCCPATH is not set: arm-none-eabi-* will be used from PATH)
$(info Using NBGL)
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
DEFINES += NBGL_KEYBOARD
endif

CC := $(CLANGPATH)clang
CFLAGS += -Wshadow -Wformat
AS := $(GCCPATH)arm-none-eabi-gcc
LD := $(GCCPATH)arm-none-eabi-gcc
LDLIBS += -lm -lgcc -lc

include $(BOLOS_SDK)/Makefile.glyphs
DEBUG = 0

APP_SOURCE_PATH += src

ifneq ($(TARGET_NAME), TARGET_NANOS)
ifneq ($(TARGET_NAME), TARGET_STAX)
SDK_SOURCE_PATH += lib_ux
endif
endif

# Main rules

load: all
python -m ledgerblue.loadApp $(APP_LOAD_PARAMS)

delete:
python -m ledgerblue.deleteApp $(COMMON_DELETE_PARAMS)

# Import generic rules from the SDK

include $(BOLOS_SDK)/Makefile.rules


listvariants:
@echo VARIANTS APP recovery_check
include $(BOLOS_SDK)/Makefile.standard_app
Binary file added icons/flex_recovery_check.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
Binary file removed icons/recovery_check.png
Binary file not shown.
File renamed without changes
2 changes: 1 addition & 1 deletion ledger_app.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[app]
build_directory = "./"
sdk = "C"
devices = ["nanos", "nanox", "nanos+", "stax"]
devices = ["nanos", "nanox", "nanos+", "stax", "flex"]

[tests]
unit_directory = "./tests/unit"
Expand Down
75 changes: 13 additions & 62 deletions src/main.c → src/app_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,43 +25,26 @@
extern enum UI_STATE uiState;
#endif

bolos_ux_params_t G_ux_params;
unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B];

static unsigned int current_text_pos; // parsing cursor in the text to display
static unsigned int text_y; // current location of the displayed text

// UI currently displayed
enum UI_STATE { UI_IDLE, UI_TEXT, UI_APPROVAL };

unsigned short io_exchange_al(unsigned char channel, unsigned short tx_len) {
switch (channel & ~(IO_FLAGS)) {
case CHANNEL_KEYBOARD:
break;

// multiplexed io exchange over a SPI channel and TLV encapsulated protocol
case CHANNEL_SPI:
if (tx_len) {
io_seproxyhal_spi_send(G_io_apdu_buffer, tx_len);

if (channel & IO_RESET_AFTER_REPLIED) {
reset();
}
return 0; // nothing received from the master so far (it's a tx
// transaction)
} else {
return io_seproxyhal_spi_recv(G_io_apdu_buffer, sizeof(G_io_apdu_buffer), 0);
}
void app_main(void) {
current_text_pos = 0;
text_y = 60;
#if defined(HAVE_BAGL)
uiState = UI_IDLE;
#endif

default:
THROW(INVALID_PARAMETER);
}
return 0;
}
#if defined(HAVE_NBGL)
nbgl_objInit();
#elif defined(HAVE_BAGL)
UX_INIT();
#endif

static void sample_main(void) {
// next timer callback in 500 ms
// UX_CALLBACK_SET_INTERVAL(500);
ui_idle_init();

uint8_t flags = 0;

Expand Down Expand Up @@ -94,7 +77,7 @@ unsigned char io_event(unsigned char channel __attribute__((unused))) {
UX_REDISPLAY();
} else {
if (G_bolos_ux_context.processing == 1) {
UX_DISPLAYED_EVENT(compare_recovery_phrase(););
UX_DISPLAYED_EVENT(compare_recovery_phrase_and_display_result(););
} else {
UX_DISPLAYED_EVENT();
}
Expand Down Expand Up @@ -129,35 +112,3 @@ unsigned char io_event(unsigned char channel __attribute__((unused))) {
// command has been processed, DO NOT reset the current APDU transport
return 1;
}

__attribute__((section(".boot"))) int main(void) {
// exit critical section
__asm volatile("cpsie i");

current_text_pos = 0;
text_y = 60;
#if defined(HAVE_BAGL)
uiState = UI_IDLE;
#endif
// ensure exception will work as planned
os_boot();

#if defined(HAVE_NBGL)
nbgl_objInit();
#elif defined(HAVE_BAGL)
UX_INIT();
#endif

BEGIN_TRY {
TRY {
io_seproxyhal_init();
ui_idle_init();
sample_main();
}
CATCH_OTHER(e) {
}
FINALLY {
}
}
END_TRY;
}
21 changes: 0 additions & 21 deletions src/ux_common/common.h → src/bagl/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,7 @@

#pragma once

#include <ux.h>

#ifdef OS_IO_SEPROXYHAL

#ifndef SPRINTF
// avoid typing the size each time
#define SPRINTF(strbuf, ...) snprintf((char*) (strbuf), sizeof(strbuf), __VA_ARGS__)
#endif

#if defined(HAVE_NBGL)
typedef const nbgl_obj_t* (*keyboard_callback_t)(unsigned int event, unsigned int value);
#else
typedef const bagl_element_t* (*keyboard_callback_t)(unsigned int event, unsigned int value);
#endif

void bolos_ux_hslider3_init(unsigned int total_count);
void bolos_ux_hslider3_set_current(unsigned int current);
void bolos_ux_hslider3_next(void);
void bolos_ux_hslider3_previous(void);

// all screens
void screen_onboarding_3_restore_init(void);
void screen_onboarding_4_restore_word_init(unsigned int action);

#endif // OS_IO_SEPROXYHAL
45 changes: 7 additions & 38 deletions src/nano/nanos_enter_phrase.c → src/bagl/nanos_enter_phrase.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <lcx_hmac.h>
#include <ledger_assert.h>

#include "common.h"
#include "constants.h"
#include "glyphs.h"
#include "ui.h"
Expand Down Expand Up @@ -213,49 +214,17 @@ const bagl_element_t* screen_onboarding_4_restore_word_keyboard_callback(unsigne
return &G_ux.tmp_element;
}

void compare_recovery_phrase(void) {
void compare_recovery_phrase_and_display_result(void) {
G_bolos_ux_context.processing = 0;

io_seproxyhal_general_status();

// convert mnemonic to hex-seed
uint8_t buffer[64];

bolos_ux_mnemonic_to_seed((unsigned char*) G_bolos_ux_context.words_buffer,
G_bolos_ux_context.words_buffer_length,
buffer);
PRINTF("Input seed:\n %.*H\n", 64, buffer);

// get rootkey from hex-seed
cx_hmac_sha512_t ctx;
const char key[] = "Bitcoin seed";

LEDGER_ASSERT(cx_hmac_sha512_init_no_throw(&ctx, (const uint8_t*) key, strlen(key)) == CX_OK,
"HMAC init failed");
LEDGER_ASSERT(cx_hmac_no_throw((cx_hmac_t*) &ctx, CX_LAST, buffer, 64, buffer, 64) == CX_OK,
"HMAC failed");
PRINTF("Root key from input:\n%.*H\n", 64, buffer);

// get rootkey from device's seed
uint8_t buffer_device[64];

// os_derive_bip32* do not accept NULL path, even with a size of 0, so we provide an empty path
const unsigned int empty_path = 0;
if (os_derive_bip32_no_throw(CX_CURVE_256K1,
&empty_path,
0,
buffer_device,
buffer_device + 32) != CX_OK) {
PRINTF("An error occurred while comparing the recovery phrase\n");
return;
}
PRINTF("Root key from device: \n%.*H\n", 64, buffer_device);

// compare both rootkey
if (os_secure_memcmp(buffer, buffer_device, 64)) {
ux_flow_init(0, flow_final_nomatch, NULL);
} else {
const bool result = compare_recovery_phrase((uint8_t*) G_bolos_ux_context.words_buffer,
G_bolos_ux_context.words_buffer_length);
if (result) {
ux_flow_init(0, flow_final_match, NULL);
} else {
ux_flow_init(0, flow_final_nomatch, NULL);
}
}

Expand Down
Loading

0 comments on commit 7608c38

Please sign in to comment.