X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=tools%2Fkwbimage.c;h=02fd0c949fff6dbb94224bf783ef4d6f1e247d92;hb=1259567ae3cd4c84acb9db6ab1fadcdcd26968a9;hp=5830549d261095412f134a4d584656378bf38ddf;hpb=75fd49c836d9a1750c9b6d86c0511b990fbe9fa8;p=oweals%2Fu-boot.git diff --git a/tools/kwbimage.c b/tools/kwbimage.c index 5830549d26..02fd0c949f 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 || defined(LIBRESSL_VERSION_NUMBER) +#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; } @@ -988,7 +1015,7 @@ static size_t image_headersz_v1(int *hasext) * The payload should be aligned on some reasonable * boundary */ - return ALIGN_SUP(headersz, 4096); + return ALIGN(headersz, 4096); } int add_binary_header_v1(uint8_t *cur) @@ -1031,7 +1058,7 @@ int add_binary_header_v1(uint8_t *cur) * up to a 4-byte boundary. Plus 4 bytes for the * next-header byte and 3-byte alignment at the end. */ - binhdrsz = ALIGN_SUP(binhdrsz, 4) + 4; + binhdrsz = ALIGN(binhdrsz, 4) + 4; hdr->headersz_lsb = cpu_to_le16(binhdrsz & 0xFFFF); hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16; @@ -1055,7 +1082,7 @@ int add_binary_header_v1(uint8_t *cur) fclose(bin); - cur += ALIGN_SUP(s.st_size, 4); + cur += ALIGN(s.st_size, 4); /* * For now, we don't support more than one binary @@ -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) { @@ -1514,7 +1548,7 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd, } /* The MVEBU BootROM does not allow non word aligned payloads */ - sbuf->st_size = ALIGN_SUP(sbuf->st_size, 4); + sbuf->st_size = ALIGN(sbuf->st_size, 4); version = image_get_version(); switch (version) { @@ -1587,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); + + 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 */