This patch adds implementation of function hw_rand() based on exynos security sub system.
Signed-off-by: Przemyslaw Marczak <p.marc...@samsung.com> cc: Akshay Saraswat <aksha...@samsung.com> cc: ARUN MANKUZHI <aru...@samsung.com> cc: Minkyu Kang <mk7.k...@samsung.com> --- arch/arm/include/asm/arch-exynos/cpu.h | 4 ++-- drivers/crypto/ace_sha.c | 41 ++++++++++++++++++++++++++++++++ drivers/crypto/ace_sha.h | 8 ++++--- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h index bccce63..a5c280d 100644 --- a/arch/arm/include/asm/arch-exynos/cpu.h +++ b/arch/arm/include/asm/arch-exynos/cpu.h @@ -48,7 +48,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 +#define EXYNOS4_ACE_SFR_BASE 0x10830000 #define EXYNOS4_DMC_PHY_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4_AUDIOSS_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4_USB_HOST_XHCI_BASE DEVICE_NOT_AVAILABLE @@ -87,7 +87,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 +#define EXYNOS4X12_ACE_SFR_BASE 0x10830000 #define EXYNOS4X12_DMC_PHY_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4X12_AUDIOSS_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4X12_USB_HOST_XHCI_BASE DEVICE_NOT_AVAILABLE diff --git a/drivers/crypto/ace_sha.c b/drivers/crypto/ace_sha.c index acbafde..d12a507 100644 --- a/drivers/crypto/ace_sha.c +++ b/drivers/crypto/ace_sha.c @@ -111,3 +111,44 @@ void hw_sha1(const unsigned char *pbuf, unsigned int buf_len, if (ace_sha_hash_digest(pbuf, buf_len, pout, ACE_SHA_TYPE_SHA1)) debug("ACE was not setup properly or it is faulty\n"); } + +unsigned int hw_rand(void) +{ + struct exynos_ace_sfr *reg = + (struct exynos_ace_sfr *)samsung_get_base_ace_sfr(); + int status, i; + int seed[5]; + unsigned int ret = 0; + + /* Seed data */ + for (i = 0; i < ACE_HASH_PRNG_REG_NUM; i++) + writel(seed[i], ®->hash_seed[i]); + + status = 0; + /* Wait for seed setup done */ + while (!(status & ACE_HASH_SEEDSETTING_MASK)) { + status = readl(®->hash_status); + if (status & ACE_HASH_PRNGERROR_MASK) + return 0; + } + + /* Start PRNG */ + writel(ACE_HASH_ENGSEL_PRNG | ACE_HASH_STARTBIT_ON, ®->hash_control); + + status = 0; + /* Wait for PRNG done */ + while (!(status & ACE_HASH_PRNGDONE_MASK)) { + status = readl(®->hash_status); + if (status & ACE_HASH_PRNGERROR_MASK) + return 0; + } + + /* Clear Done IRQ */ + writel(ACE_HASH_PRNGDONE_MASK, ®->hash_status); + + /* Read a PRNG result */ + for (i = 0; i < ACE_HASH_PRNG_REG_NUM; i++) + ret += readl(®->hash_prng[i]); + + return ret; +} diff --git a/drivers/crypto/ace_sha.h b/drivers/crypto/ace_sha.h index a426d52..f1097f7 100644 --- a/drivers/crypto/ace_sha.h +++ b/drivers/crypto/ace_sha.h @@ -72,9 +72,10 @@ struct exynos_ace_sfr { 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 hash_seed[5]; + unsigned char res14[12]; + unsigned int hash_prng[5]; + unsigned char res15[0x18c]; unsigned int pka_sfr[5]; /* base + 0x700 */ }; @@ -291,6 +292,7 @@ struct exynos_ace_sfr { #define ACE_HASH_PRNGERROR_MASK (1 << 7) #define ACE_HASH_PRNGERROR_OFF (0 << 7) #define ACE_HASH_PRNGERROR_ON (1 << 7) +#define ACE_HASH_PRNG_REG_NUM 5 #define ACE_SHA_TYPE_SHA1 1 #define ACE_SHA_TYPE_SHA256 2 -- 1.7.9.5 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot