+// SPDX-License-Identifier: GPL-2.0+
/*
* Image manipulator for Marvell SoCs
* supports Kirkwood, Dove, Armada 370, Armada XP, and Armada 38x
* (C) Copyright 2013 Thomas Petazzoni
* <thomas.petazzoni@free-electrons.com>
*
- * SPDX-License-Identifier: GPL-2.0+
- *
* Not implemented: support for the register headers in v1 images
*/
#include <openssl/err.h>
#include <openssl/evp.h>
-#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)
{
*d = r->d;
}
-#else
+#elif !defined(LIBRESSL_VERSION_NUMBER)
void EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
{
EVP_MD_CTX_reset(ctx);
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;
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;
}
* 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)
* 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;
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
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) {
}
/* 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) {
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 */