|
|
|
@ -28,7 +28,9 @@
|
|
|
|
|
#include "embed/extmod/trezorobj.h"
|
|
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include "blake2s.h"
|
|
|
|
|
#include "common.h"
|
|
|
|
|
#include "flash.h"
|
|
|
|
|
|
|
|
|
|
/// def consteq(sec: bytes, pub: bytes) -> bool:
|
|
|
|
|
/// """
|
|
|
|
@ -117,6 +119,49 @@ STATIC mp_obj_t mod_trezorutils_halt(size_t n_args, const mp_obj_t *args) {
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorutils_halt_obj, 0, 1,
|
|
|
|
|
mod_trezorutils_halt);
|
|
|
|
|
|
|
|
|
|
/// def firmware_hash(challenge: bytes | None = None) -> bytes:
|
|
|
|
|
/// """
|
|
|
|
|
/// Computes the Blake2s hash of the firmware with an optional challenge as
|
|
|
|
|
/// the key.
|
|
|
|
|
/// """
|
|
|
|
|
STATIC mp_obj_t mod_trezorutils_firmware_hash(size_t n_args,
|
|
|
|
|
const mp_obj_t *args) {
|
|
|
|
|
BLAKE2S_CTX ctx;
|
|
|
|
|
mp_buffer_info_t chal = {0};
|
|
|
|
|
if (n_args > 0 && args[0] != mp_const_none) {
|
|
|
|
|
mp_get_buffer_raise(args[0], &chal, MP_BUFFER_READ);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (chal.len != 0) {
|
|
|
|
|
if (blake2s_InitKey(&ctx, BLAKE2S_DIGEST_LENGTH, chal.buf, chal.len) != 0) {
|
|
|
|
|
mp_raise_msg(&mp_type_ValueError, "Invalid challenge.");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < FIRMWARE_SECTORS_COUNT; i++) {
|
|
|
|
|
uint8_t sector = FIRMWARE_SECTORS[i];
|
|
|
|
|
uint32_t size = flash_sector_size(sector);
|
|
|
|
|
const void *data = flash_get_address(sector, 0, size);
|
|
|
|
|
if (data == NULL) {
|
|
|
|
|
mp_raise_msg(&mp_type_RuntimeError, "Failed to read firmware.");
|
|
|
|
|
}
|
|
|
|
|
blake2s_Update(&ctx, data, size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vstr_t vstr = {0};
|
|
|
|
|
vstr_init_len(&vstr, BLAKE2S_DIGEST_LENGTH);
|
|
|
|
|
if (blake2s_Final(&ctx, vstr.buf, vstr.len) != 0) {
|
|
|
|
|
vstr_clear(&vstr);
|
|
|
|
|
mp_raise_msg(&mp_type_RuntimeError, "Failed to finalize firmware hash.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
|
|
|
|
}
|
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorutils_firmware_hash_obj, 0,
|
|
|
|
|
1, mod_trezorutils_firmware_hash);
|
|
|
|
|
|
|
|
|
|
STATIC mp_obj_str_t mod_trezorutils_revision_obj = {
|
|
|
|
|
{&mp_type_bytes}, 0, sizeof(SCM_REVISION) - 1, (const byte *)SCM_REVISION};
|
|
|
|
|
|
|
|
|
@ -133,6 +178,8 @@ STATIC const mp_rom_map_elem_t mp_module_trezorutils_globals_table[] = {
|
|
|
|
|
{MP_ROM_QSTR(MP_QSTR_consteq), MP_ROM_PTR(&mod_trezorutils_consteq_obj)},
|
|
|
|
|
{MP_ROM_QSTR(MP_QSTR_memcpy), MP_ROM_PTR(&mod_trezorutils_memcpy_obj)},
|
|
|
|
|
{MP_ROM_QSTR(MP_QSTR_halt), MP_ROM_PTR(&mod_trezorutils_halt_obj)},
|
|
|
|
|
{MP_ROM_QSTR(MP_QSTR_firmware_hash),
|
|
|
|
|
MP_ROM_PTR(&mod_trezorutils_firmware_hash_obj)},
|
|
|
|
|
// various built-in constants
|
|
|
|
|
{MP_ROM_QSTR(MP_QSTR_SCM_REVISION),
|
|
|
|
|
MP_ROM_PTR(&mod_trezorutils_revision_obj)},
|
|
|
|
|