Message ID | 1882e4320da26486d3759d81f1b440a0f89457b8.1394038415.git.p.marczak@samsung.com |
---|---|
State | Deferred |
Delegated to: | Tom Rini |
Headers | show |
On 03/06/2014 01:57 AM, Przemyslaw Marczak wrote: > This patch adds implementation of function hw_rand() based on exynos > security sub system. > > 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> > --- > Changes v2: > - none > > 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; > + } Can it use "do{ }while"? > + > + /* 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 >
On 06/03/14 01:57, Przemyslaw Marczak wrote: > This patch adds implementation of function hw_rand() based on exynos > security sub system. > > 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> > --- > Changes v2: > - none > > 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 please sort this list as others. > #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 Thanks, Minkyu Kang.
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
This patch adds implementation of function hw_rand() based on exynos security sub system. 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> --- Changes v2: - none 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(-)