[U-Boot] [PATCH 0/4] Add ACE HW support for SHA 256

This patch set adds hardware acceleration for SHA 256 with the help of ACE.
Akshay Saraswat (4): Exynos: Add hardware accelerated SHA 256 Exynos: config: Enable ACE HW for SHA 256 for Exynos gen: Add sha256 command Exynos: Flush memory region before starting SHA DMA operation
arch/arm/cpu/armv7/exynos/Makefile | 4 + arch/arm/cpu/armv7/exynos/ace_sha.c | 123 ++++++++++++ arch/arm/include/asm/arch-exynos/ace_sfr.h | 310 +++++++++++++++++++++++++++++ arch/arm/include/asm/arch-exynos/ace_sha.h | 41 ++++ arch/arm/include/asm/arch-exynos/cpu.h | 4 + common/Makefile | 1 + common/cmd_sha256.c | 69 +++++++ include/configs/exynos5250-dt.h | 3 + 8 files changed, 555 insertions(+) create mode 100644 arch/arm/cpu/armv7/exynos/ace_sha.c create mode 100644 arch/arm/include/asm/arch-exynos/ace_sfr.h create mode 100644 arch/arm/include/asm/arch-exynos/ace_sha.h create mode 100644 common/cmd_sha256.c

SHA-256 and SHA-1 accelerated using ACE hardware.
TEST=sha256 0x40008000 0x2B 0x40009000 Used mm and md to write a standard string to memory location 0x40008000 and ran the above command to verify the output.
Signed-off-by: ARUN MANKUZHI arun.m@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com --- arch/arm/cpu/armv7/exynos/Makefile | 4 + arch/arm/cpu/armv7/exynos/ace_sha.c | 118 +++++++++++ arch/arm/include/asm/arch-exynos/ace_sfr.h | 310 +++++++++++++++++++++++++++++ arch/arm/include/asm/arch-exynos/ace_sha.h | 41 ++++ arch/arm/include/asm/arch-exynos/cpu.h | 4 + 5 files changed, 477 insertions(+) create mode 100644 arch/arm/cpu/armv7/exynos/ace_sha.c create mode 100644 arch/arm/include/asm/arch-exynos/ace_sfr.h create mode 100644 arch/arm/include/asm/arch-exynos/ace_sha.h
diff --git a/arch/arm/cpu/armv7/exynos/Makefile b/arch/arm/cpu/armv7/exynos/Makefile index 9119961..0a93a52 100644 --- a/arch/arm/cpu/armv7/exynos/Makefile +++ b/arch/arm/cpu/armv7/exynos/Makefile @@ -24,6 +24,10 @@ LIB = $(obj)lib$(SOC).o
COBJS += clock.o power.o soc.o system.o pinmux.o
+ifdef CONFIG_EXYNOS_ACE_SHA +COBJS += ace_sha.o +endif + SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
diff --git a/arch/arm/cpu/armv7/exynos/ace_sha.c b/arch/arm/cpu/armv7/exynos/ace_sha.c new file mode 100644 index 0000000..2715a03 --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/ace_sha.c @@ -0,0 +1,118 @@ +/* + * Advanced Crypto Engine - SHA Firmware + * + * Copyright (c) 2012 Samsung Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include <common.h> +#include <asm/arch/ace_sha.h> +#include <asm/arch/ace_sfr.h> + +/* Maximum input data size is 8 MB. Timeout observed for data size above 8MB */ +#define TIMEOUT_MS 100 + +#define SHA1_DIGEST_LEN 20 +#define SHA256_DIGEST_LEN 32 + +/* SHA1 value for the message of zero length */ +static const unsigned char sha1_digest_emptymsg[SHA1_DIGEST_LEN] = { + 0xDA, 0x39, 0xA3, 0xEE, 0x5E, 0x6B, 0x4B, 0x0D, + 0x32, 0x55, 0xBF, 0xFF, 0x95, 0x60, 0x18, 0x90, + 0xAF, 0xD8, 0x07, 0x09}; + +/* SHA256 value for the message of zero length */ +static const unsigned char sha256_digest_emptymsg[SHA256_DIGEST_LEN] = { + 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, + 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, + 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, + 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55}; + +int ace_sha_hash_digest( + unsigned char *pout, unsigned char *pbuf, + unsigned int buf_len, unsigned int hash_type) +{ + unsigned int i, reg, len; + unsigned int *pdigest; + ulong start; + struct exynos_ace_sfr *ace_sha_reg = + (struct exynos_ace_sfr *) samsung_get_base_ace_sfr(); + + if (buf_len == 0) { + /* ACE H/W cannot compute hash value for empty string */ + if (hash_type == ACE_SHA_TYPE_SHA1) + memcpy(pout, sha1_digest_emptymsg, SHA1_DIGEST_LEN); + else + memcpy(pout, sha256_digest_emptymsg, SHA256_DIGEST_LEN); + return 0; + } + + /* Flush HRDMA */ + writel(ACE_FC_HRDMACFLUSH_ON, &ace_sha_reg->fc_hrdmac); + writel(ACE_FC_HRDMACFLUSH_OFF, &ace_sha_reg->fc_hrdmac); + + /* Set byte swap of data in */ + writel(ACE_HASH_SWAPDI_ON | ACE_HASH_SWAPDO_ON | ACE_HASH_SWAPIV_ON, + &ace_sha_reg->hash_byteswap); + + /* Select Hash input mux as external source */ + reg = readl(&ace_sha_reg->fc_fifoctrl); + reg = (reg & ~ACE_FC_SELHASH_MASK) | ACE_FC_SELHASH_EXOUT; + writel(reg, &ace_sha_reg->fc_fifoctrl); + + /* Set Hash as SHA1 or SHA256 and start Hash engine */ + reg = (hash_type == ACE_SHA_TYPE_SHA1) ? + ACE_HASH_ENGSEL_SHA1HASH : ACE_HASH_ENGSEL_SHA256HASH; + reg |= ACE_HASH_STARTBIT_ON; + writel(reg, &ace_sha_reg->hash_control); + + /* Enable FIFO mode */ + writel(ACE_HASH_FIFO_ON, &ace_sha_reg->hash_fifo_mode); + + /* Set message length */ + writel(buf_len, &ace_sha_reg->hash_msgsize_low); + writel(0, &ace_sha_reg->hash_msgsize_high); + + /* Set HRDMA */ + writel((unsigned int)pbuf, &ace_sha_reg->fc_hrdmas); + writel(buf_len, &ace_sha_reg->fc_hrdmal); + + start = get_timer(0); + + while ((readl(&ace_sha_reg->hash_status) & ACE_HASH_MSGDONE_MASK) == + ACE_HASH_MSGDONE_OFF) { + + if (get_timer(start) > TIMEOUT_MS) { + debug("%s: Timeout waiting for ACE\n", __func__); + return -1; + } + } + + /* Clear MSG_DONE bit */ + writel(ACE_HASH_MSGDONE_ON, &ace_sha_reg->hash_status); + + /* Read hash result */ + pdigest = (unsigned int *)pout; + len = (hash_type == ACE_SHA_TYPE_SHA1) ? 5 : 8; + + for (i = 0; i < len ; i++) + pdigest[i] = readl(&ace_sha_reg->hash_result[i]); + + /* Clear HRDMA pending bit */ + writel(ACE_FC_HRDMA, &ace_sha_reg->fc_intpend); + + return 0; +} diff --git a/arch/arm/include/asm/arch-exynos/ace_sfr.h b/arch/arm/include/asm/arch-exynos/ace_sfr.h new file mode 100644 index 0000000..8f1c893 --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/ace_sfr.h @@ -0,0 +1,310 @@ +/* + * Header file for Advanced Crypto Engine - SFR definitions + * + * Copyright (c) 2012 Samsung Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ACE_SFR_H +#define __ACE_SFR_H + +struct exynos_ace_sfr { + unsigned int fc_intstat; /* base + 0 */ + unsigned int fc_intenset; + unsigned int fc_intenclr; + unsigned int fc_intpend; + unsigned int fc_fifostat; + unsigned int fc_fifoctrl; + unsigned int fc_global; + unsigned int res1; + unsigned int fc_brdmas; + unsigned int fc_brdmal; + unsigned int fc_brdmac; + unsigned int res2; + unsigned int fc_btdmas; + unsigned int fc_btdmal; + unsigned int fc_btdmac; + unsigned int res3; + unsigned int fc_hrdmas; + unsigned int fc_hrdmal; + unsigned int fc_hrdmac; + unsigned int res4; + unsigned int fc_pkdmas; + unsigned int fc_pkdmal; + unsigned int fc_pkdmac; + unsigned int fc_pkdmao; + unsigned char res5[0x1a0]; + + unsigned int aes_control; /* base + 0x200 */ + unsigned int aes_status; + unsigned char res6[0x8]; + unsigned int aes_in[4]; + unsigned int aes_out[4]; + unsigned int aes_iv[4]; + unsigned int aes_cnt[4]; + unsigned char res7[0x30]; + unsigned int aes_key[8]; + unsigned char res8[0x60]; + + unsigned int tdes_control; /* base + 0x300 */ + unsigned int tdes_status; + unsigned char res9[0x8]; + unsigned int tdes_key[6]; + unsigned int tdes_iv[2]; + unsigned int tdes_in[2]; + unsigned int tdes_out[2]; + unsigned char res10[0xc0]; + + unsigned int hash_control; /* base + 0x400 */ + unsigned int hash_control2; + unsigned int hash_fifo_mode; + unsigned int hash_byteswap; + unsigned int hash_status; + unsigned char res11[0xc]; + unsigned int hash_msgsize_low; + unsigned int hash_msgsize_high; + unsigned int hash_prelen_low; + unsigned int hash_prelen_high; + unsigned int hash_in[16]; + unsigned int hash_key_in[16]; + unsigned int hash_iv[8]; + unsigned char res12[0x30]; + unsigned int hash_result[8]; + unsigned char res13[0x20]; + unsigned int hash_seed[8]; + unsigned int hash_prng[8]; + unsigned char res14[0x180]; + + unsigned int pka_sfr[5]; /* base + 0x700 */ +}; + +/* ACE_FC_INT */ +#define ACE_FC_PKDMA (1 << 0) +#define ACE_FC_HRDMA (1 << 1) +#define ACE_FC_BTDMA (1 << 2) +#define ACE_FC_BRDMA (1 << 3) +#define ACE_FC_PRNG_ERROR (1 << 4) +#define ACE_FC_MSG_DONE (1 << 5) +#define ACE_FC_PRNG_DONE (1 << 6) +#define ACE_FC_PARTIAL_DONE (1 << 7) + +/* ACE_FC_FIFOSTAT */ +#define ACE_FC_PKFIFO_EMPTY (1 << 0) +#define ACE_FC_PKFIFO_FULL (1 << 1) +#define ACE_FC_HRFIFO_EMPTY (1 << 2) +#define ACE_FC_HRFIFO_FULL (1 << 3) +#define ACE_FC_BTFIFO_EMPTY (1 << 4) +#define ACE_FC_BTFIFO_FULL (1 << 5) +#define ACE_FC_BRFIFO_EMPTY (1 << 6) +#define ACE_FC_BRFIFO_FULL (1 << 7) + +/* ACE_FC_FIFOCTRL */ +#define ACE_FC_SELHASH_MASK (3 << 0) +#define ACE_FC_SELHASH_EXOUT (0 << 0) /* independent source */ +#define ACE_FC_SELHASH_BCIN (1 << 0) /* blk cipher input */ +#define ACE_FC_SELHASH_BCOUT (2 << 0) /* blk cipher output */ +#define ACE_FC_SELBC_MASK (1 << 2) +#define ACE_FC_SELBC_AES (0 << 2) /* AES */ +#define ACE_FC_SELBC_DES (1 << 2) /* DES */ + +/* ACE_FC_GLOBAL */ +#define ACE_FC_SSS_RESET (1 << 0) +#define ACE_FC_DMA_RESET (1 << 1) +#define ACE_FC_AES_RESET (1 << 2) +#define ACE_FC_DES_RESET (1 << 3) +#define ACE_FC_HASH_RESET (1 << 4) +#define ACE_FC_AXI_ENDIAN_MASK (3 << 6) +#define ACE_FC_AXI_ENDIAN_LE (0 << 6) +#define ACE_FC_AXI_ENDIAN_BIBE (1 << 6) +#define ACE_FC_AXI_ENDIAN_WIBE (2 << 6) + +/* Feed control - BRDMA control */ +#define ACE_FC_BRDMACFLUSH_OFF (0 << 0) +#define ACE_FC_BRDMACFLUSH_ON (1 << 0) +#define ACE_FC_BRDMACSWAP_ON (1 << 1) +#define ACE_FC_BRDMACARPROT_MASK (0x7 << 2) +#define ACE_FC_BRDMACARPROT_OFS (2) +#define ACE_FC_BRDMACARCACHE_MASK (0xf << 5) +#define ACE_FC_BRDMACARCACHE_OFS (5) + +/* Feed control - BTDMA control */ +#define ACE_FC_BTDMACFLUSH_OFF (0 << 0) +#define ACE_FC_BTDMACFLUSH_ON (1 << 0) +#define ACE_FC_BTDMACSWAP_ON (1 << 1) +#define ACE_FC_BTDMACAWPROT_MASK (0x7 << 2) +#define ACE_FC_BTDMACAWPROT_OFS (2) +#define ACE_FC_BTDMACAWCACHE_MASK (0xf << 5) +#define ACE_FC_BTDMACAWCACHE_OFS (5) + +/* Feed control - HRDMA control */ +#define ACE_FC_HRDMACFLUSH_OFF (0 << 0) +#define ACE_FC_HRDMACFLUSH_ON (1 << 0) +#define ACE_FC_HRDMACSWAP_ON (1 << 1) +#define ACE_FC_HRDMACARPROT_MASK (0x7 << 2) +#define ACE_FC_HRDMACARPROT_OFS (2) +#define ACE_FC_HRDMACARCACHE_MASK (0xf << 5) +#define ACE_FC_HRDMACARCACHE_OFS (5) + +/* Feed control - PKDMA control */ +#define ACE_FC_PKDMACBYTESWAP_ON (1 << 3) +#define ACE_FC_PKDMACDESEND_ON (1 << 2) +#define ACE_FC_PKDMACTRANSMIT_ON (1 << 1) +#define ACE_FC_PKDMACFLUSH_ON (1 << 0) + +/* Feed control - PKDMA offset */ +#define ACE_FC_SRAMOFFSET_MASK (0xfff) + +/* AES control */ +#define ACE_AES_MODE_MASK (1 << 0) +#define ACE_AES_MODE_ENC (0 << 0) +#define ACE_AES_MODE_DEC (1 << 0) +#define ACE_AES_OPERMODE_MASK (3 << 1) +#define ACE_AES_OPERMODE_ECB (0 << 1) +#define ACE_AES_OPERMODE_CBC (1 << 1) +#define ACE_AES_OPERMODE_CTR (2 << 1) +#define ACE_AES_FIFO_MASK (1 << 3) +#define ACE_AES_FIFO_OFF (0 << 3) /* CPU mode */ +#define ACE_AES_FIFO_ON (1 << 3) /* FIFO mode */ +#define ACE_AES_KEYSIZE_MASK (3 << 4) +#define ACE_AES_KEYSIZE_128 (0 << 4) +#define ACE_AES_KEYSIZE_192 (1 << 4) +#define ACE_AES_KEYSIZE_256 (2 << 4) +#define ACE_AES_KEYCNGMODE_MASK (1 << 6) +#define ACE_AES_KEYCNGMODE_OFF (0 << 6) +#define ACE_AES_KEYCNGMODE_ON (1 << 6) +#define ACE_AES_SWAP_MASK (0x1f << 7) +#define ACE_AES_SWAPKEY_OFF (0 << 7) +#define ACE_AES_SWAPKEY_ON (1 << 7) +#define ACE_AES_SWAPCNT_OFF (0 << 8) +#define ACE_AES_SWAPCNT_ON (1 << 8) +#define ACE_AES_SWAPIV_OFF (0 << 9) +#define ACE_AES_SWAPIV_ON (1 << 9) +#define ACE_AES_SWAPDO_OFF (0 << 10) +#define ACE_AES_SWAPDO_ON (1 << 10) +#define ACE_AES_SWAPDI_OFF (0 << 11) +#define ACE_AES_SWAPDI_ON (1 << 11) +#define ACE_AES_COUNTERSIZE_MASK (3 << 12) +#define ACE_AES_COUNTERSIZE_128 (0 << 12) +#define ACE_AES_COUNTERSIZE_64 (1 << 12) +#define ACE_AES_COUNTERSIZE_32 (2 << 12) +#define ACE_AES_COUNTERSIZE_16 (3 << 12) + +/* AES status */ +#define ACE_AES_OUTRDY_MASK (1 << 0) +#define ACE_AES_OUTRDY_OFF (0 << 0) +#define ACE_AES_OUTRDY_ON (1 << 0) +#define ACE_AES_INRDY_MASK (1 << 1) +#define ACE_AES_INRDY_OFF (0 << 1) +#define ACE_AES_INRDY_ON (1 << 1) +#define ACE_AES_BUSY_MASK (1 << 2) +#define ACE_AES_BUSY_OFF (0 << 2) +#define ACE_AES_BUSY_ON (1 << 2) + +/* TDES control */ +#define ACE_TDES_MODE_MASK (1 << 0) +#define ACE_TDES_MODE_ENC (0 << 0) +#define ACE_TDES_MODE_DEC (1 << 0) +#define ACE_TDES_OPERMODE_MASK (1 << 1) +#define ACE_TDES_OPERMODE_ECB (0 << 1) +#define ACE_TDES_OPERMODE_CBC (1 << 1) +#define ACE_TDES_SEL_MASK (3 << 3) +#define ACE_TDES_SEL_DES (0 << 3) +#define ACE_TDES_SEL_TDESEDE (1 << 3) /* TDES EDE mode */ +#define ACE_TDES_SEL_TDESEEE (3 << 3) /* TDES EEE mode */ +#define ACE_TDES_FIFO_MASK (1 << 5) +#define ACE_TDES_FIFO_OFF (0 << 5) /* CPU mode */ +#define ACE_TDES_FIFO_ON (1 << 5) /* FIFO mode */ +#define ACE_TDES_SWAP_MASK (0xf << 6) +#define ACE_TDES_SWAPKEY_OFF (0 << 6) +#define ACE_TDES_SWAPKEY_ON (1 << 6) +#define ACE_TDES_SWAPIV_OFF (0 << 7) +#define ACE_TDES_SWAPIV_ON (1 << 7) +#define ACE_TDES_SWAPDO_OFF (0 << 8) +#define ACE_TDES_SWAPDO_ON (1 << 8) +#define ACE_TDES_SWAPDI_OFF (0 << 9) +#define ACE_TDES_SWAPDI_ON (1 << 9) + +/* TDES status */ +#define ACE_TDES_OUTRDY_MASK (1 << 0) +#define ACE_TDES_OUTRDY_OFF (0 << 0) +#define ACE_TDES_OUTRDY_ON (1 << 0) +#define ACE_TDES_INRDY_MASK (1 << 1) +#define ACE_TDES_INRDY_OFF (0 << 1) +#define ACE_TDES_INRDY_ON (1 << 1) +#define ACE_TDES_BUSY_MASK (1 << 2) +#define ACE_TDES_BUSY_OFF (0 << 2) +#define ACE_TDES_BUSY_ON (1 << 2) + +/* Hash control */ +#define ACE_HASH_ENGSEL_MASK (0xf << 0) +#define ACE_HASH_ENGSEL_SHA1HASH (0x0 << 0) +#define ACE_HASH_ENGSEL_SHA1HMAC (0x1 << 0) +#define ACE_HASH_ENGSEL_SHA1HMACIN (0x1 << 0) +#define ACE_HASH_ENGSEL_SHA1HMACOUT (0x9 << 0) +#define ACE_HASH_ENGSEL_MD5HASH (0x2 << 0) +#define ACE_HASH_ENGSEL_MD5HMAC (0x3 << 0) +#define ACE_HASH_ENGSEL_MD5HMACIN (0x3 << 0) +#define ACE_HASH_ENGSEL_MD5HMACOUT (0xb << 0) +#define ACE_HASH_ENGSEL_SHA256HASH (0x4 << 0) +#define ACE_HASH_ENGSEL_SHA256HMAC (0x5 << 0) +#define ACE_HASH_ENGSEL_PRNG (0x8 << 0) +#define ACE_HASH_STARTBIT_ON (1 << 4) +#define ACE_HASH_USERIV_EN (1 << 5) + +/* Hash control 2 */ +#define ACE_HASH_PAUSE_ON (1 << 0) + +/* Hash control - FIFO mode */ +#define ACE_HASH_FIFO_MASK (1 << 0) +#define ACE_HASH_FIFO_OFF (0 << 0) +#define ACE_HASH_FIFO_ON (1 << 0) + +/* Hash control - byte swap */ +#define ACE_HASH_SWAP_MASK (0xf << 0) +#define ACE_HASH_SWAPKEY_OFF (0 << 0) +#define ACE_HASH_SWAPKEY_ON (1 << 0) +#define ACE_HASH_SWAPIV_OFF (0 << 1) +#define ACE_HASH_SWAPIV_ON (1 << 1) +#define ACE_HASH_SWAPDO_OFF (0 << 2) +#define ACE_HASH_SWAPDO_ON (1 << 2) +#define ACE_HASH_SWAPDI_OFF (0 << 3) +#define ACE_HASH_SWAPDI_ON (1 << 3) + +/* Hash status */ +#define ACE_HASH_BUFRDY_MASK (1 << 0) +#define ACE_HASH_BUFRDY_OFF (0 << 0) +#define ACE_HASH_BUFRDY_ON (1 << 0) +#define ACE_HASH_SEEDSETTING_MASK (1 << 1) +#define ACE_HASH_SEEDSETTING_OFF (0 << 1) +#define ACE_HASH_SEEDSETTING_ON (1 << 1) +#define ACE_HASH_PRNGBUSY_MASK (1 << 2) +#define ACE_HASH_PRNGBUSY_OFF (0 << 2) +#define ACE_HASH_PRNGBUSY_ON (1 << 2) +#define ACE_HASH_PARTIALDONE_MASK (1 << 4) +#define ACE_HASH_PARTIALDONE_OFF (0 << 4) +#define ACE_HASH_PARTIALDONE_ON (1 << 4) +#define ACE_HASH_PRNGDONE_MASK (1 << 5) +#define ACE_HASH_PRNGDONE_OFF (0 << 5) +#define ACE_HASH_PRNGDONE_ON (1 << 5) +#define ACE_HASH_MSGDONE_MASK (1 << 6) +#define ACE_HASH_MSGDONE_OFF (0 << 6) +#define ACE_HASH_MSGDONE_ON (1 << 6) +#define ACE_HASH_PRNGERROR_MASK (1 << 7) +#define ACE_HASH_PRNGERROR_OFF (0 << 7) +#define ACE_HASH_PRNGERROR_ON (1 << 7) + +#endif diff --git a/arch/arm/include/asm/arch-exynos/ace_sha.h b/arch/arm/include/asm/arch-exynos/ace_sha.h new file mode 100644 index 0000000..ed4e4d5 --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/ace_sha.h @@ -0,0 +1,41 @@ +/* + * Header file for SHA firmware + * + * Copyright (c) 2012 Samsung Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef __ACE_FW_SHA1_H +#define __ACE_FW_SHA1_H + +#define ACE_SHA_TYPE_SHA1 1 +#define ACE_SHA_TYPE_SHA256 2 + +/** + * Computes hash value of input pbuf using ACE + * + * @param pout 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 pbuf A pointer to the input buffer + * @param buflen Byte length of input buffer + * @param hash_type SHA1 or SHA256 + * + * @return 0 Success + */ +int ace_sha_hash_digest(uchar *pout, uchar *pbuf, uint buflen, uint hash_type); + +#endif diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h index eb34422..2a20558 100644 --- a/arch/arm/include/asm/arch-exynos/cpu.h +++ b/arch/arm/include/asm/arch-exynos/cpu.h @@ -62,6 +62,7 @@ #define EXYNOS4_GPIO_PART4_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4_DP_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4_SPI_ISP_BASE DEVICE_NOT_AVAILABLE +#define EXYNOS4_ACE_SFR_BASE DEVICE_NOT_AVAILABLE
/* EXYNOS4X12 */ #define EXYNOS4X12_GPIO_PART3_BASE 0x03860000 @@ -95,6 +96,7 @@ #define EXYNOS4X12_I2S_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4X12_SPI_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4X12_SPI_ISP_BASE DEVICE_NOT_AVAILABLE +#define EXYNOS4X12_ACE_SFR_BASE DEVICE_NOT_AVAILABLE
/* EXYNOS5 Common*/ #define EXYNOS5_I2C_SPACING 0x10000 @@ -106,6 +108,7 @@ #define EXYNOS5_SWRESET 0x10040400 #define EXYNOS5_SYSREG_BASE 0x10050000 #define EXYNOS5_WATCHDOG_BASE 0x101D0000 +#define EXYNOS5_ACE_SFR_BASE 0x10830000 #define EXYNOS5_DMC_PHY0_BASE 0x10C00000 #define EXYNOS5_DMC_PHY1_BASE 0x10C10000 #define EXYNOS5_GPIO_PART3_BASE 0x10D10000 @@ -205,6 +208,7 @@ static inline unsigned int samsung_get_base_##device(void) \
SAMSUNG_BASE(adc, ADC_BASE) SAMSUNG_BASE(clock, CLOCK_BASE) +SAMSUNG_BASE(ace_sfr, ACE_SFR_BASE) SAMSUNG_BASE(dp, DP_BASE) SAMSUNG_BASE(sysreg, SYSREG_BASE) SAMSUNG_BASE(fimd, FIMD_BASE)

On Wed, 27 Feb 2013 10:24:39 -0500 Akshay Saraswat akshay.s@samsung.com wrote:
SHA-256 and SHA-1 accelerated using ACE hardware.
TEST=sha256 0x40008000 0x2B 0x40009000 Used mm and md to write a standard string to memory location 0x40008000 and ran the above command to verify the output.
can we get rid of this TEST= infrastructure format? It's not used on upstream u-boot.
Signed-off-by: ARUN MANKUZHI arun.m@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com
arch/arm/cpu/armv7/exynos/Makefile | 4 + arch/arm/cpu/armv7/exynos/ace_sha.c | 118 +++++++++++ arch/arm/include/asm/arch-exynos/ace_sfr.h | 310 +++++++++++++++++++++++++++++ arch/arm/include/asm/arch-exynos/ace_sha.h | 41 ++++ arch/arm/include/asm/arch-exynos/cpu.h | 4 + 5 files changed, 477 insertions(+) create mode 100644 arch/arm/cpu/armv7/exynos/ace_sha.c create mode 100644 arch/arm/include/asm/arch-exynos/ace_sfr.h create mode 100644 arch/arm/include/asm/arch-exynos/ace_sha.h
I doubt there's anything binding this to arch-exynos, and I bet the h/w is going to be available - if not already - on some other parts, so it probably belongs in a new drivers/crypto directory.
+/* Maximum input data size is 8 MB. Timeout observed for data size above 8MB */ +#define TIMEOUT_MS 100
So if there's a drop in processor frequency, the driver times out too early? Not good.
+#define SHA1_DIGEST_LEN 20 +#define SHA256_DIGEST_LEN 32
don't duplicate definitions that already exist in include/sha*.h.
- if (buf_len == 0) {
/* ACE H/W cannot compute hash value for empty string */
if (hash_type == ACE_SHA_TYPE_SHA1)
memcpy(pout, sha1_digest_emptymsg, SHA1_DIGEST_LEN);
else
memcpy(pout, sha256_digest_emptymsg, SHA256_DIGEST_LEN);
return 0;
- }
there's no protection from buf_len going over the h/w 8MB limit mentioned above - why not fall back to the s/w implementation in both those cases? Or, if the h/w can be programmed to perform multiple hash updates in 8MB data chunks, add support to do that.
- /* Read hash result */
- pdigest = (unsigned int *)pout;
- len = (hash_type == ACE_SHA_TYPE_SHA1) ? 5 : 8;
magic numbers - use SHAx_SUM_LEN / 4.
Kim

This enables SHA 256 for exynos.
TEST=sha256 0x40008000 0x2B 0x40009000 Used mm and md to write a standard string to memory location 0x40008000 and ran the above command to verify the output.
Signed-off-by: ARUN MANKUZHI arun.m@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com --- include/configs/exynos5250-dt.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h index cabd2f2..3963aaf 100644 --- a/include/configs/exynos5250-dt.h +++ b/include/configs/exynos5250-dt.h @@ -45,6 +45,9 @@ /* Keep L2 Cache Disabled */ #define CONFIG_SYS_DCACHE_OFF
+#define CONFIG_CMD_SHA256 +#define CONFIG_EXYNOS_ACE_SHA + #define CONFIG_SYS_SDRAM_BASE 0x40000000 #define CONFIG_SYS_TEXT_BASE 0x43E00000

Hi Akshay,
On Wed, Feb 27, 2013 at 7:24 AM, Akshay Saraswat akshay.s@samsung.com wrote:
This enables SHA 256 for exynos.
TEST=sha256 0x40008000 0x2B 0x40009000 Used mm and md to write a standard string to memory location 0x40008000 and ran the above command to verify the output.
Signed-off-by: ARUN MANKUZHI arun.m@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com
include/configs/exynos5250-dt.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h index cabd2f2..3963aaf 100644 --- a/include/configs/exynos5250-dt.h +++ b/include/configs/exynos5250-dt.h @@ -45,6 +45,9 @@ /* Keep L2 Cache Disabled */ #define CONFIG_SYS_DCACHE_OFF
+#define CONFIG_CMD_SHA256
This should not be needed, you can use CONFIG_CMD_HASH instead.
+#define CONFIG_EXYNOS_ACE_SHA
#define CONFIG_SYS_SDRAM_BASE 0x40000000 #define CONFIG_SYS_TEXT_BASE 0x43E00000
-- 1.8.0
Regards, Simon

sha256 command is added which can be used to test SHA 256 hash algorithm.
TEST=sha256 0x40008000 0x2B 0x40009000 Used mm and md to write a standard string to memory location 0x40008000 and ran the above command to verify the output.
Signed-off-by: ARUN MANKUZHI arun.m@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com --- common/Makefile | 1 + common/cmd_sha256.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 common/cmd_sha256.c
diff --git a/common/Makefile b/common/Makefile index 54fcc81..6170ed5 100644 --- a/common/Makefile +++ b/common/Makefile @@ -201,6 +201,7 @@ COBJS-$(CONFIG_MENU) += menu.o COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o COBJS-$(CONFIG_UPDATE_TFTP) += update.o COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o +COBJS-$(CONFIG_CMD_SHA256) += cmd_sha256.o COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o endif diff --git a/common/cmd_sha256.c b/common/cmd_sha256.c new file mode 100644 index 0000000..e4f6b56 --- /dev/null +++ b/common/cmd_sha256.c @@ -0,0 +1,69 @@ +/* + * Copyright 2000-2009 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#ifdef CONFIG_EXYNOS_ACE_SHA +#include <asm/arch/ace_sha.h> +#else +#include <sha256.h> +#endif + +int do_sha256(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unsigned long inlen; + unsigned char *input, *out; + int i; +#ifndef CONFIG_EXYNOS_ACE_SHA + sha256_context sha_cnxt; +#endif + if (argc < 4) { + printf("usage: sha256 <input> <input length> <output>\n"); + return 0; + } + input = (unsigned char *)simple_strtoul(argv[1], NULL, 16); + inlen = simple_strtoul(argv[2], NULL, 16); + out = (unsigned char *)simple_strtoul(argv[3], NULL, 16); + +#ifdef CONFIG_EXYNOS_ACE_SHA + ace_sha_hash_digest(out, input, inlen, 2); +#else + sha256_starts(&sha_cnxt); + + sha256_update(&sha_cnxt, input, inlen); + + sha256_finish(&sha_cnxt, out); +#endif + + for (i = 0; i < 32; i++) + printf("0x%02X ", out[i]); + printf("\n"); + + return 0; +} + +U_BOOT_CMD( + sha256, 4, 1, do_sha256, + "print hash result", + "<input> <inputlength> <output>" +);

Hi Akshay,
On Wed, Feb 27, 2013 at 7:24 AM, Akshay Saraswat akshay.s@samsung.com wrote:
sha256 command is added which can be used to test SHA 256 hash algorithm.
TEST=sha256 0x40008000 0x2B 0x40009000 Used mm and md to write a standard string to memory location 0x40008000 and ran the above command to verify the output.
Signed-off-by: ARUN MANKUZHI arun.m@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com
common/Makefile | 1 + common/cmd_sha256.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 common/cmd_sha256.c
Rather than adding this command, can you please use 'hash sha256' instead? This is in common/hash.c.
Regards, Simon
diff --git a/common/Makefile b/common/Makefile index 54fcc81..6170ed5 100644 --- a/common/Makefile +++ b/common/Makefile @@ -201,6 +201,7 @@ COBJS-$(CONFIG_MENU) += menu.o COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o COBJS-$(CONFIG_UPDATE_TFTP) += update.o COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o +COBJS-$(CONFIG_CMD_SHA256) += cmd_sha256.o COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o endif diff --git a/common/cmd_sha256.c b/common/cmd_sha256.c new file mode 100644 index 0000000..e4f6b56 --- /dev/null +++ b/common/cmd_sha256.c @@ -0,0 +1,69 @@ +/*
- Copyright 2000-2009
- Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- See file CREDITS for list of people who contributed to this
- project.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include <common.h> +#include <command.h> +#ifdef CONFIG_EXYNOS_ACE_SHA +#include <asm/arch/ace_sha.h> +#else +#include <sha256.h> +#endif
+int do_sha256(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{
unsigned long inlen;
unsigned char *input, *out;
int i;
+#ifndef CONFIG_EXYNOS_ACE_SHA
sha256_context sha_cnxt;
+#endif
if (argc < 4) {
printf("usage: sha256 <input> <input length> <output>\n");
return 0;
}
input = (unsigned char *)simple_strtoul(argv[1], NULL, 16);
inlen = simple_strtoul(argv[2], NULL, 16);
out = (unsigned char *)simple_strtoul(argv[3], NULL, 16);
+#ifdef CONFIG_EXYNOS_ACE_SHA
ace_sha_hash_digest(out, input, inlen, 2);
+#else
sha256_starts(&sha_cnxt);
sha256_update(&sha_cnxt, input, inlen);
sha256_finish(&sha_cnxt, out);
+#endif
for (i = 0; i < 32; i++)
printf("0x%02X ", out[i]);
printf("\n");
return 0;
+}
+U_BOOT_CMD(
sha256, 4, 1, do_sha256,
"print hash result",
"<input> <inputlength> <output>"
+);
1.8.0

Hi Akshay,
On Wed, Feb 27, 2013 at 12:22 PM, Simon Glass sjg@chromium.org wrote:
Hi Akshay,
On Wed, Feb 27, 2013 at 7:24 AM, Akshay Saraswat akshay.s@samsung.com wrote:
sha256 command is added which can be used to test SHA 256 hash algorithm.
TEST=sha256 0x40008000 0x2B 0x40009000 Used mm and md to write a standard string to memory location 0x40008000 and ran the above command to verify the output.
Signed-off-by: ARUN MANKUZHI arun.m@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com
common/Makefile | 1 + common/cmd_sha256.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 common/cmd_sha256.c
Rather than adding this command, can you please use 'hash sha256' instead? This is in common/hash.c.
And to be a bit more clear, if you plumb in your sha256 implementation into the list of implementations at the top of hash.c, and put it earlier than the software implementation, then it will get priority.
Regards, Simon
Regards, Simon
diff --git a/common/Makefile b/common/Makefile index 54fcc81..6170ed5 100644 --- a/common/Makefile +++ b/common/Makefile @@ -201,6 +201,7 @@ COBJS-$(CONFIG_MENU) += menu.o COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o COBJS-$(CONFIG_UPDATE_TFTP) += update.o COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o +COBJS-$(CONFIG_CMD_SHA256) += cmd_sha256.o COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o endif diff --git a/common/cmd_sha256.c b/common/cmd_sha256.c new file mode 100644 index 0000000..e4f6b56 --- /dev/null +++ b/common/cmd_sha256.c @@ -0,0 +1,69 @@ +/*
- Copyright 2000-2009
- Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- See file CREDITS for list of people who contributed to this
- project.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include <common.h> +#include <command.h> +#ifdef CONFIG_EXYNOS_ACE_SHA +#include <asm/arch/ace_sha.h> +#else +#include <sha256.h> +#endif
+int do_sha256(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{
unsigned long inlen;
unsigned char *input, *out;
int i;
+#ifndef CONFIG_EXYNOS_ACE_SHA
sha256_context sha_cnxt;
+#endif
if (argc < 4) {
printf("usage: sha256 <input> <input length> <output>\n");
return 0;
}
input = (unsigned char *)simple_strtoul(argv[1], NULL, 16);
inlen = simple_strtoul(argv[2], NULL, 16);
out = (unsigned char *)simple_strtoul(argv[3], NULL, 16);
+#ifdef CONFIG_EXYNOS_ACE_SHA
ace_sha_hash_digest(out, input, inlen, 2);
+#else
sha256_starts(&sha_cnxt);
sha256_update(&sha_cnxt, input, inlen);
sha256_finish(&sha_cnxt, out);
+#endif
for (i = 0; i < 32; i++)
printf("0x%02X ", out[i]);
printf("\n");
return 0;
+}
+U_BOOT_CMD(
sha256, 4, 1, do_sha256,
"print hash result",
"<input> <inputlength> <output>"
+);
1.8.0

SHA256 commands weren't giving desired output since the data we set in the memory addresses through mw.l commands was not getting updated in actual memory. Adding this patch resolves the issue.
TEST=sha256 0x40008000 0x2B 0x40009000 Used mm and md to write a standard string to memory location 0x40008000 and ran the above command to verify the output.
Signed-off-by: Ajay Kumar ajaykumar.rs@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com --- arch/arm/cpu/armv7/exynos/ace_sha.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/arm/cpu/armv7/exynos/ace_sha.c b/arch/arm/cpu/armv7/exynos/ace_sha.c index 2715a03..9ac34be 100644 --- a/arch/arm/cpu/armv7/exynos/ace_sha.c +++ b/arch/arm/cpu/armv7/exynos/ace_sha.c @@ -51,6 +51,11 @@ int ace_sha_hash_digest( struct exynos_ace_sfr *ace_sha_reg = (struct exynos_ace_sfr *) samsung_get_base_ace_sfr();
+ /* Flush input and output memory buffers berore starting DMA */ + flush_dcache_range((unsigned long) pout, (unsigned long)(pout + 0x20)); + flush_dcache_range((unsigned long) pbuf, + (unsigned long)(pbuf + buf_len)); + if (buf_len == 0) { /* ACE H/W cannot compute hash value for empty string */ if (hash_type == ACE_SHA_TYPE_SHA1)

On Wed, 27 Feb 2013 10:24:42 -0500 Akshay Saraswat akshay.s@samsung.com wrote:
SHA256 commands weren't giving desired output since the data we set in the memory addresses through mw.l commands was not getting updated in actual memory. Adding this patch resolves the issue.
why not use the dcache flush command instead?
Kim
participants (3)
-
Akshay Saraswat
-
Kim Phillips
-
Simon Glass