diff options
author | Pali Rohár <pali@kernel.org> | 2021-10-25 15:12:55 +0200 |
---|---|---|
committer | Stefan Roese <sr@denx.de> | 2021-11-03 06:45:27 +0100 |
commit | ad9a3ac5005e7b70a50b621a5340cead6fcc673f (patch) | |
tree | 64975f0dfce4a7c46027dd44bc6b748326730fdc /tools | |
parent | 5923ef686a61c7ac15ed990487e4a4fd312ddeec (diff) | |
download | u-boot-ad9a3ac5005e7b70a50b621a5340cead6fcc673f.zip u-boot-ad9a3ac5005e7b70a50b621a5340cead6fcc673f.tar.gz u-boot-ad9a3ac5005e7b70a50b621a5340cead6fcc673f.tar.bz2 |
tools: kwboot: Validate 4-byte image data checksum
Data part of the image contains 4-byte checksum. Validate it when
processing the image.
Signed-off-by: Pali Rohár <pali@kernel.org>
[ refactored ]
Signed-off-by: Marek Behún <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/kwboot.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/tools/kwboot.c b/tools/kwboot.c index 4e29317..bc44301 100644 --- a/tools/kwboot.c +++ b/tools/kwboot.c @@ -1251,6 +1251,37 @@ kwboot_hdr_csum8(const void *hdr) return csum; } +static uint32_t * +kwboot_img_csum32_ptr(void *img) +{ + struct main_hdr_v1 *hdr = img; + uint32_t datasz; + + datasz = le32_to_cpu(hdr->blocksize) - sizeof(uint32_t); + + return img + le32_to_cpu(hdr->srcaddr) + datasz; +} + +static uint32_t +kwboot_img_csum32(const void *img) +{ + const struct main_hdr_v1 *hdr = img; + uint32_t datasz, csum = 0; + const uint32_t *data; + + datasz = le32_to_cpu(hdr->blocksize) - sizeof(csum); + if (datasz % sizeof(uint32_t)) + return 0; + + data = img + le32_to_cpu(hdr->srcaddr); + while (datasz > 0) { + csum += le32_to_cpu(*data++); + datasz -= 4; + } + + return cpu_to_le32(csum); +} + static int kwboot_img_is_secure(void *img) { @@ -1462,6 +1493,9 @@ kwboot_img_patch(void *img, size_t *size, int baudrate) *size < le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize)) goto err; + if (kwboot_img_csum32(img) != *kwboot_img_csum32_ptr(img)) + goto err; + is_secure = kwboot_img_is_secure(img); if (hdr->blockid != IBR_HDR_UART_ID) { |