All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 1/3] crypto: add md5 to common hash functions
@ 2018-06-06 16:03 Ben Whitten
  2018-06-06 16:03 ` [U-Boot] [PATCH v2 2/3] fit: allow fit to call hardware accelerated hash Ben Whitten
  2018-06-06 16:03 ` [U-Boot] [PATCH v2 3/3] crypto: add Atmel hardware acceleration for SHA1 & 256 Ben Whitten
  0 siblings, 2 replies; 6+ messages in thread
From: Ben Whitten @ 2018-06-06 16:03 UTC (permalink / raw)
  To: u-boot

The md5 function was missing from the common hash functions

Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
 common/hash.c        | 8 ++++++++
 include/image.h      | 1 +
 include/u-boot/md5.h | 7 ++++---
 lib/Makefile         | 1 +
 lib/md5.c            | 4 ++--
 5 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/common/hash.c b/common/hash.c
index ef14651..d2f4b3f 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -168,6 +168,14 @@ static struct hash_algo hash_algo[] = {
 		.hash_update	= hash_update_crc32,
 		.hash_finish	= hash_finish_crc32,
 	},
+#ifdef CONFIG_MD5
+	{
+		.name		= "md5",
+		.digest_size	= 16,
+		.chunk_size	= CHUNKSZ_MD5,
+		.hash_func_ws 	= md5_wd,
+	},
+#endif
 };
 
 /* Try to minimize code size for boards that don't want much hashing */
diff --git a/include/image.h b/include/image.h
index 9522ee4..a5a5807 100644
--- a/include/image.h
+++ b/include/image.h
@@ -32,6 +32,7 @@ struct fdt_region;
 #define CONFIG_FIT_ENABLE_SHA256_SUPPORT
 #define CONFIG_SHA1
 #define CONFIG_SHA256
+#define CONFIG_MD5
 
 #define IMAGE_ENABLE_IGNORE	0
 #define IMAGE_INDENT_STRING	""
diff --git a/include/u-boot/md5.h b/include/u-boot/md5.h
index e09c16a..365d125 100644
--- a/include/u-boot/md5.h
+++ b/include/u-boot/md5.h
@@ -21,14 +21,15 @@ struct MD5Context {
  * Calculate and store in 'output' the MD5 digest of 'len' bytes at
  * 'input'. 'output' must have enough space to hold 16 bytes.
  */
-void md5 (unsigned char *input, int len, unsigned char output[16]);
+
+void md5 (const unsigned char *input, unsigned int len, unsigned char *output);
 
 /*
  * Calculate and store in 'output' the MD5 digest of 'len' bytes at 'input'.
  * 'output' must have enough space to hold 16 bytes. If 'chunk' Trigger the
  * watchdog every 'chunk_sz' bytes of input processed.
  */
-void md5_wd (unsigned char *input, int len, unsigned char output[16],
-		unsigned int chunk_sz);
+void md5_wd (const unsigned char *input, unsigned int len,
+		unsigned char *output, unsigned int chunk_sz);
 
 #endif /* _MD5_H */
diff --git a/lib/Makefile b/lib/Makefile
index d531ea5..5c4aa73 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -78,6 +78,7 @@ obj-y += div64.o
 obj-y += hang.o
 obj-y += linux_compat.o
 obj-y += linux_string.o
+obj-$(CONFIG_$(SPL_TPL_)MD5_SUPPORT) += md5.o
 obj-y += membuff.o
 obj-$(CONFIG_REGEX) += slre.o
 obj-y += string.o
diff --git a/lib/md5.c b/lib/md5.c
index 2ae4a06..2278001 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -268,7 +268,7 @@ MD5Transform(__u32 buf[4], __u32 const in[16])
  * 'input'. 'output' must have enough space to hold 16 bytes.
  */
 void
-md5 (unsigned char *input, int len, unsigned char output[16])
+md5 (const unsigned char *input, unsigned int len, unsigned char *output)
 {
 	struct MD5Context context;
 
@@ -284,7 +284,7 @@ md5 (unsigned char *input, int len, unsigned char output[16])
  * watchdog every 'chunk_sz' bytes of input processed.
  */
 void
-md5_wd (unsigned char *input, int len, unsigned char output[16],
+md5_wd (const unsigned char *input, unsigned int len, unsigned char *output,
 	unsigned int chunk_sz)
 {
 	struct MD5Context context;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v2 2/3] fit: allow fit to call hardware accelerated hash
  2018-06-06 16:03 [U-Boot] [PATCH v2 1/3] crypto: add md5 to common hash functions Ben Whitten
@ 2018-06-06 16:03 ` Ben Whitten
  2018-06-18 16:59   ` Tom Rini
  2018-06-06 16:03 ` [U-Boot] [PATCH v2 3/3] crypto: add Atmel hardware acceleration for SHA1 & 256 Ben Whitten
  1 sibling, 1 reply; 6+ messages in thread
From: Ben Whitten @ 2018-06-06 16:03 UTC (permalink / raw)
  To: u-boot

Move to calling the abstraction which allows for hardware acceleration.
We also remove unneeded defines and only include objects if required.

Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
 common/hash.c      |  4 ++++
 common/image-fit.c | 27 +++++++++------------------
 include/image.h    | 42 ++++++++++++++++++++++--------------------
 lib/Makefile       |  5 ++++-
 4 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/common/hash.c b/common/hash.c
index d2f4b3f..ceee124 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -85,6 +85,7 @@ static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void
 }
 #endif
 
+#if defined(CONFIG_CRC32)
 static int hash_init_crc32(struct hash_algo *algo, void **ctxp)
 {
 	uint32_t *ctx = malloc(sizeof(uint32_t));
@@ -110,6 +111,7 @@ static int hash_finish_crc32(struct hash_algo *algo, void *ctx, void *dest_buf,
 	free(ctx);
 	return 0;
 }
+#endif
 
 /*
  * These are the hash algorithms we support.  If we have hardware acceleration
@@ -159,6 +161,7 @@ static struct hash_algo hash_algo[] = {
 #endif
 	},
 #endif
+#ifdef CONFIG_CRC32
 	{
 		.name		= "crc32",
 		.digest_size	= 4,
@@ -168,6 +171,7 @@ static struct hash_algo hash_algo[] = {
 		.hash_update	= hash_update_crc32,
 		.hash_finish	= hash_finish_crc32,
 	},
+#endif
 #ifdef CONFIG_MD5
 	{
 		.name		= "md5",
diff --git a/common/image-fit.c b/common/image-fit.c
index 8c15ed1..7d8c961 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1082,26 +1082,17 @@ int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
 int calculate_hash(const void *data, int data_len, const char *algo,
 			uint8_t *value, int *value_len)
 {
-	if (IMAGE_ENABLE_CRC32 && strcmp(algo, "crc32") == 0) {
-		*((uint32_t *)value) = crc32_wd(0, data, data_len,
-							CHUNKSZ_CRC32);
-		*((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value));
-		*value_len = 4;
-	} else if (IMAGE_ENABLE_SHA1 && strcmp(algo, "sha1") == 0) {
-		sha1_csum_wd((unsigned char *)data, data_len,
-			     (unsigned char *)value, CHUNKSZ_SHA1);
-		*value_len = 20;
-	} else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) {
-		sha256_csum_wd((unsigned char *)data, data_len,
-			       (unsigned char *)value, CHUNKSZ_SHA256);
-		*value_len = SHA256_SUM_LEN;
-	} else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) {
-		md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
-		*value_len = 16;
-	} else {
+	struct hash_algo *hash_algo;
+	int ret;
+
+	ret = hash_lookup_algo(algo, &hash_algo);
+	if (ret) {
 		debug("Unsupported hash alogrithm\n");
-		return -1;
 	}
+	hash_algo->hash_func_ws((unsigned char *)data, data_len,
+			(unsigned char *)value, hash_algo->chunk_size);
+	*value_len = hash_algo->digest_size;
+
 	return 0;
 }
 
diff --git a/include/image.h b/include/image.h
index a5a5807..16bc097 100644
--- a/include/image.h
+++ b/include/image.h
@@ -32,6 +32,7 @@ struct fdt_region;
 #define CONFIG_FIT_ENABLE_SHA256_SUPPORT
 #define CONFIG_SHA1
 #define CONFIG_SHA256
+#define CONFIG_CRC32
 #define CONFIG_MD5
 
 #define IMAGE_ENABLE_IGNORE	0
@@ -58,38 +59,39 @@ struct fdt_region;
 #include <fdt_support.h>
 # ifdef CONFIG_SPL_BUILD
 #  ifdef CONFIG_SPL_CRC32_SUPPORT
-#   define IMAGE_ENABLE_CRC32	1
+#   define CONFIG_CRC32
+#  else
+#   undef CONFIG_CRC32
 #  endif
 #  ifdef CONFIG_SPL_MD5_SUPPORT
-#   define IMAGE_ENABLE_MD5	1
+#   define CONFIG_MD5
+#  else
+#   undef CONFIG_MD5
 #  endif
 #  ifdef CONFIG_SPL_SHA1_SUPPORT
-#   define IMAGE_ENABLE_SHA1	1
+#   define CONFIG_SHA1
+#  else
+#   undef CONFIG_SHA1
 #  endif
 # else
+#  ifndef CONFIG_CRC32
 #  define CONFIG_CRC32		/* FIT images need CRC32 support */
-#  define IMAGE_ENABLE_CRC32	1
-#  define IMAGE_ENABLE_MD5	1
-#  define IMAGE_ENABLE_SHA1	1
+#  endif
+#  ifndef CONFIG_MD5
+#  define CONFIG_MD5
+#  endif
+#  ifndef CONFIG_SHA1
+#  define CONFIG_SHA1
+#  endif
 # endif
 
-#ifndef IMAGE_ENABLE_CRC32
-#define IMAGE_ENABLE_CRC32	0
-#endif
-
-#ifndef IMAGE_ENABLE_MD5
-#define IMAGE_ENABLE_MD5	0
-#endif
-
-#ifndef IMAGE_ENABLE_SHA1
-#define IMAGE_ENABLE_SHA1	0
-#endif
-
 #if defined(CONFIG_FIT_ENABLE_SHA256_SUPPORT) || \
 	defined(CONFIG_SPL_SHA256_SUPPORT)
-#define IMAGE_ENABLE_SHA256	1
+#ifndef CONFIG_SHA256
+#define CONFIG_SHA256
+#endif
 #else
-#define IMAGE_ENABLE_SHA256	0
+#undef CONFIG_SHA256
 #endif
 
 #endif /* IMAGE_ENABLE_FIT */
diff --git a/lib/Makefile b/lib/Makefile
index 5c4aa73..5b40444 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_USB_TTY) += circbuf.o
 obj-y += crc7.o
 obj-y += crc8.o
 obj-y += crc16.o
+obj-$(CONFIG_CRC32) += crc32.o
 obj-$(CONFIG_ERRNO_STR) += errno_str.o
 obj-$(CONFIG_FIT) += fdtdec_common.o
 obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o
@@ -61,6 +62,8 @@ obj-$(CONFIG_$(SPL_TPL_)OF_CONTROL) += fdtdec_common.o
 obj-$(CONFIG_$(SPL_TPL_)OF_CONTROL) += fdtdec.o
 endif
 
+
+
 ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
 obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o
@@ -71,7 +74,7 @@ obj-y += errno.o
 obj-y += display_options.o
 CFLAGS_display_options.o := $(if $(BUILD_TAG),-DBUILD_TAG='"$(BUILD_TAG)"')
 obj-$(CONFIG_BCH) += bch.o
-obj-y += crc32.o
+obj-$(CONFIG_$(SPL_TPL_)CRC32_SUPPORT) += crc32.o
 obj-$(CONFIG_CRC32C) += crc32c.o
 obj-y += ctype.o
 obj-y += div64.o
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v2 3/3] crypto: add Atmel hardware acceleration for SHA1 & 256
  2018-06-06 16:03 [U-Boot] [PATCH v2 1/3] crypto: add md5 to common hash functions Ben Whitten
  2018-06-06 16:03 ` [U-Boot] [PATCH v2 2/3] fit: allow fit to call hardware accelerated hash Ben Whitten
@ 2018-06-06 16:03 ` Ben Whitten
  1 sibling, 0 replies; 6+ messages in thread
From: Ben Whitten @ 2018-06-06 16:03 UTC (permalink / raw)
  To: u-boot

We can use the hardware hash block to reduce space, particularly useful
for verifying FIT signatures from SPL.

Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
 drivers/crypto/Kconfig     |   5 +
 drivers/crypto/Makefile    |   1 +
 drivers/crypto/atmel_sha.c | 289 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/crypto/atmel_sha.h |  52 ++++++++
 lib/Makefile               |   2 +
 5 files changed, 349 insertions(+)
 create mode 100644 drivers/crypto/atmel_sha.c
 create mode 100644 drivers/crypto/atmel_sha.h

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 1ea116b..7a20edb 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -2,4 +2,9 @@ menu "Hardware crypto devices"
 
 source drivers/crypto/fsl/Kconfig
 
+config ATMEL_SHA
+	bool "Atmel SHA Driver support"
+	help
+	  Enables the Atmel SHA accelerator.
+
 endmenu
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index efbd1d3..07af449 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -4,5 +4,6 @@
 # 	http://www.samsung.com
 
 obj-$(CONFIG_EXYNOS_ACE_SHA)	+= ace_sha.o
+obj-$(CONFIG_ATMEL_SHA)	+= atmel_sha.o
 obj-y += rsa_mod_exp/
 obj-y += fsl/
diff --git a/drivers/crypto/atmel_sha.c b/drivers/crypto/atmel_sha.c
new file mode 100644
index 0000000..ef969eb
--- /dev/null
+++ b/drivers/crypto/atmel_sha.c
@@ -0,0 +1,289 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Atmel SHA engine
+ * Copyright (c) 2018  Laird
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include "atmel_sha.h"
+
+#ifdef CONFIG_SHA_HW_ACCEL
+#include <u-boot/sha256.h>
+#include <u-boot/sha1.h>
+#include <hw_sha.h>
+
+#include <asm/io.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/at91_pmc.h>
+
+enum atmel_hash_algos {
+	ATMEL_HASH_SHA1,
+	ATMEL_HASH_SHA256
+};
+
+struct sha_ctx {
+	enum atmel_hash_algos algo;
+	u32		length;
+	u8 		buffer[64];
+};
+
+const u8 sha256_der_prefix[SHA256_DER_LEN] = {
+	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+	0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+	0x00, 0x04, 0x20
+};
+
+const u8 sha1_der_prefix[SHA1_DER_LEN] = {
+	0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
+	0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
+};
+
+static enum atmel_hash_algos get_hash_type(struct hash_algo *algo)
+{
+	if (!strcmp(algo->name, "sha1"))
+		return ATMEL_HASH_SHA1;
+	else
+		return ATMEL_HASH_SHA256;
+};
+
+static int atmel_sha_process(const u8 *in_addr, u8 buflen)
+{
+	struct atmel_sha *sha = (struct atmel_sha *)ATMEL_BASE_SHA;
+	int i;
+	u32 *addr_buf;
+
+	/* Copy data in */
+	addr_buf = (u32 *)in_addr;
+	for (i = 0; i < (buflen / 4); i++)
+		sha->idatarx[i] = addr_buf[i];
+	debug("Atmel sha, engine is loaded\n");
+
+	/* Wait for hash to complete */
+	while ((readl(&sha->isr) & ATMEL_HASH_ISR_MASK)
+			!= ATMEL_HASH_ISR_DATRDY)
+		;
+	debug("Atmel sha, engine signaled completion\n");
+
+	return 0;
+}
+
+static int atmel_sha_chunk(struct sha_ctx *ctx, const u8 *buf, unsigned int size)
+{
+	u8 remaining, fill;
+
+	/* Chunk to 64 byte blocks */
+	remaining = ctx->length & 0x3F;
+	fill = 64 - remaining;
+
+	/* If we have things in the buffer transfer the remaining into it */
+	if (remaining && size >= fill) {
+		memcpy(ctx->buffer + remaining, buf, fill);
+
+		/* Process 64 byte chunk */
+		atmel_sha_process(ctx->buffer, 64);
+
+		size -= fill;
+		buf += fill;
+		ctx->length += fill;
+		remaining = 0;
+	}
+
+	/* We are aligned take from source for any additional */
+	while (size >= 64) {
+		/* Process 64 byte chunk */
+		atmel_sha_process(buf, 64);
+
+		size -= 64;
+		buf += 64;
+		ctx->length += 64;
+	}
+
+	if (size) {
+		memcpy(ctx->buffer + remaining, buf, size);
+		ctx->length += size;
+	}
+
+	return 0;
+}
+
+static int atmel_sha_fill_padding(struct sha_ctx *ctx)
+{
+	unsigned int index, padlen;
+	u64 size, bits;
+	u8 sha256_padding[64] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+	};
+
+	size = ctx->length;
+
+	bits = cpu_to_be64(size << 3);
+
+	/* 64 byte, 512 bit block size */
+	index = ctx->length & 0x3F;
+	padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
+
+	/* set last entry to be 0x80 then 0's*/
+	atmel_sha_chunk(ctx, sha256_padding, padlen);
+	/* Bolt number of bits to the end */
+	atmel_sha_chunk(ctx, (u8 *)&bits, 8);
+
+	if (ctx->length & 0x3F)
+		debug("ERROR, Remainder after PADDING");
+
+	return 0;
+}
+
+/**
+ * Computes hash value of input pbuf using h/w acceleration
+ *
+ * @param in_addr	A pointer to the input buffer
+ * @param buflen	Byte length of input buffer
+ * @param out_addr	A pointer to the output buffer. When complete
+ *			32 bytes are copied to pout[0]...pout[31]. Thus, a user
+ *			should allocate at least 32 bytes at pOut in advance.
+ * @param chunk_size	chunk size for sha256
+ */
+void hw_sha256(const uchar *in_addr, uint buflen,
+			uchar *out_addr, uint chunk_size)
+{
+	struct hash_algo *algo;
+	struct sha_ctx *ctx;
+
+	hash_lookup_algo("sha256", &algo);
+	hw_sha_init(algo, (void *)&ctx);
+	atmel_sha_chunk((void *)ctx, in_addr, buflen);
+	atmel_sha_fill_padding(ctx);
+	hw_sha_finish(algo, (void *)ctx, out_addr, buflen);
+}
+
+/**
+ * Computes hash value of input pbuf using h/w acceleration
+ *
+ * @param in_addr	A pointer to the input buffer
+ * @param buflen	Byte length of input buffer
+ * @param out_addr	A pointer to the output buffer. When complete
+ *			32 bytes are copied to pout[0]...pout[31]. Thus, a user
+ *			should allocate at least 32 bytes at pOut in advance.
+ * @param chunk_size	chunk_size for sha1
+ */
+void hw_sha1(const uchar *in_addr, uint buflen,
+			uchar *out_addr, uint chunk_size)
+{
+	struct hash_algo *algo;
+	struct sha_ctx *ctx;
+
+	hash_lookup_algo("sha1", &algo);
+	hw_sha_init(algo, (void *)&ctx);
+	atmel_sha_chunk((void *)ctx, in_addr, buflen);
+	atmel_sha_fill_padding(ctx);
+	hw_sha_finish(algo, (void *)ctx, out_addr, buflen);
+}
+
+/*
+ * Create the context for sha progressive hashing using h/w acceleration
+ *
+ * @algo: Pointer to the hash_algo struct
+ * @ctxp: Pointer to the pointer of the context for hashing
+ * @return 0 if ok, -ve on error
+ */
+int hw_sha_init(struct hash_algo *algo, void **ctxp)
+{
+	struct atmel_sha *sha = (struct atmel_sha *)ATMEL_BASE_SHA;
+	struct sha_ctx *ctx;
+	u32 reg;
+
+	ctx = malloc(sizeof(struct sha_ctx));
+	if (!ctx) {
+		debug("Failed to allocate context\n");
+		return -ENOMEM;
+	}
+	*ctxp = ctx;
+
+	ctx->algo = get_hash_type(algo);
+	ctx->length = 0;
+
+	debug("Atmel sha init\n");
+	at91_periph_clk_enable(ATMEL_ID_SHA);
+
+	/* Reset the SHA engine */
+	writel(ATMEL_HASH_CR_SWRST, &sha->cr);
+
+	/* Set AUTO mode and fastest operation */
+	reg = ATMEL_HASH_MR_SMOD_AUTO | ATMEL_HASH_MR_PROCDLY_SHORT;
+	if (ctx->algo == ATMEL_HASH_SHA1)
+		reg |= ATMEL_HASH_MR_ALGO_SHA1;
+	else
+		reg |= ATMEL_HASH_MR_ALGO_SHA256;
+	writel(reg, &sha->mr);
+
+	/* Set ready to receive first */
+	writel(ATMEL_HASH_CR_FIRST, &sha->cr);
+
+	/* Ready to roll */
+	return 0;
+}
+
+/*
+ * Update buffer for sha progressive hashing using h/w acceleration
+ *
+ * The context is freed by this function if an error occurs.
+ *
+ * @algo: Pointer to the hash_algo struct
+ * @ctx: Pointer to the context for hashing
+ * @buf: Pointer to the buffer being hashed
+ * @size: Size of the buffer being hashed
+ * @is_last: 1 if this is the last update; 0 otherwise
+ * @return 0 if ok, -ve on error
+ */
+int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf,
+		     unsigned int size, int is_last)
+{
+	struct sha_ctx *sha_ctx = ctx;
+
+	debug("Atmel sha update: %d bytes\n", size);
+
+	/* Send down in chunks */
+	atmel_sha_chunk(sha_ctx, buf, size);
+
+	if (is_last)
+		atmel_sha_fill_padding(sha_ctx);
+
+	return 0;
+}
+
+/*
+ * Copy sha hash result at destination location
+ *
+ * The context is freed after completion of hash operation or after an error.
+ *
+ * @algo: Pointer to the hash_algo struct
+ * @ctx: Pointer to the context for hashing
+ * @dest_buf: Pointer to the destination buffer where hash is to be copied
+ * @size: Size of the buffer being hashed
+ * @return 0 if ok, -ve on error
+ */
+int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf,
+		     int size)
+{
+	struct atmel_sha *sha = (struct atmel_sha *)ATMEL_BASE_SHA;
+	struct sha_ctx *sha_ctx = ctx;
+	unsigned int len, i;
+	u32 *addr_buf;
+
+	/* Copy data back */
+	len = (sha_ctx->algo == ATMEL_HASH_SHA1) ?
+		SHA1_SUM_LEN : SHA256_SUM_LEN;
+	addr_buf = (u32 *)dest_buf;
+	for (i = 0; i < (len / 4); i++)
+		addr_buf[i] = sha->iodatarx[i];
+
+	free(ctx);
+
+	return 0;
+}
+
+#endif /* CONFIG_SHA_HW_ACCEL */
diff --git a/drivers/crypto/atmel_sha.h b/drivers/crypto/atmel_sha.h
new file mode 100644
index 0000000..68ed988
--- /dev/null
+++ b/drivers/crypto/atmel_sha.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Header file for Atmel SHA engine - SFR definitions
+ *
+ * Copyright (c) 2018 Laird
+ */
+
+#ifndef __DRIVERS_ATMEL_SHA_H__
+#define __DRIVERS_ATMEL_SHA_H__
+
+/* SHA register footprint */
+
+struct atmel_sha {
+	u32 cr;
+	u32 mr;
+	u32 reserved0[2];
+	u32 ier;
+	u32 idr;
+	u32 imr;
+	u32 isr;
+	u32 reserved1[8];
+	u32 idatarx[16];
+	u32 iodatarx[16];
+	u32 reserved2[16];
+};
+
+/* CR */
+#define	ATMEL_HASH_CR_MASK 		(0xffff << 0)
+#define ATMEL_HASH_CR_START		(1 << 0)
+#define ATMEL_HASH_CR_FIRST		(1 << 4)
+#define ATMEL_HASH_CR_SWRST		(1 << 8)
+
+/* MR */
+#define	ATMEL_HASH_MR_MASK 			(0xffff << 0)
+#define ATMEL_HASH_MR_SMOD_MANUAL	(0 << 0)
+#define ATMEL_HASH_MR_SMOD_AUTO		(1 << 0)
+#define ATMEL_HASH_MR_SMOD_IDATAR0	(2 << 0)
+#define ATMEL_HASH_MR_PROCDLY_SHORT	(0 << 4)
+#define ATMEL_HASH_MR_PROCDLY_LONG	(1 << 4)
+#define ATMEL_HASH_MR_ALGO_SHA1		(0 << 8)
+#define ATMEL_HASH_MR_ALGO_SHA256	(1 << 8)
+#define ATMEL_HASH_MR_ALGO_SHA384	(2 << 8)
+#define ATMEL_HASH_MR_ALGO_SHA512	(3 << 8)
+#define ATMEL_HASH_MR_ALGO_SHA224	(4 << 8)
+#define ATMEL_HASH_MR_DUALBUFF_INACTIVE (0 << 16)
+#define ATMEL_HASH_MR_DUALBUFF_ACTIVE	(1 << 16)
+
+/* ISR */
+#define ATMEL_HASH_ISR_MASK 		(1 << 0)
+#define ATMEL_HASH_ISR_DATRDY 		(1 << 0)
+
+#endif /* __DRIVERS_ATMEL_SHA_H__ */
diff --git a/lib/Makefile b/lib/Makefile
index 5b40444..834826c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -47,8 +47,10 @@ obj-y += list_sort.o
 endif
 
 obj-$(CONFIG_RSA) += rsa/
+ifneq ($(CONFIG_SHA_PROG_HW_ACCEL),y)
 obj-$(CONFIG_SHA1) += sha1.o
 obj-$(CONFIG_SHA256) += sha256.o
+endif
 
 obj-$(CONFIG_$(SPL_)ZLIB) += zlib/
 obj-$(CONFIG_$(SPL_)GZIP) += gunzip.o
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v2 2/3] fit: allow fit to call hardware accelerated hash
  2018-06-06 16:03 ` [U-Boot] [PATCH v2 2/3] fit: allow fit to call hardware accelerated hash Ben Whitten
@ 2018-06-18 16:59   ` Tom Rini
  2018-06-28 15:46     ` Ben Whitten
  0 siblings, 1 reply; 6+ messages in thread
From: Tom Rini @ 2018-06-18 16:59 UTC (permalink / raw)
  To: u-boot

On Wed, Jun 06, 2018 at 05:03:57PM +0100, Ben Whitten wrote:

> Move to calling the abstraction which allows for hardware acceleration.
> We also remove unneeded defines and only include objects if required.
> 
> Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
[snip]
> diff --git a/common/image-fit.c b/common/image-fit.c
> index 8c15ed1..7d8c961 100644
> --- a/common/image-fit.c
> +++ b/common/image-fit.c
> @@ -1082,26 +1082,17 @@ int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
>  int calculate_hash(const void *data, int data_len, const char *algo,
>  			uint8_t *value, int *value_len)
>  {
> -	if (IMAGE_ENABLE_CRC32 && strcmp(algo, "crc32") == 0) {
> -		*((uint32_t *)value) = crc32_wd(0, data, data_len,
> -							CHUNKSZ_CRC32);
> -		*((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value));
> -		*value_len = 4;
> -	} else if (IMAGE_ENABLE_SHA1 && strcmp(algo, "sha1") == 0) {
> -		sha1_csum_wd((unsigned char *)data, data_len,
> -			     (unsigned char *)value, CHUNKSZ_SHA1);
> -		*value_len = 20;
> -	} else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) {
> -		sha256_csum_wd((unsigned char *)data, data_len,
> -			       (unsigned char *)value, CHUNKSZ_SHA256);
> -		*value_len = SHA256_SUM_LEN;
> -	} else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) {
> -		md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
> -		*value_len = 16;
> -	} else {
> +	struct hash_algo *hash_algo;
> +	int ret;
> +
> +	ret = hash_lookup_algo(algo, &hash_algo);

This is unfortunately not code equivalent.  There's a little bit missing
to switch this over to using SPL_CRC32_SUPPORT as well.  A good test
would be to make sure that a sunxi platform still builds after this (it
doesn't currently with the series) and use buildman -Ssdel to compare
before/after sizes and make sure it's a tiny change in size related to
the code switch and not a huge change due to droppped (or added!)
support.  Thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180618/585cbd04/attachment.sig>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v2 2/3] fit: allow fit to call hardware accelerated hash
  2018-06-18 16:59   ` Tom Rini
@ 2018-06-28 15:46     ` Ben Whitten
  2018-06-28 18:14       ` Tom Rini
  0 siblings, 1 reply; 6+ messages in thread
From: Ben Whitten @ 2018-06-28 15:46 UTC (permalink / raw)
  To: u-boot

Hi Tom,

> Subject: Re: [U-Boot] [PATCH v2 2/3] fit: allow fit to call hardware accelerated
> hash
> 
> On Wed, Jun 06, 2018 at 05:03:57PM +0100, Ben Whitten wrote:
> 
> > Move to calling the abstraction which allows for hardware acceleration.
> > We also remove unneeded defines and only include objects if required.
> >
> > Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
> [snip]
> > diff --git a/common/image-fit.c b/common/image-fit.c
> > index 8c15ed1..7d8c961 100644
> > --- a/common/image-fit.c
> > +++ b/common/image-fit.c
> > @@ -1082,26 +1082,17 @@ int fit_set_timestamp(void *fit, int noffset,
> time_t timestamp)
> >  int calculate_hash(const void *data, int data_len, const char *algo,
> >  			uint8_t *value, int *value_len)
> >  {
> > -	if (IMAGE_ENABLE_CRC32 && strcmp(algo, "crc32") == 0) {
> > -		*((uint32_t *)value) = crc32_wd(0, data, data_len,
> > -							CHUNKSZ_CRC32);
> > -		*((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value));
> > -		*value_len = 4;
> > -	} else if (IMAGE_ENABLE_SHA1 && strcmp(algo, "sha1") == 0) {
> > -		sha1_csum_wd((unsigned char *)data, data_len,
> > -			     (unsigned char *)value, CHUNKSZ_SHA1);
> > -		*value_len = 20;
> > -	} else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) {
> > -		sha256_csum_wd((unsigned char *)data, data_len,
> > -			       (unsigned char *)value, CHUNKSZ_SHA256);
> > -		*value_len = SHA256_SUM_LEN;
> > -	} else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) {
> > -		md5_wd((unsigned char *)data, data_len, value,
> CHUNKSZ_MD5);
> > -		*value_len = 16;
> > -	} else {
> > +	struct hash_algo *hash_algo;
> > +	int ret;
> > +
> > +	ret = hash_lookup_algo(algo, &hash_algo);
> 
> This is unfortunately not code equivalent.  There's a little bit missing
> to switch this over to using SPL_CRC32_SUPPORT as well.  A good test
> would be to make sure that a sunxi platform still builds after this (it
> doesn't currently with the series) and use buildman -Ssdel to compare
> before/after sizes and make sure it's a tiny change in size related to
> the code switch and not a huge change due to droppped (or added!)
> support.  Thanks!

I see that I should be including the crc32.o file regardless in non SPL builds,
now the sunxi board build passes locally.
I tested a fit image with all hashes enabled and they all passed so atleast the
calling of the functions seems to work. Did you spot another inequivalence?
I am un-familiar with the buildman tool, but I shall give it a go as you suggest.

Thanks,
Ben

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v2 2/3] fit: allow fit to call hardware accelerated hash
  2018-06-28 15:46     ` Ben Whitten
@ 2018-06-28 18:14       ` Tom Rini
  0 siblings, 0 replies; 6+ messages in thread
From: Tom Rini @ 2018-06-28 18:14 UTC (permalink / raw)
  To: u-boot

On Thu, Jun 28, 2018 at 03:46:27PM +0000, Ben Whitten wrote:
> Hi Tom,
> 
> > Subject: Re: [U-Boot] [PATCH v2 2/3] fit: allow fit to call hardware accelerated
> > hash
> > 
> > On Wed, Jun 06, 2018 at 05:03:57PM +0100, Ben Whitten wrote:
> > 
> > > Move to calling the abstraction which allows for hardware acceleration.
> > > We also remove unneeded defines and only include objects if required.
> > >
> > > Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
> > [snip]
> > > diff --git a/common/image-fit.c b/common/image-fit.c
> > > index 8c15ed1..7d8c961 100644
> > > --- a/common/image-fit.c
> > > +++ b/common/image-fit.c
> > > @@ -1082,26 +1082,17 @@ int fit_set_timestamp(void *fit, int noffset,
> > time_t timestamp)
> > >  int calculate_hash(const void *data, int data_len, const char *algo,
> > >  			uint8_t *value, int *value_len)
> > >  {
> > > -	if (IMAGE_ENABLE_CRC32 && strcmp(algo, "crc32") == 0) {
> > > -		*((uint32_t *)value) = crc32_wd(0, data, data_len,
> > > -							CHUNKSZ_CRC32);
> > > -		*((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value));
> > > -		*value_len = 4;
> > > -	} else if (IMAGE_ENABLE_SHA1 && strcmp(algo, "sha1") == 0) {
> > > -		sha1_csum_wd((unsigned char *)data, data_len,
> > > -			     (unsigned char *)value, CHUNKSZ_SHA1);
> > > -		*value_len = 20;
> > > -	} else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) {
> > > -		sha256_csum_wd((unsigned char *)data, data_len,
> > > -			       (unsigned char *)value, CHUNKSZ_SHA256);
> > > -		*value_len = SHA256_SUM_LEN;
> > > -	} else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) {
> > > -		md5_wd((unsigned char *)data, data_len, value,
> > CHUNKSZ_MD5);
> > > -		*value_len = 16;
> > > -	} else {
> > > +	struct hash_algo *hash_algo;
> > > +	int ret;
> > > +
> > > +	ret = hash_lookup_algo(algo, &hash_algo);
> > 
> > This is unfortunately not code equivalent.  There's a little bit missing
> > to switch this over to using SPL_CRC32_SUPPORT as well.  A good test
> > would be to make sure that a sunxi platform still builds after this (it
> > doesn't currently with the series) and use buildman -Ssdel to compare
> > before/after sizes and make sure it's a tiny change in size related to
> > the code switch and not a huge change due to droppped (or added!)
> > support.  Thanks!
> 
> I see that I should be including the crc32.o file regardless in non SPL builds,
> now the sunxi board build passes locally.
> I tested a fit image with all hashes enabled and they all passed so atleast the
> calling of the functions seems to work. Did you spot another inequivalence?
> I am un-familiar with the buildman tool, but I shall give it a go as you suggest.

If the size tests above are pretty-close (as in, you can see it's just a
size change due to code change and not due to now including/excluding an
algorithm), I think we're there.  Thanks again!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180628/13e0f55f/attachment.sig>

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-06-28 18:14 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-06 16:03 [U-Boot] [PATCH v2 1/3] crypto: add md5 to common hash functions Ben Whitten
2018-06-06 16:03 ` [U-Boot] [PATCH v2 2/3] fit: allow fit to call hardware accelerated hash Ben Whitten
2018-06-18 16:59   ` Tom Rini
2018-06-28 15:46     ` Ben Whitten
2018-06-28 18:14       ` Tom Rini
2018-06-06 16:03 ` [U-Boot] [PATCH v2 3/3] crypto: add Atmel hardware acceleration for SHA1 & 256 Ben Whitten

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.