diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/ahash.c | 2 | ||||
-rw-r--r-- | crypto/algapi.c | 6 | ||||
-rw-r--r-- | crypto/api.c | 35 | ||||
-rw-r--r-- | crypto/authenc.c | 24 | ||||
-rw-r--r-- | crypto/blkcipher.c | 2 | ||||
-rw-r--r-- | crypto/ccm.c | 2 | ||||
-rw-r--r-- | crypto/lrw.c | 8 | ||||
-rw-r--r-- | crypto/scatterwalk.c | 3 | ||||
-rw-r--r-- | crypto/shash.c | 7 |
9 files changed, 62 insertions, 27 deletions
diff --git a/crypto/ahash.c b/crypto/ahash.c index ba5292d69ebd..b2d1ee32cfe8 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -214,7 +214,7 @@ static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg) seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? "yes" : "no"); seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); - seq_printf(m, "digestsize : %u\n", alg->cra_hash.digestsize); + seq_printf(m, "digestsize : %u\n", alg->cra_ahash.digestsize); } const struct crypto_type crypto_ahash_type = { diff --git a/crypto/algapi.c b/crypto/algapi.c index 7c41e7405c41..56c62e2858d5 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 9975a7bd246c..38a2bc02a98c 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -215,8 +215,19 @@ struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask) mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD); type &= mask; - alg = try_then_request_module(crypto_alg_lookup(name, type, mask), - name); + alg = crypto_alg_lookup(name, type, mask); + if (!alg) { + char tmp[CRYPTO_MAX_ALG_NAME]; + + request_module(name); + + if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask) && + snprintf(tmp, sizeof(tmp), "%s-all", name) < sizeof(tmp)) + request_module(tmp); + + alg = crypto_alg_lookup(name, type, mask); + } + if (alg) return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg; @@ -557,34 +568,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 40b6e9ec9e3a..5793b64c81a8 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 4a7e65c4df4d..d70a41c002df 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 7cf7e5a6b781..c36d654cf56a 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/lrw.c b/crypto/lrw.c index 8ef664e3bcd9..358f80be2bf9 100644 --- a/crypto/lrw.c +++ b/crypto/lrw.c @@ -45,7 +45,13 @@ struct priv { static inline void setbit128_bbe(void *b, int bit) { - __set_bit(bit ^ 0x78, b); + __set_bit(bit ^ (0x80 - +#ifdef __BIG_ENDIAN + BITS_PER_LONG +#else + BITS_PER_BYTE +#endif + ), b); } static int setkey(struct crypto_tfm *parent, const u8 *key, diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c index 9aeeb52004a5..3de89a424401 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 c9df367332ff..d5a2b619c55f 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; |