diff options
author | Philipp Tomsich <philipp.tomsich@theobroma-systems.com> | 2018-11-25 19:22:19 +0100 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2018-12-08 20:18:44 -0500 |
commit | 51c2345bd24837f9f67f16268da6dc71573f1325 (patch) | |
tree | 318af05398baae25f2ac5ecc8baad6a2e194b365 | |
parent | a740ee913ec8ba04cc53100440f94841648324e2 (diff) | |
download | u-boot-51c2345bd24837f9f67f16268da6dc71573f1325.tar.gz |
Roll CRC16-CCITT into the hash infrastructure
The CRC16-CCITT checksum function is useful for space-constrained
applications (such as obtaining a checksum across a 2KBit or 4KBit
EEPROM) in boot applications. It has not been accessible from boot
scripts until now (due to not having a dedicated command and not being
supported by the hash infrstructure) limiting its applicability
outside of custom commands.
This adds the CRC16-CCITT (poly 0x1021, init 0x0) algorithm to the
list of available hashes and adds a new crc16_ccitt_wd_buf() to make
this possible.
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
[trini: Fix building crc16.o for SPL/TPL]
Signed-off-by: Tom Rini <trini@konsulko.com>
-rw-r--r-- | common/hash.c | 36 | ||||
-rw-r--r-- | include/u-boot/crc.h | 11 | ||||
-rw-r--r-- | lib/Makefile | 1 | ||||
-rw-r--r-- | lib/crc16.c | 23 | ||||
-rw-r--r-- | tools/Makefile | 1 |
5 files changed, 66 insertions, 6 deletions
diff --git a/common/hash.c b/common/hash.c index ef146513a0..413a5bfcda 100644 --- a/common/hash.c +++ b/common/hash.c @@ -85,6 +85,33 @@ static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void } #endif +static int hash_init_crc16_ccitt(struct hash_algo *algo, void **ctxp) +{ + uint16_t *ctx = malloc(sizeof(uint16_t)); + *ctx = 0; + *ctxp = ctx; + return 0; +} + +static int hash_update_crc16_ccitt(struct hash_algo *algo, void *ctx, + const void *buf, unsigned int size, + int is_last) +{ + *((uint16_t *)ctx) = crc16_ccitt(*((uint16_t *)ctx), buf, size); + return 0; +} + +static int hash_finish_crc16_ccitt(struct hash_algo *algo, void *ctx, + void *dest_buf, int size) +{ + if (size < algo->digest_size) + return -1; + + *((uint16_t *)dest_buf) = *((uint16_t *)ctx); + free(ctx); + return 0; +} + static int hash_init_crc32(struct hash_algo *algo, void **ctxp) { uint32_t *ctx = malloc(sizeof(uint32_t)); @@ -160,6 +187,15 @@ static struct hash_algo hash_algo[] = { }, #endif { + .name = "crc16-ccitt", + .digest_size = 2, + .chunk_size = CHUNKSZ, + .hash_func_ws = crc16_ccitt_wd_buf, + .hash_init = hash_init_crc16_ccitt, + .hash_update = hash_update_crc16_ccitt, + .hash_finish = hash_finish_crc16_ccitt, + }, + { .name = "crc32", .digest_size = 4, .chunk_size = CHUNKSZ_CRC32, diff --git a/include/u-boot/crc.h b/include/u-boot/crc.h index 111b22c4b6..788ef29a17 100644 --- a/include/u-boot/crc.h +++ b/include/u-boot/crc.h @@ -13,6 +13,17 @@ unsigned int crc8(unsigned int crc_start, const unsigned char *vptr, int len); /* lib/crc16.c - 16 bit CRC with polynomial x^16+x^12+x^5+1 (CRC-CCITT) */ uint16_t crc16_ccitt(uint16_t crc_start, const unsigned char *s, int len); +/** + * crc16_ccitt_wd_buf - Perform CRC16-CCIT on an input buffer and return the + * 16-bit result (network byte-order) in an output buffer + * + * @in: input buffer + * @len: input buffer length + * @out: output buffer (at least 2 bytes) + * @chunk_sz: ignored + */ +void crc16_ccitt_wd_buf(const uint8_t *in, uint len, + uint8_t *out, uint chunk_sz); /* lib/crc32.c */ uint32_t crc32 (uint32_t, const unsigned char *, uint); diff --git a/lib/Makefile b/lib/Makefile index 8321355a44..a6dd928a92 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -76,6 +76,7 @@ endif ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o +obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o endif obj-$(CONFIG_ADDR_MAP) += addr_map.o diff --git a/lib/crc16.c b/lib/crc16.c index 25bdfd8e72..f46ba727c9 100644 --- a/lib/crc16.c +++ b/lib/crc16.c @@ -22,6 +22,11 @@ *========================================================================== */ +#ifdef USE_HOSTCC +#include <arpa/inet.h> +#else +#include <common.h> +#endif #include <u-boot/crc.h> /* Table of CRC constants - implements x^16+x^12+x^5+1 */ @@ -60,14 +65,20 @@ static const uint16_t crc16_tab[] = { 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, }; -uint16_t crc16_ccitt(uint16_t crc_start, unsigned char *buf, int len) +uint16_t crc16_ccitt(uint16_t cksum, const unsigned char *buf, int len) { - int i; - uint16_t cksum; - - cksum = crc_start; - for (i = 0; i < len; i++) + for (int i = 0; i < len; i++) cksum = crc16_tab[((cksum>>8) ^ *buf++) & 0xff] ^ (cksum << 8); return cksum; } + +void crc16_ccitt_wd_buf(const uint8_t *in, uint len, + uint8_t *out, uint chunk_sz) +{ + uint16_t crc; + + crc = crc16_ccitt(0, in, len); + crc = htons(crc); + memcpy(out, &crc, sizeof(crc)); +} diff --git a/tools/Makefile b/tools/Makefile index c93d17a42f..c26b631560 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -106,6 +106,7 @@ dumpimage-mkimage-objs := aisimage.o \ stm32image.o \ $(ROCKCHIP_OBS) \ socfpgaimage.o \ + lib/crc16.o \ lib/sha1.o \ lib/sha256.o \ common/hash.o \ |