[PATCH v6 1/6] hwrng: remove msm hw_random driver

2018-07-15 Thread Vinod Koul
This driver is for a psedo-rng so should not be added in hwrng.
Remove it so that it's replacement can be added.

Signed-off-by: Vinod Koul 
---
 drivers/char/hw_random/Kconfig   |  13 ---
 drivers/char/hw_random/Makefile  |   1 -
 drivers/char/hw_random/msm-rng.c | 183 ---
 3 files changed, 197 deletions(-)
 delete mode 100644 drivers/char/hw_random/msm-rng.c

diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index c34b257d852d..dac895dc01b9 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -307,19 +307,6 @@ config HW_RANDOM_HISI
 
  If unsure, say Y.
 
-config HW_RANDOM_MSM
-   tristate "Qualcomm SoCs Random Number Generator support"
-   depends on HW_RANDOM && ARCH_QCOM
-   default HW_RANDOM
-   ---help---
- This driver provides kernel-side support for the Random Number
- Generator hardware found on Qualcomm SoCs.
-
- To compile this driver as a module, choose M here. the
- module will be called msm-rng.
-
- If unsure, say Y.
-
 config HW_RANDOM_ST
tristate "ST Microelectronics HW Random Number Generator support"
depends on HW_RANDOM && ARCH_STI
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 533e913c93d1..e35ec3ce3a20 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -29,7 +29,6 @@ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
 obj-$(CONFIG_HW_RANDOM_HISI)   += hisi-rng.o
 obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
 obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o
-obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o
 obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o
 obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o
 obj-$(CONFIG_HW_RANDOM_STM32) += stm32-rng.o
diff --git a/drivers/char/hw_random/msm-rng.c b/drivers/char/hw_random/msm-rng.c
deleted file mode 100644
index 841fee845ec9..
--- a/drivers/char/hw_random/msm-rng.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 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 
-
-/* Device specific register offsets */
-#define PRNG_DATA_OUT  0x
-#define PRNG_STATUS0x0004
-#define PRNG_LFSR_CFG  0x0100
-#define PRNG_CONFIG0x0104
-
-/* Device specific register masks and config values */
-#define PRNG_LFSR_CFG_MASK 0x
-#define PRNG_LFSR_CFG_CLOCKS   0x
-#define PRNG_CONFIG_HW_ENABLE  BIT(1)
-#define PRNG_STATUS_DATA_AVAIL BIT(0)
-
-#define MAX_HW_FIFO_DEPTH  16
-#define MAX_HW_FIFO_SIZE   (MAX_HW_FIFO_DEPTH * 4)
-#define WORD_SZ4
-
-struct msm_rng {
-   void __iomem *base;
-   struct clk *clk;
-   struct hwrng hwrng;
-};
-
-#define to_msm_rng(p)  container_of(p, struct msm_rng, hwrng)
-
-static int msm_rng_enable(struct hwrng *hwrng, int enable)
-{
-   struct msm_rng *rng = to_msm_rng(hwrng);
-   u32 val;
-   int ret;
-
-   ret = clk_prepare_enable(rng->clk);
-   if (ret)
-   return ret;
-
-   if (enable) {
-   /* Enable PRNG only if it is not already enabled */
-   val = readl_relaxed(rng->base + PRNG_CONFIG);
-   if (val & PRNG_CONFIG_HW_ENABLE)
-   goto already_enabled;
-
-   val = readl_relaxed(rng->base + PRNG_LFSR_CFG);
-   val &= ~PRNG_LFSR_CFG_MASK;
-   val |= PRNG_LFSR_CFG_CLOCKS;
-   writel(val, rng->base + PRNG_LFSR_CFG);
-
-   val = readl_relaxed(rng->base + PRNG_CONFIG);
-   val |= PRNG_CONFIG_HW_ENABLE;
-   writel(val, rng->base + PRNG_CONFIG);
-   } else {
-   val = readl_relaxed(rng->base + PRNG_CONFIG);
-   val &= ~PRNG_CONFIG_HW_ENABLE;
-   writel(val, rng->base + PRNG_CONFIG);
-   }
-
-already_enabled:
-   clk_disable_unprepare(rng->clk);
-   return 0;
-}
-
-static int msm_rng_read(struct hwrng *hwrng, void *data, size_t max, bool wait)
-{
-   struct msm_rng *rng = to_msm_rng(hwrng);
-   size_t currsize = 0;
-   u32 *retdata = data;
-   size_t maxsize;
-   int ret;
-   u32 val;
-
-   /* calculate max size bytes to transfer back to caller */
-   maxsize = min_t(size_t, MAX_HW_FIFO_SIZE, max);
-
-   ret = clk_prepare_enable(rng->clk);
-   if (ret)
-   return ret;
-
- 

[PATCH v6 4/6] dt-bindings: crypto: Add new compatible qcom,prng-ee

2018-07-15 Thread Vinod Koul
Later qcom chips support v2 of the prng, which exposes an EE
(Execution Environment) for OS to use so add new compatible
qcom,prng-ee for this.

Signed-off-by: Vinod Koul 
---
 Documentation/devicetree/bindings/crypto/qcom,prng.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/crypto/qcom,prng.txt 
b/Documentation/devicetree/bindings/crypto/qcom,prng.txt
index 8e5853c2879b..7ee0e9eac973 100644
--- a/Documentation/devicetree/bindings/crypto/qcom,prng.txt
+++ b/Documentation/devicetree/bindings/crypto/qcom,prng.txt
@@ -2,7 +2,9 @@ Qualcomm MSM pseudo random number generator.
 
 Required properties:
 
-- compatible  : should be "qcom,prng"
+- compatible  : should be "qcom,prng" for 8916 etc
+  : should be "qcom,prng-ee" for 8996 and later using EE
+   (Execution Environment) slice of prng
 - reg : specifies base physical address and size of the registers map
 - clocks  : phandle to clock-controller plus clock-specifier pair
 - clock-names : "core" clocks all registers, FIFO and circuits in PRNG IP block
-- 
2.14.4



[PATCH v6 5/6] crypto: qcom: Add support for prng-ee

2018-07-15 Thread Vinod Koul
Qcom 8996 and later chips features multiple Execution Environments
(EE) and secure world is typically responsible for configuring the
prng.

Add driver data for qcom,prng as 0 and qcom,prng-ee as 1 and use
that to skip initialization routine.

Signed-off-by: Vinod Koul 
---
 drivers/crypto/qcom-rng.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/qcom-rng.c b/drivers/crypto/qcom-rng.c
index e921382099d7..80544326e310 100644
--- a/drivers/crypto/qcom-rng.c
+++ b/drivers/crypto/qcom-rng.c
@@ -28,6 +28,7 @@ struct qcom_rng {
struct mutex lock;
void __iomem *base;
struct clk *clk;
+   unsigned int skip_init;
 };
 
 struct qcom_rng_ctx {
@@ -128,7 +129,10 @@ static int qcom_rng_init(struct crypto_tfm *tfm)
 
ctx->rng = qcom_rng_dev;
 
-   return qcom_rng_enable(ctx->rng);
+   if (!ctx->rng->skip_init)
+   return qcom_rng_enable(ctx->rng);
+
+   return 0;
 }
 
 static struct rng_alg qcom_rng_alg = {
@@ -168,6 +172,8 @@ static int qcom_rng_probe(struct platform_device *pdev)
if (IS_ERR(rng->clk))
return PTR_ERR(rng->clk);
 
+   rng->skip_init = (unsigned long)device_get_match_data(>dev);
+
qcom_rng_dev = rng;
ret = crypto_register_rng(_rng_alg);
if (ret) {
@@ -188,7 +194,8 @@ static int qcom_rng_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id qcom_rng_of_match[] = {
-   { .compatible = "qcom,prng" },
+   { .compatible = "qcom,prng", .data = (void *)0},
+   { .compatible = "qcom,prng-ee", .data = (void *)1},
{}
 };
 MODULE_DEVICE_TABLE(of, qcom_rng_of_match);
-- 
2.14.4



[PATCH v6 3/6] crypto: Add Qcom prng driver

2018-07-15 Thread Vinod Koul
This ports the Qcom prng from older hw_random driver.

No change of functionality and move from hw_random to crypto
APIs is done.

Reviewed-by: Linus Walleij 
Signed-off-by: Vinod Koul 
---
 drivers/crypto/Kconfig|  11 +++
 drivers/crypto/Makefile   |   1 +
 drivers/crypto/qcom-rng.c | 208 ++
 3 files changed, 220 insertions(+)
 create mode 100644 drivers/crypto/qcom-rng.c

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 43cccf6aff61..4156f9e8e397 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -585,6 +585,17 @@ config CRYPTO_DEV_QCE
  hardware. To compile this driver as a module, choose M here. The
  module will be called qcrypto.
 
+config CRYPTO_DEV_QCOM_RNG
+   tristate "Qualcomm Random Number Generator Driver"
+   depends on ARCH_QCOM || COMPILE_TEST
+   select CRYPTO_RNG
+   help
+ This driver provides support for the Random Number
+ Generator hardware found on Qualcomm SoCs.
+
+ To compile this driver as a module, choose M here. The
+  module will be called qcom-rng. If unsure, say N.
+
 config CRYPTO_DEV_VMX
bool "Support for VMX cryptographic acceleration instructions"
depends on PPC64 && VSX
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 7ae87b4f6c8d..3602875c4f80 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o
 obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
 obj-$(CONFIG_CRYPTO_DEV_QAT) += qat/
 obj-$(CONFIG_CRYPTO_DEV_QCE) += qce/
+obj-$(CONFIG_CRYPTO_DEV_QCOM_RNG) += qcom-rng.o
 obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rockchip/
 obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
 obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o
diff --git a/drivers/crypto/qcom-rng.c b/drivers/crypto/qcom-rng.c
new file mode 100644
index ..e921382099d7
--- /dev/null
+++ b/drivers/crypto/qcom-rng.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017-18 Linaro Limited
+//
+// Based on msm-rng.c and downstream driver
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Device specific register offsets */
+#define PRNG_DATA_OUT  0x
+#define PRNG_STATUS0x0004
+#define PRNG_LFSR_CFG  0x0100
+#define PRNG_CONFIG0x0104
+
+/* Device specific register masks and config values */
+#define PRNG_LFSR_CFG_MASK 0x
+#define PRNG_LFSR_CFG_CLOCKS   0x
+#define PRNG_CONFIG_HW_ENABLE  BIT(1)
+#define PRNG_STATUS_DATA_AVAIL BIT(0)
+
+#define WORD_SZ4
+
+struct qcom_rng {
+   struct mutex lock;
+   void __iomem *base;
+   struct clk *clk;
+};
+
+struct qcom_rng_ctx {
+   struct qcom_rng *rng;
+};
+
+static struct qcom_rng *qcom_rng_dev;
+
+static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max)
+{
+   unsigned int currsize = 0;
+   u32 val;
+
+   /* read random data from hardware */
+   do {
+   val = readl_relaxed(rng->base + PRNG_STATUS);
+   if (!(val & PRNG_STATUS_DATA_AVAIL))
+   break;
+
+   val = readl_relaxed(rng->base + PRNG_DATA_OUT);
+   if (!val)
+   break;
+
+   if ((max - currsize) >= WORD_SZ) {
+   memcpy(data, , WORD_SZ);
+   data += WORD_SZ;
+   currsize += WORD_SZ;
+   } else {
+   /* copy only remaining bytes */
+   memcpy(data, , max - currsize);
+   break;
+   }
+   } while (currsize < max);
+
+   return currsize;
+}
+
+static int qcom_rng_generate(struct crypto_rng *tfm,
+const u8 *src, unsigned int slen,
+u8 *dstn, unsigned int dlen)
+{
+   struct qcom_rng_ctx *ctx = crypto_rng_ctx(tfm);
+   struct qcom_rng *rng = ctx->rng;
+   int ret;
+
+   ret = clk_prepare_enable(rng->clk);
+   if (ret)
+   return ret;
+
+   mutex_lock(>lock);
+
+   ret = qcom_rng_read(rng, dstn, dlen);
+
+   mutex_unlock(>lock);
+   clk_disable_unprepare(rng->clk);
+
+   return 0;
+}
+
+static int qcom_rng_seed(struct crypto_rng *tfm, const u8 *seed,
+unsigned int slen)
+{
+   return 0;
+}
+
+static int qcom_rng_enable(struct qcom_rng *rng)
+{
+   u32 val;
+   int ret;
+
+   ret = clk_prepare_enable(rng->clk);
+   if (ret)
+   return ret;
+
+   /* Enable PRNG only if it is not already enabled */
+   val = readl_relaxed(rng->base + PRNG_CONFIG);
+   if (val & PRNG_CONFIG_HW_ENABLE)
+   goto already_enabled;
+
+   val = readl_relaxed(rng->base + PRNG_LFSR_CFG);
+   val &= ~PRNG_LFSR_CFG_MASK;
+   val |= PRNG_LFSR_CFG_CLOCKS;
+   writel(val, 

[PATCH v6 6/6] crypto: qcom: Add ACPI support

2018-07-15 Thread Vinod Koul
From: Timur Tabi 

Add support for probing on ACPI systems, with ACPI HID QCOM8160.

On ACPI systems, clocks are always enabled, the PRNG should
already be enabled, and the register region is read-only.
The driver only verifies that the hardware is already
enabled never tries to disable or configure it.

Signed-off-by: Timur Tabi 
Tested-by: Jeffrey Hugo 
[port to crypto API]
Signed-off-by: Vinod Koul 
---
 drivers/crypto/qcom-rng.c | 20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/qcom-rng.c b/drivers/crypto/qcom-rng.c
index 80544326e310..e54249ccc009 100644
--- a/drivers/crypto/qcom-rng.c
+++ b/drivers/crypto/qcom-rng.c
@@ -4,6 +4,7 @@
 // Based on msm-rng.c and downstream driver
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -168,9 +169,13 @@ static int qcom_rng_probe(struct platform_device *pdev)
if (IS_ERR(rng->base))
return PTR_ERR(rng->base);
 
-   rng->clk = devm_clk_get(>dev, "core");
-   if (IS_ERR(rng->clk))
-   return PTR_ERR(rng->clk);
+   /* ACPI systems have clk already on, so skip clk_get */
+   if (!has_acpi_companion(>dev)) {
+   rng->clk = devm_clk_get(>dev, "core");
+   if (IS_ERR(rng->clk))
+   return PTR_ERR(rng->clk);
+   }
+
 
rng->skip_init = (unsigned long)device_get_match_data(>dev);
 
@@ -193,6 +198,14 @@ static int qcom_rng_remove(struct platform_device *pdev)
return 0;
 }
 
+#if IS_ENABLED(CONFIG_ACPI)
+static const struct acpi_device_id qcom_rng_acpi_match[] = {
+   { .id = "QCOM8160", .driver_data = 1 },
+   {}
+};
+MODULE_DEVICE_TABLE(acpi, qcom_rng_acpi_match);
+#endif
+
 static const struct of_device_id qcom_rng_of_match[] = {
{ .compatible = "qcom,prng", .data = (void *)0},
{ .compatible = "qcom,prng-ee", .data = (void *)1},
@@ -206,6 +219,7 @@ static struct platform_driver qcom_rng_driver = {
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = of_match_ptr(qcom_rng_of_match),
+   .acpi_match_table = ACPI_PTR(qcom_rng_acpi_match),
}
 };
 module_platform_driver(qcom_rng_driver);
-- 
2.14.4



[PATCH v6 0/6] crypto: Add Qcom PRNG support

2018-07-15 Thread Vinod Koul
This series removes the hwrng qcom driver and replaces it with crypto qcom
driver and then adds support for Execution Environment (EE) found in v2
version of the hardware and ACPI support for these

Changes in v6:
 - Fix a typo in kconfig. Remove of_device.h and add of.h header
 - Add review and tested tags

Changes in v5:
 - Update ACPI check and use generic driver data API

Changes in v4:
 - Use memcpy for data copy
 - Fix trailing bytes copy
 - Fix ACPI ID table name

Timur Tabi (1):
  crypto: qcom: Add ACPI support

Vinod Koul (5):
  hwrng: remove msm hw_random driver
  dt-bindings: crypto: Move prng binding to crypto
  crypto: Add Qcom prng driver
  dt-bindings: crypto: Add new compatible qcom,prng-ee
  crypto: qcom: Add support for prng-ee

 .../bindings/{rng => crypto}/qcom,prng.txt |   4 +-
 drivers/char/hw_random/Kconfig |  13 --
 drivers/char/hw_random/Makefile|   1 -
 drivers/char/hw_random/msm-rng.c   | 183 
 drivers/crypto/Kconfig |  11 +
 drivers/crypto/Makefile|   1 +
 drivers/crypto/qcom-rng.c  | 229 +
 7 files changed, 244 insertions(+), 198 deletions(-)
 rename Documentation/devicetree/bindings/{rng => crypto}/qcom,prng.txt (73%)
 delete mode 100644 drivers/char/hw_random/msm-rng.c
 create mode 100644 drivers/crypto/qcom-rng.c

-- 
2.14.4



[PATCH v6 2/6] dt-bindings: crypto: Move prng binding to crypto

2018-07-15 Thread Vinod Koul
Now that we are adding new driver for prng in crypto, move the
binding as well.

Signed-off-by: Vinod Koul 
---
 Documentation/devicetree/bindings/{rng => crypto}/qcom,prng.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Documentation/devicetree/bindings/{rng => crypto}/qcom,prng.txt (100%)

diff --git a/Documentation/devicetree/bindings/rng/qcom,prng.txt 
b/Documentation/devicetree/bindings/crypto/qcom,prng.txt
similarity index 100%
rename from Documentation/devicetree/bindings/rng/qcom,prng.txt
rename to Documentation/devicetree/bindings/crypto/qcom,prng.txt
-- 
2.14.4



Re: [PATCH] crypto: Add 0 walk-offset check in scatterwalk_pagedone()

2018-07-15 Thread Eric Biggers
Hi Liu,

On Mon, Jul 09, 2018 at 05:10:19PM +0800, Liu Chao wrote:
> From: Luo Xinqiang 
> 
> In function scatterwalk_pagedone(), a kernel panic of invalid
> page will occur if walk->offset equals 0. This patch fixes the
> problem by setting the page addresswith sg_page(walk->sg)
> directly if walk->offset equals 0.
> 
> Panic call stack:
> [] blkcipher_walk_done+0x430/0x8dc
> [] blkcipher_walk_next+0x750/0x9e8
> [] blkcipher_walk_first+0x110/0x2c0
> [] blkcipher_walk_virt+0xcc/0xe0
> [] cbc_decrypt+0xdc/0x1a8
> [] ablk_decrypt+0x138/0x224
> [] skcipher_decrypt_ablkcipher+0x130/0x150
> [] skcipher_recvmsg_sync.isra.17+0x270/0x404
> [] skcipher_recvmsg+0x98/0xb8
> [] SyS_recvfrom+0x2ac/0x2fc
> [] el0_svc_naked+0x34/0x38
> 
> Test: do syskaller fuzz test on 4.9 & 4.4
> 
> Signed-off-by: Gao Kui 
> Signed-off-by: Luo Xinqiang 
> ---
>  crypto/scatterwalk.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
> index bc769c4..a265907 100644
> --- a/crypto/scatterwalk.c
> +++ b/crypto/scatterwalk.c
> @@ -53,7 +53,11 @@ static void scatterwalk_pagedone(struct scatter_walk 
> *walk, int out,
>   if (out) {
>   struct page *page;
>  
> - page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
> + if (likely(walk->offset))
> + page = sg_page(walk->sg) +
> + ((walk->offset - 1) >> PAGE_SHIFT);
> + else
> + page = sg_page(walk->sg);
>   /* Test ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE first as
>* PageSlab cannot be optimised away per se due to
>* use of volatile pointer.

Interesting, I guess the reason this wasn't found by syzbot yet is that syzbot
currently only runs on x86, where ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE isn't
defined.  Otherwise this crash reproduces on the latest kernel by running the
following program:

#include 
#include 
#include 

int main()
{
struct sockaddr_alg addr = {
.salg_type = "skcipher",
.salg_name = "cbc(aes)",
};
int algfd, reqfd;
char buffer[4096] __attribute__((aligned(4096))) = { 0 };

algfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
bind(algfd, (void *), sizeof(addr));
setsockopt(algfd, SOL_ALG, ALG_SET_KEY, buffer, 32);
reqfd = accept(algfd, NULL, NULL);
write(reqfd, buffer, 15);
read(reqfd, buffer, 15);
}

I don't think your fix makes sense though, because if walk->offset = 0 then no
data was processed, so there would be no need to flush any page at all.  I think
the original intent was that scatterwalk_pagedone() only be called when a
nonzero length was processed.  So a better fix is probably to update
blkcipher_walk_done() (and skcipher_walk_done() and ablkcipher_walk_done()) to
avoid calling scatterwalk_pagedone() in the error case where no bytes were
processed.  I'm working on that fix but it's not ready quite yet.

Thanks!

- Eric