Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

Pull crypto update from Herbert Xu:
 - add multibuffer infrastructure (single_task_running scheduler helper,
   OKed by Peter on lkml.
 - add SHA1 multibuffer implementation for AVX2.
 - reenable "by8" AVX CTR optimisation after fixing counter overflow.
 - add APM X-Gene SoC RNG support.
 - SHA256/SHA512 now handles unaligned input correctly.
 - set lz4 decompressed length correctly.
 - fix algif socket buffer allocation failure for 64K page machines.
 - misc fixes

* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (47 commits)
  crypto: sha - Handle unaligned input data in generic sha256 and sha512.
  Revert "crypto: aesni - disable "by8" AVX CTR optimization"
  crypto: aesni - remove unused defines in "by8" variant
  crypto: aesni - fix counter overflow handling in "by8" variant
  hwrng: printk replacement
  crypto: qat - Removed unneeded partial state
  crypto: qat - Fix typo in name of tasklet_struct
  crypto: caam - Dynamic allocation of addresses for various memory blocks in CAAM.
  crypto: mcryptd - Fix typos in CRYPTO_MCRYPTD description
  crypto: algif - avoid excessive use of socket buffer in skcipher
  arm64: dts: add random number generator dts node to APM X-Gene platform.
  Documentation: rng: Add X-Gene SoC RNG driver documentation
  hwrng: xgene - add support for APM X-Gene SoC RNG support
  crypto: mv_cesa - Add missing #define
  crypto: testmgr - add test for lz4 and lz4hc
  crypto: lz4,lz4hc - fix decompression
  crypto: qat - Use pci_enable_msix_exact() instead of pci_enable_msix()
  crypto: drbg - fix maximum value checks on 32 bit systems
  crypto: drbg - fix sparse warning for cpu_to_be[32|64]
  crypto: sha-mb - sha1_mb_alg_state can be static
  ...
This commit is contained in:
Linus Torvalds
2014-10-08 06:44:48 -04:00
50 changed files with 4723 additions and 854 deletions
+30
View File
@@ -158,6 +158,20 @@ config CRYPTO_CRYPTD
converts an arbitrary synchronous software crypto algorithm
into an asynchronous algorithm that executes in a kernel thread.
config CRYPTO_MCRYPTD
tristate "Software async multi-buffer crypto daemon"
select CRYPTO_BLKCIPHER
select CRYPTO_HASH
select CRYPTO_MANAGER
select CRYPTO_WORKQUEUE
help
This is a generic software asynchronous crypto daemon that
provides the kernel thread to assist multi-buffer crypto
algorithms for submitting jobs and flushing jobs in multi-buffer
crypto algorithms. Multi-buffer crypto algorithms are executed
in the context of this kernel thread and drivers can post
their crypto request asynchronously to be processed by this daemon.
config CRYPTO_AUTHENC
tristate "Authenc support"
select CRYPTO_AEAD
@@ -559,6 +573,22 @@ config CRYPTO_SHA1_PPC
This is the powerpc hardware accelerated implementation of the
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
config CRYPTO_SHA1_MB
tristate "SHA1 digest algorithm (x86_64 Multi-Buffer, Experimental)"
depends on X86 && 64BIT
select CRYPTO_SHA1
select CRYPTO_HASH
select CRYPTO_MCRYPTD
help
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
using multi-buffer technique. This algorithm computes on
multiple data lanes concurrently with SIMD instructions for
better throughput. It should not be enabled by default but
used when there is significant amount of work to keep the keep
the data lanes filled to get performance benefit. If the data
lanes remain unfilled, a flush operation will be initiated to
process the crypto jobs, adding a slight latency.
config CRYPTO_SHA256
tristate "SHA224 and SHA256 digest algorithm"
select CRYPTO_HASH
+1
View File
@@ -60,6 +60,7 @@ obj-$(CONFIG_CRYPTO_GCM) += gcm.o
obj-$(CONFIG_CRYPTO_CCM) += ccm.o
obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o
obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
obj-$(CONFIG_CRYPTO_MCRYPTD) += mcryptd.o
obj-$(CONFIG_CRYPTO_DES) += des_generic.o
obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o
obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish_generic.o
+9 -3
View File
@@ -131,8 +131,10 @@ int crypto_hash_walk_first(struct ahash_request *req,
{
walk->total = req->nbytes;
if (!walk->total)
if (!walk->total) {
walk->entrylen = 0;
return 0;
}
walk->alignmask = crypto_ahash_alignmask(crypto_ahash_reqtfm(req));
walk->sg = req->src;
@@ -147,8 +149,10 @@ int crypto_ahash_walk_first(struct ahash_request *req,
{
walk->total = req->nbytes;
if (!walk->total)
if (!walk->total) {
walk->entrylen = 0;
return 0;
}
walk->alignmask = crypto_ahash_alignmask(crypto_ahash_reqtfm(req));
walk->sg = req->src;
@@ -167,8 +171,10 @@ int crypto_hash_walk_first_compat(struct hash_desc *hdesc,
{
walk->total = len;
if (!walk->total)
if (!walk->total) {
walk->entrylen = 0;
return 0;
}
walk->alignmask = crypto_hash_alignmask(hdesc->tfm);
walk->sg = sg;
+1 -1
View File
@@ -49,7 +49,7 @@ struct skcipher_ctx {
struct ablkcipher_request req;
};
#define MAX_SGL_ENTS ((PAGE_SIZE - sizeof(struct skcipher_sg_list)) / \
#define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_sg_list)) / \
sizeof(struct scatterlist) - 1)
static inline int skcipher_sndbuf(struct sock *sk)
+40 -90
View File
@@ -117,27 +117,18 @@ static const struct drbg_core drbg_cores[] = {
{
.flags = DRBG_CTR | DRBG_STRENGTH128,
.statelen = 32, /* 256 bits as defined in 10.2.1 */
.max_addtllen = 35,
.max_bits = 19,
.max_req = 48,
.blocklen_bytes = 16,
.cra_name = "ctr_aes128",
.backend_cra_name = "ecb(aes)",
}, {
.flags = DRBG_CTR | DRBG_STRENGTH192,
.statelen = 40, /* 320 bits as defined in 10.2.1 */
.max_addtllen = 35,
.max_bits = 19,
.max_req = 48,
.blocklen_bytes = 16,
.cra_name = "ctr_aes192",
.backend_cra_name = "ecb(aes)",
}, {
.flags = DRBG_CTR | DRBG_STRENGTH256,
.statelen = 48, /* 384 bits as defined in 10.2.1 */
.max_addtllen = 35,
.max_bits = 19,
.max_req = 48,
.blocklen_bytes = 16,
.cra_name = "ctr_aes256",
.backend_cra_name = "ecb(aes)",
@@ -147,36 +138,24 @@ static const struct drbg_core drbg_cores[] = {
{
.flags = DRBG_HASH | DRBG_STRENGTH128,
.statelen = 55, /* 440 bits */
.max_addtllen = 35,
.max_bits = 19,
.max_req = 48,
.blocklen_bytes = 20,
.cra_name = "sha1",
.backend_cra_name = "sha1",
}, {
.flags = DRBG_HASH | DRBG_STRENGTH256,
.statelen = 111, /* 888 bits */
.max_addtllen = 35,
.max_bits = 19,
.max_req = 48,
.blocklen_bytes = 48,
.cra_name = "sha384",
.backend_cra_name = "sha384",
}, {
.flags = DRBG_HASH | DRBG_STRENGTH256,
.statelen = 111, /* 888 bits */
.max_addtllen = 35,
.max_bits = 19,
.max_req = 48,
.blocklen_bytes = 64,
.cra_name = "sha512",
.backend_cra_name = "sha512",
}, {
.flags = DRBG_HASH | DRBG_STRENGTH256,
.statelen = 55, /* 440 bits */
.max_addtllen = 35,
.max_bits = 19,
.max_req = 48,
.blocklen_bytes = 32,
.cra_name = "sha256",
.backend_cra_name = "sha256",
@@ -186,36 +165,24 @@ static const struct drbg_core drbg_cores[] = {
{
.flags = DRBG_HMAC | DRBG_STRENGTH128,
.statelen = 20, /* block length of cipher */
.max_addtllen = 35,
.max_bits = 19,
.max_req = 48,
.blocklen_bytes = 20,
.cra_name = "hmac_sha1",
.backend_cra_name = "hmac(sha1)",
}, {
.flags = DRBG_HMAC | DRBG_STRENGTH256,
.statelen = 48, /* block length of cipher */
.max_addtllen = 35,
.max_bits = 19,
.max_req = 48,
.blocklen_bytes = 48,
.cra_name = "hmac_sha384",
.backend_cra_name = "hmac(sha384)",
}, {
.flags = DRBG_HMAC | DRBG_STRENGTH256,
.statelen = 64, /* block length of cipher */
.max_addtllen = 35,
.max_bits = 19,
.max_req = 48,
.blocklen_bytes = 64,
.cra_name = "hmac_sha512",
.backend_cra_name = "hmac(sha512)",
}, {
.flags = DRBG_HMAC | DRBG_STRENGTH256,
.statelen = 32, /* block length of cipher */
.max_addtllen = 35,
.max_bits = 19,
.max_req = 48,
.blocklen_bytes = 32,
.cra_name = "hmac_sha256",
.backend_cra_name = "hmac(sha256)",
@@ -302,20 +269,19 @@ static bool drbg_fips_continuous_test(struct drbg_state *drbg,
* Convert an integer into a byte representation of this integer.
* The byte representation is big-endian
*
* @buf buffer holding the converted integer
* @val value to be converted
* @buflen length of buffer
* @buf buffer holding the converted integer -- caller must ensure that
* buffer size is at least 32 bit
*/
#if (defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_CTR))
static inline void drbg_int2byte(unsigned char *buf, uint64_t val,
size_t buflen)
static inline void drbg_cpu_to_be32(__u32 val, unsigned char *buf)
{
unsigned char *byte;
uint64_t i;
struct s {
__be32 conv;
};
struct s *conversion = (struct s *) buf;
byte = buf + (buflen - 1);
for (i = 0; i < buflen; i++)
*(byte--) = val >> (i * 8) & 0xff;
conversion->conv = cpu_to_be32(val);
}
/*
@@ -483,10 +449,10 @@ static int drbg_ctr_df(struct drbg_state *drbg,
/* 10.4.2 step 2 -- calculate the entire length of all input data */
list_for_each_entry(seed, seedlist, list)
inputlen += seed->len;
drbg_int2byte(&L_N[0], inputlen, 4);
drbg_cpu_to_be32(inputlen, &L_N[0]);
/* 10.4.2 step 3 */
drbg_int2byte(&L_N[4], bytes_to_return, 4);
drbg_cpu_to_be32(bytes_to_return, &L_N[4]);
/* 10.4.2 step 5: length is L_N, input_string, one byte, padding */
padlen = (inputlen + sizeof(L_N) + 1) % (drbg_blocklen(drbg));
@@ -517,7 +483,7 @@ static int drbg_ctr_df(struct drbg_state *drbg,
* holds zeros after allocation -- even the increment of i
* is irrelevant as the increment remains within length of i
*/
drbg_int2byte(iv, i, 4);
drbg_cpu_to_be32(i, iv);
/* 10.4.2 step 9.2 -- BCC and concatenation with temp */
ret = drbg_ctr_bcc(drbg, temp + templen, K, &bcc_list);
if (ret)
@@ -729,11 +695,9 @@ static int drbg_hmac_update(struct drbg_state *drbg, struct list_head *seed,
LIST_HEAD(seedlist);
LIST_HEAD(vdatalist);
if (!reseed) {
/* 10.1.2.3 step 2 */
memset(drbg->C, 0, drbg_statelen(drbg));
if (!reseed)
/* 10.1.2.3 step 2 -- memset(0) of C is implicit with kzalloc */
memset(drbg->V, 1, drbg_statelen(drbg));
}
drbg_string_fill(&seed1, drbg->V, drbg_statelen(drbg));
list_add_tail(&seed1.list, &seedlist);
@@ -862,7 +826,7 @@ static int drbg_hash_df(struct drbg_state *drbg,
/* 10.4.1 step 3 */
input[0] = 1;
drbg_int2byte(&input[1], (outlen * 8), 4);
drbg_cpu_to_be32((outlen * 8), &input[1]);
/* 10.4.1 step 4.1 -- concatenation of data for input into hash */
drbg_string_fill(&data, input, 5);
@@ -1023,7 +987,10 @@ static int drbg_hash_generate(struct drbg_state *drbg,
{
int len = 0;
int ret = 0;
unsigned char req[8];
union {
unsigned char req[8];
__be64 req_int;
} u;
unsigned char prefix = DRBG_PREFIX3;
struct drbg_string data1, data2;
LIST_HEAD(datalist);
@@ -1053,8 +1020,8 @@ static int drbg_hash_generate(struct drbg_state *drbg,
drbg->scratchpad, drbg_blocklen(drbg));
drbg_add_buf(drbg->V, drbg_statelen(drbg),
drbg->C, drbg_statelen(drbg));
drbg_int2byte(req, drbg->reseed_ctr, sizeof(req));
drbg_add_buf(drbg->V, drbg_statelen(drbg), req, 8);
u.req_int = cpu_to_be64(drbg->reseed_ctr);
drbg_add_buf(drbg->V, drbg_statelen(drbg), u.req, 8);
out:
memset(drbg->scratchpad, 0, drbg_blocklen(drbg));
@@ -1142,6 +1109,11 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
pr_devel("DRBG: using personalization string\n");
}
if (!reseed) {
memset(drbg->V, 0, drbg_statelen(drbg));
memset(drbg->C, 0, drbg_statelen(drbg));
}
ret = drbg->d_ops->update(drbg, &seedlist, reseed);
if (ret)
goto out;
@@ -1151,8 +1123,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
drbg->reseed_ctr = 1;
out:
if (entropy)
kzfree(entropy);
kzfree(entropy);
return ret;
}
@@ -1161,19 +1132,15 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg)
{
if (!drbg)
return;
if (drbg->V)
kzfree(drbg->V);
kzfree(drbg->V);
drbg->V = NULL;
if (drbg->C)
kzfree(drbg->C);
kzfree(drbg->C);
drbg->C = NULL;
if (drbg->scratchpad)
kzfree(drbg->scratchpad);
kzfree(drbg->scratchpad);
drbg->scratchpad = NULL;
drbg->reseed_ctr = 0;
#ifdef CONFIG_CRYPTO_FIPS
if (drbg->prev)
kzfree(drbg->prev);
kzfree(drbg->prev);
drbg->prev = NULL;
drbg->fips_primed = false;
#endif
@@ -1188,17 +1155,14 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
int ret = -ENOMEM;
unsigned int sb_size = 0;
if (!drbg)
return -EINVAL;
drbg->V = kzalloc(drbg_statelen(drbg), GFP_KERNEL);
drbg->V = kmalloc(drbg_statelen(drbg), GFP_KERNEL);
if (!drbg->V)
goto err;
drbg->C = kzalloc(drbg_statelen(drbg), GFP_KERNEL);
drbg->C = kmalloc(drbg_statelen(drbg), GFP_KERNEL);
if (!drbg->C)
goto err;
#ifdef CONFIG_CRYPTO_FIPS
drbg->prev = kzalloc(drbg_blocklen(drbg), GFP_KERNEL);
drbg->prev = kmalloc(drbg_blocklen(drbg), GFP_KERNEL);
if (!drbg->prev)
goto err;
drbg->fips_primed = false;
@@ -1263,15 +1227,6 @@ static int drbg_make_shadow(struct drbg_state *drbg, struct drbg_state **shadow)
int ret = -ENOMEM;
struct drbg_state *tmp = NULL;
if (!drbg || !drbg->core || !drbg->V || !drbg->C) {
pr_devel("DRBG: attempt to generate shadow copy for "
"uninitialized DRBG state rejected\n");
return -EINVAL;
}
/* HMAC does not have a scratchpad */
if (!(drbg->core->flags & DRBG_HMAC) && NULL == drbg->scratchpad)
return -EINVAL;
tmp = kzalloc(sizeof(struct drbg_state), GFP_KERNEL);
if (!tmp)
return -ENOMEM;
@@ -1293,8 +1248,7 @@ static int drbg_make_shadow(struct drbg_state *drbg, struct drbg_state **shadow)
return 0;
err:
if (tmp)
kzfree(tmp);
kzfree(tmp);
return ret;
}
@@ -1385,11 +1339,9 @@ static int drbg_generate(struct drbg_state *drbg,
shadow->seeded = false;
/* allocate cipher handle */
if (shadow->d_ops->crypto_init) {
len = shadow->d_ops->crypto_init(shadow);
if (len)
goto err;
}
len = shadow->d_ops->crypto_init(shadow);
if (len)
goto err;
if (shadow->pr || !shadow->seeded) {
pr_devel("DRBG: reseeding before generation (prediction "
@@ -1471,8 +1423,7 @@ static int drbg_generate(struct drbg_state *drbg,
#endif
err:
if (shadow->d_ops->crypto_fini)
shadow->d_ops->crypto_fini(shadow);
shadow->d_ops->crypto_fini(shadow);
drbg_restore_shadow(drbg, &shadow);
return len;
}
@@ -1566,11 +1517,10 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
return ret;
ret = -EFAULT;
if (drbg->d_ops->crypto_init && drbg->d_ops->crypto_init(drbg))
if (drbg->d_ops->crypto_init(drbg))
goto err;
ret = drbg_seed(drbg, pers, false);
if (drbg->d_ops->crypto_fini)
drbg->d_ops->crypto_fini(drbg);
drbg->d_ops->crypto_fini(drbg);
if (ret)
goto err;
+1 -1
View File
@@ -68,7 +68,7 @@ static int lz4_decompress_crypto(struct crypto_tfm *tfm, const u8 *src,
size_t tmp_len = *dlen;
size_t __slen = slen;
err = lz4_decompress(src, &__slen, dst, tmp_len);
err = lz4_decompress_unknownoutputsize(src, __slen, dst, &tmp_len);
if (err < 0)
return -EINVAL;
+1 -1
View File
@@ -68,7 +68,7 @@ static int lz4hc_decompress_crypto(struct crypto_tfm *tfm, const u8 *src,
size_t tmp_len = *dlen;
size_t __slen = slen;
err = lz4_decompress(src, &__slen, dst, tmp_len);
err = lz4_decompress_unknownoutputsize(src, __slen, dst, &tmp_len);
if (err < 0)
return -EINVAL;
+705
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -24,6 +24,7 @@
#include <linux/types.h>
#include <crypto/sha.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
static inline u32 Ch(u32 x, u32 y, u32 z)
{
@@ -42,7 +43,7 @@ static inline u32 Maj(u32 x, u32 y, u32 z)
static inline void LOAD_OP(int I, u32 *W, const u8 *input)
{
W[I] = __be32_to_cpu( ((__be32*)(input))[I] );
W[I] = get_unaligned_be32((__u32 *)input + I);
}
static inline void BLEND_OP(int I, u32 *W)
+2 -1
View File
@@ -20,6 +20,7 @@
#include <crypto/sha.h>
#include <linux/percpu.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
static inline u64 Ch(u64 x, u64 y, u64 z)
{
@@ -68,7 +69,7 @@ static const u64 sha512_K[80] = {
static inline void LOAD_OP(int I, u64 *W, const u8 *input)
{
W[I] = __be64_to_cpu( ((__be64*)(input))[I] );
W[I] = get_unaligned_be64((__u64 *)input + I);
}
static inline void BLEND_OP(int I, u64 *W)
+498 -502
View File
File diff suppressed because it is too large Load Diff
+66
View File
@@ -29473,4 +29473,70 @@ static struct hash_testvec bfin_crc_tv_template[] = {
};
#define LZ4_COMP_TEST_VECTORS 1
#define LZ4_DECOMP_TEST_VECTORS 1
static struct comp_testvec lz4_comp_tv_template[] = {
{
.inlen = 70,
.outlen = 45,
.input = "Join us now and share the software "
"Join us now and share the software ",
.output = "\xf0\x10\x4a\x6f\x69\x6e\x20\x75"
"\x73\x20\x6e\x6f\x77\x20\x61\x6e"
"\x64\x20\x73\x68\x61\x72\x65\x20"
"\x74\x68\x65\x20\x73\x6f\x66\x74"
"\x77\x0d\x00\x0f\x23\x00\x0b\x50"
"\x77\x61\x72\x65\x20",
},
};
static struct comp_testvec lz4_decomp_tv_template[] = {
{
.inlen = 45,
.outlen = 70,
.input = "\xf0\x10\x4a\x6f\x69\x6e\x20\x75"
"\x73\x20\x6e\x6f\x77\x20\x61\x6e"
"\x64\x20\x73\x68\x61\x72\x65\x20"
"\x74\x68\x65\x20\x73\x6f\x66\x74"
"\x77\x0d\x00\x0f\x23\x00\x0b\x50"
"\x77\x61\x72\x65\x20",
.output = "Join us now and share the software "
"Join us now and share the software ",
},
};
#define LZ4HC_COMP_TEST_VECTORS 1
#define LZ4HC_DECOMP_TEST_VECTORS 1
static struct comp_testvec lz4hc_comp_tv_template[] = {
{
.inlen = 70,
.outlen = 45,
.input = "Join us now and share the software "
"Join us now and share the software ",
.output = "\xf0\x10\x4a\x6f\x69\x6e\x20\x75"
"\x73\x20\x6e\x6f\x77\x20\x61\x6e"
"\x64\x20\x73\x68\x61\x72\x65\x20"
"\x74\x68\x65\x20\x73\x6f\x66\x74"
"\x77\x0d\x00\x0f\x23\x00\x0b\x50"
"\x77\x61\x72\x65\x20",
},
};
static struct comp_testvec lz4hc_decomp_tv_template[] = {
{
.inlen = 45,
.outlen = 70,
.input = "\xf0\x10\x4a\x6f\x69\x6e\x20\x75"
"\x73\x20\x6e\x6f\x77\x20\x61\x6e"
"\x64\x20\x73\x68\x61\x72\x65\x20"
"\x74\x68\x65\x20\x73\x6f\x66\x74"
"\x77\x0d\x00\x0f\x23\x00\x0b\x50"
"\x77\x61\x72\x65\x20",
.output = "Join us now and share the software "
"Join us now and share the software ",
},
};
#endif /* _CRYPTO_TESTMGR_H */