X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=tools%2Fkwbimage.c;h=a88a3830c0c8d41c93765474622205f8b43c22d8;hb=dd0ee9ea857c4e4d927ae41791c1626fd57c301d;hp=8c0e730e7bbb6f04934417764bfb448676baf08d;hpb=22f3368e71321db1e0e15dfbf54b052367890ec7;p=u-boot diff --git a/tools/kwbimage.c b/tools/kwbimage.c index 8c0e730e7b..a88a3830c0 100644 --- a/tools/kwbimage.c +++ b/tools/kwbimage.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Image manipulator for Marvell SoCs * supports Kirkwood, Dove, Armada 370, Armada XP, and Armada 38x @@ -5,8 +6,6 @@ * (C) Copyright 2013 Thomas Petazzoni * * - * SPDX-License-Identifier: GPL-2.0+ - * * Not implemented: support for the register headers in v1 images */ @@ -24,7 +23,8 @@ #include #include -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if OPENSSL_VERSION_NUMBER < 0x10100000L || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) static void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) { @@ -36,7 +36,7 @@ static void RSA_get0_key(const RSA *r, *d = r->d; } -#else +#elif !defined(LIBRESSL_VERSION_NUMBER) void EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { EVP_MD_CTX_reset(ctx); @@ -290,6 +290,33 @@ static uint8_t image_checksum8(void *start, uint32_t len) return csum; } +size_t kwbimage_header_size(unsigned char *ptr) +{ + if (image_version((void *)ptr) == 0) + return sizeof(struct main_hdr_v0); + else + return KWBHEADER_V1_SIZE((struct main_hdr_v1 *)ptr); +} + +/* + * Verify checksum over a complete header that includes the checksum field. + * Return 1 when OK, otherwise 0. + */ +static int main_hdr_checksum_ok(void *hdr) +{ + /* Offsets of checksum in v0 and v1 headers are the same */ + struct main_hdr_v0 *main_hdr = (struct main_hdr_v0 *)hdr; + uint8_t checksum; + + checksum = image_checksum8(hdr, kwbimage_header_size(hdr)); + /* Calculated checksum includes the header checksum field. Compensate + * for that. + */ + checksum -= main_hdr->checksum; + + return checksum == main_hdr->checksum; +} + static uint32_t image_checksum32(void *start, uint32_t len) { uint32_t csum = 0; @@ -1476,47 +1503,6 @@ static int image_get_version(void) return e->version; } -static int image_version_file(const char *input) -{ - FILE *fcfg; - int version; - int ret; - - fcfg = fopen(input, "r"); - if (!fcfg) { - fprintf(stderr, "Could not open input file %s\n", input); - return -1; - } - - image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX * - sizeof(struct image_cfg_element)); - if (!image_cfg) { - fprintf(stderr, "Cannot allocate memory\n"); - fclose(fcfg); - return -1; - } - - memset(image_cfg, 0, - IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element)); - rewind(fcfg); - - ret = image_create_config_parse(fcfg); - fclose(fcfg); - if (ret) { - free(image_cfg); - return -1; - } - - version = image_get_version(); - /* Fallback to version 0 is no version is provided in the cfg file */ - if (version == -1) - version = 0; - - free(image_cfg); - - return version; -} - static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd, struct image_tool_params *params) { @@ -1628,14 +1614,13 @@ static int kwbimage_check_image_types(uint8_t type) static int kwbimage_verify_header(unsigned char *ptr, int image_size, struct image_tool_params *params) { - struct main_hdr_v0 *main_hdr; uint8_t checksum; + size_t header_size = kwbimage_header_size(ptr); + + if (header_size > image_size) + return -FDT_ERR_BADSTRUCTURE; - main_hdr = (struct main_hdr_v0 *)ptr; - checksum = image_checksum8(ptr, - sizeof(struct main_hdr_v0) - - sizeof(uint8_t)); - if (checksum != main_hdr->checksum) + if (!main_hdr_checksum_ok(ptr)) return -FDT_ERR_BADSTRUCTURE; /* Only version 0 extended header has checksum */ @@ -1657,18 +1642,62 @@ static int kwbimage_verify_header(unsigned char *ptr, int image_size, static int kwbimage_generate(struct image_tool_params *params, struct image_type_params *tparams) { + FILE *fcfg; int alloc_len; + int version; void *hdr; - int version = 0; + int ret; - version = image_version_file(params->imagename); - if (version == 0) { + fcfg = fopen(params->imagename, "r"); + if (!fcfg) { + fprintf(stderr, "Could not open input file %s\n", + params->imagename); + exit(EXIT_FAILURE); + } + + image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX * + sizeof(struct image_cfg_element)); + if (!image_cfg) { + fprintf(stderr, "Cannot allocate memory\n"); + fclose(fcfg); + exit(EXIT_FAILURE); + } + + memset(image_cfg, 0, + IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element)); + rewind(fcfg); + + ret = image_create_config_parse(fcfg); + fclose(fcfg); + if (ret) { + free(image_cfg); + exit(EXIT_FAILURE); + } + + version = image_get_version(); + switch (version) { + /* + * Fallback to version 0 if no version is provided in the + * cfg file + */ + case -1: + case 0: alloc_len = sizeof(struct main_hdr_v0) + sizeof(struct ext_hdr_v0); - } else { + break; + + case 1: alloc_len = image_headersz_v1(NULL); + break; + + default: + fprintf(stderr, "Unsupported version %d\n", version); + free(image_cfg); + exit(EXIT_FAILURE); } + free(image_cfg); + hdr = malloc(alloc_len); if (!hdr) { fprintf(stderr, "%s: malloc return failure: %s\n",