diff --git a/speculos/cxlib/stax-api-level-cx-15.elf b/speculos/cxlib/stax-api-level-cx-15.elf new file mode 100755 index 00000000..7a312c04 Binary files /dev/null and b/speculos/cxlib/stax-api-level-cx-15.elf differ diff --git a/speculos/fonts/stax-fonts-15.bin b/speculos/fonts/stax-fonts-15.bin new file mode 100644 index 00000000..a3f89191 Binary files /dev/null and b/speculos/fonts/stax-fonts-15.bin differ diff --git a/src/bolos/fonts_info.c b/src/bolos/fonts_info.c index 5000566b..4783fc80 100644 --- a/src/bolos/fonts_info.c +++ b/src/bolos/fonts_info.c @@ -5,14 +5,15 @@ #include "fonts.h" #include "sdk.h" -#define MAX_BITMAP_CHAR (MAX_NB_FONTS * 128) +#define MAX_BITMAP_CHAR (MAX_NB_FONTS * 128) +#define MAX_BITMAP_CHAR_12 (MAX_NB_FONTS_12 * 128) typedef struct { const uint8_t *bitmap; uint32_t character; } BITMAP_CHAR; -BITMAP_CHAR bitmap_char[MAX_BITMAP_CHAR]; +BITMAP_CHAR bitmap_char[MAX_BITMAP_CHAR_12]; uint32_t nb_bitmap_char; // Return the real addr depending on where the app was loaded @@ -31,9 +32,16 @@ static void *remap_addr(void *code, uint32_t addr, uint32_t text_load_addr) // Store bitmap/character pair static void add_bitmap_character(uint8_t *bitmap, uint32_t character) { - if (nb_bitmap_char >= MAX_BITMAP_CHAR) { - fprintf(stdout, "ERROR: we reached MAX_BITMAP_CHAR!\n"); - return; + if (sdk_version > SDK_API_LEVEL_14) { + if (nb_bitmap_char >= MAX_BITMAP_CHAR) { + fprintf(stdout, "ERROR: we reached MAX_BITMAP_CHAR!\n"); + return; + } + } else { + if (nb_bitmap_char >= MAX_BITMAP_CHAR_12) { + fprintf(stdout, "ERROR: we reached MAX_BITMAP_CHAR_12!\n"); + return; + } } // Space character is empty and have no bitmap -> erase it with next character if (nb_bitmap_char && bitmap_char[nb_bitmap_char - 1].bitmap == bitmap) { @@ -81,6 +89,25 @@ static void parse_nbgl_font(nbgl_font_t *nbgl_font) uint8_t *bitmap = nbgl_font->bitmap; nbgl_font_character_t *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 (%u) 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 NBGL font and add bitmap/character pairs +static void parse_nbgl_font_14(nbgl_font_t_14 *nbgl_font) +{ + uint8_t *bitmap = nbgl_font->bitmap; + nbgl_font_character_t_14 *characters = nbgl_font->characters; + for (uint32_t c = nbgl_font->first_char; c <= nbgl_font->last_char; c++, characters++) { // Be sure data is coherent @@ -203,6 +230,7 @@ void parse_fonts(void *code, unsigned long text_load_addr, case SDK_API_LEVEL_12: case SDK_API_LEVEL_13: case SDK_API_LEVEL_14: + case SDK_API_LEVEL_15: break; default: // Unsupported API_LEVEL, will not parse fonts! @@ -211,7 +239,11 @@ void parse_fonts(void *code, unsigned long text_load_addr, // On Stax, fonts are loaded at a known location if (hw_model == MODEL_STAX) { fonts = (void *)STAX_FONTS_ARRAY_ADDR; - nb_fonts = STAX_NB_FONTS; + if (sdk_version > SDK_API_LEVEL_14) { + nb_fonts = STAX_NB_FONTS; + } else { + nb_fonts = STAX_NB_FONTS_12; + } } else { fonts = remap_addr(code, fonts_addr, text_load_addr); nb_fonts = fonts_size / 4; @@ -228,10 +260,20 @@ void parse_fonts(void *code, unsigned long text_load_addr, nb_fonts, fonts[nb_fonts]); return; } - if (nb_fonts > MAX_NB_FONTS) { - fprintf(stdout, "ERROR: nb_fonts (%u) is bigger than MAX_NB_FONTS (%d)!\n", - nb_fonts, MAX_NB_FONTS); - return; + if (sdk_version > SDK_API_LEVEL_14) { + if (nb_fonts > MAX_NB_FONTS) { + fprintf(stdout, + "ERROR: nb_fonts (%u) is bigger than MAX_NB_FONTS (%d)!\n", + nb_fonts, MAX_NB_FONTS); + return; + } + } else { + if (nb_fonts > MAX_NB_FONTS_12) { + fprintf(stdout, + "ERROR: nb_fonts (%u) is bigger than MAX_NB_FONTS_12 (%d)!\n", + nb_fonts, MAX_NB_FONTS_12); + return; + } } // Parse all those fonts and add bitmap/character pairs @@ -242,6 +284,9 @@ void parse_fonts(void *code, unsigned long text_load_addr, case SDK_API_LEVEL_13: parse_nbgl_font_12((void *)fonts[i]); break; + case SDK_API_LEVEL_14: + parse_nbgl_font_14((void *)fonts[i]); + break; default: parse_nbgl_font((void *)fonts[i]); break; diff --git a/src/fonts.h b/src/fonts.h index b4e13f5b..8ef3eeec 100644 --- a/src/fonts.h +++ b/src/fonts.h @@ -5,9 +5,13 @@ // ============================================================================ #define STAX_FONTS_ARRAY_ADDR 0x00805000 -#define STAX_NB_FONTS 7 +// Latest (starting from SDK_API_LEVEL_15) +#define STAX_NB_FONTS 6 +// SDK_API_LEVEL_12 to SDK_API_LEVEL_14 +#define STAX_NB_FONTS_12 7 -#define MAX_NB_FONTS STAX_NB_FONTS +#define MAX_NB_FONTS STAX_NB_FONTS +#define MAX_NB_FONTS_12 STAX_NB_FONTS_12 // ============================================================================ // BAGL font related structures @@ -81,7 +85,33 @@ typedef struct { // (They are defined in the SDK, in lib_nbgl/include/nbgl_fonts.h // ============================================================================ -// Current API_LEVEL (14) +// Current API_LEVEL (15) +typedef struct { + uint32_t bitmap_offset; + uint32_t encoding : 1; + uint32_t width : 6; + uint32_t x_min_offset : 4; + uint32_t y_min_offset : 6; + uint32_t x_max_offset : 4; + uint32_t y_max_offset : 6; +} nbgl_font_character_t; + +typedef struct { + uint32_t bitmap_len; + uint8_t font_id; + 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; + uint8_t last_char; + nbgl_font_character_t *characters; + uint8_t *bitmap; +} nbgl_font_t; + +// SDK_API_LEVEL_14 typedef struct { uint32_t encoding : 1; uint32_t bitmap_offset : 14; @@ -90,7 +120,7 @@ typedef struct { uint32_t y_min_offset : 3; uint32_t x_max_offset : 2; uint32_t y_max_offset : 3; -} nbgl_font_character_t; +} nbgl_font_character_t_14; typedef struct { uint32_t bitmap_len; @@ -103,9 +133,9 @@ typedef struct { uint8_t y_min; uint8_t first_char; uint8_t last_char; - nbgl_font_character_t *characters; + nbgl_font_character_t_14 *characters; uint8_t *bitmap; -} nbgl_font_t; +} nbgl_font_t_14; // SDK_API_LEVEL_12 and SDK_API_LEVEL_13 typedef struct { diff --git a/src/launcher.c b/src/launcher.c index 4c831f8d..7d52b3b6 100644 --- a/src/launcher.c +++ b/src/launcher.c @@ -791,7 +791,7 @@ int main(int argc, char *argv[]) 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_14) { + sdk_version != SDK_API_LEVEL_14 && sdk_version != SDK_API_LEVEL_15) { errx(1, "invalid SDK version for the Ledger Stax"); } break; diff --git a/src/sdk.h b/src/sdk.h index dd409b91..161f74a6 100644 --- a/src/sdk.h +++ b/src/sdk.h @@ -29,6 +29,7 @@ typedef enum { SDK_API_LEVEL_12, SDK_API_LEVEL_13, SDK_API_LEVEL_14, + SDK_API_LEVEL_15, SDK_COUNT } sdk_version_t;