mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 07:28:10 +00:00
feat(legacy): implement firmware dumping
This commit is contained in:
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…
Reference in New Issue
Block a user