diff --git a/Makefile.include b/Makefile.include index c9e8fd578..d257bd329 100644 --- a/Makefile.include +++ b/Makefile.include @@ -13,7 +13,7 @@ AS := as OPTFLAGS ?= -O3 DBGFLAGS ?= -g3 -ggdb3 -CPUFLAGS ?= -m32 +CPUFLAGS ?= FPUFLAGS ?= else PREFIX ?= arm-none-eabi- diff --git a/bootloader/bootloader.c b/bootloader/bootloader.c index 6093fce32..b47fedae8 100644 --- a/bootloader/bootloader.c +++ b/bootloader/bootloader.c @@ -81,19 +81,19 @@ void __attribute__((noreturn)) load_app(int signed_firmware) // zero out SRAM memset_reg(_ram_start, _ram_end, 0); - jump_to_firmware((const vector_table_t *) FLASH_APP_START, signed_firmware); + jump_to_firmware((const vector_table_t *) FLASH_PTR(FLASH_APP_START), signed_firmware); } bool firmware_present(void) { #ifndef APPVER - if (memcmp((const void *)FLASH_META_MAGIC, "TRZR", 4)) { // magic does not match + if (memcmp(FLASH_PTR(FLASH_META_MAGIC), "TRZR", 4)) { // magic does not match return false; } - if (*((const uint32_t *)FLASH_META_CODELEN) < 4096) { // firmware reports smaller size than 4kB + if (*((const uint32_t *)FLASH_PTR(FLASH_META_CODELEN)) < 4096) { // firmware reports smaller size than 4kB return false; } - if (*((const uint32_t *)FLASH_META_CODELEN) > FLASH_TOTAL_SIZE - (FLASH_APP_START - FLASH_ORIGIN)) { // firmware reports bigger size than flash size + if (*((const uint32_t *)FLASH_PTR(FLASH_META_CODELEN)) > FLASH_TOTAL_SIZE - (FLASH_APP_START - FLASH_ORIGIN)) { // firmware reports bigger size than flash size return false; } #endif diff --git a/bootloader/usb.c b/bootloader/usb.c index 51bee89e7..ec69a818b 100644 --- a/bootloader/usb.c +++ b/bootloader/usb.c @@ -302,7 +302,7 @@ static void erase_metadata_sectors(void) static void backup_metadata(uint8_t *backup) { - memcpy(backup, (void *)FLASH_META_START, FLASH_META_LEN); + memcpy(backup, FLASH_PTR(FLASH_META_START), FLASH_META_LEN); } static void restore_metadata(const uint8_t *backup) @@ -434,7 +434,7 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep) // compute hash of written test pattern uint8_t hash[32]; - sha256_Raw((unsigned char *)FLASH_META_START, FLASH_META_LEN, hash); + sha256_Raw(FLASH_PTR(FLASH_META_START), FLASH_META_LEN, hash); // restore metadata from backup erase_metadata_sectors(); @@ -504,7 +504,7 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep) // flash status register should show now error and // the config block should contain only \xff. uint8_t hash[32]; - sha256_Raw((unsigned char *)FLASH_META_START, FLASH_META_LEN, hash); + sha256_Raw(FLASH_PTR(FLASH_META_START), FLASH_META_LEN, hash); if ((FLASH_SR & (FLASH_SR_PGAERR | FLASH_SR_PGPERR | FLASH_SR_PGSERR | FLASH_SR_WRPERR)) != 0 || memcmp(hash, "\x2d\x86\x4c\x0b\x78\x9a\x43\x21\x4e\xee\x85\x24\xd3\x18\x20\x75\x12\x5e\x5c\xa2\xcd\x52\x7f\x35\x82\xec\x87\xff\xd9\x40\x76\xbc", 32) != 0) { send_msg_failure(dev); @@ -619,7 +619,7 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep) return; } uint8_t hash[32]; - sha256_Raw((unsigned char *)FLASH_APP_START, flash_len - FLASH_META_DESC_LEN, hash); + sha256_Raw(FLASH_PTR(FLASH_APP_START), flash_len - FLASH_META_DESC_LEN, hash); layoutFirmwareHash(hash); do { delay(100000); @@ -630,7 +630,7 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep) bool hash_check_ok = brand_new_firmware || button.YesUp; layoutProgress("INSTALLING ... Please wait", 1000); - uint8_t flags = *((uint8_t *)FLASH_META_FLAGS); + uint8_t flags = *FLASH_PTR(FLASH_META_FLAGS); // wipe storage if: // 0) there was no firmware // 1) old firmware was unsigned diff --git a/emulator/emulator.h b/emulator/emulator.h index deaa73dea..abb41355a 100644 --- a/emulator/emulator.h +++ b/emulator/emulator.h @@ -26,8 +26,6 @@ #include -extern void *emulator_flash_base; - void emulatorPoll(void); void emulatorRandom(void *buffer, size_t size); diff --git a/emulator/flash.c b/emulator/flash.c index 708dd2598..b168d86bb 100644 --- a/emulator/flash.c +++ b/emulator/flash.c @@ -17,8 +17,6 @@ * along with this library. If not, see . */ -#include - #include #include "memory.h" @@ -66,7 +64,7 @@ static void *sector_to_address(uint8_t sector) { return NULL; } - return (void *) (FLASH_ORIGIN + offset); + return (void *) FLASH_PTR(FLASH_ORIGIN + offset); } static ssize_t sector_to_size(uint8_t sector) { @@ -106,9 +104,9 @@ void flash_erase_all_sectors(uint32_t program_size) { } void flash_program_word(uint32_t address, uint32_t data) { - MMIO32(address) = data; + *(volatile uint32_t *)FLASH_PTR(address) = data; } void flash_program_byte(uint32_t address, uint8_t data) { - MMIO8(address) = data; + *(volatile uint8_t *)FLASH_PTR(address) = data; } diff --git a/emulator/setup.c b/emulator/setup.c index b5effa83c..8000aa4ea 100644 --- a/emulator/setup.c +++ b/emulator/setup.c @@ -34,7 +34,7 @@ #define EMULATOR_FLASH_FILE "emulator.img" -void *emulator_flash_base = NULL; +uint8_t *emulator_flash_base = NULL; uint32_t __stack_chk_guard; diff --git a/firmware/fsm.c b/firmware/fsm.c index 592a35fc0..698106cce 100644 --- a/firmware/fsm.c +++ b/firmware/fsm.c @@ -1678,7 +1678,7 @@ void fsm_msgDebugLinkMemoryRead(DebugLinkMemoryRead *msg) if (msg->has_length && msg->length < length) length = msg->length; resp->has_memory = true; - memcpy(resp->memory.bytes, (void*) msg->address, length); + memcpy(resp->memory.bytes, FLASH_PTR(msg->address), length); resp->memory.size = length; msg_debug_write(MessageType_MessageType_DebugLinkMemory, resp); } @@ -1696,7 +1696,9 @@ void fsm_msgDebugLinkMemoryWrite(DebugLinkMemoryWrite *msg) } flash_lock(); } else { +#if !EMULATOR memcpy((void *) msg->address, msg->memory.bytes, length); +#endif } } diff --git a/firmware/protect.c b/firmware/protect.c index ffbe4aa39..d0ef4a8ff 100644 --- a/firmware/protect.c +++ b/firmware/protect.c @@ -19,6 +19,7 @@ #include "protect.h" #include "storage.h" +#include "memory.h" #include "messages.h" #include "usb.h" #include "oled.h" @@ -159,8 +160,8 @@ bool protectPin(bool use_cached) if (!storage_hasPin() || (use_cached && session_isPinCached())) { return true; } - uint32_t *fails = storage_getPinFailsPtr(); - uint32_t wait = ~*fails; + uint32_t fails = storage_getPinFailsOffset(); + uint32_t wait = ~*(const uint32_t*)FLASH_PTR(fails); protectCheckMaxTry(wait); usbTiny(1); while (wait > 0) { @@ -205,7 +206,7 @@ bool protectPin(bool use_cached) storage_resetPinFails(fails); return true; } else { - protectCheckMaxTry(~*fails); + protectCheckMaxTry(~*(const uint32_t*)FLASH_PTR(fails)); fsm_sendFailure(FailureType_Failure_PinInvalid, NULL); return false; } diff --git a/firmware/storage.c b/firmware/storage.c index 27a16296a..2167b8a40 100644 --- a/firmware/storage.c +++ b/firmware/storage.c @@ -48,27 +48,13 @@ static const uint32_t storage_magic = 0x726f7473; // 'stor' as uint32_t static uint32_t storage_uuid[12 / sizeof(uint32_t)]; -#ifndef __clang__ -// TODO: Fix this for Clang -_Static_assert(((uint32_t)storage_uuid & 3) == 0, "uuid unaligned"); -_Static_assert((sizeof(storage_uuid) & 3) == 0, "uuid unaligned"); -#endif +_Static_assert(sizeof(storage_uuid) == 12, "storage_uuid has wrong size"); -Storage CONFIDENTIAL storageUpdate; -#ifndef __clang__ -// TODO: Fix this for Clang -_Static_assert(((uint32_t)&storageUpdate & 3) == 0, "storage unaligned"); +Storage CONFIDENTIAL storageUpdate __attribute__((aligned(4))); _Static_assert((sizeof(storageUpdate) & 3) == 0, "storage unaligned"); -#endif -#define STORAGE_ROM ((const Storage *)(FLASH_STORAGE_START + sizeof(storage_magic) + sizeof(storage_uuid))) - -#if EMULATOR -// TODO: Fix this for emulator -#define storageRom STORAGE_ROM -#else -const Storage *storageRom = STORAGE_ROM; -#endif +#define FLASH_STORAGE (FLASH_STORAGE_START + sizeof(storage_magic) + sizeof(storage_uuid)) +#define storageRom ((const Storage *) FLASH_PTR(FLASH_STORAGE)) char storage_uuid_str[25]; @@ -146,7 +132,7 @@ void storage_check_flash_errors(void) bool storage_from_flash(void) { storage_clear_update(); - if (memcmp((void *)FLASH_STORAGE_START, &storage_magic, sizeof(storage_magic)) != 0) { + if (memcmp(FLASH_PTR(FLASH_STORAGE_START), &storage_magic, sizeof(storage_magic)) != 0) { // wrong magic return false; } @@ -167,7 +153,7 @@ bool storage_from_flash(void) } // load uuid - memcpy(storage_uuid, (void *)(FLASH_STORAGE_START + sizeof(storage_magic)), sizeof(storage_uuid)); + memcpy(storage_uuid, FLASH_PTR(FLASH_STORAGE_START + sizeof(storage_magic)), sizeof(storage_uuid)); data2hex(storage_uuid, sizeof(storage_uuid), storage_uuid_str); #define OLD_STORAGE_SIZE(last_member) (((offsetof(Storage, last_member) + pb_membersize(Storage, last_member)) + 3) & ~3) @@ -215,20 +201,17 @@ bool storage_from_flash(void) flash_erase_sector(FLASH_META_SECTOR_LAST, FLASH_CR_PROGRAM_X32); flash_program_word(FLASH_STORAGE_PINAREA, 0xffffffff << pinctr); // erase storageRom.has_pin_failed_attempts and storageRom.pin_failed_attempts -#if !EMULATOR -// TODO: Fix this for emulator - _Static_assert(((uint32_t)&STORAGE_ROM->pin_failed_attempts & 3) == 0, "storage.pin_failed_attempts unaligned"); -#endif - flash_program_byte((uint32_t)&storageRom->has_pin_failed_attempts, 0); - flash_program_word((uint32_t)&storageRom->pin_failed_attempts, 0); + _Static_assert(((FLASH_STORAGE + offsetof(Storage, pin_failed_attempts)) & 3) == 0, "storage.pin_failed_attempts unaligned"); + flash_program_byte(FLASH_STORAGE + offsetof(Storage, has_pin_failed_attempts), 0); + flash_program_word(FLASH_STORAGE + offsetof(Storage, pin_failed_attempts), 0); flash_lock(); storage_check_flash_errors(); } - uint32_t *u2fptr = (uint32_t*) FLASH_STORAGE_U2FAREA; + const uint32_t *u2fptr = (const uint32_t*) FLASH_PTR(FLASH_STORAGE_U2FAREA); while (*u2fptr == 0) { u2fptr++; } - storage_u2f_offset = 32 * (u2fptr - (uint32_t*) FLASH_STORAGE_U2FAREA); + storage_u2f_offset = 32 * (u2fptr - (const uint32_t*) FLASH_PTR(FLASH_STORAGE_U2FAREA)); uint32_t u2fword = *u2fptr; while ((u2fword & 1) == 0) { storage_u2f_offset++; @@ -374,7 +357,7 @@ static void storage_commit_locked(bool update) // backup meta uint32_t meta_backup[FLASH_META_DESC_LEN / sizeof(uint32_t)]; - memcpy(meta_backup, (uint8_t*)FLASH_META_START, FLASH_META_DESC_LEN); + memcpy(meta_backup, FLASH_PTR(FLASH_META_START), FLASH_META_DESC_LEN); // erase storage flash_erase_sector(FLASH_META_SECTOR_FIRST, FLASH_CR_PROGRAM_X32); @@ -763,14 +746,14 @@ static void storage_area_recycle(uint32_t new_pinfails) // first clear storage marker. In case of a failure below it is better // to clear the storage than to allow restarting with zero PIN failures flash_program_word(FLASH_STORAGE_START, 0); - if (*(uint32_t *)FLASH_STORAGE_START != 0) { + if (*(const uint32_t *)FLASH_PTR(FLASH_STORAGE_START) != 0) { storage_show_error(); } // erase storage sector flash_erase_sector(FLASH_META_SECTOR_LAST, FLASH_CR_PROGRAM_X32); flash_program_word(FLASH_STORAGE_PINAREA, new_pinfails); - if (*(uint32_t *)FLASH_STORAGE_PINAREA != new_pinfails) { + if (*(const uint32_t *)FLASH_PTR(FLASH_STORAGE_PINAREA) != new_pinfails) { storage_show_error(); } @@ -782,24 +765,24 @@ static void storage_area_recycle(uint32_t new_pinfails) } } -void storage_resetPinFails(uint32_t *pinfailsptr) +void storage_resetPinFails(uint32_t flash_pinfails) { flash_clear_status_flags(); flash_unlock(); - if ((uint32_t) (pinfailsptr + 1) + if (flash_pinfails + sizeof(uint32_t) >= FLASH_STORAGE_PINAREA + FLASH_STORAGE_PINAREA_LEN) { // recycle extra storage sector storage_area_recycle(0xffffffff); } else { - flash_program_word((uint32_t) pinfailsptr, 0); + flash_program_word(flash_pinfails, 0); } flash_lock(); storage_check_flash_errors(); } -bool storage_increasePinFails(uint32_t *pinfailsptr) +bool storage_increasePinFails(uint32_t flash_pinfails) { - uint32_t newctr = *pinfailsptr << 1; + uint32_t newctr = *(const uint32_t*)FLASH_PTR(flash_pinfails) << 1; // counter already at maximum, we do not increase it any more // return success so that a good pin is accepted if (!newctr) @@ -807,19 +790,19 @@ bool storage_increasePinFails(uint32_t *pinfailsptr) flash_clear_status_flags(); flash_unlock(); - flash_program_word((uint32_t) pinfailsptr, newctr); + flash_program_word(flash_pinfails, newctr); flash_lock(); storage_check_flash_errors(); - return *pinfailsptr == newctr; + return *(const uint32_t*)FLASH_PTR(flash_pinfails) == newctr; } -uint32_t *storage_getPinFailsPtr(void) +uint32_t storage_getPinFailsOffset(void) { - uint32_t *pinfailsptr = (uint32_t *) FLASH_STORAGE_PINAREA; - while (*pinfailsptr == 0) - pinfailsptr++; - return pinfailsptr; + uint32_t flash_pinfails = FLASH_STORAGE_PINAREA; + while (*(const uint32_t*)FLASH_PTR(flash_pinfails) == 0) + flash_pinfails += sizeof(uint32_t); + return flash_pinfails; } bool storage_isInitialized(void) @@ -866,15 +849,17 @@ uint32_t storage_getFlags(void) uint32_t storage_nextU2FCounter(void) { - uint32_t *ptr = ((uint32_t *) FLASH_STORAGE_U2FAREA) + (storage_u2f_offset / 32); + uint32_t flash_u2f_offset = FLASH_STORAGE_U2FAREA + + sizeof(uint32_t) * (storage_u2f_offset / 32); uint32_t newval = 0xfffffffe << (storage_u2f_offset & 31); flash_clear_status_flags(); flash_unlock(); - flash_program_word((uint32_t) ptr, newval); + flash_program_word(flash_u2f_offset, newval); storage_u2f_offset++; if (storage_u2f_offset >= 8 * FLASH_STORAGE_U2FAREA_LEN) { - storage_area_recycle(*storage_getPinFailsPtr()); + storage_area_recycle(*(const uint32_t*) + FLASH_PTR(storage_getPinFailsOffset())); } flash_lock(); storage_check_flash_errors(); diff --git a/firmware/storage.h b/firmware/storage.h index 431e830c6..945ca135c 100644 --- a/firmware/storage.h +++ b/firmware/storage.h @@ -122,9 +122,9 @@ void storage_setPin(const char *pin); void session_cachePin(void); bool session_isPinCached(void); void storage_clearPinArea(void); -void storage_resetPinFails(uint32_t *pinfailptr); -bool storage_increasePinFails(uint32_t *pinfailptr); -uint32_t *storage_getPinFailsPtr(void); +void storage_resetPinFails(uint32_t flash_pinfails); +bool storage_increasePinFails(uint32_t flash_pinfails); +uint32_t storage_getPinFailsOffset(void); uint32_t storage_nextU2FCounter(void); void storage_setU2FCounter(uint32_t u2fcounter); diff --git a/memory.c b/memory.c index e2416159f..1d68a3a2a 100644 --- a/memory.c +++ b/memory.c @@ -69,7 +69,7 @@ void memory_write_unlock(void) int memory_bootloader_hash(uint8_t *hash) { - sha256_Raw((const uint8_t *)FLASH_BOOT_START, FLASH_BOOT_LEN, hash); + sha256_Raw(FLASH_PTR(FLASH_BOOT_START), FLASH_BOOT_LEN, hash); sha256_Raw(hash, 32, hash); return 32; } diff --git a/memory.h b/memory.h index 7a342a4f6..8bb9aac27 100644 --- a/memory.h +++ b/memory.h @@ -20,6 +20,8 @@ #ifndef __MEMORY_H__ #define __MEMORY_H__ +#include + /* flash memory layout: @@ -62,10 +64,13 @@ */ +#define FLASH_ORIGIN (0x08000000) + #if EMULATOR -#define FLASH_ORIGIN ((uint32_t) emulator_flash_base) +extern uint8_t *emulator_flash_base; +#define FLASH_PTR(x) (emulator_flash_base + (x - FLASH_ORIGIN)) #else -#define FLASH_ORIGIN (0x08000000) +#define FLASH_PTR(x) (const uint8_t*) (x) #endif #define FLASH_TOTAL_SIZE (512 * 1024)