mirror of https://github.com/thesofproject/sof.git
cavs: add support for cavs2.5 code signing
cavs 2.5 uses a larger key and the RSA signing PSS mode. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
This commit is contained in:
parent
68b3693de1
commit
db40934e57
|
@ -529,6 +529,118 @@ static int parse_cse(const toml_table_t *toml, struct parse_ctx *pctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void dump_cse_v2_5(const struct CsePartitionDirHeader_v2_5 *cse_header,
|
||||
const struct CsePartitionDirEntry *cse_entry)
|
||||
{
|
||||
int i;
|
||||
|
||||
DUMP("\ncse");
|
||||
DUMP_KEY("partition_name", "'%s'", cse_header->partition_name);
|
||||
DUMP_KEY("header_version", "%d", cse_header->header_version);
|
||||
DUMP_KEY("entry_version", "%d", cse_header->entry_version);
|
||||
DUMP_KEY("nb_entries", "%d", cse_header->nb_entries);
|
||||
for (i = 0; i < cse_header->nb_entries; ++i) {
|
||||
DUMP_KEY("entry.name", "'%s'", cse_entry[i].entry_name);
|
||||
DUMP_KEY("entry.offset", "0x%x", cse_entry[i].offset);
|
||||
DUMP_KEY("entry.length", "0x%x", cse_entry[i].length);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: fix up constants in headers for v2.5 */
|
||||
static int parse_cse_v2_5(const toml_table_t *toml, struct parse_ctx *pctx,
|
||||
struct CsePartitionDirHeader_v2_5 *hdr, struct CsePartitionDirEntry *out,
|
||||
int entry_capacity, bool verbose)
|
||||
{
|
||||
toml_array_t *cse_entry_array;
|
||||
toml_table_t *cse_entry;
|
||||
struct parse_ctx ctx;
|
||||
toml_table_t *cse;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */
|
||||
cse = toml_table_in(toml, "cse");
|
||||
if (!cse)
|
||||
return err_key_not_found("cse");
|
||||
++pctx->table_cnt;
|
||||
parse_ctx_init(&ctx);
|
||||
|
||||
/* non-configurable fields */
|
||||
hdr->header_marker = CSE_HEADER_MAKER;
|
||||
hdr->header_length = sizeof(struct CsePartitionDirHeader_v2_5);
|
||||
|
||||
/* configurable fields */
|
||||
hdr->header_version = parse_uint32_key(cse, &ctx, "header_version", 2, &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
hdr->entry_version = parse_uint32_key(cse, &ctx, "entry_version", 1, &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
parse_str_key(cse, &ctx, "partition_name", (char *)hdr->partition_name,
|
||||
sizeof(hdr->partition_name), &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* check everything parsed, expect 1 table */
|
||||
ctx.array_cnt += 1;
|
||||
ret = assert_everything_parsed(cse, &ctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* entry array */
|
||||
cse_entry_array = toml_array_in(cse, "entry");
|
||||
if (!cse_entry_array)
|
||||
return err_key_not_found("entry");
|
||||
if (toml_array_kind(cse_entry_array) != 't' ||
|
||||
toml_array_nelem(cse_entry_array) != entry_capacity)
|
||||
return err_key_parse("entry", "wrong array type or length != %d", entry_capacity);
|
||||
|
||||
/* parse entry array elements */
|
||||
for (i = 0; i < toml_array_nelem(cse_entry_array); ++i) {
|
||||
cse_entry = toml_table_at(cse_entry_array, i);
|
||||
if (!cse_entry)
|
||||
return err_key_parse("entry", NULL);
|
||||
|
||||
/* initialize parse context for each array element */
|
||||
parse_ctx_init(&ctx);
|
||||
|
||||
/* non-configurable fields */
|
||||
|
||||
/* configurable fields */
|
||||
parse_str_key(cse_entry, &ctx, "name", (char *)out[i].entry_name,
|
||||
sizeof(out[i].entry_name), &ret);
|
||||
if (ret < 0)
|
||||
return err_key_parse("entry", NULL);
|
||||
|
||||
out[i].offset = parse_uint32_hex_key(cse_entry, &ctx, "offset", -1, &ret);
|
||||
if (ret < 0)
|
||||
return err_key_parse("offset", NULL);
|
||||
|
||||
out[i].length = parse_uint32_hex_key(cse_entry, &ctx, "length", -1, &ret);
|
||||
if (ret < 0)
|
||||
return err_key_parse("length", NULL);
|
||||
|
||||
/* check everything parsed */
|
||||
ret = assert_everything_parsed(cse_entry, &ctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
hdr->nb_entries = toml_array_nelem(cse_entry_array);
|
||||
|
||||
if (1 || verbose)
|
||||
dump_cse_v2_5(hdr, out);
|
||||
|
||||
/*
|
||||
* values set in other places in code:
|
||||
* - checksum
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dump_css_v1_5(const struct css_header_v1_5 *css)
|
||||
{
|
||||
DUMP("\ncss 1.5");
|
||||
|
@ -697,6 +809,96 @@ static int parse_css_v1_8(const toml_table_t *toml, struct parse_ctx *pctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void dump_css_v2_5(const struct css_header_v2_5 *css)
|
||||
{
|
||||
DUMP("\ncss 2.5");
|
||||
DUMP_KEY("header_type", "%d", css->header_type);
|
||||
DUMP_KEY("header_len", "%d", css->header_len);
|
||||
DUMP_KEY("header_version", "0x%x", css->header_version);
|
||||
DUMP_KEY("module_vendor", "0x%x", css->module_vendor);
|
||||
DUMP_KEY("size", "%d", css->size);
|
||||
DUMP_KEY("svn", "%d", css->svn);
|
||||
DUMP_KEY("modulus_size", "%d", css->modulus_size);
|
||||
DUMP_KEY("exponent_size", "%d", css->exponent_size);
|
||||
}
|
||||
|
||||
static int parse_css_v2_5(const toml_table_t *toml, struct parse_ctx *pctx,
|
||||
struct css_header_v2_5 *out, bool verbose)
|
||||
{
|
||||
static const uint8_t hdr_id[4] = MAN_CSS_HDR_ID;
|
||||
struct parse_ctx ctx;
|
||||
toml_table_t *css;
|
||||
int ret;
|
||||
|
||||
/* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */
|
||||
css = toml_table_in(toml, "css");
|
||||
if (!css)
|
||||
return err_key_not_found("css");
|
||||
++pctx->table_cnt;
|
||||
parse_ctx_init(&ctx);
|
||||
|
||||
/* non-configurable fields */
|
||||
memcpy(out->header_id, hdr_id, sizeof(out->header_id));
|
||||
|
||||
/* configurable fields */
|
||||
out->header_type = parse_uint32_key(css, &ctx, "header_type", MAN_CSS_MOD_TYPE, &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
out->header_len = parse_uint32_key(css, &ctx, "header_len", MAN_CSS_HDR_SIZE_2_5, &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
out->header_version = parse_uint32_hex_key(css, &ctx, "header_version", MAN_CSS_HDR_VERSION_2_5,
|
||||
&ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
out->module_vendor = parse_uint32_hex_key(css, &ctx, "module_vendor", MAN_CSS_MOD_VENDOR,
|
||||
&ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
out->size = parse_uint32_key(css, &ctx, "size", 281, &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
out->svn = parse_uint32_key(css, &ctx, "svn", 0, &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
out->modulus_size = parse_uint32_key(css, &ctx, "modulus_size", MAN_CSS_MOD_SIZE_2_5, &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
out->exponent_size = parse_uint32_key(css, &ctx, "exponent_size", MAN_CSS_EXP_SIZE, &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* hardcoded to align with meu */
|
||||
out->reserved0 = 0;
|
||||
out->reserved1[0] = 0xf;
|
||||
out->reserved1[1] = 0x048e0000; // TODO: what is this ?
|
||||
|
||||
/* check everything parsed */
|
||||
ret = assert_everything_parsed(css, &ctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (verbose)
|
||||
dump_css_v2_5(out);
|
||||
|
||||
/*
|
||||
* values set in other places in code:
|
||||
* - date
|
||||
* - version
|
||||
* - modulus
|
||||
* - exponent
|
||||
* - signature
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dump_signed_pkg(const struct signed_pkg_info_ext *signed_pkg)
|
||||
{
|
||||
int i;
|
||||
|
@ -853,6 +1055,163 @@ static int parse_signed_pkg(const toml_table_t *toml, struct parse_ctx *pctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void dump_signed_pkg_v2_5(const struct signed_pkg_info_ext_v2_5 *signed_pkg)
|
||||
{
|
||||
int i;
|
||||
|
||||
DUMP("\nsigned_pkg");
|
||||
DUMP_KEY("name", "'%s'", signed_pkg->name);
|
||||
DUMP_KEY("vcn", "%d", signed_pkg->vcn);
|
||||
DUMP_KEY("svn", "%d", signed_pkg->svn);
|
||||
DUMP_KEY("fw_type", "%d", signed_pkg->fw_type);
|
||||
DUMP_KEY("fw_sub_type", "%d", signed_pkg->fw_sub_type);
|
||||
for (i = 0; i < ARRAY_SIZE(signed_pkg->bitmap); ++i)
|
||||
DUMP_KEY("bitmap", "%d", signed_pkg->bitmap[i]);
|
||||
for (i = 0; i < ARRAY_SIZE(signed_pkg->module); ++i) {
|
||||
DUMP_KEY("meta.name", "'%s'", signed_pkg->module[i].name);
|
||||
DUMP_KEY("meta.type", "0x%x", signed_pkg->module[i].type);
|
||||
DUMP_KEY("meta.hash_algo", "0x%x", signed_pkg->module[i].hash_algo);
|
||||
DUMP_KEY("meta.hash_size", "0x%x", signed_pkg->module[i].hash_size);
|
||||
DUMP_KEY("meta.meta_size", "%d", signed_pkg->module[i].meta_size);
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_signed_pkg_v2_5(const toml_table_t *toml, struct parse_ctx *pctx,
|
||||
struct signed_pkg_info_ext_v2_5 *out, bool verbose)
|
||||
{
|
||||
struct signed_pkg_info_module_v2_5 *mod;
|
||||
toml_array_t *bitmap_array;
|
||||
toml_array_t *module_array;
|
||||
toml_table_t *signed_pkg;
|
||||
struct parse_ctx ctx;
|
||||
toml_table_t *module;
|
||||
toml_raw_t raw;
|
||||
int64_t temp_i;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* look for subtable in toml, increment pctx parsed table cnt and initialize local ctx */
|
||||
signed_pkg = toml_table_in(toml, "signed_pkg");
|
||||
if (!signed_pkg)
|
||||
return err_key_not_found("signed_pkg");
|
||||
++pctx->table_cnt;
|
||||
parse_ctx_init(&ctx);
|
||||
|
||||
/* non-configurable fields */
|
||||
out->ext_type = SIGN_PKG_EXT_TYPE;
|
||||
out->ext_len = sizeof(struct signed_pkg_info_ext_v2_5);
|
||||
|
||||
/* configurable fields */
|
||||
parse_str_key(signed_pkg, &ctx, "name", (char *)out->name, sizeof(out->name), &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
out->vcn = parse_uint32_key(signed_pkg, &ctx, "vcn", 0, &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
out->svn = parse_uint32_key(signed_pkg, &ctx, "svn", 0, &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
out->fw_type = parse_uint32_hex_key(signed_pkg, &ctx, "fw_type", 0, &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
out->fw_sub_type = parse_uint32_hex_key(signed_pkg, &ctx, "fw_sub_type", 0, &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* bitmap array */
|
||||
bitmap_array = toml_array_in(signed_pkg, "bitmap");
|
||||
if (!bitmap_array) {
|
||||
/* default value - some use 0x10*/
|
||||
out->bitmap[4] = 0x8;
|
||||
} else {
|
||||
++ctx.array_cnt;
|
||||
if (toml_array_kind(bitmap_array) != 'v' || toml_array_type(bitmap_array) != 'i' ||
|
||||
toml_array_nelem(bitmap_array) > ARRAY_SIZE(out->bitmap))
|
||||
return err_key_parse("bitmap", "wrong array type or length > %d",
|
||||
ARRAY_SIZE(out->bitmap));
|
||||
|
||||
for (i = 0; i < toml_array_nelem(bitmap_array); ++i) {
|
||||
raw = toml_raw_at(bitmap_array, i);
|
||||
if (!raw)
|
||||
return err_key_parse("bitmap", NULL);
|
||||
|
||||
ret = toml_rtoi(raw, &temp_i);
|
||||
if (ret < 0 || temp_i < 0)
|
||||
return err_key_parse("bitmap", "values can't be negative");
|
||||
out->bitmap[i] = temp_i;
|
||||
}
|
||||
}
|
||||
|
||||
/* check everything parsed, expect 1 more array */
|
||||
ctx.array_cnt += 1;
|
||||
ret = assert_everything_parsed(signed_pkg, &ctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* modules array */
|
||||
module_array = toml_array_in(signed_pkg, "module");
|
||||
if (!module_array)
|
||||
return err_key_not_found("module");
|
||||
if (toml_array_kind(module_array) != 't' ||
|
||||
toml_array_nelem(module_array) != ARRAY_SIZE(out->module))
|
||||
return err_key_parse("module", "wrong array type or length != %d",
|
||||
ARRAY_SIZE(out->module));
|
||||
|
||||
/* parse modules array elements */
|
||||
for (i = 0; i < toml_array_nelem(module_array); ++i) {
|
||||
module = toml_table_at(module_array, i);
|
||||
if (!module)
|
||||
return err_key_parse("module", NULL);
|
||||
mod = &out->module[i];
|
||||
|
||||
/* initialize parse context for each array element */
|
||||
parse_ctx_init(&ctx);
|
||||
|
||||
/* non-configurable fields */
|
||||
|
||||
/* configurable fields */
|
||||
parse_str_key(module, &ctx, "name", (char *)mod->name, sizeof(mod->name), &ret);
|
||||
if (ret < 0)
|
||||
return err_key_parse("module", NULL);
|
||||
|
||||
mod->type = parse_uint32_hex_key(module, &ctx, "type", 0x03, &ret);
|
||||
if (ret < 0)
|
||||
return err_key_parse("module", NULL);
|
||||
|
||||
mod->hash_algo = parse_uint32_hex_key(module, &ctx, "hash_algo", 0x00, &ret);
|
||||
if (ret < 0)
|
||||
return err_key_parse("module", NULL);
|
||||
|
||||
mod->hash_size = parse_uint32_hex_key(module, &ctx, "hash_size", 0x30, &ret);
|
||||
if (ret < 0)
|
||||
return err_key_parse("module", NULL);
|
||||
|
||||
mod->meta_size = parse_uint32_key(module, &ctx, "meta_size", 112, &ret);
|
||||
if (ret < 0)
|
||||
return err_key_parse("module", NULL);
|
||||
|
||||
/* check everything parsed */
|
||||
ret = assert_everything_parsed(module, &ctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
dump_signed_pkg_v2_5(out);
|
||||
|
||||
/*
|
||||
* values set in other places in code:
|
||||
* - module.hash
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void dump_partition_info_ext(const struct partition_info_ext *part_info)
|
||||
{
|
||||
int i;
|
||||
|
@ -982,6 +1341,26 @@ static int parse_partition_info_ext(const toml_table_t *toml, struct parse_ctx *
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int parse_info_ext_0x16(const toml_table_t *toml, struct parse_ctx *pctx,
|
||||
struct info_ext_0x16 *out, bool verbose)
|
||||
{
|
||||
/* known */
|
||||
out->ext_type = 0x16;
|
||||
out->ext_len = sizeof(*out);
|
||||
out->name[0] = 'A';
|
||||
out->name[1] = 'D';
|
||||
out->name[2] = 'S';
|
||||
out->name[3] = 'P';
|
||||
|
||||
/* copied from meu - unknown */
|
||||
out->data[0] = 0x10000000;
|
||||
out->data[2] = 0x1;
|
||||
out->data[3] = 0x0;
|
||||
out->data[4] = 0x3003;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dump_adsp_file_ext_v1_8(const struct sof_man_adsp_meta_file_ext_v1_8 *adsp_file)
|
||||
{
|
||||
int i;
|
||||
|
@ -1487,7 +1866,7 @@ static int parse_adsp_config_v2_5(const toml_table_t *toml, struct adsp *out,
|
|||
memset(out->man_v2_5, 0, sizeof(*out->man_v2_5));
|
||||
|
||||
/* assign correct write functions */
|
||||
out->write_firmware = NULL;
|
||||
out->write_firmware = man_write_fw_v2_5;
|
||||
out->write_firmware_meu = man_write_fw_meu_v2_5;
|
||||
|
||||
/* version array has already been parsed, so increment ctx.array_cnt */
|
||||
|
@ -1499,20 +1878,20 @@ static int parse_adsp_config_v2_5(const toml_table_t *toml, struct adsp *out,
|
|||
if (ret < 0)
|
||||
return err_key_parse("adsp", NULL);
|
||||
|
||||
ret = parse_cse(toml, &ctx, &out->man_v2_5->cse_partition_dir_header,
|
||||
ret = parse_cse_v2_5(toml, &ctx, &out->man_v2_5->cse_partition_dir_header,
|
||||
out->man_v2_5->cse_partition_dir_entry, MAN_CSE_PARTS, verbose);
|
||||
if (ret < 0)
|
||||
return err_key_parse("cse", NULL);
|
||||
|
||||
ret = parse_css_v1_8(toml, &ctx, &out->man_v2_5->css, verbose);
|
||||
ret = parse_css_v2_5(toml, &ctx, &out->man_v2_5->css, verbose);
|
||||
if (ret < 0)
|
||||
return err_key_parse("css", NULL);
|
||||
|
||||
ret = parse_signed_pkg(toml, &ctx, &out->man_v2_5->signed_pkg, verbose);
|
||||
ret = parse_signed_pkg_v2_5(toml, &ctx, &out->man_v2_5->signed_pkg, verbose);
|
||||
if (ret < 0)
|
||||
return err_key_parse("signed_pkg", NULL);
|
||||
|
||||
ret = parse_partition_info_ext(toml, &ctx, &out->man_v2_5->partition_info, verbose);
|
||||
ret = parse_info_ext_0x16(toml, &ctx, &out->man_v2_5->info_0x16, verbose);
|
||||
if (ret < 0)
|
||||
return err_key_parse("partition_info", NULL);
|
||||
|
||||
|
|
|
@ -179,6 +179,7 @@ int simple_write_firmware(struct image *image);
|
|||
int man_write_fw_v1_5(struct image *image);
|
||||
int man_write_fw_v1_5_sue(struct image *image);
|
||||
int man_write_fw_v1_8(struct image *image);
|
||||
int man_write_fw_v2_5(struct image *image);
|
||||
int man_write_fw_meu_v1_5(struct image *image);
|
||||
int man_write_fw_meu_v1_8(struct image *image);
|
||||
int man_write_fw_meu_v2_5(struct image *image);
|
||||
|
|
|
@ -162,6 +162,7 @@ void module_sha_update(struct image *image, uint8_t *data, size_t bytes);
|
|||
void module_sha_complete(struct image *image, uint8_t *hash);
|
||||
int ri_manifest_sign_v1_5(struct image *image);
|
||||
int ri_manifest_sign_v1_8(struct image *image);
|
||||
int ri_manifest_sign_v2_5(struct image *image);
|
||||
void ri_sha256(struct image *image, unsigned int offset, unsigned int size,
|
||||
uint8_t *hash);
|
||||
void ri_sha384(struct image *image, unsigned int offset, unsigned int size,
|
||||
|
|
123
src/manifest.c
123
src/manifest.c
|
@ -121,6 +121,19 @@ static int man_init_image_v1_8(struct image *image)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int man_init_image_v2_5(struct image *image)
|
||||
{
|
||||
/* allocate image and copy template manifest */
|
||||
image->fw_image = calloc(image->adsp->image_size, 1);
|
||||
if (!image->fw_image)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(image->fw_image, image->adsp->man_v2_5,
|
||||
sizeof(struct fw_image_manifest_v2_5));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we should call this after all segments size set up via iterate */
|
||||
static uint32_t elf_to_file_offset(struct image *image,
|
||||
struct module *module,
|
||||
|
@ -1190,3 +1203,113 @@ err:
|
|||
unlink(image->out_file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* used by others */
|
||||
int man_write_fw_v2_5(struct image *image)
|
||||
{
|
||||
struct sof_man_fw_desc *desc;
|
||||
struct fw_image_manifest_v2_5 *m;
|
||||
uint8_t hash[SOF_MAN_MOD_SHA384_LEN];
|
||||
int ret, i;
|
||||
|
||||
/* init image */
|
||||
ret = man_init_image_v2_5(image);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* use default meu offset for TGL if not provided */
|
||||
if (!image->meu_offset)
|
||||
image->meu_offset = MAN_FW_DESC_OFFSET_V2_5 - 0x10;
|
||||
|
||||
/* open ROM image */
|
||||
ret = man_open_rom_file(image);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* open unsigned firmware */
|
||||
ret = man_open_unsigned_file(image);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* create the manifest */
|
||||
ret = man_open_manifest_file(image);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* create the module */
|
||||
m = image->fw_image;
|
||||
desc = image->fw_image + MAN_DESC_OFFSET_V1_8;
|
||||
|
||||
/* firmware and build version */
|
||||
m->css.version.major_version = image->fw_ver_major;
|
||||
m->css.version.minor_version = image->fw_ver_minor;
|
||||
m->css.version.build_version = image->fw_ver_build;
|
||||
m->desc.header.major_version = image->fw_ver_major;
|
||||
m->desc.header.minor_version = image->fw_ver_minor;
|
||||
m->desc.header.build_version = image->fw_ver_build;
|
||||
|
||||
/* create each module */
|
||||
m->desc.header.num_module_entries = image->num_modules;
|
||||
man_create_modules(image, desc, FILE_TEXT_OFFSET_V1_8);
|
||||
|
||||
fprintf(stdout, "Firmware completing manifest v2.5\n");
|
||||
|
||||
/* create structures from end of file to start of file */
|
||||
ri_adsp_meta_data_create_v2_5(image, MAN_META_EXT_OFFSET_V2_5,
|
||||
image->meu_offset);
|
||||
ri_plat_ext_data_create_v2_5(image);
|
||||
ri_css_v2_5_hdr_create(image);
|
||||
ri_cse_create_v2_5(image);
|
||||
|
||||
fprintf(stdout, "Firmware file size 0x%x page count %d\n",
|
||||
FILE_TEXT_OFFSET_V1_8 - MAN_DESC_OFFSET_V1_8 + image->image_end,
|
||||
desc->header.preload_page_count);
|
||||
|
||||
/* calculate hash for each module */
|
||||
man_hash_modules(image, desc);
|
||||
|
||||
/* calculate hash inside ADSP meta data extension for padding to end */
|
||||
ri_sha384(image, image->meu_offset, image->image_end - image->meu_offset,
|
||||
m->adsp_file_ext.comp_desc[0].hash);
|
||||
|
||||
/* mue writes 0xff to 16 bytes of padding */
|
||||
for (i = 0; i < 16; i++)
|
||||
m->reserved[i] = 0xff;
|
||||
|
||||
/* calculate hash inside ext info 16 of sof_man_adsp_meta_file_ext_v2_5 */
|
||||
ri_sha384(image, MAN_META_EXT_OFFSET_V2_5,
|
||||
sizeof(struct sof_man_adsp_meta_file_ext_v2_5), hash);
|
||||
|
||||
/* hash values in reverse order */
|
||||
for (i = 0; i < SOF_MAN_MOD_SHA384_LEN; i++) {
|
||||
m->signed_pkg.module[0].hash[i] =
|
||||
hash[SOF_MAN_MOD_SHA384_LEN - 1 - i];
|
||||
}
|
||||
|
||||
/* sign manifest */
|
||||
ret = ri_manifest_sign_v2_5(image);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* write the firmware */
|
||||
ret = man_write_fw_mod(image);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* write the unsigned files*/
|
||||
ret = man_write_unsigned_mod(image, MAN_META_EXT_OFFSET_V2_5,
|
||||
MAN_FW_DESC_OFFSET_V2_5,
|
||||
sizeof(struct sof_man_adsp_meta_file_ext_v2_5));
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
fprintf(stdout, "Firmware manifest and signing completed !\n");
|
||||
return 0;
|
||||
|
||||
err:
|
||||
free(image->rom_image);
|
||||
free(image->fw_image);
|
||||
unlink(image->out_file);
|
||||
unlink(image->out_rom_file);
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue