mirror of https://github.com/wolfSSL/wolfBoot.git
parent
0bcc49ab3c
commit
153ad2b0af
|
|
@ -221,9 +221,23 @@ static void header_append_u16(uint8_t* header, uint32_t* idx, uint16_t tmp16)
|
|||
memcpy(&header[*idx], &tmp16, sizeof(tmp16));
|
||||
*idx += sizeof(tmp16);
|
||||
}
|
||||
|
||||
static uint32_t header_append_limit(void);
|
||||
|
||||
static void header_append_tag(uint8_t* header, uint32_t* idx, uint16_t tag,
|
||||
uint16_t len, void* data)
|
||||
uint16_t len, const void* data)
|
||||
{
|
||||
const uint32_t append_sz = (uint32_t)(sizeof(tag) + sizeof(len)) + len;
|
||||
const uint32_t header_sz = header_append_limit();
|
||||
|
||||
if ((*idx > header_sz) || (append_sz > (header_sz - *idx))) {
|
||||
fprintf(stderr,
|
||||
"Header overflow while appending tag 0x%04x "
|
||||
"(offset=%u, size=%u, header=%u)\n",
|
||||
tag, *idx, append_sz, header_sz);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
header_append_u16(header, idx, tag);
|
||||
header_append_u16(header, idx, len);
|
||||
memcpy(&header[*idx], data, len);
|
||||
|
|
@ -296,6 +310,11 @@ static struct cmd_options CMD = {
|
|||
.hybrid = 0
|
||||
};
|
||||
|
||||
static uint32_t header_append_limit(void)
|
||||
{
|
||||
return CMD.header_sz;
|
||||
}
|
||||
|
||||
static void zero_and_free(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
volatile uint8_t *p;
|
||||
|
|
@ -1124,6 +1143,114 @@ static int sign_digest(int sign, int hash_algo,
|
|||
#define ALIGN_8(x) while ((x % 8) != 4) { x++; }
|
||||
#define ALIGN_4(x) while ((x % 4) != 0) { x++; }
|
||||
|
||||
static void header_size_align_8(uint32_t *idx)
|
||||
{
|
||||
while ((*idx % 8U) != 4U) {
|
||||
(*idx)++;
|
||||
}
|
||||
}
|
||||
|
||||
static void header_size_align_4(uint32_t *idx)
|
||||
{
|
||||
while ((*idx % 4U) != 0U) {
|
||||
(*idx)++;
|
||||
}
|
||||
}
|
||||
|
||||
static void header_size_append_tag(uint32_t *idx, uint32_t len)
|
||||
{
|
||||
*idx += 4U + len;
|
||||
}
|
||||
|
||||
static uint32_t header_digest_size(int hash_algo)
|
||||
{
|
||||
switch (hash_algo) {
|
||||
case HASH_SHA256:
|
||||
return HDR_SHA256_LEN;
|
||||
case HASH_SHA384:
|
||||
return HDR_SHA384_LEN;
|
||||
case HASH_SHA3:
|
||||
return HDR_SHA3_384_LEN;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t header_required_size(int is_diff, uint32_t cert_chain_sz,
|
||||
uint32_t secondary_key_sz)
|
||||
{
|
||||
uint32_t idx = 0;
|
||||
uint32_t digest_sz = header_digest_size(CMD.hash_algo);
|
||||
uint32_t i;
|
||||
|
||||
idx += 2U * sizeof(uint32_t);
|
||||
header_size_append_tag(&idx, HDR_VERSION_LEN);
|
||||
header_size_align_8(&idx);
|
||||
|
||||
if (!CMD.no_ts) {
|
||||
header_size_append_tag(&idx, HDR_TIMESTAMP_LEN);
|
||||
}
|
||||
|
||||
header_size_append_tag(&idx, HDR_IMG_TYPE_LEN);
|
||||
|
||||
if (is_diff) {
|
||||
header_size_align_4(&idx);
|
||||
header_size_append_tag(&idx, 4);
|
||||
header_size_append_tag(&idx, 4);
|
||||
header_size_align_4(&idx);
|
||||
header_size_append_tag(&idx, 4);
|
||||
header_size_append_tag(&idx, 4);
|
||||
|
||||
if (!CMD.no_base_sha && digest_sz > 0U) {
|
||||
header_size_align_8(&idx);
|
||||
header_size_append_tag(&idx, digest_sz);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < CMD.custom_tlvs; i++) {
|
||||
header_size_align_8(&idx);
|
||||
header_size_append_tag(&idx, CMD.custom_tlv[i].len);
|
||||
}
|
||||
|
||||
if (cert_chain_sz > 0U) {
|
||||
header_size_align_8(&idx);
|
||||
header_size_append_tag(&idx, cert_chain_sz);
|
||||
}
|
||||
|
||||
if (digest_sz > 0U) {
|
||||
header_size_align_8(&idx);
|
||||
header_size_append_tag(&idx, digest_sz);
|
||||
header_size_align_8(&idx);
|
||||
|
||||
if (CMD.hybrid && secondary_key_sz > 0U) {
|
||||
header_size_append_tag(&idx, 2);
|
||||
header_size_align_8(&idx);
|
||||
header_size_append_tag(&idx, digest_sz);
|
||||
header_size_align_8(&idx);
|
||||
}
|
||||
|
||||
header_size_append_tag(&idx, digest_sz);
|
||||
}
|
||||
|
||||
if (CMD.sign != NO_SIGN) {
|
||||
header_size_align_8(&idx);
|
||||
header_size_append_tag(&idx, CMD.signature_sz);
|
||||
|
||||
if (CMD.hybrid) {
|
||||
header_size_align_8(&idx);
|
||||
header_size_append_tag(&idx, CMD.secondary_signature_sz);
|
||||
}
|
||||
|
||||
if (CMD.policy_sign) {
|
||||
header_size_align_8(&idx);
|
||||
header_size_append_tag(&idx,
|
||||
CMD.policy_sz + (uint32_t)sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
|
||||
const char *image_file, const char *outfile,
|
||||
uint32_t delta_base_version, uint32_t patch_len, uint32_t patch_inv_off,
|
||||
|
|
@ -1157,14 +1284,8 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
|
|||
|
||||
/* Get the file size */
|
||||
if (stat(CMD.cert_chain_file, &file_stat) == 0) {
|
||||
/* 2 bytes for tag + 2 bytes for length field */
|
||||
const uint32_t tag_len_size = 4;
|
||||
/* Maximum alignment padding that might be needed */
|
||||
const uint32_t max_alignment = 8;
|
||||
/* Required space = tag(2) + length(2) + data + potential alignment
|
||||
* * padding */
|
||||
const uint32_t required_space =
|
||||
tag_len_size + file_stat.st_size + max_alignment;
|
||||
const uint32_t required_space = header_required_size(is_diff,
|
||||
(uint32_t)file_stat.st_size, secondary_key_sz);
|
||||
|
||||
/* If the current header size is too small, increase it */
|
||||
if (CMD.header_sz < required_space) {
|
||||
|
|
|
|||
|
|
@ -220,6 +220,58 @@ START_TEST(test_make_header_ex_fails_when_image_reopen_fails)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_make_header_ex_grows_header_for_cert_chain_and_digest_tlvs)
|
||||
{
|
||||
char tempdir[] = "/tmp/wolfboot-sign-XXXXXX";
|
||||
char image_path[PATH_MAX];
|
||||
char output_path[PATH_MAX];
|
||||
char cert_chain_path[PATH_MAX];
|
||||
uint8_t image_buf[] = { 0x01, 0x02, 0x03, 0x04 };
|
||||
uint8_t cert_chain_buf[200];
|
||||
uint8_t pubkey[] = { 0xA5 };
|
||||
struct stat st;
|
||||
int ret;
|
||||
|
||||
ck_assert_ptr_nonnull(mkdtemp(tempdir));
|
||||
|
||||
snprintf(image_path, sizeof(image_path), "%s/image.bin", tempdir);
|
||||
snprintf(output_path, sizeof(output_path), "%s/output.bin", tempdir);
|
||||
snprintf(cert_chain_path, sizeof(cert_chain_path), "%s/cert-chain.bin",
|
||||
tempdir);
|
||||
|
||||
memset(cert_chain_buf, 0xC3, sizeof(cert_chain_buf));
|
||||
ck_assert_int_eq(write_file(image_path, image_buf, sizeof(image_buf)), 0);
|
||||
ck_assert_int_eq(write_file(cert_chain_path, cert_chain_buf,
|
||||
sizeof(cert_chain_buf)), 0);
|
||||
|
||||
memset(&CMD, 0, sizeof(CMD));
|
||||
CMD.sign = NO_SIGN;
|
||||
CMD.hash_algo = HASH_SHA256;
|
||||
CMD.partition_id = HDR_IMG_TYPE_APP;
|
||||
CMD.header_sz = 256;
|
||||
CMD.fw_version = "7";
|
||||
CMD.no_ts = 1;
|
||||
CMD.cert_chain_file = cert_chain_path;
|
||||
|
||||
reset_mocks(NULL, 0);
|
||||
ret = make_header_ex(0, pubkey, sizeof(pubkey), image_path, output_path,
|
||||
0, 0, 0, 0, NULL, 0, NULL, 0);
|
||||
|
||||
ck_assert_int_eq(ret, 0);
|
||||
ck_assert_uint_eq(CMD.header_sz, 512);
|
||||
ck_assert_int_eq(stat(output_path, &st), 0);
|
||||
ck_assert_uint_eq((uint32_t)st.st_size, CMD.header_sz + sizeof(image_buf));
|
||||
ck_assert_int_eq(mock_null_fwrite_calls, 0);
|
||||
ck_assert_int_eq(mock_null_fread_calls, 0);
|
||||
ck_assert_int_eq(mock_null_fclose_calls, 0);
|
||||
|
||||
unlink(output_path);
|
||||
unlink(cert_chain_path);
|
||||
unlink(image_path);
|
||||
rmdir(tempdir);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *wolfboot_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("sign-encrypted-output");
|
||||
|
|
@ -227,6 +279,8 @@ Suite *wolfboot_suite(void)
|
|||
|
||||
tcase_add_test(tcase, test_make_header_ex_fails_when_encrypted_output_open_fails);
|
||||
tcase_add_test(tcase, test_make_header_ex_fails_when_image_reopen_fails);
|
||||
tcase_add_test(tcase,
|
||||
test_make_header_ex_grows_header_for_cert_chain_and_digest_tlvs);
|
||||
suite_add_tcase(s, tcase);
|
||||
|
||||
return s;
|
||||
|
|
|
|||
Loading…
Reference in New Issue