Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

Pull crypto updates from Herbert Xu:
 "API:
   - Add support for allocating transforms on a specific NUMA Node
   - Introduce the flag CRYPTO_ALG_ALLOCATES_MEMORY for storage users

  Algorithms:
   - Drop PMULL based ghash on arm64
   - Fixes for building with clang on x86
   - Add sha256 helper that does the digest in one go
   - Add SP800-56A rev 3 validation checks to dh

  Drivers:
   - Permit users to specify NUMA node in hisilicon/zip
   - Add support for i.MX6 in imx-rngc
   - Add sa2ul crypto driver
   - Add BA431 hwrng driver
   - Add Ingenic JZ4780 and X1000 hwrng driver
   - Spread IRQ affinity in inside-secure and marvell/cesa"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (157 commits)
  crypto: sa2ul - Fix inconsistent IS_ERR and PTR_ERR
  hwrng: core - remove redundant initialization of variable ret
  crypto: x86/curve25519 - Remove unused carry variables
  crypto: ingenic - Add hardware RNG for Ingenic JZ4780 and X1000
  dt-bindings: RNG: Add Ingenic RNG bindings.
  crypto: caam/qi2 - add module alias
  crypto: caam - add more RNG hw error codes
  crypto: caam/jr - remove incorrect reference to caam_jr_register()
  crypto: caam - silence .setkey in case of bad key length
  crypto: caam/qi2 - create ahash shared descriptors only once
  crypto: caam/qi2 - fix error reporting for caam_hash_alloc
  crypto: caam - remove deadcode on 32-bit platforms
  crypto: ccp - use generic power management
  crypto: xts - Replace memcpy() invocation with simple assignment
  crypto: marvell/cesa - irq balance
  crypto: inside-secure - irq balance
  crypto: ecc - SP800-56A rev 3 local public key validation
  crypto: dh - SP800-56A rev 3 local public key validation
  crypto: dh - check validity of Z before export
  lib/mpi: Add mpi_sub_ui()
  ...
This commit is contained in:
Linus Torvalds
2020-08-03 10:40:14 -07:00
257 changed files with 6651 additions and 5500 deletions

View File

@@ -74,6 +74,16 @@ config HW_RANDOM_ATMEL
If unsure, say Y.
config HW_RANDOM_BA431
tristate "Silex Insight BA431 Random Number Generator support"
depends on HAS_IOMEM
help
This driver provides kernel-side support for the Random Number
Generator hardware based on Silex Insight BA431 IP.
To compile this driver as a module, choose M here: the
module will be called ba431-rng.
config HW_RANDOM_BCM2835
tristate "Broadcom BCM2835/BCM63xx Random Number Generator support"
depends on ARCH_BCM2835 || ARCH_BCM_NSP || ARCH_BCM_5301X || \
@@ -245,7 +255,7 @@ config HW_RANDOM_MXC_RNGA
config HW_RANDOM_IMX_RNGC
tristate "Freescale i.MX RNGC Random Number Generator"
depends on HAS_IOMEM && HAVE_CLK
depends on SOC_IMX25 || COMPILE_TEST
depends on SOC_IMX25 || SOC_IMX6SL || SOC_IMX6SLL || SOC_IMX6UL || COMPILE_TEST
default HW_RANDOM
help
This driver provides kernel-side support for the Random Number
@@ -257,6 +267,21 @@ config HW_RANDOM_IMX_RNGC
If unsure, say Y.
config HW_RANDOM_INGENIC_RNG
tristate "Ingenic Random Number Generator support"
depends on HW_RANDOM
depends on MACH_JZ4780 || MACH_X1000
default HW_RANDOM
help
This driver provides kernel-side support for the Random Number Generator
hardware found in ingenic JZ4780 and X1000 SoC. MIPS Creator CI20 uses
JZ4780 SoC, YSH & ATIL CU1000-Neo uses X1000 SoC.
To compile this driver as a module, choose M here: the
module will be called ingenic-rng.
If unsure, say Y.
config HW_RANDOM_NOMADIK
tristate "ST-Ericsson Nomadik Random Number Generator support"
depends on ARCH_NOMADIK

View File

@@ -9,6 +9,7 @@ obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o
obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
obj-$(CONFIG_HW_RANDOM_ATMEL) += atmel-rng.o
obj-$(CONFIG_HW_RANDOM_BA431) += ba431-rng.o
obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o
n2-rng-y := n2-drv.o n2-asm.o
@@ -22,6 +23,7 @@ obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
obj-$(CONFIG_HW_RANDOM_IMX_RNGC) += imx-rngc.o
obj-$(CONFIG_HW_RANDOM_INGENIC_RNG) += ingenic-rng.o
obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o

View File

@@ -0,0 +1,235 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Silex Insight
#include <linux/delay.h>
#include <linux/hw_random.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#define BA431_RESET_DELAY 1 /* usec */
#define BA431_RESET_READ_STATUS_TIMEOUT 1000 /* usec */
#define BA431_RESET_READ_STATUS_INTERVAL 10 /* usec */
#define BA431_READ_RETRY_INTERVAL 1 /* usec */
#define BA431_REG_CTRL 0x00
#define BA431_REG_FIFO_LEVEL 0x04
#define BA431_REG_STATUS 0x30
#define BA431_REG_FIFODATA 0x80
#define BA431_CTRL_ENABLE BIT(0)
#define BA431_CTRL_SOFTRESET BIT(8)
#define BA431_STATUS_STATE_MASK (BIT(1) | BIT(2) | BIT(3))
#define BA431_STATUS_STATE_OFFSET 1
enum ba431_state {
BA431_STATE_RESET,
BA431_STATE_STARTUP,
BA431_STATE_FIFOFULLON,
BA431_STATE_FIFOFULLOFF,
BA431_STATE_RUNNING,
BA431_STATE_ERROR
};
struct ba431_trng {
struct device *dev;
void __iomem *base;
struct hwrng rng;
atomic_t reset_pending;
struct work_struct reset_work;
};
static inline u32 ba431_trng_read_reg(struct ba431_trng *ba431, u32 reg)
{
return ioread32(ba431->base + reg);
}
static inline void ba431_trng_write_reg(struct ba431_trng *ba431, u32 reg,
u32 val)
{
iowrite32(val, ba431->base + reg);
}
static inline enum ba431_state ba431_trng_get_state(struct ba431_trng *ba431)
{
u32 status = ba431_trng_read_reg(ba431, BA431_REG_STATUS);
return (status & BA431_STATUS_STATE_MASK) >> BA431_STATUS_STATE_OFFSET;
}
static int ba431_trng_is_in_error(struct ba431_trng *ba431)
{
enum ba431_state state = ba431_trng_get_state(ba431);
if ((state < BA431_STATE_STARTUP) ||
(state >= BA431_STATE_ERROR))
return 1;
return 0;
}
static int ba431_trng_reset(struct ba431_trng *ba431)
{
int ret;
/* Disable interrupts, random generation and enable the softreset */
ba431_trng_write_reg(ba431, BA431_REG_CTRL, BA431_CTRL_SOFTRESET);
udelay(BA431_RESET_DELAY);
ba431_trng_write_reg(ba431, BA431_REG_CTRL, BA431_CTRL_ENABLE);
/* Wait until the state changed */
if (readx_poll_timeout(ba431_trng_is_in_error, ba431, ret, !ret,
BA431_RESET_READ_STATUS_INTERVAL,
BA431_RESET_READ_STATUS_TIMEOUT)) {
dev_err(ba431->dev, "reset failed (state: %d)\n",
ba431_trng_get_state(ba431));
return -ETIMEDOUT;
}
dev_info(ba431->dev, "reset done\n");
return 0;
}
static void ba431_trng_reset_work(struct work_struct *work)
{
struct ba431_trng *ba431 = container_of(work, struct ba431_trng,
reset_work);
ba431_trng_reset(ba431);
atomic_set(&ba431->reset_pending, 0);
}
static void ba431_trng_schedule_reset(struct ba431_trng *ba431)
{
if (atomic_cmpxchg(&ba431->reset_pending, 0, 1))
return;
schedule_work(&ba431->reset_work);
}
static int ba431_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
{
struct ba431_trng *ba431 = container_of(rng, struct ba431_trng, rng);
u32 *data = buf;
unsigned int level, i;
int n = 0;
while (max > 0) {
level = ba431_trng_read_reg(ba431, BA431_REG_FIFO_LEVEL);
if (!level) {
if (ba431_trng_is_in_error(ba431)) {
ba431_trng_schedule_reset(ba431);
break;
}
if (!wait)
break;
udelay(BA431_READ_RETRY_INTERVAL);
continue;
}
i = level;
do {
data[n++] = ba431_trng_read_reg(ba431,
BA431_REG_FIFODATA);
max -= sizeof(*data);
} while (--i && (max > 0));
if (ba431_trng_is_in_error(ba431)) {
n -= (level - i);
ba431_trng_schedule_reset(ba431);
break;
}
}
n *= sizeof(data);
return (n || !wait) ? n : -EIO;
}
static void ba431_trng_cleanup(struct hwrng *rng)
{
struct ba431_trng *ba431 = container_of(rng, struct ba431_trng, rng);
ba431_trng_write_reg(ba431, BA431_REG_CTRL, 0);
cancel_work_sync(&ba431->reset_work);
}
static int ba431_trng_init(struct hwrng *rng)
{
struct ba431_trng *ba431 = container_of(rng, struct ba431_trng, rng);
return ba431_trng_reset(ba431);
}
static int ba431_trng_probe(struct platform_device *pdev)
{
struct ba431_trng *ba431;
struct resource *res;
int ret;
ba431 = devm_kzalloc(&pdev->dev, sizeof(*ba431), GFP_KERNEL);
if (!ba431)
return -ENOMEM;
ba431->dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ba431->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(ba431->base))
return PTR_ERR(ba431->base);
atomic_set(&ba431->reset_pending, 0);
INIT_WORK(&ba431->reset_work, ba431_trng_reset_work);
ba431->rng.name = pdev->name;
ba431->rng.init = ba431_trng_init;
ba431->rng.cleanup = ba431_trng_cleanup;
ba431->rng.read = ba431_trng_read;
platform_set_drvdata(pdev, ba431);
ret = hwrng_register(&ba431->rng);
if (ret) {
dev_err(&pdev->dev, "BA431 registration failed (%d)\n", ret);
return ret;
}
dev_info(&pdev->dev, "BA431 TRNG registered\n");
return 0;
}
static int ba431_trng_remove(struct platform_device *pdev)
{
struct ba431_trng *ba431 = platform_get_drvdata(pdev);
hwrng_unregister(&ba431->rng);
return 0;
}
static const struct of_device_id ba431_trng_dt_ids[] = {
{ .compatible = "silex-insight,ba431-rng", .data = NULL },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ba431_trng_dt_ids);
static struct platform_driver ba431_trng_driver = {
.driver = {
.name = "ba431-rng",
.of_match_table = ba431_trng_dt_ids,
},
.probe = ba431_trng_probe,
.remove = ba431_trng_remove,
};
module_platform_driver(ba431_trng_driver);
MODULE_AUTHOR("Olivier Sobrie <olivier@sobrie.be>");
MODULE_DESCRIPTION("TRNG driver for Silex Insight BA431");
MODULE_LICENSE("GPL");

View File

@@ -139,7 +139,6 @@ static int bcm2835_rng_probe(struct platform_device *pdev)
{
const struct bcm2835_rng_of_data *of_data;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
const struct of_device_id *rng_id;
struct bcm2835_rng_priv *priv;
int err;
@@ -166,7 +165,7 @@ static int bcm2835_rng_probe(struct platform_device *pdev)
priv->rng.cleanup = bcm2835_rng_cleanup;
if (dev_of_node(dev)) {
rng_id = of_match_node(bcm2835_rng_of_match, np);
rng_id = of_match_node(bcm2835_rng_of_match, dev->of_node);
if (!rng_id)
return -EINVAL;
@@ -188,7 +187,7 @@ static int bcm2835_rng_probe(struct platform_device *pdev)
MODULE_DEVICE_TABLE(of, bcm2835_rng_of_match);
static struct platform_device_id bcm2835_rng_devtype[] = {
static const struct platform_device_id bcm2835_rng_devtype[] = {
{ .name = "bcm2835-rng" },
{ .name = "bcm63xx-rng" },
{ /* sentinel */ }

View File

@@ -611,7 +611,7 @@ EXPORT_SYMBOL_GPL(devm_hwrng_unregister);
static int __init hwrng_modinit(void)
{
int ret = -ENOMEM;
int ret;
/* kmalloc makes this safe for virt_to_page() in virtio_rng.c */
rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL);

View File

@@ -99,7 +99,7 @@ static int hisi_rng_probe(struct platform_device *pdev)
return 0;
}
static const struct of_device_id hisi_rng_dt_ids[] = {
static const struct of_device_id hisi_rng_dt_ids[] __maybe_unused = {
{ .compatible = "hisilicon,hip04-rng" },
{ .compatible = "hisilicon,hip05-rng" },
{ }

View File

@@ -0,0 +1,154 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Ingenic Random Number Generator driver
* Copyright (c) 2017 PrasannaKumar Muralidharan <prasannatsmkumar@gmail.com>
* Copyright (c) 2020 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
*/
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/hw_random.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
/* RNG register offsets */
#define RNG_REG_ERNG_OFFSET 0x0
#define RNG_REG_RNG_OFFSET 0x4
/* bits within the ERND register */
#define ERNG_READY BIT(31)
#define ERNG_ENABLE BIT(0)
enum ingenic_rng_version {
ID_JZ4780,
ID_X1000,
};
/* Device associated memory */
struct ingenic_rng {
enum ingenic_rng_version version;
void __iomem *base;
struct hwrng rng;
};
static int ingenic_rng_init(struct hwrng *rng)
{
struct ingenic_rng *priv = container_of(rng, struct ingenic_rng, rng);
writel(ERNG_ENABLE, priv->base + RNG_REG_ERNG_OFFSET);
return 0;
}
static void ingenic_rng_cleanup(struct hwrng *rng)
{
struct ingenic_rng *priv = container_of(rng, struct ingenic_rng, rng);
writel(0, priv->base + RNG_REG_ERNG_OFFSET);
}
static int ingenic_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
{
struct ingenic_rng *priv = container_of(rng, struct ingenic_rng, rng);
u32 *data = buf;
u32 status;
int ret;
if (priv->version >= ID_X1000) {
ret = readl_poll_timeout(priv->base + RNG_REG_ERNG_OFFSET, status,
status & ERNG_READY, 10, 1000);
if (ret == -ETIMEDOUT) {
pr_err("%s: Wait for RNG data ready timeout\n", __func__);
return ret;
}
} else {
/*
* 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.
*/
udelay(20);
}
*data = readl(priv->base + RNG_REG_RNG_OFFSET);
return 4;
}
static int ingenic_rng_probe(struct platform_device *pdev)
{
struct ingenic_rng *priv;
int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base)) {
pr_err("%s: Failed to map RNG registers\n", __func__);
ret = PTR_ERR(priv->base);
goto err_free_rng;
}
priv->version = (enum ingenic_rng_version)of_device_get_match_data(&pdev->dev);
priv->rng.name = pdev->name;
priv->rng.init = ingenic_rng_init;
priv->rng.cleanup = ingenic_rng_cleanup;
priv->rng.read = ingenic_rng_read;
ret = hwrng_register(&priv->rng);
if (ret) {
dev_err(&pdev->dev, "Failed to register hwrng\n");
goto err_free_rng;
}
platform_set_drvdata(pdev, priv);
dev_info(&pdev->dev, "Ingenic RNG driver registered\n");
return 0;
err_free_rng:
kfree(priv);
return ret;
}
static int ingenic_rng_remove(struct platform_device *pdev)
{
struct ingenic_rng *priv = platform_get_drvdata(pdev);
hwrng_unregister(&priv->rng);
writel(0, priv->base + RNG_REG_ERNG_OFFSET);
return 0;
}
static const struct of_device_id ingenic_rng_of_match[] = {
{ .compatible = "ingenic,jz4780-rng", .data = (void *) ID_JZ4780 },
{ .compatible = "ingenic,x1000-rng", .data = (void *) ID_X1000 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ingenic_rng_of_match);
static struct platform_driver ingenic_rng_driver = {
.probe = ingenic_rng_probe,
.remove = ingenic_rng_remove,
.driver = {
.name = "ingenic-rng",
.of_match_table = ingenic_rng_of_match,
},
};
module_platform_driver(ingenic_rng_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("PrasannaKumar Muralidharan <prasannatsmkumar@gmail.com>");
MODULE_AUTHOR("周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>");
MODULE_DESCRIPTION("Ingenic Random Number Generator driver");

View File

@@ -2,7 +2,7 @@
/*
* Random Number Generator driver for the Keystone SOC
*
* Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com
* Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com
*
* Authors: Sandeep Nair
* Vitaly Andrianov

View File

@@ -76,7 +76,7 @@ static int nmk_rng_remove(struct amba_device *dev)
return 0;
}
static struct amba_id nmk_rng_ids[] = {
static const struct amba_id nmk_rng_ids[] = {
{
.id = 0x000805e1,
.mask = 0x000fffff, /* top bits are rev and cfg: accept all */

View File

@@ -161,7 +161,7 @@ static const struct dev_pm_ops npcm_rng_pm_ops = {
pm_runtime_force_resume)
};
static const struct of_device_id rng_dt_id[] = {
static const struct of_device_id rng_dt_id[] __maybe_unused = {
{ .compatible = "nuvoton,npcm750-rng", },
{},
};

View File

@@ -33,7 +33,7 @@ static int octeon_rng_init(struct hwrng *rng)
ctl.u64 = 0;
ctl.s.ent_en = 1; /* Enable the entropy source. */
ctl.s.rng_en = 1; /* Enable the RNG hardware. */
cvmx_write_csr((u64)p->control_status, ctl.u64);
cvmx_write_csr((__force u64)p->control_status, ctl.u64);
return 0;
}
@@ -44,14 +44,14 @@ static void octeon_rng_cleanup(struct hwrng *rng)
ctl.u64 = 0;
/* Disable everything. */
cvmx_write_csr((u64)p->control_status, ctl.u64);
cvmx_write_csr((__force u64)p->control_status, ctl.u64);
}
static int octeon_rng_data_read(struct hwrng *rng, u32 *data)
{
struct octeon_rng *p = container_of(rng, struct octeon_rng, ops);
*data = cvmx_read64_uint32((u64)p->result);
*data = cvmx_read64_uint32((__force u64)p->result);
return sizeof(u32);
}

View File

@@ -22,6 +22,7 @@
#include <linux/platform_device.h>
#include <linux/hw_random.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
@@ -243,7 +244,6 @@ static struct omap_rng_pdata omap2_rng_pdata = {
.cleanup = omap2_rng_cleanup,
};
#if defined(CONFIG_OF)
static inline u32 omap4_rng_data_present(struct omap_rng_dev *priv)
{
return omap_rng_read(priv, RNG_STATUS_REG) & RNG_REG_STATUS_RDY;
@@ -358,7 +358,7 @@ static struct omap_rng_pdata eip76_rng_pdata = {
.cleanup = omap4_rng_cleanup,
};
static const struct of_device_id omap_rng_of_match[] = {
static const struct of_device_id omap_rng_of_match[] __maybe_unused = {
{
.compatible = "ti,omap2-rng",
.data = &omap2_rng_pdata,
@@ -418,13 +418,6 @@ static int of_get_omap_rng_device_details(struct omap_rng_dev *priv,
}
return 0;
}
#else
static int of_get_omap_rng_device_details(struct omap_rng_dev *omap_rng,
struct platform_device *pdev)
{
return -EINVAL;
}
#endif
static int get_omap_rng_device_details(struct omap_rng_dev *omap_rng)
{

View File

@@ -119,7 +119,7 @@ static int pic32_rng_remove(struct platform_device *pdev)
return 0;
}
static const struct of_device_id pic32_rng_of_match[] = {
static const struct of_device_id pic32_rng_of_match[] __maybe_unused = {
{ .compatible = "microchip,pic32mzda-rng", },
{ /* sentinel */ }
};

View File

@@ -12,6 +12,7 @@
#include <linux/delay.h>
#include <linux/hw_random.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@@ -121,7 +122,7 @@ static int st_rng_remove(struct platform_device *pdev)
return 0;
}
static const struct of_device_id st_rng_match[] = {
static const struct of_device_id st_rng_match[] __maybe_unused = {
{ .compatible = "st,rng" },
{},
};

View File

@@ -195,7 +195,7 @@ static int virtrng_restore(struct virtio_device *vdev)
}
#endif
static struct virtio_device_id id_table[] = {
static const struct virtio_device_id id_table[] = {
{ VIRTIO_ID_RNG, VIRTIO_DEV_ANY_ID },
{ 0 },
};