Skip to content

Commit 46645a0

Browse files
committed
sign tool: encode header fields as little-endian
F/2584
1 parent 657e337 commit 46645a0

2 files changed

Lines changed: 125 additions & 23 deletions

File tree

tools/keytools/sign.c

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,37 @@ static inline int fp_truncate(FILE *f, size_t len)
211211
#define ENC_MAX_KEY_SZ ENCRYPT_KEY_SIZE_AES256 /* 32 */
212212
#define ENC_MAX_IV_SZ ENCRYPT_NONCE_SIZE_AES /* 16 */
213213

214+
static void header_store_u16_le(uint8_t *dst, uint16_t val)
215+
{
216+
dst[0] = (uint8_t)(val & 0xFFU);
217+
dst[1] = (uint8_t)((val >> 8) & 0xFFU);
218+
}
219+
220+
static void header_store_u32_le(uint8_t *dst, uint32_t val)
221+
{
222+
dst[0] = (uint8_t)(val & 0xFFU);
223+
dst[1] = (uint8_t)((val >> 8) & 0xFFU);
224+
dst[2] = (uint8_t)((val >> 16) & 0xFFU);
225+
dst[3] = (uint8_t)((val >> 24) & 0xFFU);
226+
}
227+
228+
static void header_store_u64_le(uint8_t *dst, uint64_t val)
229+
{
230+
uint32_t lo = (uint32_t)(val & 0xFFFFFFFFULL);
231+
uint32_t hi = (uint32_t)(val >> 32);
232+
233+
header_store_u32_le(dst, lo);
234+
header_store_u32_le(dst + 4, hi);
235+
}
236+
214237
static void header_append_u32(uint8_t* header, uint32_t* idx, uint32_t tmp32)
215238
{
216-
memcpy(&header[*idx], &tmp32, sizeof(tmp32));
239+
header_store_u32_le(&header[*idx], tmp32);
217240
*idx += sizeof(tmp32);
218241
}
219242
static void header_append_u16(uint8_t* header, uint32_t* idx, uint16_t tmp16)
220243
{
221-
memcpy(&header[*idx], &tmp16, sizeof(tmp16));
244+
header_store_u16_le(&header[*idx], tmp16);
222245
*idx += sizeof(tmp16);
223246
}
224247

@@ -244,6 +267,33 @@ static void header_append_tag(uint8_t* header, uint32_t* idx, uint16_t tag,
244267
*idx += len;
245268
}
246269

270+
static void header_append_tag_u16(uint8_t *header, uint32_t *idx, uint16_t tag,
271+
uint16_t val)
272+
{
273+
uint8_t tmp[sizeof(val)];
274+
275+
header_store_u16_le(tmp, val);
276+
header_append_tag(header, idx, tag, sizeof(val), tmp);
277+
}
278+
279+
static void header_append_tag_u32(uint8_t *header, uint32_t *idx, uint16_t tag,
280+
uint32_t val)
281+
{
282+
uint8_t tmp[sizeof(val)];
283+
284+
header_store_u32_le(tmp, val);
285+
header_append_tag(header, idx, tag, sizeof(val), tmp);
286+
}
287+
288+
static void header_append_tag_u64(uint8_t *header, uint32_t *idx, uint16_t tag,
289+
uint64_t val)
290+
{
291+
uint8_t tmp[sizeof(val)];
292+
293+
header_store_u64_le(tmp, val);
294+
header_append_tag(header, idx, tag, sizeof(val), tmp);
295+
}
296+
247297
#include "../lms/lms_common.h"
248298
#include "../xmss/xmss_common.h"
249299

@@ -1340,41 +1390,39 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
13401390

13411391
/* Append Version field */
13421392
fw_version32 = strtol(CMD.fw_version, NULL, 10);
1343-
header_append_tag(header, &header_idx, HDR_VERSION, HDR_VERSION_LEN,
1344-
&fw_version32);
1393+
header_append_tag_u32(header, &header_idx, HDR_VERSION, fw_version32);
13451394

13461395
/* Append pad bytes, so timestamp val field is 8-byte aligned */
13471396
ALIGN_8(header_idx);
13481397

13491398
if (!CMD.no_ts) {
13501399
/* Append Timestamp field */
13511400
stat(image_file, &attrib);
1352-
header_append_tag(header, &header_idx, HDR_TIMESTAMP, HDR_TIMESTAMP_LEN,
1353-
&attrib.st_ctime);
1401+
header_append_tag_u64(header, &header_idx, HDR_TIMESTAMP,
1402+
(uint64_t)attrib.st_ctime);
13541403
}
13551404

13561405
/* Append Image type field */
13571406
image_type = (uint16_t)CMD.sign & HDR_IMG_TYPE_AUTH_MASK;
13581407
image_type |= CMD.partition_id;
13591408
if (is_diff)
13601409
image_type |= HDR_IMG_TYPE_DIFF;
1361-
header_append_tag(header, &header_idx, HDR_IMG_TYPE, HDR_IMG_TYPE_LEN,
1362-
&image_type);
1410+
header_append_tag_u16(header, &header_idx, HDR_IMG_TYPE, image_type);
13631411

13641412
if (is_diff) {
13651413
/* Append pad bytes, so fields are 4-byte aligned */
13661414
ALIGN_4(header_idx);
1367-
header_append_tag(header, &header_idx, HDR_IMG_DELTA_BASE, 4,
1368-
&delta_base_version);
1369-
header_append_tag(header, &header_idx, HDR_IMG_DELTA_SIZE, 4,
1370-
&patch_len);
1415+
header_append_tag_u32(header, &header_idx, HDR_IMG_DELTA_BASE,
1416+
delta_base_version);
1417+
header_append_tag_u32(header, &header_idx, HDR_IMG_DELTA_SIZE,
1418+
patch_len);
13711419

13721420
/* Append pad bytes, so fields are 4-byte aligned */
13731421
ALIGN_4(header_idx);
1374-
header_append_tag(header, &header_idx, HDR_IMG_DELTA_INVERSE, 4,
1375-
&patch_inv_off);
1376-
header_append_tag(header, &header_idx, HDR_IMG_DELTA_INVERSE_SIZE, 4,
1377-
&patch_inv_len);
1422+
header_append_tag_u32(header, &header_idx, HDR_IMG_DELTA_INVERSE,
1423+
patch_inv_off);
1424+
header_append_tag_u32(header, &header_idx, HDR_IMG_DELTA_INVERSE_SIZE,
1425+
patch_inv_len);
13781426

13791427
if (!CMD.no_base_sha) {
13801428
/* Append pad bytes, so base hash is 8-byte aligned */
@@ -1535,7 +1583,8 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
15351583
wc_Sha256Final(&sha, second_buf);
15361584
wc_Sha256Free(&sha);
15371585
/* Add Secondary cipher to header */
1538-
header_append_tag(header, &header_idx, HDR_SECONDARY_CIPHER, 2, &CMD.secondary_sign);
1586+
header_append_tag_u16(header, &header_idx,
1587+
HDR_SECONDARY_CIPHER, (uint16_t)CMD.secondary_sign);
15391588
ALIGN_8(header_idx);
15401589
/* Add Secondary Pubkey Hash to header */
15411590
header_append_tag(header, &header_idx, HDR_SECONDARY_PUBKEY, digest_sz, second_buf);
@@ -1612,7 +1661,8 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
16121661
if (ret == 0) {
16131662
wc_Sha384Final(&sha, second_buf);
16141663
/* Add Secondary cipher to header */
1615-
header_append_tag(header, &header_idx, HDR_SECONDARY_CIPHER, 2, &CMD.secondary_sign);
1664+
header_append_tag_u16(header, &header_idx,
1665+
HDR_SECONDARY_CIPHER, (uint16_t)CMD.secondary_sign);
16161666
/* Add Secondary Pubkey Hash to header */
16171667
header_append_tag(header, &header_idx, HDR_SECONDARY_PUBKEY, digest_sz, second_buf);
16181668
DEBUG_PRINT("Secondary pubkey hash %d\n", digest_sz);
@@ -1683,7 +1733,8 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
16831733
if (ret == 0) {
16841734
ret = wc_Sha3_384_Final(&sha, second_buf);
16851735
/* Add Secondary cipher to header */
1686-
header_append_tag(header, &header_idx, HDR_SECONDARY_CIPHER, 2, &CMD.secondary_sign);
1736+
header_append_tag_u16(header, &header_idx,
1737+
HDR_SECONDARY_CIPHER, (uint16_t)CMD.secondary_sign);
16871738
header_append_tag(header, &header_idx, HDR_SECONDARY_PUBKEY, digest_sz, second_buf);
16881739
DEBUG_PRINT("Secondary pubkey hash %d\n", digest_sz);
16891740
DEBUG_BUFFER(second_buf, digest_sz);

tools/unit-tests/unit-sign-encrypted-output.c

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,20 @@ static void assert_header_bytes(const uint8_t *image, uint16_t tag,
237237
"Tag 0x%04x mismatch", tag);
238238
}
239239

240+
static void store_u16_le(uint8_t *dst, uint16_t val)
241+
{
242+
dst[0] = (uint8_t)(val & 0xFFU);
243+
dst[1] = (uint8_t)((val >> 8) & 0xFFU);
244+
}
245+
246+
static void store_u32_le(uint8_t *dst, uint32_t val)
247+
{
248+
dst[0] = (uint8_t)(val & 0xFFU);
249+
dst[1] = (uint8_t)((val >> 8) & 0xFFU);
250+
dst[2] = (uint8_t)((val >> 16) & 0xFFU);
251+
dst[3] = (uint8_t)((val >> 24) & 0xFFU);
252+
}
253+
240254
static uint16_t find_exact_fill_custom_len(void)
241255
{
242256
uint16_t len;
@@ -413,6 +427,39 @@ START_TEST(test_make_header_ex_grows_header_for_cert_chain_and_digest_tlvs)
413427
}
414428
END_TEST
415429

430+
START_TEST(test_header_append_helpers_emit_little_endian_bytes)
431+
{
432+
uint8_t header[32];
433+
uint8_t value[] = { 0xAA, 0x55, 0x77 };
434+
uint32_t idx = 0;
435+
436+
reset_cmd_defaults();
437+
CMD.header_sz = sizeof(header);
438+
memset(header, 0x00, sizeof(header));
439+
440+
header_append_u32(header, &idx, 0x11223344U);
441+
ck_assert_uint_eq(idx, 4);
442+
ck_assert_uint_eq(header[0], 0x44);
443+
ck_assert_uint_eq(header[1], 0x33);
444+
ck_assert_uint_eq(header[2], 0x22);
445+
ck_assert_uint_eq(header[3], 0x11);
446+
447+
header_append_u16(header, &idx, 0x5566U);
448+
ck_assert_uint_eq(idx, 6);
449+
ck_assert_uint_eq(header[4], 0x66);
450+
ck_assert_uint_eq(header[5], 0x55);
451+
452+
header_append_tag(header, &idx, 0xABCDU, (uint16_t)sizeof(value), value);
453+
ck_assert_uint_eq(idx, 13);
454+
ck_assert_uint_eq(header[6], 0xCD);
455+
ck_assert_uint_eq(header[7], 0xAB);
456+
ck_assert_uint_eq(header[8], (uint8_t)sizeof(value));
457+
ck_assert_uint_eq(header[9], 0x00);
458+
ck_assert_msg(memcmp(&header[10], value, sizeof(value)) == 0,
459+
"header_append_tag payload mismatch");
460+
}
461+
END_TEST
462+
416463
START_TEST(test_make_header_ex_roundtrip_custom_tlvs_via_wolfboot_parser)
417464
{
418465
char tempdir[] = "/tmp/wolfboot-sign-XXXXXX";
@@ -427,6 +474,8 @@ START_TEST(test_make_header_ex_roundtrip_custom_tlvs_via_wolfboot_parser)
427474
uint8_t tlv_three[] = { 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28 };
428475
uint16_t image_type;
429476
uint32_t version = 7;
477+
uint8_t version_le[4];
478+
uint8_t image_type_le[2];
430479
size_t output_len;
431480
int ret;
432481

@@ -460,10 +509,11 @@ START_TEST(test_make_header_ex_roundtrip_custom_tlvs_via_wolfboot_parser)
460509
ck_assert_int_eq(ret, 0);
461510
ck_assert_int_eq(read_file(output_path, &output_buf, &output_len), 0);
462511
ck_assert_uint_eq(output_len, CMD.header_sz + sizeof(image_buf));
463-
assert_header_bytes(output_buf, HDR_VERSION, (uint8_t *)&version,
464-
sizeof(version));
465-
assert_header_bytes(output_buf, HDR_IMG_TYPE, (uint8_t *)&image_type,
466-
sizeof(image_type));
512+
store_u32_le(version_le, version);
513+
store_u16_le(image_type_le, image_type);
514+
assert_header_bytes(output_buf, HDR_VERSION, version_le, sizeof(version_le));
515+
assert_header_bytes(output_buf, HDR_IMG_TYPE, image_type_le,
516+
sizeof(image_type_le));
467517
assert_header_bytes(output_buf, 0x30, tlv_one, sizeof(tlv_one));
468518
assert_header_bytes(output_buf, 0x31, tlv_two, sizeof(tlv_two));
469519
assert_header_bytes(output_buf, 0x32, tlv_three, sizeof(tlv_three));
@@ -658,6 +708,7 @@ Suite *wolfboot_suite(void)
658708
tcase_add_test(tcase, test_make_header_ex_fails_when_image_reopen_fails);
659709
tcase_add_test(tcase,
660710
test_make_header_ex_grows_header_for_cert_chain_and_digest_tlvs);
711+
tcase_add_test(tcase, test_header_append_helpers_emit_little_endian_bytes);
661712
tcase_add_test(tcase,
662713
test_make_header_ex_roundtrip_custom_tlvs_via_wolfboot_parser);
663714
tcase_add_test(tcase,

0 commit comments

Comments
 (0)