feat(legacy): implement firmware dumping

pull/2251/head
matejcik 2 years ago committed by Martin Milata
parent 37c61c1381
commit 64df33d8d8

@ -30,6 +30,7 @@
#include "curves.h"
#include "debug.h"
#include "ecdsa.h"
#include "flash.h"
#include "fsm.h"
#include "fw_signatures.h"
#include "gettext.h"

@ -70,6 +70,8 @@ void fsm_msgWordAck(const WordAck *msg);
void fsm_msgSetU2FCounter(const SetU2FCounter *msg);
void fsm_msgGetNextU2FCounter(void);
void fsm_msgGetFirmwareHash(const GetFirmwareHash *msg);
void fsm_msgGetFirmware(const GetFirmware *msg);
void fsm_msgFirmwareChunkAck(const FirmwareChunkAck *msg);
// coin
void fsm_msgGetPublicKey(const GetPublicKey *msg);

@ -562,3 +562,73 @@ void fsm_msgGetFirmwareHash(const GetFirmwareHash *msg) {
msg_write(MessageType_MessageType_FirmwareHash, resp);
layoutHome();
}
static bool in_dump_firmware = false;
static uint8_t sector = 0;
static uint32_t sector_offset = 0;
static uint32_t total_bytes_sent = 0;
#define FIRMWARE_PROGRESS_TOTAL (128 * 1024 * 7 + 64 * 1024)
void firmware_dump_abort(void) {
in_dump_firmware = false;
sector = 0;
sector_offset = 0;
total_bytes_sent = 0;
}
void send_next_firmware_chunk(void) {
if (!in_dump_firmware) {
return;
}
if (sector_offset >= flash_sector_size(sector)) {
sector++;
sector_offset = 0;
}
if (sector > FLASH_CODE_SECTOR_LAST) {
fsm_sendSuccess(_("Firmware extracted"));
layoutHome();
firmware_dump_abort();
return;
}
RESP_INIT(FirmwareChunk);
if (memory_firmware_read(resp->chunk.bytes, sector, sector_offset,
sizeof(resp->chunk.bytes)) != 0) {
fsm_sendFailure(FailureType_Failure_FirmwareError, NULL);
firmware_dump_abort();
return;
}
sector_offset += sizeof(resp->chunk.bytes);
resp->chunk.size = sizeof(resp->chunk.bytes);
total_bytes_sent += sizeof(resp->chunk.bytes);
layoutProgress(_("Extracting..."),
1000 * total_bytes_sent / FIRMWARE_PROGRESS_TOTAL);
msg_write(MessageType_MessageType_FirmwareChunk, resp);
}
void fsm_msgGetFirmware(const GetFirmware *msg) {
(void)msg;
layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL,
_("Do you want to"), _("extract firmware?"), NULL,
_("Your seed will"), _("not be revealed."), NULL);
if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) {
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
layoutHome();
return;
}
layoutProgressSwipe(_("Extracting..."), 0);
sector = FLASH_CODE_SECTOR_FIRST;
sector_offset = 0;
total_bytes_sent = 0;
in_dump_firmware = true;
send_next_firmware_chunk();
}
void fsm_msgFirmwareChunkAck(const FirmwareChunkAck *msg) {
(void)msg;
if (!in_dump_firmware) {
fsm_sendFailure(FailureType_Failure_UnexpectedMessage, NULL);
} else {
send_next_firmware_chunk();
}
}

@ -38,3 +38,5 @@ Nonce.nonce max_size:32
GetFirmwareHash.challenge max_size:32
FirmwareHash.hash max_size:32
FirmwareChunk.chunk max_size:2048

@ -20,6 +20,7 @@
#include "memory.h"
#include <libopencm3/stm32/flash.h>
#include <stdint.h>
#include <string.h>
#include "blake2s.h"
#include "flash.h"
#include "layout.h"
@ -114,3 +115,16 @@ int memory_firmware_hash(const uint8_t *challenge, uint32_t challenge_size,
return blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH);
}
int memory_firmware_read(uint8_t *dest, uint8_t sector, uint32_t offset,
uint32_t size) {
if (sector < FLASH_CODE_SECTOR_FIRST || sector > FLASH_CODE_SECTOR_LAST) {
return 1;
}
const void *data = flash_get_address(sector, offset, size);
if (data == NULL) {
return 1;
}
memcpy(dest, data, size);
return 0;
}

@ -96,6 +96,8 @@ int memory_bootloader_hash(uint8_t *hash);
int memory_firmware_hash(const uint8_t *challenge, uint32_t challenge_size,
void (*progress_callback)(uint32_t, uint32_t),
uint8_t hash[32]);
int memory_firmware_read(uint8_t *dest, uint8_t sector_idx, uint32_t offset,
uint32_t len);
static inline void flash_write32(uint32_t addr, uint32_t word) {
*(volatile uint32_t *)FLASH_PTR(addr) = word;

Loading…
Cancel
Save