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

Pull crypto update from Herbert Xu:
 "API:

   - Crypto self tests can now be disabled at boot/run time.
   - Add async support to algif_aead.

  Algorithms:

   - A large number of fixes to MPI from Nicolai Stange.
   - Performance improvement for HMAC DRBG.

  Drivers:

   - Use generic crypto engine in omap-des.
   - Merge ppc4xx-rng and crypto4xx drivers.
   - Fix lockups in sun4i-ss driver by disabling IRQs.
   - Add DMA engine support to ccp.
   - Reenable talitos hash algorithms.
   - Add support for Hisilicon SoC RNG.
   - Add basic crypto driver for the MXC SCC.

  Others:

   - Do not allocate crypto hash tfm in NORECLAIM context in ecryptfs"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (77 commits)
  crypto: qat - change the adf_ctl_stop_devices to void
  crypto: caam - fix caam_jr_alloc() ret code
  crypto: vmx - comply with ABIs that specify vrsave as reserved.
  crypto: testmgr - Add a flag allowing the self-tests to be disabled at runtime.
  crypto: ccp - constify ccp_actions structure
  crypto: marvell/cesa - Use dma_pool_zalloc
  crypto: qat - make adf_vf_isr.c dependant on IOV config
  crypto: qat - Fix typo in comments
  lib: asn1_decoder - add MODULE_LICENSE("GPL")
  crypto: omap-sham - Use dma_request_chan() for requesting DMA channel
  crypto: omap-des - Use dma_request_chan() for requesting DMA channel
  crypto: omap-aes - Use dma_request_chan() for requesting DMA channel
  crypto: omap-des - Integrate with the crypto engine framework
  crypto: s5p-sss - fix incorrect usage of scatterlists api
  crypto: s5p-sss - Fix missed interrupts when working with 8 kB blocks
  crypto: s5p-sss - Use common BIT macro
  crypto: mxc-scc - fix unwinding in mxc_scc_crypto_register()
  crypto: mxc-scc - signedness bugs in mxc_scc_ablkcipher_req_init()
  crypto: talitos - fix ahash algorithms registration
  crypto: ccp - Ensure all dependencies are specified
  ...
This commit is contained in:
Linus Torvalds
2016-05-17 09:33:39 -07:00
76 changed files with 3092 additions and 778 deletions
+3 -3
View File
@@ -1936,9 +1936,9 @@ static int test_skcipher(void)
}
req = skcipher_request_alloc(skcipher, GFP_KERNEL);
if (IS_ERR(req)) {
pr_info("could not allocate request queue\n");
ret = PTR_ERR(req);
if (!req) {
pr_info("could not allocate skcipher request\n");
ret = -ENOMEM;
goto out;
}
@@ -0,0 +1,21 @@
Freescale Security Controller (SCC)
Required properties:
- compatible : Should be "fsl,imx25-scc".
- reg : Should contain register location and length.
- interrupts : Should contain interrupt numbers for SCM IRQ and SMN IRQ.
- interrupt-names : Should specify the names "scm" and "smn" for the
SCM IRQ and SMN IRQ.
- clocks: Should contain the clock driving the SCC core.
- clock-names: Should be set to "ipg".
Example:
scc: crypto@53fac000 {
compatible = "fsl,imx25-scc";
reg = <0x53fac000 0x4000>;
clocks = <&clks 111>;
clock-names = "ipg";
interrupts = <49>, <50>;
interrupt-names = "scm", "smn";
};
@@ -23,10 +23,8 @@ Required properties:
- "samsung,exynos4210-secss" for Exynos4210, Exynos4212, Exynos4412, Exynos5250,
Exynos5260 and Exynos5420 SoCs.
- reg : Offset and length of the register set for the module
- interrupts : interrupt specifiers of SSS module interrupts, should contain
following entries:
- first : feed control interrupt (required for all variants),
- second : hash interrupt (required only for samsung,s5pv210-secss).
- interrupts : interrupt specifiers of SSS module interrupts (one feed
control interrupt).
- clocks : list of clock phandle and specifier pairs for all clocks listed in
clock-names property.
@@ -0,0 +1,12 @@
Hisilicon Random Number Generator
Required properties:
- compatible : Should be "hisilicon,hip04-rng" or "hisilicon,hip05-rng"
- reg : Offset and length of the register set of this block
Example:
rng@d1010000 {
compatible = "hisilicon,hip05-rng";
reg = <0xd1010000 0x100>;
};
+3
View File
@@ -838,6 +838,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.
cryptomgr.notests
[KNL] Disable crypto self-tests
cs89x0_dma= [HW,NET]
Format: <dma>
+1
View File
@@ -627,6 +627,7 @@ F: include/linux/altera_jtaguart.h
AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER
M: Tom Lendacky <thomas.lendacky@amd.com>
M: Gary Hook <gary.hook@amd.com>
L: linux-crypto@vger.kernel.org
S: Supported
F: drivers/crypto/ccp/
+9
View File
@@ -420,6 +420,15 @@
interrupts = <41>;
};
scc: crypto@53fac000 {
compatible = "fsl,imx25-scc";
reg = <0x53fac000 0x4000>;
clocks = <&clks 111>;
clock-names = "ipg";
interrupts = <49>, <50>;
interrupt-names = "scm", "smn";
};
esdhc1: esdhc@53fb4000 {
compatible = "fsl,imx25-esdhc";
reg = <0x53fb4000 0x4000>;
+237 -31
View File
@@ -13,7 +13,7 @@
* any later version.
*/
#include <crypto/aead.h>
#include <crypto/internal/aead.h>
#include <crypto/scatterwalk.h>
#include <crypto/if_alg.h>
#include <linux/init.h>
@@ -29,15 +29,24 @@ struct aead_sg_list {
struct scatterlist sg[ALG_MAX_PAGES];
};
struct aead_async_rsgl {
struct af_alg_sgl sgl;
struct list_head list;
};
struct aead_async_req {
struct scatterlist *tsgl;
struct aead_async_rsgl first_rsgl;
struct list_head list;
struct kiocb *iocb;
unsigned int tsgls;
char iv[];
};
struct aead_ctx {
struct aead_sg_list tsgl;
/*
* RSGL_MAX_ENTRIES is an artificial limit where user space at maximum
* can cause the kernel to allocate RSGL_MAX_ENTRIES * ALG_MAX_PAGES
* pages
*/
#define RSGL_MAX_ENTRIES ALG_MAX_PAGES
struct af_alg_sgl rsgl[RSGL_MAX_ENTRIES];
struct aead_async_rsgl first_rsgl;
struct list_head list;
void *iv;
@@ -75,6 +84,17 @@ static inline bool aead_sufficient_data(struct aead_ctx *ctx)
return ctx->used >= ctx->aead_assoclen + as;
}
static void aead_reset_ctx(struct aead_ctx *ctx)
{
struct aead_sg_list *sgl = &ctx->tsgl;
sg_init_table(sgl->sg, ALG_MAX_PAGES);
sgl->cur = 0;
ctx->used = 0;
ctx->more = 0;
ctx->merge = 0;
}
static void aead_put_sgl(struct sock *sk)
{
struct alg_sock *ask = alg_sk(sk);
@@ -90,11 +110,7 @@ static void aead_put_sgl(struct sock *sk)
put_page(sg_page(sg + i));
sg_assign_page(sg + i, NULL);
}
sg_init_table(sg, ALG_MAX_PAGES);
sgl->cur = 0;
ctx->used = 0;
ctx->more = 0;
ctx->merge = 0;
aead_reset_ctx(ctx);
}
static void aead_wmem_wakeup(struct sock *sk)
@@ -349,23 +365,188 @@ unlock:
return err ?: size;
}
static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored, int flags)
#define GET_ASYM_REQ(req, tfm) (struct aead_async_req *) \
((char *)req + sizeof(struct aead_request) + \
crypto_aead_reqsize(tfm))
#define GET_REQ_SIZE(tfm) sizeof(struct aead_async_req) + \
crypto_aead_reqsize(tfm) + crypto_aead_ivsize(tfm) + \
sizeof(struct aead_request)
static void aead_async_cb(struct crypto_async_request *_req, int err)
{
struct sock *sk = _req->data;
struct alg_sock *ask = alg_sk(sk);
struct aead_ctx *ctx = ask->private;
struct crypto_aead *tfm = crypto_aead_reqtfm(&ctx->aead_req);
struct aead_request *req = aead_request_cast(_req);
struct aead_async_req *areq = GET_ASYM_REQ(req, tfm);
struct scatterlist *sg = areq->tsgl;
struct aead_async_rsgl *rsgl;
struct kiocb *iocb = areq->iocb;
unsigned int i, reqlen = GET_REQ_SIZE(tfm);
list_for_each_entry(rsgl, &areq->list, list) {
af_alg_free_sg(&rsgl->sgl);
if (rsgl != &areq->first_rsgl)
sock_kfree_s(sk, rsgl, sizeof(*rsgl));
}
for (i = 0; i < areq->tsgls; i++)
put_page(sg_page(sg + i));
sock_kfree_s(sk, areq->tsgl, sizeof(*areq->tsgl) * areq->tsgls);
sock_kfree_s(sk, req, reqlen);
__sock_put(sk);
iocb->ki_complete(iocb, err, err);
}
static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg,
int flags)
{
struct sock *sk = sock->sk;
struct alg_sock *ask = alg_sk(sk);
struct aead_ctx *ctx = ask->private;
struct crypto_aead *tfm = crypto_aead_reqtfm(&ctx->aead_req);
struct aead_async_req *areq;
struct aead_request *req = NULL;
struct aead_sg_list *sgl = &ctx->tsgl;
struct aead_async_rsgl *last_rsgl = NULL, *rsgl;
unsigned int as = crypto_aead_authsize(tfm);
unsigned int i, reqlen = GET_REQ_SIZE(tfm);
int err = -ENOMEM;
unsigned long used;
size_t outlen;
size_t usedpages = 0;
lock_sock(sk);
if (ctx->more) {
err = aead_wait_for_data(sk, flags);
if (err)
goto unlock;
}
used = ctx->used;
outlen = used;
if (!aead_sufficient_data(ctx))
goto unlock;
req = sock_kmalloc(sk, reqlen, GFP_KERNEL);
if (unlikely(!req))
goto unlock;
areq = GET_ASYM_REQ(req, tfm);
memset(&areq->first_rsgl, '\0', sizeof(areq->first_rsgl));
INIT_LIST_HEAD(&areq->list);
areq->iocb = msg->msg_iocb;
memcpy(areq->iv, ctx->iv, crypto_aead_ivsize(tfm));
aead_request_set_tfm(req, tfm);
aead_request_set_ad(req, ctx->aead_assoclen);
aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
aead_async_cb, sk);
used -= ctx->aead_assoclen + (ctx->enc ? as : 0);
/* take over all tx sgls from ctx */
areq->tsgl = sock_kmalloc(sk, sizeof(*areq->tsgl) * sgl->cur,
GFP_KERNEL);
if (unlikely(!areq->tsgl))
goto free;
sg_init_table(areq->tsgl, sgl->cur);
for (i = 0; i < sgl->cur; i++)
sg_set_page(&areq->tsgl[i], sg_page(&sgl->sg[i]),
sgl->sg[i].length, sgl->sg[i].offset);
areq->tsgls = sgl->cur;
/* create rx sgls */
while (iov_iter_count(&msg->msg_iter)) {
size_t seglen = min_t(size_t, iov_iter_count(&msg->msg_iter),
(outlen - usedpages));
if (list_empty(&areq->list)) {
rsgl = &areq->first_rsgl;
} else {
rsgl = sock_kmalloc(sk, sizeof(*rsgl), GFP_KERNEL);
if (unlikely(!rsgl)) {
err = -ENOMEM;
goto free;
}
}
rsgl->sgl.npages = 0;
list_add_tail(&rsgl->list, &areq->list);
/* make one iovec available as scatterlist */
err = af_alg_make_sg(&rsgl->sgl, &msg->msg_iter, seglen);
if (err < 0)
goto free;
usedpages += err;
/* chain the new scatterlist with previous one */
if (last_rsgl)
af_alg_link_sg(&last_rsgl->sgl, &rsgl->sgl);
last_rsgl = rsgl;
/* we do not need more iovecs as we have sufficient memory */
if (outlen <= usedpages)
break;
iov_iter_advance(&msg->msg_iter, err);
}
err = -EINVAL;
/* ensure output buffer is sufficiently large */
if (usedpages < outlen)
goto free;
aead_request_set_crypt(req, areq->tsgl, areq->first_rsgl.sgl.sg, used,
areq->iv);
err = ctx->enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
if (err) {
if (err == -EINPROGRESS) {
sock_hold(sk);
err = -EIOCBQUEUED;
aead_reset_ctx(ctx);
goto unlock;
} else if (err == -EBADMSG) {
aead_put_sgl(sk);
}
goto free;
}
aead_put_sgl(sk);
free:
list_for_each_entry(rsgl, &areq->list, list) {
af_alg_free_sg(&rsgl->sgl);
if (rsgl != &areq->first_rsgl)
sock_kfree_s(sk, rsgl, sizeof(*rsgl));
}
if (areq->tsgl)
sock_kfree_s(sk, areq->tsgl, sizeof(*areq->tsgl) * areq->tsgls);
if (req)
sock_kfree_s(sk, req, reqlen);
unlock:
aead_wmem_wakeup(sk);
release_sock(sk);
return err ? err : outlen;
}
static int aead_recvmsg_sync(struct socket *sock, struct msghdr *msg, int flags)
{
struct sock *sk = sock->sk;
struct alg_sock *ask = alg_sk(sk);
struct aead_ctx *ctx = ask->private;
unsigned as = crypto_aead_authsize(crypto_aead_reqtfm(&ctx->aead_req));
struct aead_sg_list *sgl = &ctx->tsgl;
unsigned int i = 0;
struct aead_async_rsgl *last_rsgl = NULL;
struct aead_async_rsgl *rsgl, *tmp;
int err = -EINVAL;
unsigned long used = 0;
size_t outlen = 0;
size_t usedpages = 0;
unsigned int cnt = 0;
/* Limit number of IOV blocks to be accessed below */
if (msg->msg_iter.nr_segs > RSGL_MAX_ENTRIES)
return -ENOMSG;
lock_sock(sk);
@@ -417,21 +598,33 @@ static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored,
size_t seglen = min_t(size_t, iov_iter_count(&msg->msg_iter),
(outlen - usedpages));
if (list_empty(&ctx->list)) {
rsgl = &ctx->first_rsgl;
} else {
rsgl = sock_kmalloc(sk, sizeof(*rsgl), GFP_KERNEL);
if (unlikely(!rsgl)) {
err = -ENOMEM;
goto unlock;
}
}
rsgl->sgl.npages = 0;
list_add_tail(&rsgl->list, &ctx->list);
/* make one iovec available as scatterlist */
err = af_alg_make_sg(&ctx->rsgl[cnt], &msg->msg_iter,
seglen);
err = af_alg_make_sg(&rsgl->sgl, &msg->msg_iter, seglen);
if (err < 0)
goto unlock;
usedpages += err;
/* chain the new scatterlist with previous one */
if (cnt)
af_alg_link_sg(&ctx->rsgl[cnt-1], &ctx->rsgl[cnt]);
if (last_rsgl)
af_alg_link_sg(&last_rsgl->sgl, &rsgl->sgl);
last_rsgl = rsgl;
/* we do not need more iovecs as we have sufficient memory */
if (outlen <= usedpages)
break;
iov_iter_advance(&msg->msg_iter, err);
cnt++;
}
err = -EINVAL;
@@ -440,8 +633,7 @@ static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored,
goto unlock;
sg_mark_end(sgl->sg + sgl->cur - 1);
aead_request_set_crypt(&ctx->aead_req, sgl->sg, ctx->rsgl[0].sg,
aead_request_set_crypt(&ctx->aead_req, sgl->sg, ctx->first_rsgl.sgl.sg,
used, ctx->iv);
aead_request_set_ad(&ctx->aead_req, ctx->aead_assoclen);
@@ -454,23 +646,35 @@ static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored,
/* EBADMSG implies a valid cipher operation took place */
if (err == -EBADMSG)
aead_put_sgl(sk);
goto unlock;
}
aead_put_sgl(sk);
err = 0;
unlock:
for (i = 0; i < cnt; i++)
af_alg_free_sg(&ctx->rsgl[i]);
list_for_each_entry_safe(rsgl, tmp, &ctx->list, list) {
af_alg_free_sg(&rsgl->sgl);
if (rsgl != &ctx->first_rsgl)
sock_kfree_s(sk, rsgl, sizeof(*rsgl));
list_del(&rsgl->list);
}
INIT_LIST_HEAD(&ctx->list);
aead_wmem_wakeup(sk);
release_sock(sk);
return err ? err : outlen;
}
static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored,
int flags)
{
return (msg->msg_iocb && !is_sync_kiocb(msg->msg_iocb)) ?
aead_recvmsg_async(sock, msg, flags) :
aead_recvmsg_sync(sock, msg, flags);
}
static unsigned int aead_poll(struct file *file, struct socket *sock,
poll_table *wait)
{
@@ -540,6 +744,7 @@ static void aead_sock_destruct(struct sock *sk)
unsigned int ivlen = crypto_aead_ivsize(
crypto_aead_reqtfm(&ctx->aead_req));
WARN_ON(atomic_read(&sk->sk_refcnt) != 0);
aead_put_sgl(sk);
sock_kzfree_s(sk, ctx->iv, ivlen);
sock_kfree_s(sk, ctx, ctx->len);
@@ -574,6 +779,7 @@ static int aead_accept_parent(void *private, struct sock *sk)
ctx->aead_assoclen = 0;
af_alg_init_completion(&ctx->completion);
sg_init_table(ctx->tsgl.sg, ALG_MAX_PAGES);
INIT_LIST_HEAD(&ctx->list);
ask->private = ctx;
+1
View File
@@ -237,6 +237,7 @@ int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen,
break;
case OID_sha224:
ctx->sinfo->sig.hash_algo = "sha224";
break;
default:
printk("Unsupported digest algo: %u\n", ctx->last_oid);
return -ENOPKG;
+25 -14
View File
@@ -592,8 +592,10 @@ static const struct drbg_state_ops drbg_ctr_ops = {
******************************************************************/
#if defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_HMAC)
static int drbg_kcapi_hash(struct drbg_state *drbg, const unsigned char *key,
unsigned char *outval, const struct list_head *in);
static int drbg_kcapi_hash(struct drbg_state *drbg, unsigned char *outval,
const struct list_head *in);
static void drbg_kcapi_hmacsetkey(struct drbg_state *drbg,
const unsigned char *key);
static int drbg_init_hash_kernel(struct drbg_state *drbg);
static int drbg_fini_hash_kernel(struct drbg_state *drbg);
#endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */
@@ -619,9 +621,11 @@ static int drbg_hmac_update(struct drbg_state *drbg, struct list_head *seed,
LIST_HEAD(seedlist);
LIST_HEAD(vdatalist);
if (!reseed)
if (!reseed) {
/* 10.1.2.3 step 2 -- memset(0) of C is implicit with kzalloc */
memset(drbg->V, 1, drbg_statelen(drbg));
drbg_kcapi_hmacsetkey(drbg, drbg->C);
}
drbg_string_fill(&seed1, drbg->V, drbg_statelen(drbg));
list_add_tail(&seed1.list, &seedlist);
@@ -641,12 +645,13 @@ static int drbg_hmac_update(struct drbg_state *drbg, struct list_head *seed,
prefix = DRBG_PREFIX1;
/* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */
seed2.buf = &prefix;
ret = drbg_kcapi_hash(drbg, drbg->C, drbg->C, &seedlist);
ret = drbg_kcapi_hash(drbg, drbg->C, &seedlist);
if (ret)
return ret;
drbg_kcapi_hmacsetkey(drbg, drbg->C);
/* 10.1.2.2 step 2 and 5 -- HMAC for V */
ret = drbg_kcapi_hash(drbg, drbg->C, drbg->V, &vdatalist);
ret = drbg_kcapi_hash(drbg, drbg->V, &vdatalist);
if (ret)
return ret;
@@ -681,7 +686,7 @@ static int drbg_hmac_generate(struct drbg_state *drbg,
while (len < buflen) {
unsigned int outlen = 0;
/* 10.1.2.5 step 4.1 */
ret = drbg_kcapi_hash(drbg, drbg->C, drbg->V, &datalist);
ret = drbg_kcapi_hash(drbg, drbg->V, &datalist);
if (ret)
return ret;
outlen = (drbg_blocklen(drbg) < (buflen - len)) ?
@@ -796,7 +801,7 @@ static int drbg_hash_df(struct drbg_state *drbg,
while (len < outlen) {
short blocklen = 0;
/* 10.4.1 step 4.1 */
ret = drbg_kcapi_hash(drbg, NULL, tmp, entropylist);
ret = drbg_kcapi_hash(drbg, tmp, entropylist);
if (ret)
goto out;
/* 10.4.1 step 4.2 */
@@ -874,7 +879,7 @@ static int drbg_hash_process_addtl(struct drbg_state *drbg,
list_add_tail(&data1.list, &datalist);
list_add_tail(&data2.list, &datalist);
list_splice_tail(addtl, &datalist);
ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &datalist);
ret = drbg_kcapi_hash(drbg, drbg->scratchpad, &datalist);
if (ret)
goto out;
@@ -907,7 +912,7 @@ static int drbg_hash_hashgen(struct drbg_state *drbg,
while (len < buflen) {
unsigned int outlen = 0;
/* 10.1.1.4 step hashgen 4.1 */
ret = drbg_kcapi_hash(drbg, NULL, dst, &datalist);
ret = drbg_kcapi_hash(drbg, dst, &datalist);
if (ret) {
len = ret;
goto out;
@@ -956,7 +961,7 @@ static int drbg_hash_generate(struct drbg_state *drbg,
list_add_tail(&data1.list, &datalist);
drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg));
list_add_tail(&data2.list, &datalist);
ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &datalist);
ret = drbg_kcapi_hash(drbg, drbg->scratchpad, &datalist);
if (ret) {
len = ret;
goto out;
@@ -1600,14 +1605,20 @@ static int drbg_fini_hash_kernel(struct drbg_state *drbg)
return 0;
}
static int drbg_kcapi_hash(struct drbg_state *drbg, const unsigned char *key,
unsigned char *outval, const struct list_head *in)
static void drbg_kcapi_hmacsetkey(struct drbg_state *drbg,
const unsigned char *key)
{
struct sdesc *sdesc = (struct sdesc *)drbg->priv_data;
crypto_shash_setkey(sdesc->shash.tfm, key, drbg_statelen(drbg));
}
static int drbg_kcapi_hash(struct drbg_state *drbg, unsigned char *outval,
const struct list_head *in)
{
struct sdesc *sdesc = (struct sdesc *)drbg->priv_data;
struct drbg_string *input = NULL;
if (key)
crypto_shash_setkey(sdesc->shash.tfm, key, drbg_statelen(drbg));
crypto_shash_init(&sdesc->shash);
list_for_each_entry(input, in, list)
crypto_shash_update(&sdesc->shash, input->buf, input->len);
+1 -1
View File
@@ -32,7 +32,7 @@ static int lzo_init(struct crypto_tfm *tfm)
struct lzo_ctx *ctx = crypto_tfm_ctx(tfm);
ctx->lzo_comp_mem = kmalloc(LZO1X_MEM_COMPRESS,
GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
GFP_KERNEL | __GFP_NOWARN);
if (!ctx->lzo_comp_mem)
ctx->lzo_comp_mem = vmalloc(LZO1X_MEM_COMPRESS);
if (!ctx->lzo_comp_mem)
+9
View File
@@ -35,6 +35,10 @@
#include "internal.h"
static bool notests;
module_param(notests, bool, 0644);
MODULE_PARM_DESC(notests, "disable crypto self-tests");
#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
/* a perfect nop */
@@ -3885,6 +3889,11 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
int j;
int rc;
if (!fips_enabled && notests) {
printk_once(KERN_INFO "alg: self-tests disabled\n");
return 0;
}
alg_test_descs_check_order();
if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
+15 -14
View File
@@ -268,19 +268,6 @@ config HW_RANDOM_NOMADIK
If unsure, say Y.
config HW_RANDOM_PPC4XX
tristate "PowerPC 4xx generic true random number generator support"
depends on PPC && 4xx
default HW_RANDOM
---help---
This driver provides the kernel-side support for the TRNG hardware
found in the security function of some PowerPC 4xx SoCs.
To compile this driver as a module, choose M here: the
module will be called ppc4xx-rng.
If unsure, say N.
config HW_RANDOM_PSERIES
tristate "pSeries HW Random Number Generator support"
depends on PPC64 && IBMVIO
@@ -309,7 +296,8 @@ config HW_RANDOM_POWERNV
config HW_RANDOM_EXYNOS
tristate "EXYNOS HW random number generator support"
depends on ARCH_EXYNOS
depends on ARCH_EXYNOS || COMPILE_TEST
depends on HAS_IOMEM
default HW_RANDOM
---help---
This driver provides kernel-side support for the Random Number
@@ -333,6 +321,19 @@ config HW_RANDOM_TPM
If unsure, say Y.
config HW_RANDOM_HISI
tristate "Hisilicon Random Number Generator support"
depends on HW_RANDOM && ARCH_HISI
default HW_RANDOM
---help---
This driver provides kernel-side support for the Random Number
Generator hardware found on Hisilicon Hip04 and Hip05 SoC.
To compile this driver as a module, choose M here: the
module will be called hisi-rng.
If unsure, say Y.
config HW_RANDOM_MSM
tristate "Qualcomm SoCs Random Number Generator support"
depends on HW_RANDOM && ARCH_QCOM
+1 -1
View File
@@ -22,10 +22,10 @@ obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o
obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o
+27 -6
View File
@@ -2,7 +2,7 @@
* exynos-rng.c - Random Number Generator driver for the exynos
*
* Copyright (C) 2012 Samsung Electronics
* Jonghwa Lee <jonghwa3.lee@smasung.com>
* Jonghwa Lee <jonghwa3.lee@samsung.com>
*
* 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
@@ -77,7 +77,8 @@ static int exynos_init(struct hwrng *rng)
pm_runtime_get_sync(exynos_rng->dev);
ret = exynos_rng_configure(exynos_rng);
pm_runtime_put_noidle(exynos_rng->dev);
pm_runtime_mark_last_busy(exynos_rng->dev);
pm_runtime_put_autosuspend(exynos_rng->dev);
return ret;
}
@@ -89,6 +90,7 @@ static int exynos_read(struct hwrng *rng, void *buf,
struct exynos_rng, rng);
u32 *data = buf;
int retry = 100;
int ret = 4;
pm_runtime_get_sync(exynos_rng->dev);
@@ -97,23 +99,27 @@ static int exynos_read(struct hwrng *rng, void *buf,
while (!(exynos_rng_readl(exynos_rng,
EXYNOS_PRNG_STATUS_OFFSET) & PRNG_DONE) && --retry)
cpu_relax();
if (!retry)
return -ETIMEDOUT;
if (!retry) {
ret = -ETIMEDOUT;
goto out;
}
exynos_rng_writel(exynos_rng, PRNG_DONE, EXYNOS_PRNG_STATUS_OFFSET);
*data = exynos_rng_readl(exynos_rng, EXYNOS_PRNG_OUT1_OFFSET);
out:
pm_runtime_mark_last_busy(exynos_rng->dev);
pm_runtime_put_sync_autosuspend(exynos_rng->dev);
return 4;
return ret;
}
static int exynos_rng_probe(struct platform_device *pdev)
{
struct exynos_rng *exynos_rng;
struct resource *res;
int ret;
exynos_rng = devm_kzalloc(&pdev->dev, sizeof(struct exynos_rng),
GFP_KERNEL);
@@ -141,7 +147,21 @@ static int exynos_rng_probe(struct platform_device *pdev)
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_enable(&pdev->dev);
return devm_hwrng_register(&pdev->dev, &exynos_rng->rng);
ret = devm_hwrng_register(&pdev->dev, &exynos_rng->rng);
if (ret) {
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);
}
return ret;
}
static int exynos_rng_remove(struct platform_device *pdev)
{
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return 0;
}
static int __maybe_unused exynos_rng_runtime_suspend(struct device *dev)
@@ -201,6 +221,7 @@ static struct platform_driver exynos_rng_driver = {
.of_match_table = exynos_rng_dt_match,
},
.probe = exynos_rng_probe,
.remove = exynos_rng_remove,
};
module_platform_driver(exynos_rng_driver);
+126
View File
@@ -0,0 +1,126 @@
/*
* Copyright (C) 2016 HiSilicon Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/hw_random.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/random.h>
#define RNG_SEED 0x0
#define RNG_CTRL 0x4
#define RNG_SEED_SEL BIT(2)
#define RNG_RING_EN BIT(1)
#define RNG_EN BIT(0)
#define RNG_RAN_NUM 0x10
#define RNG_PHY_SEED 0x14
#define to_hisi_rng(p) container_of(p, struct hisi_rng, rng)
static int seed_sel;
module_param(seed_sel, int, S_IRUGO);
MODULE_PARM_DESC(seed_sel, "Auto reload seed. 0, use LFSR(default); 1, use ring oscillator.");
struct hisi_rng {
void __iomem *base;
struct hwrng rng;
};
static int hisi_rng_init(struct hwrng *rng)
{
struct hisi_rng *hrng = to_hisi_rng(rng);
int val = RNG_EN;
u32 seed;
/* get a random number as initial seed */
get_random_bytes(&seed, sizeof(seed));
writel_relaxed(seed, hrng->base + RNG_SEED);
/**
* The seed is reload periodically, there are two choice
* of seeds, default seed using the value from LFSR, or
* will use seed generated by ring oscillator.
*/
if (seed_sel == 1)
val |= RNG_RING_EN | RNG_SEED_SEL;
writel_relaxed(val, hrng->base + RNG_CTRL);
return 0;
}
static void hisi_rng_cleanup(struct hwrng *rng)
{
struct hisi_rng *hrng = to_hisi_rng(rng);
writel_relaxed(0, hrng->base + RNG_CTRL);
}
static int hisi_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
{
struct hisi_rng *hrng = to_hisi_rng(rng);
u32 *data = buf;
*data = readl_relaxed(hrng->base + RNG_RAN_NUM);
return 4;
}
static int hisi_rng_probe(struct platform_device *pdev)
{
struct hisi_rng *rng;
struct resource *res;
int ret;
rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
if (!rng)
return -ENOMEM;
platform_set_drvdata(pdev, rng);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
rng->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(rng->base))
return PTR_ERR(rng->base);
rng->rng.name = pdev->name;
rng->rng.init = hisi_rng_init;
rng->rng.cleanup = hisi_rng_cleanup;
rng->rng.read = hisi_rng_read;
ret = devm_hwrng_register(&pdev->dev, &rng->rng);
if (ret) {
dev_err(&pdev->dev, "failed to register hwrng\n");
return ret;
}
return 0;
}
static const struct of_device_id hisi_rng_dt_ids[] = {
{ .compatible = "hisilicon,hip04-rng" },
{ .compatible = "hisilicon,hip05-rng" },
{ }
};
MODULE_DEVICE_TABLE(of, hisi_rng_dt_ids);
static struct platform_driver hisi_rng_driver = {
.probe = hisi_rng_probe,
.driver = {
.name = "hisi-rng",
.of_match_table = of_match_ptr(hisi_rng_dt_ids),
},
};
module_platform_driver(hisi_rng_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kefeng Wang <wangkefeng.wang@huawei>");
MODULE_DESCRIPTION("Hisilicon random number generator driver");
-147
View File
@@ -1,147 +0,0 @@
/*
* Generic PowerPC 44x RNG driver
*
* Copyright 2011 IBM Corporation
*
* 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; version 2 of the License.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/hw_random.h>
#include <linux/delay.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <asm/io.h>
#define PPC4XX_TRNG_DEV_CTRL 0x60080
#define PPC4XX_TRNGE 0x00020000
#define PPC4XX_TRNG_CTRL 0x0008
#define PPC4XX_TRNG_CTRL_DALM 0x20
#define PPC4XX_TRNG_STAT 0x0004
#define PPC4XX_TRNG_STAT_B 0x1
#define PPC4XX_TRNG_DATA 0x0000
#define MODULE_NAME "ppc4xx_rng"
static int ppc4xx_rng_data_present(struct hwrng *rng, int wait)
{
void __iomem *rng_regs = (void __iomem *) rng->priv;
int busy, i, present = 0;
for (i = 0; i < 20; i++) {
busy = (in_le32(rng_regs + PPC4XX_TRNG_STAT) & PPC4XX_TRNG_STAT_B);
if (!busy || !wait) {
present = 1;
break;
}
udelay(10);
}
return present;
}
static int ppc4xx_rng_data_read(struct hwrng *rng, u32 *data)
{
void __iomem *rng_regs = (void __iomem *) rng->priv;
*data = in_le32(rng_regs + PPC4XX_TRNG_DATA);
return 4;
}
static int ppc4xx_rng_enable(int enable)
{
struct device_node *ctrl;
void __iomem *ctrl_reg;
int err = 0;
u32 val;
/* Find the main crypto device node and map it to turn the TRNG on */
ctrl = of_find_compatible_node(NULL, NULL, "amcc,ppc4xx-crypto");
if (!ctrl)
return -ENODEV;
ctrl_reg = of_iomap(ctrl, 0);
if (!ctrl_reg) {
err = -ENODEV;
goto out;
}
val = in_le32(ctrl_reg + PPC4XX_TRNG_DEV_CTRL);
if (enable)
val |= PPC4XX_TRNGE;
else
val = val & ~PPC4XX_TRNGE;
out_le32(ctrl_reg + PPC4XX_TRNG_DEV_CTRL, val);
iounmap(ctrl_reg);
out:
of_node_put(ctrl);
return err;
}
static struct hwrng ppc4xx_rng = {
.name = MODULE_NAME,
.data_present = ppc4xx_rng_data_present,
.data_read = ppc4xx_rng_data_read,
};
static int ppc4xx_rng_probe(struct platform_device *dev)
{
void __iomem *rng_regs;
int err = 0;
rng_regs = of_iomap(dev->dev.of_node, 0);
if (!rng_regs)
return -ENODEV;
err = ppc4xx_rng_enable(1);
if (err)
return err;
out_le32(rng_regs + PPC4XX_TRNG_CTRL, PPC4XX_TRNG_CTRL_DALM);
ppc4xx_rng.priv = (unsigned long) rng_regs;
err = hwrng_register(&ppc4xx_rng);
return err;
}
static int ppc4xx_rng_remove(struct platform_device *dev)
{
void __iomem *rng_regs = (void __iomem *) ppc4xx_rng.priv;
hwrng_unregister(&ppc4xx_rng);
ppc4xx_rng_enable(0);
iounmap(rng_regs);
return 0;
}
static const struct of_device_id ppc4xx_rng_match[] = {
{ .compatible = "ppc4xx-rng", },
{ .compatible = "amcc,ppc460ex-rng", },
{ .compatible = "amcc,ppc440epx-rng", },
{},
};
MODULE_DEVICE_TABLE(of, ppc4xx_rng_match);
static struct platform_driver ppc4xx_rng_driver = {
.driver = {
.name = MODULE_NAME,
.of_match_table = ppc4xx_rng_match,
},
.probe = ppc4xx_rng_probe,
.remove = ppc4xx_rng_remove,
};
module_platform_driver(ppc4xx_rng_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Josh Boyer <jwboyer@linux.vnet.ibm.com>");
MODULE_DESCRIPTION("HW RNG driver for PPC 4xx processors");
+23 -4
View File
@@ -279,6 +279,14 @@ config CRYPTO_DEV_PPC4XX
help
This option allows you to have support for AMCC crypto acceleration.
config HW_RANDOM_PPC4XX
bool "PowerPC 4xx generic true random number generator support"
depends on CRYPTO_DEV_PPC4XX && HW_RANDOM
default y
---help---
This option provides the kernel-side support for the TRNG hardware
found in the security function of some PowerPC 4xx SoCs.
config CRYPTO_DEV_OMAP_SHAM
tristate "Support for OMAP MD5/SHA1/SHA2 hw accelerator"
depends on ARCH_OMAP2PLUS
@@ -302,15 +310,16 @@ config CRYPTO_DEV_OMAP_AES
want to use the OMAP module for AES algorithms.
config CRYPTO_DEV_OMAP_DES
tristate "Support for OMAP DES3DES hw engine"
tristate "Support for OMAP DES/3DES hw engine"
depends on ARCH_OMAP2PLUS
select CRYPTO_DES
select CRYPTO_BLKCIPHER
select CRYPTO_ENGINE
help
OMAP processors have DES/3DES module accelerator. Select this if you
want to use the OMAP module for DES and 3DES algorithms. Currently
the ECB and CBC modes of operation supported by the driver. Also
accesses made on unaligned boundaries are also supported.
the ECB and CBC modes of operation are supported by the driver. Also
accesses made on unaligned boundaries are supported.
config CRYPTO_DEV_PICOXCELL
tristate "Support for picoXcell IPSEC and Layer2 crypto engines"
@@ -340,9 +349,19 @@ config CRYPTO_DEV_SAHARA
This option enables support for the SAHARA HW crypto accelerator
found in some Freescale i.MX chips.
config CRYPTO_DEV_MXC_SCC
tristate "Support for Freescale Security Controller (SCC)"
depends on ARCH_MXC && OF
select CRYPTO_BLKCIPHER
select CRYPTO_DES
help
This option enables support for the Security Controller (SCC)
found in Freescale i.MX25 chips.
config CRYPTO_DEV_S5P
tristate "Support for Samsung S5PV210/Exynos crypto accelerator"
depends on ARCH_S5PV210 || ARCH_EXYNOS
depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
depends on HAS_IOMEM && HAS_DMA
select CRYPTO_AES
select CRYPTO_BLKCIPHER
help
+1
View File
@@ -23,6 +23,7 @@ obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o
obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o
obj-$(CONFIG_CRYPTO_DEV_MXC_SCC) += mxc-scc.o
obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/
obj-$(CONFIG_CRYPTO_DEV_QAT) += qat/
+1
View File
@@ -1,2 +1,3 @@
obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += crypto4xx.o
crypto4xx-y := crypto4xx_core.o crypto4xx_alg.o crypto4xx_sa.o
crypto4xx-$(CONFIG_HW_RANDOM_PPC4XX) += crypto4xx_trng.o

Some files were not shown because too many files have changed in this diff Show More