mirror of https://github.com/thesofproject/sof.git
rimage: add functionality to resign fw image
Add function to resign already signed images. This can be done with switch "q" as follows: "rimage -q sof-tgl.ri -o sof-tgl-mod.ri -c tgl.toml -k key.pem" Signed-off-by: Jaska Uimonen <jaska.uimonen@linux.intel.com>
This commit is contained in:
parent
bcbcec79e5
commit
bd51ec1aef
|
@ -73,6 +73,7 @@ struct module {
|
|||
struct image {
|
||||
|
||||
const char *out_file;
|
||||
const char *in_file;
|
||||
FILE *out_fd;
|
||||
void *pos;
|
||||
|
||||
|
@ -201,6 +202,9 @@ int pkcs_v1_5_verify_man_v2_5(struct image *image,
|
|||
void *ptr1, unsigned int size1, void *ptr2,
|
||||
unsigned int size2);
|
||||
|
||||
int resign_image(struct image *image);
|
||||
int get_key_size(struct image *image);
|
||||
|
||||
int elf_parse_module(struct image *image, int module_index, const char *name);
|
||||
void elf_free_module(struct image *image, int module_index);
|
||||
int elf_is_rom(struct image *image, Elf32_Shdr *section);
|
||||
|
|
124
src/manifest.c
124
src/manifest.c
|
@ -1427,3 +1427,127 @@ out:
|
|||
fclose(in_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int resign_image(struct image *image)
|
||||
{
|
||||
int key_size, key_file_size;
|
||||
size_t size, read;
|
||||
FILE *in_file;
|
||||
void *buffer;
|
||||
int ret, i;
|
||||
|
||||
/* open image for reading */
|
||||
in_file = fopen(image->in_file, "rb");
|
||||
if (!in_file) {
|
||||
fprintf(stderr, "error: unable to open %s for reading %d\n",
|
||||
image->in_file, errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/* get file size */
|
||||
ret = fseek(in_file, 0, SEEK_END);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error: unable to seek eof %s for reading %d\n",
|
||||
image->verify_file, errno);
|
||||
ret = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
size = ftell(in_file);
|
||||
if (size < 0) {
|
||||
fprintf(stderr, "error: unable to get file size for %s %d\n",
|
||||
image->verify_file, errno);
|
||||
ret = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = fseek(in_file, 0, SEEK_SET);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error: unable to seek %s for reading %d\n",
|
||||
image->verify_file, errno);
|
||||
ret = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* allocate buffer for parsing */
|
||||
buffer = malloc(size);
|
||||
if (!buffer) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* read file into buffer */
|
||||
read = fread(buffer, 1, size, in_file);
|
||||
if (read != size) {
|
||||
fprintf(stderr, "error: unable to read %ld bytes from %s err %d\n",
|
||||
size, image->in_file, errno);
|
||||
ret = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fclose(in_file);
|
||||
|
||||
for (i = 0; i < size; i += sizeof(uint32_t)) {
|
||||
/* find CSE header marker "$CPD" */
|
||||
if (*(uint32_t *)(buffer + i) == CSE_HEADER_MAKER) {
|
||||
image->fw_image = buffer + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= size) {
|
||||
fprintf(stderr, "error: didn't found header marker %d\n", i);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
image->image_end = size;
|
||||
|
||||
/* check that key size matches */
|
||||
if (image->adsp->man_v2_5) {
|
||||
key_size = 384;
|
||||
} else {
|
||||
key_size = 256;
|
||||
}
|
||||
|
||||
key_file_size = get_key_size(image);
|
||||
|
||||
if (key_file_size > key_size) {
|
||||
fprintf(stderr, "error: key size %d is longer than original key %d\n",
|
||||
key_file_size, key_size);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* resign */
|
||||
if (image->adsp->man_v1_5)
|
||||
ret = ri_manifest_sign_v1_5(image);
|
||||
else if (image->adsp->man_v1_8)
|
||||
ret = ri_manifest_sign_v1_8(image);
|
||||
else if (image->adsp->man_v2_5)
|
||||
ret = ri_manifest_sign_v2_5(image);
|
||||
else
|
||||
ret = -EINVAL;
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error: unable to sign image\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* open outfile for writing */
|
||||
unlink(image->out_file);
|
||||
image->out_fd = fopen(image->out_file, "wb");
|
||||
if (!image->out_fd) {
|
||||
fprintf(stderr, "error: unable to open %s for writing %d\n",
|
||||
image->out_file, errno);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
man_write_fw_mod(image);
|
||||
|
||||
out:
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -694,3 +694,38 @@ int ri_manifest_verify_v2_5(struct image *image)
|
|||
|
||||
return pkcs_v1_5_verify_man_v2_5(image, man, data1, size1, data2, size2);
|
||||
}
|
||||
|
||||
int get_key_size(struct image *image)
|
||||
{
|
||||
RSA *priv_rsa = NULL;
|
||||
EVP_PKEY *privkey;
|
||||
FILE *fp;
|
||||
int key_length;
|
||||
char path[256];
|
||||
|
||||
/* require private key */
|
||||
if (!image->key_name) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* load in RSA private key from PEM file */
|
||||
memset(path, 0, sizeof(path));
|
||||
strncpy(path, image->key_name, sizeof(path) - 1);
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "error: can't open file %s %d\n",
|
||||
path, -errno);
|
||||
return -errno;
|
||||
}
|
||||
PEM_read_PrivateKey(fp, &privkey, NULL, NULL);
|
||||
fclose(fp);
|
||||
|
||||
priv_rsa = EVP_PKEY_get1_RSA(privkey);
|
||||
key_length = RSA_size(priv_rsa);
|
||||
|
||||
RSA_free(priv_rsa);
|
||||
EVP_PKEY_free(privkey);
|
||||
|
||||
return key_length;
|
||||
}
|
||||
|
|
11
src/rimage.c
11
src/rimage.c
|
@ -30,6 +30,7 @@ static void usage(char *name)
|
|||
fprintf(stdout, "\t -b build version\n");
|
||||
fprintf(stdout, "\t -e build extended manifest\n");
|
||||
fprintf(stdout, "\t -y verify signed file\n");
|
||||
fprintf(stdout, "\t -q resign binary\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
@ -43,7 +44,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
memset(&image, 0, sizeof(image));
|
||||
|
||||
while ((opt = getopt(argc, argv, "ho:va:s:k:ri:x:f:b:ec:y:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "ho:va:s:k:ri:x:f:b:ec:y:q:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
image.out_file = optarg;
|
||||
|
@ -84,6 +85,9 @@ int main(int argc, char *argv[])
|
|||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
case 'q':
|
||||
image.in_file = optarg;
|
||||
break;
|
||||
default:
|
||||
/* getopt's default error message is good enough */
|
||||
return 1;
|
||||
|
@ -152,6 +156,11 @@ int main(int argc, char *argv[])
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (image.in_file) {
|
||||
fprintf(stdout, "going to re-sign\n");
|
||||
return resign_image(&image);
|
||||
}
|
||||
|
||||
/* set IMR Type in found machine definition */
|
||||
if (image.adsp->man_v1_8)
|
||||
image.adsp->man_v1_8->adsp_file_ext.imr_type = imr_type;
|
||||
|
|
Loading…
Reference in New Issue