X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=tools%2Fkwbimage.c;h=b8f8d38212f5c00ee79bf89dd63ef585b27eacb2;hb=beeb57f0a66658aacad3f12f1a31e65f5d22e46d;hp=8c0e730e7bbb6f04934417764bfb448676baf08d;hpb=e15843b11504abe833695ecfe4104502bcd0a998;p=oweals%2Fu-boot.git diff --git a/tools/kwbimage.c b/tools/kwbimage.c index 8c0e730e7b..b8f8d38212 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; @@ -674,7 +701,7 @@ int kwb_verify(RSA *key, void *data, int datasz, struct sig_v1 *sig, goto err_ctx; } - if (!EVP_VerifyFinal(ctx, sig->sig, sizeof(sig->sig), evp_key)) { + if (EVP_VerifyFinal(ctx, sig->sig, sizeof(sig->sig), evp_key) != 1) { ret = openssl_err("Could not verify signature"); goto err_ctx; } @@ -1246,6 +1273,13 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params, e = image_find_option(IMAGE_CFG_DEBUG); if (e) main_hdr->flags = e->debug ? 0x1 : 0; + e = image_find_option(IMAGE_CFG_BINARY); + if (e) { + char *s = strrchr(e->binary.file, '/'); + + if (strcmp(s, "/binary.0") == 0) + main_hdr->destaddr = cpu_to_le32(params->addr); + } #if defined(CONFIG_KWB_SECURE) if (image_get_csk_index() >= 0) { @@ -1476,47 +1510,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 +1621,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); - 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 (header_size > image_size) + return -FDT_ERR_BADSTRUCTURE; + + if (!main_hdr_checksum_ok(ptr)) return -FDT_ERR_BADSTRUCTURE; /* Only version 0 extended header has checksum */ @@ -1657,18 +1649,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; + + 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); + } - version = image_version_file(params->imagename); - if (version == 0) { + 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",