aboutsummaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/algapi.c6
-rw-r--r--crypto/api.c20
-rw-r--r--crypto/authenc.c24
-rw-r--r--crypto/blkcipher.c2
-rw-r--r--crypto/ccm.c2
-rw-r--r--crypto/scatterwalk.c3
-rw-r--r--crypto/shash.c7
7 files changed, 41 insertions, 23 deletions
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 7c41e7405c4..56c62e2858d 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -149,6 +149,9 @@ static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
if (q == alg)
goto err;
+ if (crypto_is_moribund(q))
+ continue;
+
if (crypto_is_larval(q)) {
if (!strcmp(alg->cra_driver_name, q->cra_driver_name))
goto err;
@@ -197,7 +200,7 @@ void crypto_alg_tested(const char *name, int err)
down_write(&crypto_alg_sem);
list_for_each_entry(q, &crypto_alg_list, cra_list) {
- if (!crypto_is_larval(q))
+ if (crypto_is_moribund(q) || !crypto_is_larval(q))
continue;
test = (struct crypto_larval *)q;
@@ -210,6 +213,7 @@ void crypto_alg_tested(const char *name, int err)
goto unlock;
found:
+ q->cra_flags |= CRYPTO_ALG_DEAD;
alg = test->adult;
if (err || list_empty(&alg->cra_list))
goto complete;
diff --git a/crypto/api.c b/crypto/api.c
index 9975a7bd246..efe77df6863 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -557,34 +557,34 @@ err:
return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
-
+
/*
- * crypto_free_tfm - Free crypto transform
+ * crypto_destroy_tfm - Free crypto transform
+ * @mem: Start of tfm slab
* @tfm: Transform to free
*
- * crypto_free_tfm() frees up the transform and any associated resources,
+ * This function frees up the transform and any associated resources,
* then drops the refcount on the associated algorithm.
*/
-void crypto_free_tfm(struct crypto_tfm *tfm)
+void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm)
{
struct crypto_alg *alg;
int size;
- if (unlikely(!tfm))
+ if (unlikely(!mem))
return;
alg = tfm->__crt_alg;
- size = sizeof(*tfm) + alg->cra_ctxsize;
+ size = ksize(mem);
if (!tfm->exit && alg->cra_exit)
alg->cra_exit(tfm);
crypto_exit_ops(tfm);
crypto_mod_put(alg);
- memset(tfm, 0, size);
- kfree(tfm);
+ memset(mem, 0, size);
+ kfree(mem);
}
-
-EXPORT_SYMBOL_GPL(crypto_free_tfm);
+EXPORT_SYMBOL_GPL(crypto_destroy_tfm);
int crypto_has_alg(const char *name, u32 type, u32 mask)
{
diff --git a/crypto/authenc.c b/crypto/authenc.c
index 40b6e9ec9e3..5793b64c81a 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -158,16 +158,19 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv,
dstp = sg_page(dst);
vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset;
- sg_init_table(cipher, 2);
- sg_set_buf(cipher, iv, ivsize);
- authenc_chain(cipher, dst, vdst == iv + ivsize);
+ if (ivsize) {
+ sg_init_table(cipher, 2);
+ sg_set_buf(cipher, iv, ivsize);
+ authenc_chain(cipher, dst, vdst == iv + ivsize);
+ dst = cipher;
+ }
cryptlen = req->cryptlen + ivsize;
- hash = crypto_authenc_hash(req, flags, cipher, cryptlen);
+ hash = crypto_authenc_hash(req, flags, dst, cryptlen);
if (IS_ERR(hash))
return PTR_ERR(hash);
- scatterwalk_map_and_copy(hash, cipher, cryptlen,
+ scatterwalk_map_and_copy(hash, dst, cryptlen,
crypto_aead_authsize(authenc), 1);
return 0;
}
@@ -285,11 +288,14 @@ static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,
srcp = sg_page(src);
vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset;
- sg_init_table(cipher, 2);
- sg_set_buf(cipher, iv, ivsize);
- authenc_chain(cipher, src, vsrc == iv + ivsize);
+ if (ivsize) {
+ sg_init_table(cipher, 2);
+ sg_set_buf(cipher, iv, ivsize);
+ authenc_chain(cipher, src, vsrc == iv + ivsize);
+ src = cipher;
+ }
- return crypto_authenc_verify(req, cipher, cryptlen + ivsize);
+ return crypto_authenc_verify(req, src, cryptlen + ivsize);
}
static int crypto_authenc_decrypt(struct aead_request *req)
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index 4a7e65c4df4..d70a41c002d 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -124,6 +124,7 @@ int blkcipher_walk_done(struct blkcipher_desc *desc,
scatterwalk_done(&walk->in, 0, nbytes);
scatterwalk_done(&walk->out, 1, nbytes);
+err:
walk->total = nbytes;
walk->nbytes = nbytes;
@@ -132,7 +133,6 @@ int blkcipher_walk_done(struct blkcipher_desc *desc,
return blkcipher_walk_next(desc, walk);
}
-err:
if (walk->iv != desc->info)
memcpy(desc->info, walk->iv, crypto_blkcipher_ivsize(tfm));
if (walk->buffer != walk->page)
diff --git a/crypto/ccm.c b/crypto/ccm.c
index 7cf7e5a6b78..c36d654cf56 100644
--- a/crypto/ccm.c
+++ b/crypto/ccm.c
@@ -266,6 +266,8 @@ static int crypto_ccm_auth(struct aead_request *req, struct scatterlist *plain,
if (assoclen) {
pctx->ilen = format_adata(idata, assoclen);
get_data_to_compute(cipher, pctx, req->assoc, req->assoclen);
+ } else {
+ pctx->ilen = 0;
}
/* compute plaintext into mac */
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index 9aeeb52004a..3de89a42440 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -54,7 +54,8 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
struct page *page;
page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
- flush_dcache_page(page);
+ if (!PageSlab(page))
+ flush_dcache_page(page);
}
if (more) {
diff --git a/crypto/shash.c b/crypto/shash.c
index c9df367332f..d5a2b619c55 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -388,10 +388,15 @@ static int crypto_init_shash_ops_compat(struct crypto_tfm *tfm)
struct shash_desc *desc = crypto_tfm_ctx(tfm);
struct crypto_shash *shash;
+ if (!crypto_mod_get(calg))
+ return -EAGAIN;
+
shash = __crypto_shash_cast(crypto_create_tfm(
calg, &crypto_shash_type));
- if (IS_ERR(shash))
+ if (IS_ERR(shash)) {
+ crypto_mod_put(calg);
return PTR_ERR(shash);
+ }
desc->tfm = shash;
tfm->exit = crypto_exit_shash_ops_compat;