diff --git a/speculos/cxlib/stax-api-level-cx-14.elf b/speculos/cxlib/stax-api-level-cx-14.elf new file mode 100644 index 00000000..ffad0c76 Binary files /dev/null and b/speculos/cxlib/stax-api-level-cx-14.elf differ diff --git a/speculos/fonts/stax-fonts-14.bin b/speculos/fonts/stax-fonts-14.bin new file mode 100644 index 00000000..ac55d7cf Binary files /dev/null and b/speculos/fonts/stax-fonts-14.bin differ diff --git a/src/bolos/cx_hmac.c b/src/bolos/cx_hmac.c index 5f59176c..fefcde93 100644 --- a/src/bolos/cx_hmac.c +++ b/src/bolos/cx_hmac.c @@ -3,7 +3,6 @@ #include #include "cx.h" -//#include "cx_utils.h" #include "bolos/exception.h" #define IPAD 0x36u diff --git a/src/bolos/fonts_info.c b/src/bolos/fonts_info.c index 84f94757..5000566b 100644 --- a/src/bolos/fonts_info.c +++ b/src/bolos/fonts_info.c @@ -94,6 +94,25 @@ static void parse_nbgl_font(nbgl_font_t *nbgl_font) } } +// Parse provided NBGL font and add bitmap/character pairs +static void parse_nbgl_font_12(nbgl_font_t_12 *nbgl_font) +{ + uint8_t *bitmap = nbgl_font->bitmap; + nbgl_font_character_t_12 *characters = nbgl_font->characters; + + for (uint32_t c = nbgl_font->first_char; c <= nbgl_font->last_char; + c++, characters++) { + // Be sure data is coherent + if (characters->bitmap_offset >= nbgl_font->bitmap_len) { + fprintf(stdout, "bitmap_offset (%d) is >= bitmap_len (%u)!\n", + characters->bitmap_offset, nbgl_font->bitmap_len); + return; + } + uint8_t *ptr = bitmap + characters->bitmap_offset; + add_bitmap_character(ptr, c); + } +} + // Parse provided BAGL font and add bitmap/character pairs static void parse_bagl_font(bagl_font_t *bagl_font, void *code, unsigned long text_load_addr) @@ -183,6 +202,7 @@ void parse_fonts(void *code, unsigned long text_load_addr, case SDK_API_LEVEL_5: case SDK_API_LEVEL_12: case SDK_API_LEVEL_13: + case SDK_API_LEVEL_14: break; default: // Unsupported API_LEVEL, will not parse fonts! @@ -217,7 +237,15 @@ void parse_fonts(void *code, unsigned long text_load_addr, // Parse all those fonts and add bitmap/character pairs for (uint32_t i = 0; i < nb_fonts; i++) { if (hw_model == MODEL_STAX) { - parse_nbgl_font((void *)fonts[i]); + switch (sdk_version) { + case SDK_API_LEVEL_12: + case SDK_API_LEVEL_13: + parse_nbgl_font_12((void *)fonts[i]); + break; + default: + parse_nbgl_font((void *)fonts[i]); + break; + } } else { void *font = remap_addr(code, fonts[i], text_load_addr); diff --git a/src/bolos/nbgl.c b/src/bolos/nbgl.c index f190f55e..ebcc8a31 100644 --- a/src/bolos/nbgl.c +++ b/src/bolos/nbgl.c @@ -112,17 +112,24 @@ unsigned long sys_nbgl_front_draw_img_file(nbgl_area_t *area, uint8_t *buffer, uint8_t header[3]; uint8_t compressed = buffer[4] & 0xF; - if (compressed && optional_uzlib_work_buffer == NULL) { + if (compressed == 1 && optional_uzlib_work_buffer == NULL) { fprintf(stderr, "no uzlib work buffer provided, failing"); return 0; } - size_t len = sizeof(nbgl_area_t) + 1; size_t buffer_len; - if (compressed) { - buffer_len = (buffer[5] | (buffer[5 + 1] << 8) | (buffer[5 + 2] << 16)) + 8; - } else { + switch (compressed) { + case 0: // no compression buffer_len = (area->width * area->height * (area->bpp + 1)) / 8; + break; + case 1: // gzlib compression + buffer_len = (buffer[5] | (buffer[5 + 1] << 8) | (buffer[5 + 2] << 16)) + 8; + break; + case 2: // rle compression + buffer_len = (buffer[5] | (buffer[5 + 1] << 8) | (buffer[5 + 2] << 16)); + buffer += 8; + return sys_nbgl_front_draw_img_rle(area, buffer, buffer_len, + ((colorMap >> (0 * 2)) & 0x3), 0); } len += buffer_len; diff --git a/src/emulate.c b/src/emulate.c index 11d06c61..0fb60ae0 100644 --- a/src/emulate.c +++ b/src/emulate.c @@ -48,6 +48,7 @@ int emulate(unsigned long syscall, unsigned long *parameters, case SDK_API_LEVEL_11: case SDK_API_LEVEL_12: case SDK_API_LEVEL_13: + case SDK_API_LEVEL_14: retid = emulate_unified_sdk(syscall, parameters, ret, verbose, version, model); break; diff --git a/src/fonts.h b/src/fonts.h index b7000588..b4e13f5b 100644 --- a/src/fonts.h +++ b/src/fonts.h @@ -81,7 +81,7 @@ typedef struct { // (They are defined in the SDK, in lib_nbgl/include/nbgl_fonts.h // ============================================================================ -// Current API_LEVEL (12) +// Current API_LEVEL (14) typedef struct { uint32_t encoding : 1; uint32_t bitmap_offset : 14; @@ -98,6 +98,7 @@ typedef struct { uint8_t bpp; uint8_t height; uint8_t line_height; + uint8_t char_kerning; uint8_t crop; uint8_t y_min; uint8_t first_char; @@ -106,6 +107,31 @@ typedef struct { uint8_t *bitmap; } nbgl_font_t; +// SDK_API_LEVEL_12 and SDK_API_LEVEL_13 +typedef struct { + uint32_t encoding : 1; + uint32_t bitmap_offset : 14; + uint32_t width : 6; + uint32_t x_min_offset : 3; + uint32_t y_min_offset : 3; + uint32_t x_max_offset : 2; + uint32_t y_max_offset : 3; +} nbgl_font_character_t_12; + +typedef struct { + uint32_t bitmap_len; + uint8_t font_id; + uint8_t bpp; + uint8_t height; + uint8_t line_height; + uint8_t crop; + uint8_t y_min; + uint8_t first_char; + uint8_t last_char; + nbgl_font_character_t_12 *characters; + uint8_t *bitmap; +} nbgl_font_t_12; + // ============================================================================ void parse_fonts(void *code, unsigned long text_load_addr, diff --git a/src/launcher.c b/src/launcher.c index 8e114d7b..43c962a9 100644 --- a/src/launcher.c +++ b/src/launcher.c @@ -450,7 +450,8 @@ static int load_fonts(char *fonts_path) sdk_version == SDK_API_LEVEL_10 || sdk_version == SDK_API_LEVEL_11 || sdk_version == SDK_API_LEVEL_12 || - sdk_version == SDK_API_LEVEL_13)) { + sdk_version == SDK_API_LEVEL_13 || + sdk_version == SDK_API_LEVEL_14)) { load_addr = STAX_FONTS_ARRAY_ADDR; load_size = 40960; } else { @@ -668,6 +669,8 @@ static sdk_version_t apilevelstr2sdkver(const char *api_level_arg) return SDK_API_LEVEL_12; } else if (strcmp("13", api_level_arg) == 0) { return SDK_API_LEVEL_13; + } else if (strcmp("14", api_level_arg) == 0) { + return SDK_API_LEVEL_14; } else { return SDK_COUNT; } @@ -818,7 +821,8 @@ int main(int argc, char *argv[]) sdk_version != SDK_API_LEVEL_5 && sdk_version != SDK_API_LEVEL_7 && sdk_version != SDK_API_LEVEL_8 && sdk_version != SDK_API_LEVEL_9 && sdk_version != SDK_API_LEVEL_10 && sdk_version != SDK_API_LEVEL_11 && - sdk_version != SDK_API_LEVEL_12 && sdk_version != SDK_API_LEVEL_13) { + sdk_version != SDK_API_LEVEL_12 && sdk_version != SDK_API_LEVEL_13 && + sdk_version != SDK_API_LEVEL_14) { errx(1, "invalid SDK version for the Ledger Stax"); } break; @@ -841,7 +845,8 @@ int main(int argc, char *argv[]) sdk_version == SDK_API_LEVEL_5 || sdk_version == SDK_API_LEVEL_7 || sdk_version == SDK_API_LEVEL_8 || sdk_version == SDK_API_LEVEL_9 || sdk_version == SDK_API_LEVEL_10 || sdk_version == SDK_API_LEVEL_11 || - sdk_version == SDK_API_LEVEL_12 || sdk_version == SDK_API_LEVEL_13) { + sdk_version == SDK_API_LEVEL_12 || sdk_version == SDK_API_LEVEL_13 || + sdk_version == SDK_API_LEVEL_14) { if (load_cxlib(cxlib_path) != 0) { return 1; } diff --git a/src/sdk.h b/src/sdk.h index 6a4e8f44..263c828c 100644 --- a/src/sdk.h +++ b/src/sdk.h @@ -24,6 +24,7 @@ typedef enum { SDK_API_LEVEL_11, SDK_API_LEVEL_12, SDK_API_LEVEL_13, + SDK_API_LEVEL_14, SDK_COUNT } sdk_version_t;