From c3f84e2949b922cea87940253907f46dce35d7ce Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Fri, 15 Dec 2023 23:50:33 +0100 Subject: [PATCH] perf(core): optimize boot speed on U5 by using has processor to calculate image hashes, switches to sha256 [no changelog] --- core/embed/boardloader/main.c | 7 + core/embed/bootloader/main.c | 8 ++ core/embed/bootloader/messages.c | 12 +- core/embed/bootloader_ci/main.c | 9 ++ core/embed/firmware/main.c | 8 ++ core/embed/lib/image.c | 52 ++++--- core/embed/lib/image.h | 5 +- core/embed/lib/image_hash_conf.h | 41 ++++++ core/embed/models/model_D001.h | 1 + core/embed/models/model_D002.h | 1 + core/embed/models/model_T1B1.h | 1 + core/embed/models/model_T2B1.h | 1 + core/embed/models/model_T2T1.h | 1 + core/embed/models/model_T3T1.h | 1 + core/embed/prodtest/main.c | 7 + core/embed/reflash/main.c | 8 ++ core/embed/trezorhal/boards/stm32u5a9j-dk.h | 1 + core/embed/trezorhal/boards/trezor_t3t1_v4.h | 1 + core/embed/trezorhal/hash_processor.h | 33 +++++ core/embed/trezorhal/stm32u5/hash_processor.c | 132 ++++++++++++++++++ .../trezorhal/stm32u5/stm32u5xx_hal_conf.h | 2 +- .../D002/vendor_dev_DO_NOT_SIGN.json | 2 +- ...endorheader_dev_DO_NOT_SIGN_signed_dev.bin | Bin 4608 -> 4608 bytes .../vendorheader_dev_DO_NOT_SIGN_unsigned.bin | Bin 4608 -> 4608 bytes .../D002/vendorheader_unsafe_signed_dev.bin | Bin 4608 -> 4608 bytes .../D002/vendorheader_unsafe_signed_prod.bin | Bin 4608 -> 0 bytes ...endorheader_dev_DO_NOT_SIGN_signed_dev.bin | Bin 4608 -> 4608 bytes .../T3T1/vendorheader_unsafe_signed_dev.bin | Bin 4608 -> 4608 bytes .../T3T1/vendorheader_unsafe_signed_prod.bin | Bin 4608 -> 0 bytes core/site_scons/boards/stm32u5_common.py | 5 + python/src/trezorlib/firmware/models.py | 10 +- python/src/trezorlib/firmware/vendor.py | 3 +- 32 files changed, 312 insertions(+), 40 deletions(-) create mode 100644 core/embed/lib/image_hash_conf.h create mode 100644 core/embed/trezorhal/hash_processor.h create mode 100644 core/embed/trezorhal/stm32u5/hash_processor.c delete mode 100644 core/embed/vendorheader/D002/vendorheader_unsafe_signed_prod.bin delete mode 100644 core/embed/vendorheader/T3T1/vendorheader_unsafe_signed_prod.bin diff --git a/core/embed/boardloader/main.c b/core/embed/boardloader/main.c index 47eed64d73..ea1a00d9b5 100644 --- a/core/embed/boardloader/main.c +++ b/core/embed/boardloader/main.c @@ -38,6 +38,9 @@ #ifdef USE_SDRAM #include "sdram.h" #endif +#ifdef USE_HASH_PROCESSOR +#include "hash_processor.h" +#endif #include "lowlevel.h" #include "model.h" @@ -266,6 +269,10 @@ int main(void) { sdram_init(); #endif +#ifdef USE_HASH_PROCESSOR + hash_processor_init(); +#endif + display_init(); display_clear(); diff --git a/core/embed/bootloader/main.c b/core/embed/bootloader/main.c index 307d77cce1..c87780bf5d 100644 --- a/core/embed/bootloader/main.c +++ b/core/embed/bootloader/main.c @@ -55,6 +55,10 @@ #ifdef USE_RGB_LED #include "rgb_led.h" #endif +#ifdef USE_HASH_PROCESSOR +#include "hash_processor.h" +#endif + #include "model.h" #include "usb.h" #include "version.h" @@ -418,6 +422,10 @@ int bootloader_main(void) { } #endif +#ifdef USE_HASH_PROCESSOR + hash_processor_init(); +#endif + #ifdef USE_DMA2D dma2d_init(); #endif diff --git a/core/embed/bootloader/messages.c b/core/embed/bootloader/messages.c index dcae074037..76fa4d5f78 100644 --- a/core/embed/bootloader/messages.c +++ b/core/embed/bootloader/messages.c @@ -599,12 +599,12 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, secbool is_ilu = secfalse; // interaction-less update if (bootargs_get_command() == BOOT_COMMAND_INSTALL_UPGRADE) { - BLAKE2S_CTX ctx; - uint8_t hash[BLAKE2S_DIGEST_LENGTH]; - blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH); - blake2s_Update(&ctx, CHUNK_BUFFER_PTR, - vhdr.hdrlen + received_hdr->hdrlen); - blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH); + IMAGE_HASH_CTX ctx; + uint8_t hash[IMAGE_HASH_DIGEST_LENGTH]; + IMAGE_HASH_INIT(&ctx); + IMAGE_HASH_UPDATE(&ctx, CHUNK_BUFFER_PTR, + vhdr.hdrlen + received_hdr->hdrlen); + IMAGE_HASH_FINAL(&ctx, hash); // the firmware must be the same as confirmed by the user if (memcmp(bootargs_get_args()->hash, hash, sizeof(hash)) != 0) { diff --git a/core/embed/bootloader_ci/main.c b/core/embed/bootloader_ci/main.c index 6ad597d6bb..40c56d58a9 100644 --- a/core/embed/bootloader_ci/main.c +++ b/core/embed/bootloader_ci/main.c @@ -39,6 +39,11 @@ #include "bootui.h" #include "messages.h" #include "model.h" + +#ifdef USE_HASH_PROCESSOR +#include "hash_processor.h" +#endif + // #include "mpu.h" #define USB_IFACE_NUM 0 @@ -207,6 +212,10 @@ int main(void) { touch_power_on(); #endif +#ifdef USE_HASH_PROCESSOR + hash_processor_init(); +#endif + mpu_config_bootloader(); #if PRODUCTION diff --git a/core/embed/firmware/main.c b/core/embed/firmware/main.c index 878049408d..db1d244eb9 100644 --- a/core/embed/firmware/main.c +++ b/core/embed/firmware/main.c @@ -74,6 +74,10 @@ #ifdef USE_SD_CARD #include "sdcard.h" #endif +#ifdef USE_HASH_PROCESSOR +#include "hash_processor.h" +#endif + #ifdef USE_OPTIGA #include "optiga_commands.h" #include "optiga_transport.h" @@ -120,6 +124,10 @@ int main(void) { enable_systemview(); #endif +#ifdef USE_HASH_PROCESSOR + hash_processor_init(); +#endif + #ifdef USE_DMA2D dma2d_init(); #endif diff --git a/core/embed/lib/image.c b/core/embed/lib/image.c index 3b15ef6db5..b2bce0f5ad 100644 --- a/core/embed/lib/image.c +++ b/core/embed/lib/image.c @@ -19,7 +19,6 @@ #include -#include "blake2s.h" #include "ed25519-donna/ed25519.h" #include "common.h" @@ -120,13 +119,13 @@ secbool check_image_model(const image_header *const hdr) { } void get_image_fingerprint(const image_header *const hdr, uint8_t *const out) { - BLAKE2S_CTX ctx; - blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH); - blake2s_Update(&ctx, hdr, IMAGE_HEADER_SIZE - IMAGE_SIG_SIZE); + IMAGE_HASH_CTX ctx; + IMAGE_HASH_INIT(&ctx); + IMAGE_HASH_UPDATE(&ctx, (uint8_t *)hdr, IMAGE_HEADER_SIZE - IMAGE_SIG_SIZE); for (int i = 0; i < IMAGE_SIG_SIZE; i++) { - blake2s_Update(&ctx, (const uint8_t *)"\x00", 1); + IMAGE_HASH_UPDATE(&ctx, (const uint8_t *)"\x00", 1); } - blake2s_Final(&ctx, out, BLAKE2S_DIGEST_LENGTH); + IMAGE_HASH_FINAL(&ctx, out); } secbool check_image_header_sig(const image_header *const hdr, uint8_t key_m, @@ -141,7 +140,7 @@ secbool check_image_header_sig(const image_header *const hdr, uint8_t key_m, return secfalse; return sectrue * - (0 == ed25519_sign_open(fingerprint, BLAKE2S_DIGEST_LENGTH, pub, + (0 == ed25519_sign_open(fingerprint, IMAGE_HASH_DIGEST_LENGTH, pub, *(const ed25519_signature *)hdr->sig)); } @@ -199,21 +198,21 @@ secbool check_vendor_header_sig(const vendor_header *const vhdr, uint8_t key_m, // check header signature - uint8_t hash[BLAKE2S_DIGEST_LENGTH]; - BLAKE2S_CTX ctx; - blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH); - blake2s_Update(&ctx, vhdr->origin, vhdr->hdrlen - IMAGE_SIG_SIZE); + uint8_t hash[IMAGE_HASH_DIGEST_LENGTH]; + IMAGE_HASH_CTX ctx; + IMAGE_HASH_INIT(&ctx); + IMAGE_HASH_UPDATE(&ctx, vhdr->origin, vhdr->hdrlen - IMAGE_SIG_SIZE); for (int i = 0; i < IMAGE_SIG_SIZE; i++) { - blake2s_Update(&ctx, (const uint8_t *)"\x00", 1); + IMAGE_HASH_UPDATE(&ctx, (const uint8_t *)"\x00", 1); } - blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH); + IMAGE_HASH_FINAL(&ctx, hash); ed25519_public_key pub; if (sectrue != compute_pubkey(key_m, key_n, keys, vhdr->sigmask, pub)) return secfalse; return sectrue * - (0 == ed25519_sign_open(hash, BLAKE2S_DIGEST_LENGTH, pub, + (0 == ed25519_sign_open(hash, IMAGE_HASH_DIGEST_LENGTH, pub, *(const ed25519_signature *)vhdr->sig)); } @@ -223,20 +222,22 @@ secbool check_vendor_header_keys(const vendor_header *const vhdr) { } void vendor_header_hash(const vendor_header *const vhdr, uint8_t *hash) { - BLAKE2S_CTX ctx; - blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH); - blake2s_Update(&ctx, vhdr->vstr, vhdr->vstr_len); - blake2s_Update(&ctx, "Trezor Vendor Header", 20); - blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH); + IMAGE_HASH_CTX ctx; + IMAGE_HASH_INIT(&ctx); + IMAGE_HASH_UPDATE(&ctx, (const uint8_t *)vhdr->vstr, vhdr->vstr_len); + IMAGE_HASH_UPDATE(&ctx, (const uint8_t *)"Trezor Vendor Header", 20); + IMAGE_HASH_FINAL(&ctx, hash); } secbool check_single_hash(const uint8_t *const hash, const uint8_t *const data, int len) { - uint8_t h[BLAKE2S_DIGEST_LENGTH]; - blake2s(data, len, h, BLAKE2S_DIGEST_LENGTH); - return sectrue * (0 == memcmp(h, hash, BLAKE2S_DIGEST_LENGTH)); + uint8_t s_c[IMAGE_HASH_DIGEST_LENGTH] = {0}; + + IMAGE_HASH_CALC(data, len, s_c); + + return sectrue * (0 == memcmp(s_c, hash, IMAGE_HASH_DIGEST_LENGTH)); } -// + secbool check_image_contents(const image_header *const hdr, uint32_t firstskip, const flash_area_t *area) { if (0 == area) { @@ -340,10 +341,7 @@ secbool check_firmware_header(const uint8_t *header, size_t header_size, get_image_fingerprint(ihdr, info->fingerprint); // calculate hash of both vendor and image headers - BLAKE2S_CTX ctx; - blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH); - blake2s_Update(&ctx, header, vhdr.hdrlen + ihdr->hdrlen); - blake2s_Final(&ctx, &info->hash, BLAKE2S_DIGEST_LENGTH); + IMAGE_HASH_CALC(header, vhdr.hdrlen + ihdr->hdrlen, info->hash); return sectrue; } diff --git a/core/embed/lib/image.h b/core/embed/lib/image.h index 326b4bb524..bb6c58a396 100644 --- a/core/embed/lib/image.h +++ b/core/embed/lib/image.h @@ -23,6 +23,7 @@ #include #include "blake2s.h" #include "flash.h" +#include "image_hash_conf.h" #include "model.h" #include "secbool.h" @@ -90,9 +91,9 @@ typedef struct { uint8_t ver_patch; uint8_t ver_build; // firmware fingerprint - uint8_t fingerprint[BLAKE2S_DIGEST_LENGTH]; + uint8_t fingerprint[IMAGE_HASH_DIGEST_LENGTH]; // hash of vendor and image header - uint8_t hash[BLAKE2S_DIGEST_LENGTH]; + uint8_t hash[IMAGE_HASH_DIGEST_LENGTH]; } firmware_header_info_t; const image_header *read_image_header(const uint8_t *const data, diff --git a/core/embed/lib/image_hash_conf.h b/core/embed/lib/image_hash_conf.h new file mode 100644 index 0000000000..1fab5efabd --- /dev/null +++ b/core/embed/lib/image_hash_conf.h @@ -0,0 +1,41 @@ +#ifndef LIB_IMAGE_HASH_H_ +#define LIB_IMAGE_HASH_H_ + +#include "model.h" +#include TREZOR_BOARD + +#ifdef IMAGE_HASH_SHA256 +#include "sha2.h" +#define IMAGE_HASH_DIGEST_LENGTH SHA256_DIGEST_LENGTH +#ifdef USE_HASH_PROCESSOR +#include "hash_processor.h" +#define IMAGE_HASH_CTX hash_sha265_context_t +#define IMAGE_HASH_INIT(ctx) hash_processor_sha256_init(ctx) +#define IMAGE_HASH_UPDATE(ctx, data, len) \ + hash_processor_sha256_update(ctx, data, len) +#define IMAGE_HASH_FINAL(ctx, output) hash_processor_sha256_final(ctx, output) +#define IMAGE_HASH_CALC(data, len, output) \ + hash_processor_sha256_calc(data, len, output) +#else +#define IMAGE_HASH_CTX SHA256_CTX +#define IMAGE_HASH_INIT(ctx) sha256_Init(ctx) +#define IMAGE_HASH_UPDATE(ctx, data, len) sha256_Update(ctx, data, len) +#define IMAGE_HASH_FINAL(ctx, output) sha256_Final(ctx, output) +#define IMAGE_HASH_CALC(data, len, output) sha256_Raw(data, len, output) +#endif + +#elif defined IMAGE_HASH_BLAKE2S +#include "blake2s.h" +#define IMAGE_HASH_DIGEST_LENGTH BLAKE2S_DIGEST_LENGTH +#define IMAGE_HASH_CTX BLAKE2S_CTX +#define IMAGE_HASH_INIT(ctx) blake2s_Init(ctx, BLAKE2S_DIGEST_LENGTH) +#define IMAGE_HASH_UPDATE(ctx, data, len) blake2s_Update(ctx, data, len) +#define IMAGE_HASH_FINAL(ctx, output) \ + blake2s_Final(ctx, output, BLAKE2S_DIGEST_LENGTH) +#define IMAGE_HASH_CALC(data, len, output) \ + blake2s(data, len, output, BLAKE2S_DIGEST_LENGTH) +#else +#error "IMAGE_HASH_SHA256 or IMAGE_HASH_BLAKE2S must be defined" +#endif + +#endif diff --git a/core/embed/models/model_D001.h b/core/embed/models/model_D001.h index def874fc33..6c52dbc5bc 100644 --- a/core/embed/models/model_D001.h +++ b/core/embed/models/model_D001.h @@ -24,6 +24,7 @@ #define FIRMWARE_START 0x08040000 #define IMAGE_CHUNK_SIZE (128 * 1024) +#define IMAGE_HASH_BLAKE2S #define BOOTLOADER_IMAGE_MAXSIZE (128 * 1024 * 1) // 128 KB #define FIRMWARE_IMAGE_MAXSIZE (128 * 1024 * 13) // 1664 KB #define NORCOW_SECTOR_SIZE (64 * 1024) diff --git a/core/embed/models/model_D002.h b/core/embed/models/model_D002.h index 7b4b52f00a..e8c9c68785 100644 --- a/core/embed/models/model_D002.h +++ b/core/embed/models/model_D002.h @@ -27,6 +27,7 @@ #define FIRMWARE_START 0x0C050000 #define IMAGE_CHUNK_SIZE SIZE_256K +#define IMAGE_HASH_SHA256 #define BOOTLOADER_IMAGE_MAXSIZE SIZE_128K #define FIRMWARE_IMAGE_MAXSIZE SIZE_3712K #define NORCOW_SECTOR_SIZE SIZE_64K diff --git a/core/embed/models/model_T1B1.h b/core/embed/models/model_T1B1.h index 4349803e56..1138d43836 100644 --- a/core/embed/models/model_T1B1.h +++ b/core/embed/models/model_T1B1.h @@ -11,6 +11,7 @@ #define FIRMWARE_START 0x08010000 #define IMAGE_CHUNK_SIZE (64 * 1024) +#define IMAGE_HASH_SHA256 #define BOOTLOADER_IMAGE_MAXSIZE (32 * 1024 * 1) // 32 KB #define FIRMWARE_IMAGE_MAXSIZE (64 * 1024 * 15) // 960 KB #define NORCOW_SECTOR_SIZE (16 * 1024) diff --git a/core/embed/models/model_T2B1.h b/core/embed/models/model_T2B1.h index 460bb372cd..cd27202be9 100644 --- a/core/embed/models/model_T2B1.h +++ b/core/embed/models/model_T2B1.h @@ -24,6 +24,7 @@ #define FIRMWARE_START 0x08040000 #define IMAGE_CHUNK_SIZE (128 * 1024) +#define IMAGE_HASH_BLAKE2S #define BOOTLOADER_IMAGE_MAXSIZE (128 * 1024 * 1) // 128 KB #define FIRMWARE_IMAGE_MAXSIZE (128 * 1024 * 13) // 1664 KB #define NORCOW_SECTOR_SIZE (64 * 1024) diff --git a/core/embed/models/model_T2T1.h b/core/embed/models/model_T2T1.h index d632951d00..4c74521485 100644 --- a/core/embed/models/model_T2T1.h +++ b/core/embed/models/model_T2T1.h @@ -24,6 +24,7 @@ #define FIRMWARE_START 0x08040000 #define IMAGE_CHUNK_SIZE (128 * 1024) +#define IMAGE_HASH_BLAKE2S #define BOOTLOADER_IMAGE_MAXSIZE (128 * 1024 * 1) // 128 KB #define FIRMWARE_IMAGE_MAXSIZE (128 * 1024 * 13) // 1664 KB #define NORCOW_SECTOR_SIZE (64 * 1024) diff --git a/core/embed/models/model_T3T1.h b/core/embed/models/model_T3T1.h index 0091f3628c..e4f7241a54 100644 --- a/core/embed/models/model_T3T1.h +++ b/core/embed/models/model_T3T1.h @@ -26,6 +26,7 @@ #define FIRMWARE_START 0x0C050000 #define IMAGE_CHUNK_SIZE (128 * 1024) +#define IMAGE_HASH_SHA256 #define BOOTLOADER_IMAGE_MAXSIZE (128 * 1024 * 1) // 128 KB #define FIRMWARE_IMAGE_MAXSIZE (128 * 1024 * 13) // 1664 KB #define NORCOW_SECTOR_SIZE (64 * 1024) diff --git a/core/embed/prodtest/main.c b/core/embed/prodtest/main.c index c8978462f5..07e5ce5c6b 100644 --- a/core/embed/prodtest/main.c +++ b/core/embed/prodtest/main.c @@ -48,6 +48,10 @@ #include "optiga_transport.h" #endif +#ifdef USE_HASH_PROCESSOR +#include "hash_processor.h" +#endif + #include "memzero.h" #ifdef STM32U5 @@ -553,6 +557,9 @@ int main(void) { display_reinit(); display_orientation(0); random_delays_init(); +#ifdef USE_HASH_PROCESSOR + hash_processor_init(); +#endif #ifdef USE_SD_CARD sdcard_init(); #endif diff --git a/core/embed/reflash/main.c b/core/embed/reflash/main.c index d1f266d62e..1c00bf336e 100644 --- a/core/embed/reflash/main.c +++ b/core/embed/reflash/main.c @@ -34,6 +34,10 @@ #include "secbool.h" #include "touch.h" +#ifdef USE_HASH_PROCESSOR +#include "hash_processor.h" +#endif + static void progress_callback(int pos, int len) { term_printf("."); } static void flash_from_sdcard(const flash_area_t* area, uint32_t source, @@ -66,6 +70,10 @@ int main(void) { sdcard_init(); touch_init(); +#ifdef USE_HASH_PROCESSOR + hash_processor_init(); +#endif + display_orientation(0); display_clear(); display_backlight(255); diff --git a/core/embed/trezorhal/boards/stm32u5a9j-dk.h b/core/embed/trezorhal/boards/stm32u5a9j-dk.h index 59f86ad3a4..3ff3673ee6 100644 --- a/core/embed/trezorhal/boards/stm32u5a9j-dk.h +++ b/core/embed/trezorhal/boards/stm32u5a9j-dk.h @@ -9,6 +9,7 @@ #define USE_TOUCH 1 //#define USE_SBU 1 //#define USE_DISP_I8080_8BIT_DW 1 +#define USE_HASH_PROCESSOR 1 #include "displays/dsi.h" diff --git a/core/embed/trezorhal/boards/trezor_t3t1_v4.h b/core/embed/trezorhal/boards/trezor_t3t1_v4.h index 836acd9edf..cf4ea3fa40 100644 --- a/core/embed/trezorhal/boards/trezor_t3t1_v4.h +++ b/core/embed/trezorhal/boards/trezor_t3t1_v4.h @@ -15,6 +15,7 @@ #define USE_DISP_I8080_8BIT_DW 1 #define USE_HAPTIC 1 #define USE_BACKLIGHT 1 +#define USE_HASH_PROCESSOR 1 #include "displays/panels/lx154a2422.h" #include "displays/st7789v.h" diff --git a/core/embed/trezorhal/hash_processor.h b/core/embed/trezorhal/hash_processor.h new file mode 100644 index 0000000000..1ebc9bb94d --- /dev/null +++ b/core/embed/trezorhal/hash_processor.h @@ -0,0 +1,33 @@ +#ifndef TREZORHAL_HASH_PROCESSOR_H_ +#define TREZORHAL_HASH_PROCESSOR_H_ + +#include + +#define HASH_SHA256_BUFFER_SIZE 4 + +typedef struct { + uint32_t length; /*!< nb bytes in buffer */ + uint8_t buffer[HASH_SHA256_BUFFER_SIZE]; /*!< data being processed */ +} hash_sha265_context_t; + +// Initialize the hash processor +void hash_processor_init(void); + +// Calculate SHA256 hash of data +// for best performance, data should be 32-bit aligned - as this allows DMA to +// be used +void hash_processor_sha256_calc(const uint8_t *data, uint32_t len, + uint8_t *hash); + +// Initialize the hash context +// This serves for calculating hashes of multiple data blocks +void hash_processor_sha256_init(hash_sha265_context_t *ctx); + +// Feed the hash next chunk of data +void hash_processor_sha256_update(hash_sha265_context_t *ctx, + const uint8_t *data, uint32_t len); + +// Finalize the hash calculation, retrieve the digest +void hash_processor_sha256_final(hash_sha265_context_t *ctx, uint8_t *output); + +#endif diff --git a/core/embed/trezorhal/stm32u5/hash_processor.c b/core/embed/trezorhal/stm32u5/hash_processor.c new file mode 100644 index 0000000000..390b2426b1 --- /dev/null +++ b/core/embed/trezorhal/stm32u5/hash_processor.c @@ -0,0 +1,132 @@ +#include "hash_processor.h" +#include +#include +#include STM32_HAL_H +#include "irq.h" +#include "memzero.h" +#include "sha2.h" + +HASH_HandleTypeDef hhash = {0}; +DMA_HandleTypeDef DMA_Handle = {0}; + +void hash_processor_init(void) { + __HAL_RCC_HASH_CLK_ENABLE(); + __HAL_RCC_GPDMA1_CLK_ENABLE(); + + hhash.Init.DataType = HASH_DATATYPE_8B; + hhash.hdmain = &DMA_Handle; + HAL_HASH_Init(&hhash); + + /* USER CODE END GPDMA1_Init 1 */ + DMA_Handle.Instance = GPDMA1_Channel12; + DMA_Handle.Init.Request = GPDMA1_REQUEST_HASH_IN; + DMA_Handle.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST; + DMA_Handle.Init.Direction = DMA_MEMORY_TO_PERIPH; + DMA_Handle.Init.SrcInc = DMA_SINC_INCREMENTED; + DMA_Handle.Init.DestInc = DMA_DINC_FIXED; + DMA_Handle.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD; + DMA_Handle.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD; + DMA_Handle.Init.Priority = DMA_LOW_PRIORITY_HIGH_WEIGHT; + DMA_Handle.Init.SrcBurstLength = 1; + DMA_Handle.Init.DestBurstLength = 4; + DMA_Handle.Init.TransferAllocatedPort = + DMA_SRC_ALLOCATED_PORT1 | DMA_DEST_ALLOCATED_PORT0; + DMA_Handle.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; + DMA_Handle.Init.Mode = DMA_NORMAL; + HAL_DMA_Init(&DMA_Handle); + HAL_DMA_ConfigChannelAttributes(&DMA_Handle, DMA_CHANNEL_SEC | + DMA_CHANNEL_SRC_SEC | + DMA_CHANNEL_DEST_SEC); + + DMA_Handle.Parent = &hhash; + + HAL_NVIC_SetPriority(GPDMA1_Channel12_IRQn, IRQ_PRI_DMA, 0); + HAL_NVIC_EnableIRQ(GPDMA1_Channel12_IRQn); +} + +void GPDMA1_Channel12_IRQHandler(void) { HAL_DMA_IRQHandler(&DMA_Handle); } + +static void hash_processor_sha256_calc_dma(const uint8_t *data, uint32_t len, + uint8_t *hash) { + while (len > 0) { + uint32_t chunk = len > 0x8000 ? 0x8000 : len; + bool last = (len - chunk) <= 0; + + __HAL_HASH_SET_MDMAT(); + + HAL_HASHEx_SHA256_Start_DMA(&hhash, (uint8_t *)data, chunk); + while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_READY) + ; + + if (last) { + HASH->STR |= HASH_STR_DCAL; + HAL_HASHEx_SHA256_Finish(&hhash, hash, 1000); + } + data += chunk; + len -= chunk; + } +} + +void hash_processor_sha256_calc(const uint8_t *data, uint32_t len, + uint8_t *hash) { + if (((uint32_t)data & 0x3) == 0) { + hash_processor_sha256_calc_dma(data, len, hash); + } else { + HAL_HASHEx_SHA256_Start(&hhash, (uint8_t *)data, len, hash, 1000); + } +} + +void hash_processor_sha256_init(hash_sha265_context_t *ctx) { + memzero(ctx, sizeof(hash_sha265_context_t)); +} + +void hash_processor_sha256_update(hash_sha265_context_t *ctx, + const uint8_t *data, uint32_t len) { + if (ctx->length > 0) { + uint32_t chunk = HASH_SHA256_BUFFER_SIZE - ctx->length; + if (chunk > len) { + chunk = len; + } + memcpy(ctx->buffer + ctx->length, data, chunk); + ctx->length += chunk; + data += chunk; + len -= chunk; + if (ctx->length == HASH_SHA256_BUFFER_SIZE) { + HAL_HASHEx_SHA256_Accmlt(&hhash, (uint8_t *)ctx->buffer, + HASH_SHA256_BUFFER_SIZE); + ctx->length = 0; + memzero(ctx->buffer, HASH_SHA256_BUFFER_SIZE); + } + } + + uint32_t len_aligned = len & ~(HASH_SHA256_BUFFER_SIZE - 1); + uint32_t len_rest = len & (HASH_SHA256_BUFFER_SIZE - 1); + + while (len_aligned > 0) { + uint32_t chunk = len_aligned > 0x8000 ? 0x8000 : len_aligned; + HAL_HASHEx_SHA256_Accmlt(&hhash, (uint8_t *)data, chunk); + data += chunk; + len_aligned -= chunk; + } + + if (len_rest > 0) { + memcpy(ctx->buffer, data, len_rest); + ctx->length = len_rest; + } +} + +void hash_processor_sha256_final(hash_sha265_context_t *ctx, uint8_t *output) { + uint32_t tmp_out[SHA256_DIGEST_LENGTH / sizeof(uint32_t)] = {0}; + + if (ctx->length > 0) { + memzero(ctx->buffer + ctx->length, HASH_SHA256_BUFFER_SIZE - ctx->length); + HAL_HASHEx_SHA256_Accmlt_End(&hhash, (uint8_t *)ctx->buffer, ctx->length, + (uint8_t *)tmp_out, 1000); + ctx->length = 0; + memzero(ctx->buffer, HASH_SHA256_BUFFER_SIZE); + } else { + HASH->STR |= HASH_STR_DCAL; + HAL_HASHEx_SHA256_Finish(&hhash, (uint8_t *)tmp_out, 1000); + } + memcpy(output, tmp_out, SHA256_DIGEST_LENGTH); +} diff --git a/core/embed/trezorhal/stm32u5/stm32u5xx_hal_conf.h b/core/embed/trezorhal/stm32u5/stm32u5xx_hal_conf.h index 8847100757..97c580fbb1 100644 --- a/core/embed/trezorhal/stm32u5/stm32u5xx_hal_conf.h +++ b/core/embed/trezorhal/stm32u5/stm32u5xx_hal_conf.h @@ -57,7 +57,7 @@ extern "C" { #define HAL_GFXMMU_MODULE_ENABLED /*#define HAL_GPU2D_MODULE_ENABLED */ #define HAL_GTZC_MODULE_ENABLED -/*#define HAL_HASH_MODULE_ENABLED */ +#define HAL_HASH_MODULE_ENABLED /*#define HAL_HRTIM_MODULE_ENABLED */ /*#define HAL_IRDA_MODULE_ENABLED */ /*#define HAL_IWDG_MODULE_ENABLED */ diff --git a/core/embed/vendorheader/D002/vendor_dev_DO_NOT_SIGN.json b/core/embed/vendorheader/D002/vendor_dev_DO_NOT_SIGN.json index 82c5dc44e0..d4483d0867 100644 --- a/core/embed/vendorheader/D002/vendor_dev_DO_NOT_SIGN.json +++ b/core/embed/vendorheader/D002/vendor_dev_DO_NOT_SIGN.json @@ -6,7 +6,7 @@ "version": [0, 0], "sig_m": 2, "trust": { - "allow_run_with_secret": false, + "allow_run_with_secret": true, "show_vendor_string": false, "require_user_click": false, "red_background": false, diff --git a/core/embed/vendorheader/D002/vendorheader_dev_DO_NOT_SIGN_signed_dev.bin b/core/embed/vendorheader/D002/vendorheader_dev_DO_NOT_SIGN_signed_dev.bin index 0689bb2efc9641221d3cc06f5e28160644513926..e338b2d0981fd26e1c7cab0e86f8bf3ebd1d5ded 100644 GIT binary patch delta 91 zcmZorX;2Xi35p715MqD=Cg%E$g6jnxx^#cD&0bkjuGO>tTJQR=J{7u?E4E#kG0WHQ sf!tL?kGn-{@3XuY`M~ZWI_c5eW4}d<-)&ZN$#d;KXCL-PfGLv^0Kp0*o&W#< delta 91 zcmZorX;2Xi35p715MqD=Cg%Se1=kBYNc99o+*$o4zUlhO`G#Ewe1#u!?c-g#K5u*Z s_7i;tSN#4==E-w>S9P)L=LeHty)oZ^zEnQ*Xw-07iEOhyVZp diff --git a/core/embed/vendorheader/D002/vendorheader_unsafe_signed_dev.bin b/core/embed/vendorheader/D002/vendorheader_unsafe_signed_dev.bin index 8db53a9fe3ed8fa16844fe4d8ad5292cfa05caa3..de32f571afd406241cbd284545a5771d3c5eb501 100644 GIT binary patch delta 72 zcmV-O0Jr~uB!DEaz!5-vN()z>x(eVY>*1h8Cv$h_B-`)c!0r6g(#dI;YSv8NkaJIT e0Fg}0ED!VWphNf1!Bo5WcldH<@x=-D_O=OMEGR($ delta 72 zcmV-O0Jr~uB!DEaz!53awE6e9ir diff --git a/core/embed/vendorheader/D002/vendorheader_unsafe_signed_prod.bin b/core/embed/vendorheader/D002/vendorheader_unsafe_signed_prod.bin deleted file mode 100644 index 82633a030ed50016f318e8bdd3a977e7dc7d7def..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4608 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 diff --git a/core/embed/vendorheader/T3T1/vendorheader_unsafe_signed_dev.bin b/core/embed/vendorheader/T3T1/vendorheader_unsafe_signed_dev.bin index 411ce61cee1feec4bb419643461870d734808424..a906b95818595806889b9eb3a373fd296f66c3bb 100644 GIT binary patch delta 72 zcmV-O0Jr~uB!DEaz!5;VL=V!WG`03r`6kvJsXbN$&Kn-WBM&TW5Equ!-nisrl$C8| eJ!ucq7nuSZvgN6P4E;NDQrA5QcD7)Ug&hES6CVNq delta 72 zcmV-O0Jr~uB!DEaz!5+u8ag=M#dsiE;`xZ68iaq2!lF__mLGNC23{+7kafpBRn2lk ekP$se%M)KAu$d(mhJgqZexU5)KYXt~L6QJuQyzH$ diff --git a/core/embed/vendorheader/T3T1/vendorheader_unsafe_signed_prod.bin b/core/embed/vendorheader/T3T1/vendorheader_unsafe_signed_prod.bin deleted file mode 100644 index d18bca9311ace0083ffa13c0eb74960f8a194f28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4608 zcmeI!`8ON*765R9DT*nvj4Fay+E7zTYpT>zN=lkqqe$&b#!^9uEow_GZK_dfnO3XH zh)`;e*jih(_O((B+E{8&)h@5+y!X!g7v2xPzufP=zua>^=bm$~jg^BPml)T-A2)!9 z#Ib>*F8n9|8D>+G194ET#-O9`KvwzNHJKZw6A}5XhMQ3AIiJu<%i+~lVqQgE!Ge_K zpCiQ=Y@@1u_}+h$TwwprGio}G$Aqb;7(=4V10?L6nz=qAzzWNU4rV1tBT$8+Jiy!g4eR>%;%qWP&rQGQ+kmJe_NASxPb zVC-@oq^E__Bar^+>?iA@Ugsh)FqY~r`^~;nXVg4nG46R~aHgB*UdCm|s+Pz>OLk1RrBZnN z3FimN;d+u&s+SA1~ULX7OWBh&=s492V_V z!Yq&Yr^yA$AV&1FX@#cE0Mz2_>I(`KPp=DXj+Z)IrTM+_fkF zxR)UOea~z2LRu}iEF4`8d4QZpTu@I2{7T6+1YY&dGxsG+liyc|@IV?0h-&dL{fsaH znyRTSNNB}6P_h0DC!+|_W@$%!-7HC?m3Dux#5XGuoOG8c?eBPzb1)GHkCx>-4R5IAKXcuG}bd}LdQbHt&uIWQN; zm6pyy7DgCes~Wb2#%$mI+7M9=znEPl&)9$9hb|V6Z2p$8yXbI>>bn~&Q0pUtEuUqP znyOp=`n7!@t&$zsSW@td{F8FHTvSi9g0c`Q_IvF#qxX<#{b(WDv#w$YC;PRh_^3DA zyhTS!p1htttm^z>v-gvy!^At^mA|r!E_(clxQ^V9UksjKk_!zZMNhMRaV>@sNCgLn z^zp7?C}w3O_hgGNS)E*7N;M0=d-)POd1XvkY;I*GJR^*n9D>A$RB7m#s))2V9V$K1 zhHS5_2~uMWUd=ueRG;jaV)x#fT8msOvG6a5(a3*^h>y2`;OmMMa{9XCjfme4Njiz^ zm`)#^%bpSaYWZ}O93BBkO3ewmHjf6dw&KDEvH~sK7tcNe5-}e5x}Tkle&~o3RWr`L zyMmHM(tlZ0L}`(EPRo_X>ey0dupQ8kqEj%uHRjgG4-(o&bLf5*t(V=1M>-NuYJ2F# zSq1m}rtMPG#A?h$>p^LreS7-9b>zC;!EJ`9;7q3zBm~zkzh9k~qeIXy=o<3%AzbW` z*0`Y@kA!6{2wL9ZWXgt0^g0PHiM^QK3T!gHgeigT4EzbAlV}@XA;Oo)>tb;Oq~!R& zZzk$reCk3cGzupgm9-1EF->5(=h_d7CqYbhU&9LoIQ8W^GV&cO$?d|u{9Z@Y(a6y? zV3P}Bt4ujFATNP&g?u!!S3vqQkWSRB7WpH|;e;4B9v9=Sl{BTiAR>!fd+$yrfomE- zt767uXHr~J#)U~9&m%^PgTPMJFIqo8!>p!ohs&R3u~Q;#84BkhavvSzgxU*P{w_TN zWDAD1mLz4sCj9iUqvf0iFRN!rCFfyvtx<}r_8@mW@79kOD_8-;i^4$yS<}E8XO3{T zU}J+ydh8G)Ev{oC6_xXC&8b) zf}L$6-}3w-fUHjf>!LLF?jY^l7BBh4CEWI;;ftddC^&Elw7yYE*q&x9SN3Ls(p`~& zM=MCKGjr{lz zRfRnc*l*iYV-9D;ApcOQ2xRneg;ej58r~@fzmwd~X z?(0!+7`vObbX9ALx56y`{2huRLTvJhvfmW+plSYUeP-_6T3y3gG_Z+blYW?|sr{v4 zJW3{oK*gZnj%KC2+uQXb$JL~gbzHG5e`q8SuF<-~rsz>10d1M1ijXqkGY-7mFnGcj z+96Q;$!SiSp%on?@2v%&Gh^l}6%XkKvh!k|XT9R&7b+6kcp@J5Pf!k74*MP&r(8zT zkrlKhbFO4;NMiMd_i4Z7&Zj*V?Qr$1JbQ$W+O=qrQ9w#5WXi!#sEUc?GQI zsoh0@g2VjKtPvZfPZH*MA+w18u7A@J&j0S6_;0W`A#aqy=vQmud~z>q_8+&^O2Yye%M6 bytes: + hash_function = Model.from_hw_model(self.hw_model).hash_params().hash_function cpy = copy(self) cpy.sigmask = 0 cpy.signature = b"\x00" * 64 - return hashlib.blake2s(cpy.build()).digest() + return hash_function(cpy.build()).digest() def vhash(self) -> bytes: h = hashlib.blake2s()