Re: [PATCH 3/6] crypto: jz4780-rng: Add Ingenic JZ4780 hardware PRNG driver

2017-08-18 Thread PrasannaKumar Muralidharan
Hi Stephan,

On 18 August 2017 at 00:22, Stephan Mueller  wrote:
> Am Donnerstag, 17. August 2017, 20:25:17 CEST schrieb PrasannaKumar
> Muralidharan:
>
> Hi PrasannaKumar,
>
>> +
>> +static int jz4780_rng_generate(struct crypto_rng *tfm,
>> +const u8 *src, unsigned int slen,
>> +u8 *dst, unsigned int dlen)
>> +{
>> + struct jz4780_rng_ctx *ctx = crypto_rng_ctx(tfm);
>> + struct jz4780_rng *rng = ctx->rng;
>> + u32 data;
>> +
>> + /*
>> +  * JZ4780 Programmers manual says the RNG should not run continuously
>> +  * for more than 1s. So enable RNG, read data and disable it.
>> +  * NOTE: No issue was observed with MIPS creator CI20 board even when
>> +  * RNG ran continuously for longer periods. This is just a precaution.
>> +  *
>> +  * A delay is required so that the current RNG data is not bit shifted
>> +  * version of previous RNG data which could happen if random data is
>> +  * read continuously from this device.
>> +  */
>> + jz4780_rng_writel(rng, 1, REG_RNG_CTRL);
>> + do {
>> + data = jz4780_rng_readl(rng, REG_RNG_DATA);
>> + memcpy((void *)dst, (void *), 4);
>
> How do you know that dst is a multiple of 4 bytes? When dlen is only 3, you
> overflow the buffer.

You are right. I initially used hw_random framework for this driver.
But later realised that PRNG driver should use crypto framework. When
I started using crypto I reused most of the code. This was because of
porting. Will change it and send next version.

>
>> + dlen -= 4;
>> + dst += 4;
>> + udelay(20);
>> + } while (dlen >= 4);
>> +
>> + if (dlen > 0) {
>> + data = jz4780_rng_readl(rng, REG_RNG_DATA);
>> + memcpy((void *)dst, (void *), dlen);
>> + }
>> + jz4780_rng_writel(rng, 0, REG_RNG_CTRL);
>> +
>> + return 0;
>> +}
>
> Ciao
> Stephan

Thanks,
PrasannaKumar


Re: [PATCH 3/6] crypto: jz4780-rng: Add Ingenic JZ4780 hardware PRNG driver

2017-08-17 Thread Stephan Mueller
Am Donnerstag, 17. August 2017, 20:25:17 CEST schrieb PrasannaKumar 
Muralidharan:

Hi PrasannaKumar,

> +
> +static int jz4780_rng_generate(struct crypto_rng *tfm,
> +const u8 *src, unsigned int slen,
> +u8 *dst, unsigned int dlen)
> +{
> + struct jz4780_rng_ctx *ctx = crypto_rng_ctx(tfm);
> + struct jz4780_rng *rng = ctx->rng;
> + u32 data;
> +
> + /*
> +  * JZ4780 Programmers manual says the RNG should not run continuously
> +  * for more than 1s. So enable RNG, read data and disable it.
> +  * NOTE: No issue was observed with MIPS creator CI20 board even when
> +  * RNG ran continuously for longer periods. This is just a precaution.
> +  *
> +  * A delay is required so that the current RNG data is not bit shifted
> +  * version of previous RNG data which could happen if random data is
> +  * read continuously from this device.
> +  */
> + jz4780_rng_writel(rng, 1, REG_RNG_CTRL);
> + do {
> + data = jz4780_rng_readl(rng, REG_RNG_DATA);
> + memcpy((void *)dst, (void *), 4);

How do you know that dst is a multiple of 4 bytes? When dlen is only 3, you 
overflow the buffer.

> + dlen -= 4;
> + dst += 4;
> + udelay(20);
> + } while (dlen >= 4);
> +
> + if (dlen > 0) {
> + data = jz4780_rng_readl(rng, REG_RNG_DATA);
> + memcpy((void *)dst, (void *), dlen);
> + }
> + jz4780_rng_writel(rng, 0, REG_RNG_CTRL);
> +
> + return 0;
> +}

Ciao
Stephan


[PATCH 3/6] crypto: jz4780-rng: Add Ingenic JZ4780 hardware PRNG driver

2017-08-17 Thread PrasannaKumar Muralidharan
JZ4780 SoC pseudo random number generator driver using crypto framework.

Adding a delay before reading RNG data and disabling RNG after reading
data was suggested by Jeffery Walton.

Tested-by: Mathieu Malaterre 
Suggested-by: Jeffrey Walton 
Signed-off-by: PrasannaKumar Muralidharan 
---
 drivers/crypto/Kconfig  |  19 +
 drivers/crypto/Makefile |   1 +
 drivers/crypto/jz4780-rng.c | 173 
 3 files changed, 193 insertions(+)
 create mode 100644 drivers/crypto/jz4780-rng.c

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 8fa7e72..8263622 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -614,6 +614,25 @@ config CRYPTO_DEV_IMGTEC_HASH
  hardware hash accelerator. Supporting MD5/SHA1/SHA224/SHA256
  hashing algorithms.
 
+config CRYPTO_DEV_JZ4780_RNG
+   tristate "JZ4780 HW pseudo random number generator support"
+   depends on MACH_JZ4780 || COMPILE_TEST
+   depends on HAS_IOMEM
+   select CRYPTO_RNG
+   select REGMAP
+   select SYSCON
+   select MFD_SYSCON
+   ---help---
+ This driver provides kernel-side support through the
+ cryptographic API for the pseudo random number generator
+ hardware found in ingenic JZ4780 and X1000 SoC. MIPS
+ Creator CI20 uses JZ4780 SoC.
+
+ To compile this driver as a module, choose M here: the
+ module will be called jz4780-rng.
+
+ If unsure, say Y.
+
 config CRYPTO_DEV_SUN4I_SS
tristate "Support for Allwinner Security System cryptographic 
accelerator"
depends on ARCH_SUNXI && !64BIT
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index b12eb3c..3a3d970 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o
 obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o
 obj-$(CONFIG_CRYPTO_DEV_IMGTEC_HASH) += img-hash.o
 obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
+obj-$(CONFIG_CRYPTO_DEV_JZ4780_RNG) += jz4780-rng.o
 obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o
 obj-$(CONFIG_CRYPTO_DEV_MARVELL_CESA) += marvell/
 obj-$(CONFIG_CRYPTO_DEV_MEDIATEK) += mediatek/
diff --git a/drivers/crypto/jz4780-rng.c b/drivers/crypto/jz4780-rng.c
new file mode 100644
index 000..a03f2a0
--- /dev/null
+++ b/drivers/crypto/jz4780-rng.c
@@ -0,0 +1,173 @@
+/*
+ * jz4780-rng.c - Random Number Generator driver for the jz4780
+ *
+ * Copyright (c) 2017 PrasannaKumar Muralidharan 
+ *
+ * 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;
+ *
+ * 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.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#define REG_RNG_CTRL   0xD8
+#define REG_RNG_DATA   0xDC
+
+/* Context for crypto */
+struct jz4780_rng_ctx {
+   struct jz4780_rng *rng;
+};
+
+/* Device associated memory */
+struct jz4780_rng {
+   struct device *dev;
+   struct regmap *regmap;
+};
+
+static struct jz4780_rng *jz4780_rng;
+
+static int jz4780_rng_readl(struct jz4780_rng *rng, u32 offset)
+{
+   u32 val = 0;
+   int ret;
+
+   ret = regmap_read(rng->regmap, offset, );
+   if (!ret)
+   return val;
+
+   return ret;
+}
+
+static int jz4780_rng_writel(struct jz4780_rng *rng, u32 val, u32 offset)
+{
+   return regmap_write(rng->regmap, offset, val);
+}
+
+static int jz4780_rng_generate(struct crypto_rng *tfm,
+  const u8 *src, unsigned int slen,
+  u8 *dst, unsigned int dlen)
+{
+   struct jz4780_rng_ctx *ctx = crypto_rng_ctx(tfm);
+   struct jz4780_rng *rng = ctx->rng;
+   u32 data;
+
+   /*
+* JZ4780 Programmers manual says the RNG should not run continuously
+* for more than 1s. So enable RNG, read data and disable it.
+* NOTE: No issue was observed with MIPS creator CI20 board even when
+* RNG ran continuously for longer periods. This is just a precaution.
+*
+* A delay is required so that the current RNG data is not bit shifted
+* version of previous RNG data which could happen if random data is
+* read continuously from this device.
+*/
+   jz4780_rng_writel(rng, 1, REG_RNG_CTRL);
+   do {
+   data = jz4780_rng_readl(rng, REG_RNG_DATA);
+   memcpy((void *)dst, (void *), 4);
+   dlen -= 4;
+   dst += 4;
+   udelay(20);
+   } while (dlen >= 4);
+
+   if (dlen > 0) {
+