1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-15 18:00:59 +00:00

loader: compute pubkey rather than use precomputed one, prepare for vendor keys

This commit is contained in:
Pavol Rusnak 2017-04-01 22:30:10 +02:00
parent 7cb7a90d27
commit 5c227a4a47
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
4 changed files with 42 additions and 35 deletions

View File

@ -116,7 +116,7 @@ bool copy_sdcard(void)
void check_and_jump(void) void check_and_jump(void)
{ {
BOOTLOADER_PRINTLN("checking loader"); BOOTLOADER_PRINTLN("checking loader");
if (image_check_signature((const uint8_t *)LOADER_START)) { if (image_check_signature((const uint8_t *)LOADER_START, NULL)) {
BOOTLOADER_PRINTLN("valid loader image"); BOOTLOADER_PRINTLN("valid loader image");
// TODO: remove debug wait // TODO: remove debug wait
BOOTLOADER_PRINTLN("waiting 1 second"); BOOTLOADER_PRINTLN("waiting 1 second");

View File

@ -47,13 +47,10 @@ void check_and_jump(void)
return; return;
} }
// TODO: use keys from vendor header in image_check_signature if (image_check_signature((const uint8_t *)(FIRMWARE_START + vhdr.hdrlen), &vhdr)) {
if (image_check_signature((const uint8_t *)(FIRMWARE_START + vhdr.hdrlen))) {
LOADER_PRINTLN("valid firmware image"); LOADER_PRINTLN("valid firmware image");
// TODO: remove debug wait
display_vendor(vhdr.vimg, (const char *)vhdr.vstr, vhdr.vstr_len); display_vendor(vhdr.vimg, (const char *)vhdr.vstr, vhdr.vstr_len);
HAL_Delay(1000); HAL_Delay(1000); // TODO: remove?
// end
LOADER_PRINTLN("JUMP!"); LOADER_PRINTLN("JUMP!");
jump_to(FIRMWARE_START + vhdr.hdrlen + HEADER_SIZE); jump_to(FIRMWARE_START + vhdr.hdrlen + HEADER_SIZE);
} else { } else {

View File

@ -38,37 +38,47 @@ bool image_parse_header(const uint8_t *data, image_header *header)
return true; return true;
} }
#define KEYMASK(A, B, C) ((1 << (A - 1)) | (1 << (B - 1)) | (1 << (C - 1))) static const uint8_t * const SATOSHILABS_PUBKEYS[] = {
(const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
(const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
(const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
(const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
(const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
};
static const uint8_t *get_pubkey(uint8_t index) static const uint8_t *compute_pubkey(const vendor_header *vhdr, uint8_t sigmask)
{ {
switch (index) { uint8_t vsig_m;
case KEYMASK(1, 2, 3): uint8_t vsig_n;
return (const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; const uint8_t * const *vpub;
case KEYMASK(1, 2, 4):
return (const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; if (vhdr) {
case KEYMASK(1, 2, 5): vsig_m = vhdr->vsig_n;
return (const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; vsig_n = vhdr->vsig_n;
case KEYMASK(1, 3, 4): vpub = vhdr->vpub;
return (const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; } else {
case KEYMASK(1, 3, 5): vsig_m = 3;
return (const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; vsig_n = 5;
case KEYMASK(1, 4, 5): vpub = SATOSHILABS_PUBKEYS;
return (const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
case KEYMASK(2, 3, 4):
return (const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
case KEYMASK(2, 3, 5):
return (const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
case KEYMASK(2, 4, 5):
return (const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
case KEYMASK(3, 4, 5):
return (const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
default:
return NULL;
} }
if (!vsig_m || !vsig_n) return NULL;
if (vsig_m > vsig_n) return NULL;
// discard bits higher than vsig_n
sigmask &= ((1 << vsig_n) - 1);
// remove if number of set bits in sigmask is not equal to vsig_m
if (__builtin_popcount(sigmask) != vsig_m) return NULL;
// TODO: add keys from vpub according to sigmask
(void)vpub;
(void)sigmask;
return NULL;
} }
bool image_check_signature(const uint8_t *data) bool image_check_signature(const uint8_t *data, const vendor_header *vhdr)
{ {
image_header hdr; image_header hdr;
if (!image_parse_header(data, &hdr)) { if (!image_parse_header(data, &hdr)) {
@ -85,7 +95,7 @@ bool image_check_signature(const uint8_t *data)
blake2s_Update(&ctx, data + HEADER_SIZE, hdr.codelen); blake2s_Update(&ctx, data + HEADER_SIZE, hdr.codelen);
blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH); blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH);
const uint8_t *pub = get_pubkey(hdr.sigmask); const uint8_t *pub = compute_pubkey(vhdr, hdr.sigmask);
// TODO: remove debug skip of unsigned // TODO: remove debug skip of unsigned
if (!pub) return true; if (!pub) return true;
@ -154,7 +164,7 @@ bool vendor_check_signature(const uint8_t *data)
} }
blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH); blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH);
const uint8_t *pub = get_pubkey(hdr.sigmask); const uint8_t *pub = compute_pubkey(NULL, hdr.sigmask);
// TODO: remove debug skip of unsigned // TODO: remove debug skip of unsigned
if (!pub) return true; if (!pub) return true;

View File

@ -34,7 +34,7 @@ typedef struct {
bool image_parse_header(const uint8_t *data, image_header *header); bool image_parse_header(const uint8_t *data, image_header *header);
bool image_check_signature(const uint8_t *data); bool image_check_signature(const uint8_t *data, const vendor_header *vhdr);
bool vendor_parse_header(const uint8_t *data, vendor_header *header); bool vendor_parse_header(const uint8_t *data, vendor_header *header);