diff options
| author | Przemyslaw Marczak <p.marczak@samsung.com> | 2014-03-25 10:58:21 +0100 | 
|---|---|---|
| committer | Tom Rini <trini@ti.com> | 2014-03-28 15:06:31 -0400 | 
| commit | 0bd937248a7a69f531e19eac28d164fce0c60855 (patch) | |
| tree | 08331c56a9c43dfd268c19392ca9a19d3f35db9b | |
| parent | 680d8f03ea558f5d75f0506d8ca24db99508e4b2 (diff) | |
| download | olio-uboot-2014.01-0bd937248a7a69f531e19eac28d164fce0c60855.tar.xz olio-uboot-2014.01-0bd937248a7a69f531e19eac28d164fce0c60855.zip | |
drivers: crypto: ace_sha: add implementation of hardware based lib rand
This patch adds implementation of rand library based on hardware random
number generator of security subsystem in Exynos SOC.
This library includes:
- srand()  - used for seed hardware block
- rand()   - returns random number
- rand_r() - the same as above with given seed
which depends on CONFIG_EXYNOS_ACE_SHA and CONFIG_LIB_HW_RAND.
Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com>
cc: Akshay Saraswat <akshay.s@samsung.com>
cc: ARUN MANKUZHI <arun.m@samsung.com>
cc: Minkyu Kang <mk7.kang@samsung.com>
Cc: Michael Walle <michael@walle.cc>
Cc: Tom Rini <trini@ti.com>
Cc: Masahiro Yamada <yamada.m@jp.panasonic.com>
| -rw-r--r-- | drivers/crypto/ace_sha.c | 73 | ||||
| -rw-r--r-- | drivers/crypto/ace_sha.h | 8 | 
2 files changed, 77 insertions, 4 deletions
| diff --git a/drivers/crypto/ace_sha.c b/drivers/crypto/ace_sha.c index acbafde97..ed4f54182 100644 --- a/drivers/crypto/ace_sha.c +++ b/drivers/crypto/ace_sha.c @@ -5,10 +5,12 @@   * SPDX-License-Identifier:	GPL-2.0+   */  #include <common.h> +#include "ace_sha.h" + +#ifdef CONFIG_SHA_HW_ACCEL  #include <sha256.h>  #include <sha1.h>  #include <asm/errno.h> -#include "ace_sha.h"  /* SHA1 value for the message of zero length */  static const unsigned char sha1_digest_emptymsg[SHA1_SUM_LEN] = { @@ -111,3 +113,72 @@ 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");  } +#endif /* CONFIG_SHA_HW_ACCEL */ + +#ifdef CONFIG_LIB_HW_RAND +static unsigned int seed_done; + +void srand(unsigned int seed) +{ +	struct exynos_ace_sfr *reg = +		(struct exynos_ace_sfr *)samsung_get_base_ace_sfr(); +	int i, status; + +	/* Seed data */ +	for (i = 0; i < ACE_HASH_PRNG_REG_NUM; i++) +		writel(seed << i, ®->hash_seed[i]); + +	/* Wait for seed setup done */ +	while (1) { +		status = readl(®->hash_status); +		if ((status & ACE_HASH_SEEDSETTING_MASK) || +		    (status & ACE_HASH_PRNGERROR_MASK)) +			break; +	} + +	seed_done = 1; +} + +unsigned int rand(void) +{ +	struct exynos_ace_sfr *reg = +		(struct exynos_ace_sfr *)samsung_get_base_ace_sfr(); +	int i, status; +	unsigned int seed = (unsigned int)&status; +	unsigned int ret = 0; + +	if (!seed_done) +		srand(seed); + +	/* Start PRNG */ +	writel(ACE_HASH_ENGSEL_PRNG | ACE_HASH_STARTBIT_ON, ®->hash_control); + +	/* Wait for PRNG done */ +	while (1) { +		status = readl(®->hash_status); +		if (status & ACE_HASH_PRNGDONE_MASK) +			break; +		if (status & ACE_HASH_PRNGERROR_MASK) { +			seed_done = 0; +			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]); + +	seed_done = 0; +	return ret; +} + +unsigned int rand_r(unsigned int *seedp) +{ +	srand(*seedp); + +	return rand(); +} +#endif /* CONFIG_LIB_HW_RAND */ diff --git a/drivers/crypto/ace_sha.h b/drivers/crypto/ace_sha.h index a426d5237..f1097f72d 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 |