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>
diff --git a/common/hash.c b/common/hash.c
index ef14651..413a5bf 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -85,6 +85,33 @@
 }
 #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 @@
 	},
 #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,