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

Pull crypto update from Herbert Xu:
 "API:
   - Try to catch hash output overrun in testmgr
   - Introduce walksize attribute for batched walking
   - Make crypto_xor() and crypto_inc() alignment agnostic

  Algorithms:
   - Add time-invariant AES algorithm
   - Add standalone CBCMAC algorithm

  Drivers:
   - Add NEON acclerated chacha20 on ARM/ARM64
   - Expose AES-CTR as synchronous skcipher on ARM64
   - Add scalar AES implementation on ARM64
   - Improve scalar AES implementation on ARM
   - Improve NEON AES implementation on ARM/ARM64
   - Merge CRC32 and PMULL instruction based drivers on ARM64
   - Add NEON acclerated CBCMAC/CMAC/XCBC AES on ARM64
   - Add IPsec AUTHENC implementation in atmel
   - Add Support for Octeon-tx CPT Engine
   - Add Broadcom SPU driver
   - Add MediaTek driver"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (142 commits)
  crypto: xts - Add ECB dependency
  crypto: cavium - switch to pci_alloc_irq_vectors
  crypto: cavium - switch to pci_alloc_irq_vectors
  crypto: cavium - remove dead MSI-X related define
  crypto: brcm - Avoid double free in ahash_finup()
  crypto: cavium - fix Kconfig dependencies
  crypto: cavium - cpt_bind_vq_to_grp could return an error code
  crypto: doc - fix typo
  hwrng: omap - update Kconfig help description
  crypto: ccm - drop unnecessary minimum 32-bit alignment
  crypto: ccm - honour alignmask of subordinate MAC cipher
  crypto: caam - fix state buffer DMA (un)mapping
  crypto: caam - abstract ahash request double buffering
  crypto: caam - fix error path for ctx_dma mapping failure
  crypto: caam - fix DMA API leaks for multiple setkey() calls
  crypto: caam - don't dma_map key for hash algorithms
  crypto: caam - use dma_map_sg() return code
  crypto: caam - replace sg_count() with sg_nents_for_len()
  crypto: caam - check sg_count() return value
  crypto: caam - fix HW S/G in ablkcipher_giv_edesc_alloc()
  ..
这个提交包含在:
Linus Torvalds
2017-02-23 09:54:19 -08:00
当前提交 5bcbe22ca4
修改 187 个文件,包含 26974 行新增9589 行删除

查看文件

@@ -172,8 +172,8 @@ config HW_RANDOM_OMAP
default HW_RANDOM
---help---
This driver provides kernel-side support for the Random Number
Generator hardware found on OMAP16xx, OMAP2/3/4/5 and AM33xx/AM43xx
multimedia processors.
Generator hardware found on OMAP16xx, OMAP2/3/4/5, AM33xx/AM43xx
multimedia processors, and Marvell Armada 7k/8k SoCs.
To compile this driver as a module, choose M here: the
module will be called omap-rng.

查看文件

@@ -57,7 +57,11 @@ static int cavium_rng_probe_vf(struct pci_dev *pdev,
return -ENOMEM;
}
rng->ops.name = "cavium rng";
rng->ops.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
"cavium-rng-%s", dev_name(&pdev->dev));
if (!rng->ops.name)
return -ENOMEM;
rng->ops.read = cavium_rng_read;
rng->ops.quality = 1000;

查看文件

@@ -1,55 +1,30 @@
/*
Added support for the AMD Geode LX RNG
(c) Copyright 2004-2005 Advanced Micro Devices, Inc.
derived from
Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
(c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
derived from
Hardware driver for the AMD 768 Random Number Generator (RNG)
(c) Copyright 2001 Red Hat Inc <alan@redhat.com>
derived from
Hardware driver for Intel i810 Random Number Generator (RNG)
Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
Added generic RNG API
Copyright 2006 Michael Buesch <m@bues.ch>
Copyright 2005 (c) MontaVista Software, Inc.
Please read Documentation/hw_random.txt for details on use.
----------------------------------------------------------
This software may be used and distributed according to the terms
of the GNU General Public License, incorporated herein by reference.
* hw_random/core.c: HWRNG core API
*
* Copyright 2006 Michael Buesch <m@bues.ch>
* Copyright 2005 (c) MontaVista Software, Inc.
*
* Please read Documentation/hw_random.txt for details on use.
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*/
#include <linux/device.h>
#include <linux/hw_random.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/miscdevice.h>
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/hw_random.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#define RNG_MODULE_NAME "hw_random"
#define PFX RNG_MODULE_NAME ": "
#define RNG_MISCDEV_MINOR 183 /* official */
static struct hwrng *current_rng;
static struct task_struct *hwrng_fill;
@@ -296,7 +271,6 @@ out_put:
goto out;
}
static const struct file_operations rng_chrdev_ops = {
.owner = THIS_MODULE,
.open = rng_dev_open,
@@ -307,14 +281,13 @@ static const struct file_operations rng_chrdev_ops = {
static const struct attribute_group *rng_dev_groups[];
static struct miscdevice rng_miscdev = {
.minor = RNG_MISCDEV_MINOR,
.minor = HWRNG_MINOR,
.name = RNG_MODULE_NAME,
.nodename = "hwrng",
.fops = &rng_chrdev_ops,
.groups = rng_dev_groups,
};
static ssize_t hwrng_attr_current_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
@@ -444,8 +417,7 @@ int hwrng_register(struct hwrng *rng)
int err = -EINVAL;
struct hwrng *old_rng, *tmp;
if (rng->name == NULL ||
(rng->data_read == NULL && rng->read == NULL))
if (!rng->name || (!rng->data_read && !rng->read))
goto out;
mutex_lock(&rng_mutex);

查看文件

@@ -21,11 +21,11 @@
#define DRV_MODULE_NAME "n2rng"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "0.2"
#define DRV_MODULE_RELDATE "July 27, 2011"
#define DRV_MODULE_VERSION "0.3"
#define DRV_MODULE_RELDATE "Jan 7, 2017"
static char version[] =
DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
MODULE_DESCRIPTION("Niagara2 RNG driver");
@@ -302,26 +302,57 @@ static int n2rng_try_read_ctl(struct n2rng *np)
return n2rng_hv_err_trans(hv_err);
}
#define CONTROL_DEFAULT_BASE \
((2 << RNG_CTL_ASEL_SHIFT) | \
(N2RNG_ACCUM_CYCLES_DEFAULT << RNG_CTL_WAIT_SHIFT) | \
RNG_CTL_LFSR)
static u64 n2rng_control_default(struct n2rng *np, int ctl)
{
u64 val = 0;
#define CONTROL_DEFAULT_0 \
(CONTROL_DEFAULT_BASE | \
(1 << RNG_CTL_VCO_SHIFT) | \
RNG_CTL_ES1)
#define CONTROL_DEFAULT_1 \
(CONTROL_DEFAULT_BASE | \
(2 << RNG_CTL_VCO_SHIFT) | \
RNG_CTL_ES2)
#define CONTROL_DEFAULT_2 \
(CONTROL_DEFAULT_BASE | \
(3 << RNG_CTL_VCO_SHIFT) | \
RNG_CTL_ES3)
#define CONTROL_DEFAULT_3 \
(CONTROL_DEFAULT_BASE | \
RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3)
if (np->data->chip_version == 1) {
val = ((2 << RNG_v1_CTL_ASEL_SHIFT) |
(N2RNG_ACCUM_CYCLES_DEFAULT << RNG_v1_CTL_WAIT_SHIFT) |
RNG_CTL_LFSR);
switch (ctl) {
case 0:
val |= (1 << RNG_v1_CTL_VCO_SHIFT) | RNG_CTL_ES1;
break;
case 1:
val |= (2 << RNG_v1_CTL_VCO_SHIFT) | RNG_CTL_ES2;
break;
case 2:
val |= (3 << RNG_v1_CTL_VCO_SHIFT) | RNG_CTL_ES3;
break;
case 3:
val |= RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3;
break;
default:
break;
}
} else {
val = ((2 << RNG_v2_CTL_ASEL_SHIFT) |
(N2RNG_ACCUM_CYCLES_DEFAULT << RNG_v2_CTL_WAIT_SHIFT) |
RNG_CTL_LFSR);
switch (ctl) {
case 0:
val |= (1 << RNG_v2_CTL_VCO_SHIFT) | RNG_CTL_ES1;
break;
case 1:
val |= (2 << RNG_v2_CTL_VCO_SHIFT) | RNG_CTL_ES2;
break;
case 2:
val |= (3 << RNG_v2_CTL_VCO_SHIFT) | RNG_CTL_ES3;
break;
case 3:
val |= RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3;
break;
default:
break;
}
}
return val;
}
static void n2rng_control_swstate_init(struct n2rng *np)
{
@@ -336,10 +367,10 @@ static void n2rng_control_swstate_init(struct n2rng *np)
for (i = 0; i < np->num_units; i++) {
struct n2rng_unit *up = &np->units[i];
up->control[0] = CONTROL_DEFAULT_0;
up->control[1] = CONTROL_DEFAULT_1;
up->control[2] = CONTROL_DEFAULT_2;
up->control[3] = CONTROL_DEFAULT_3;
up->control[0] = n2rng_control_default(np, 0);
up->control[1] = n2rng_control_default(np, 1);
up->control[2] = n2rng_control_default(np, 2);
up->control[3] = n2rng_control_default(np, 3);
}
np->hv_state = HV_RNG_STATE_UNCONFIGURED;
@@ -399,6 +430,7 @@ static int n2rng_data_read(struct hwrng *rng, u32 *data)
} else {
int err = n2rng_generic_read_data(ra);
if (!err) {
np->flags |= N2RNG_FLAG_BUFFER_VALID;
np->buffer = np->test_data >> 32;
*data = np->test_data & 0xffffffff;
len = 4;
@@ -487,9 +519,21 @@ static void n2rng_dump_test_buffer(struct n2rng *np)
static int n2rng_check_selftest_buffer(struct n2rng *np, unsigned long unit)
{
u64 val = SELFTEST_VAL;
u64 val;
int err, matches, limit;
switch (np->data->id) {
case N2_n2_rng:
case N2_vf_rng:
case N2_kt_rng:
case N2_m4_rng: /* yes, m4 uses the old value */
val = RNG_v1_SELFTEST_VAL;
break;
default:
val = RNG_v2_SELFTEST_VAL;
break;
}
matches = 0;
for (limit = 0; limit < SELFTEST_LOOPS_MAX; limit++) {
matches += n2rng_test_buffer_find(np, val);
@@ -512,14 +556,32 @@ static int n2rng_check_selftest_buffer(struct n2rng *np, unsigned long unit)
static int n2rng_control_selftest(struct n2rng *np, unsigned long unit)
{
int err;
u64 base, base3;
np->test_control[0] = (0x2 << RNG_CTL_ASEL_SHIFT);
np->test_control[1] = (0x2 << RNG_CTL_ASEL_SHIFT);
np->test_control[2] = (0x2 << RNG_CTL_ASEL_SHIFT);
np->test_control[3] = ((0x2 << RNG_CTL_ASEL_SHIFT) |
RNG_CTL_LFSR |
((SELFTEST_TICKS - 2) << RNG_CTL_WAIT_SHIFT));
switch (np->data->id) {
case N2_n2_rng:
case N2_vf_rng:
case N2_kt_rng:
base = RNG_v1_CTL_ASEL_NOOUT << RNG_v1_CTL_ASEL_SHIFT;
base3 = base | RNG_CTL_LFSR |
((RNG_v1_SELFTEST_TICKS - 2) << RNG_v1_CTL_WAIT_SHIFT);
break;
case N2_m4_rng:
base = RNG_v2_CTL_ASEL_NOOUT << RNG_v2_CTL_ASEL_SHIFT;
base3 = base | RNG_CTL_LFSR |
((RNG_v1_SELFTEST_TICKS - 2) << RNG_v2_CTL_WAIT_SHIFT);
break;
default:
base = RNG_v2_CTL_ASEL_NOOUT << RNG_v2_CTL_ASEL_SHIFT;
base3 = base | RNG_CTL_LFSR |
(RNG_v2_SELFTEST_TICKS << RNG_v2_CTL_WAIT_SHIFT);
break;
}
np->test_control[0] = base;
np->test_control[1] = base;
np->test_control[2] = base;
np->test_control[3] = base3;
err = n2rng_entropy_diag_read(np, unit, np->test_control,
HV_RNG_STATE_HEALTHCHECK,
@@ -557,11 +619,19 @@ static int n2rng_control_configure_units(struct n2rng *np)
struct n2rng_unit *up = &np->units[unit];
unsigned long ctl_ra = __pa(&up->control[0]);
int esrc;
u64 base;
u64 base, shift;
base = ((np->accum_cycles << RNG_CTL_WAIT_SHIFT) |
(2 << RNG_CTL_ASEL_SHIFT) |
RNG_CTL_LFSR);
if (np->data->chip_version == 1) {
base = ((np->accum_cycles << RNG_v1_CTL_WAIT_SHIFT) |
(RNG_v1_CTL_ASEL_NOOUT << RNG_v1_CTL_ASEL_SHIFT) |
RNG_CTL_LFSR);
shift = RNG_v1_CTL_VCO_SHIFT;
} else {
base = ((np->accum_cycles << RNG_v2_CTL_WAIT_SHIFT) |
(RNG_v2_CTL_ASEL_NOOUT << RNG_v2_CTL_ASEL_SHIFT) |
RNG_CTL_LFSR);
shift = RNG_v2_CTL_VCO_SHIFT;
}
/* XXX This isn't the best. We should fetch a bunch
* XXX of words using each entropy source combined XXX
@@ -570,7 +640,7 @@ static int n2rng_control_configure_units(struct n2rng *np)
*/
for (esrc = 0; esrc < 3; esrc++)
up->control[esrc] = base |
(esrc << RNG_CTL_VCO_SHIFT) |
(esrc << shift) |
(RNG_CTL_ES1 << esrc);
up->control[3] = base |
@@ -589,6 +659,7 @@ static void n2rng_work(struct work_struct *work)
{
struct n2rng *np = container_of(work, struct n2rng, work.work);
int err = 0;
static int retries = 4;
if (!(np->flags & N2RNG_FLAG_CONTROL)) {
err = n2rng_guest_check(np);
@@ -606,7 +677,9 @@ static void n2rng_work(struct work_struct *work)
dev_info(&np->op->dev, "RNG ready\n");
}
if (err && !(np->flags & N2RNG_FLAG_SHUTDOWN))
if (--retries == 0)
dev_err(&np->op->dev, "Self-test retries failed, RNG not ready\n");
else if (err && !(np->flags & N2RNG_FLAG_SHUTDOWN))
schedule_delayed_work(&np->work, HZ * 2);
}
@@ -622,24 +695,23 @@ static const struct of_device_id n2rng_match[];
static int n2rng_probe(struct platform_device *op)
{
const struct of_device_id *match;
int multi_capable;
int err = -ENOMEM;
struct n2rng *np;
match = of_match_device(n2rng_match, &op->dev);
if (!match)
return -EINVAL;
multi_capable = (match->data != NULL);
n2rng_driver_version();
np = devm_kzalloc(&op->dev, sizeof(*np), GFP_KERNEL);
if (!np)
goto out;
np->op = op;
np->data = (struct n2rng_template *)match->data;
INIT_DELAYED_WORK(&np->work, n2rng_work);
if (multi_capable)
if (np->data->multi_capable)
np->flags |= N2RNG_FLAG_MULTI;
err = -ENODEV;
@@ -670,8 +742,9 @@ static int n2rng_probe(struct platform_device *op)
dev_err(&op->dev, "VF RNG lacks rng-#units property\n");
goto out_hvapi_unregister;
}
} else
} else {
np->num_units = 1;
}
dev_info(&op->dev, "Registered RNG HVAPI major %lu minor %lu\n",
np->hvapi_major, np->hvapi_minor);
@@ -692,7 +765,7 @@ static int n2rng_probe(struct platform_device *op)
"multi-unit-capable" : "single-unit"),
np->num_units);
np->hwrng.name = "n2rng";
np->hwrng.name = DRV_MODULE_NAME;
np->hwrng.data_read = n2rng_data_read;
np->hwrng.priv = (unsigned long) np;
@@ -728,30 +801,61 @@ static int n2rng_remove(struct platform_device *op)
return 0;
}
static struct n2rng_template n2_template = {
.id = N2_n2_rng,
.multi_capable = 0,
.chip_version = 1,
};
static struct n2rng_template vf_template = {
.id = N2_vf_rng,
.multi_capable = 1,
.chip_version = 1,
};
static struct n2rng_template kt_template = {
.id = N2_kt_rng,
.multi_capable = 1,
.chip_version = 1,
};
static struct n2rng_template m4_template = {
.id = N2_m4_rng,
.multi_capable = 1,
.chip_version = 2,
};
static struct n2rng_template m7_template = {
.id = N2_m7_rng,
.multi_capable = 1,
.chip_version = 2,
};
static const struct of_device_id n2rng_match[] = {
{
.name = "random-number-generator",
.compatible = "SUNW,n2-rng",
.data = &n2_template,
},
{
.name = "random-number-generator",
.compatible = "SUNW,vf-rng",
.data = (void *) 1,
.data = &vf_template,
},
{
.name = "random-number-generator",
.compatible = "SUNW,kt-rng",
.data = (void *) 1,
.data = &kt_template,
},
{
.name = "random-number-generator",
.compatible = "ORCL,m4-rng",
.data = (void *) 1,
.data = &m4_template,
},
{
.name = "random-number-generator",
.compatible = "ORCL,m7-rng",
.data = (void *) 1,
.data = &m7_template,
},
{},
};

查看文件

@@ -6,18 +6,34 @@
#ifndef _N2RNG_H
#define _N2RNG_H
#define RNG_CTL_WAIT 0x0000000001fffe00ULL /* Minimum wait time */
#define RNG_CTL_WAIT_SHIFT 9
#define RNG_CTL_BYPASS 0x0000000000000100ULL /* VCO voltage source */
#define RNG_CTL_VCO 0x00000000000000c0ULL /* VCO rate control */
#define RNG_CTL_VCO_SHIFT 6
#define RNG_CTL_ASEL 0x0000000000000030ULL /* Analog MUX select */
#define RNG_CTL_ASEL_SHIFT 4
/* ver1 devices - n2-rng, vf-rng, kt-rng */
#define RNG_v1_CTL_WAIT 0x0000000001fffe00ULL /* Minimum wait time */
#define RNG_v1_CTL_WAIT_SHIFT 9
#define RNG_v1_CTL_BYPASS 0x0000000000000100ULL /* VCO voltage source */
#define RNG_v1_CTL_VCO 0x00000000000000c0ULL /* VCO rate control */
#define RNG_v1_CTL_VCO_SHIFT 6
#define RNG_v1_CTL_ASEL 0x0000000000000030ULL /* Analog MUX select */
#define RNG_v1_CTL_ASEL_SHIFT 4
#define RNG_v1_CTL_ASEL_NOOUT 2
/* these are the same in v2 as in v1 */
#define RNG_CTL_LFSR 0x0000000000000008ULL /* Use LFSR or plain shift */
#define RNG_CTL_ES3 0x0000000000000004ULL /* Enable entropy source 3 */
#define RNG_CTL_ES2 0x0000000000000002ULL /* Enable entropy source 2 */
#define RNG_CTL_ES1 0x0000000000000001ULL /* Enable entropy source 1 */
/* ver2 devices - m4-rng, m7-rng */
#define RNG_v2_CTL_WAIT 0x0000000007fff800ULL /* Minimum wait time */
#define RNG_v2_CTL_WAIT_SHIFT 12
#define RNG_v2_CTL_BYPASS 0x0000000000000400ULL /* VCO voltage source */
#define RNG_v2_CTL_VCO 0x0000000000000300ULL /* VCO rate control */
#define RNG_v2_CTL_VCO_SHIFT 9
#define RNG_v2_CTL_PERF 0x0000000000000180ULL /* Perf */
#define RNG_v2_CTL_ASEL 0x0000000000000070ULL /* Analog MUX select */
#define RNG_v2_CTL_ASEL_SHIFT 4
#define RNG_v2_CTL_ASEL_NOOUT 7
#define HV_FAST_RNG_GET_DIAG_CTL 0x130
#define HV_FAST_RNG_CTL_READ 0x131
#define HV_FAST_RNG_CTL_WRITE 0x132
@@ -60,6 +76,20 @@ extern unsigned long sun4v_rng_data_read_diag_v2(unsigned long data_ra,
extern unsigned long sun4v_rng_data_read(unsigned long data_ra,
unsigned long *tick_delta);
enum n2rng_compat_id {
N2_n2_rng,
N2_vf_rng,
N2_kt_rng,
N2_m4_rng,
N2_m7_rng,
};
struct n2rng_template {
enum n2rng_compat_id id;
int multi_capable;
int chip_version;
};
struct n2rng_unit {
u64 control[HV_RNG_NUM_CONTROL];
};
@@ -74,6 +104,7 @@ struct n2rng {
#define N2RNG_FLAG_SHUTDOWN 0x00000010 /* Driver unregistering */
#define N2RNG_FLAG_BUFFER_VALID 0x00000020 /* u32 buffer holds valid data */
struct n2rng_template *data;
int num_units;
struct n2rng_unit *units;
@@ -97,8 +128,10 @@ struct n2rng {
u64 scratch_control[HV_RNG_NUM_CONTROL];
#define SELFTEST_TICKS 38859
#define SELFTEST_VAL ((u64)0xB8820C7BD387E32C)
#define RNG_v1_SELFTEST_TICKS 38859
#define RNG_v1_SELFTEST_VAL ((u64)0xB8820C7BD387E32C)
#define RNG_v2_SELFTEST_TICKS 64
#define RNG_v2_SELFTEST_VAL ((u64)0xffffffffffffffff)
#define SELFTEST_POLY ((u64)0x231DCEE91262B8A3)
#define SELFTEST_MATCH_GOAL 6
#define SELFTEST_LOOPS_MAX 40000