Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto updates from Herbert Xu: "Here is the crypto update for 4.15: API: - Disambiguate EBUSY when queueing crypto request by adding ENOSPC. This change touches code outside the crypto API. - Reset settings when empty string is written to rng_current. Algorithms: - Add OSCCA SM3 secure hash. Drivers: - Remove old mv_cesa driver (replaced by marvell/cesa). - Enable rfc3686/ecb/cfb/ofb AES in crypto4xx. - Add ccm/gcm AES in crypto4xx. - Add support for BCM7278 in iproc-rng200. - Add hash support on Exynos in s5p-sss. - Fix fallback-induced error in vmx. - Fix output IV in atmel-aes. - Fix empty GCM hash in mediatek. Others: - Fix DoS potential in lib/mpi. - Fix potential out-of-order issues with padata" * 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (162 commits) lib/mpi: call cond_resched() from mpi_powm() loop crypto: stm32/hash - Fix return issue on update crypto: dh - Remove pointless checks for NULL 'p' and 'g' crypto: qat - Clean up error handling in qat_dh_set_secret() crypto: dh - Don't permit 'key' or 'g' size longer than 'p' crypto: dh - Don't permit 'p' to be 0 crypto: dh - Fix double free of ctx->p hwrng: iproc-rng200 - Add support for BCM7278 dt-bindings: rng: Document BCM7278 RNG200 compatible crypto: chcr - Replace _manual_ swap with swap macro crypto: marvell - Add a NULL entry at the end of mv_cesa_plat_id_table[] hwrng: virtio - Virtio RNG devices need to be re-registered after suspend/resume crypto: atmel - remove empty functions crypto: ecdh - remove empty exit() MAINTAINERS: update maintainer for qat crypto: caam - remove unused param of ctx_map_to_sec4_sg() crypto: caam - remove unneeded edesc zeroization crypto: atmel-aes - Reset the controller before each use crypto: atmel-aes - properly set IV after {en,de}crypt hwrng: core - Reset user selected rng by writing "" to rng_current ...
This commit is contained in:
@@ -92,74 +92,33 @@ static sector_t verity_position_at_level(struct dm_verity *v, sector_t block,
|
||||
return block >> (level * v->hash_per_block_bits);
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback function for asynchrnous crypto API completion notification
|
||||
*/
|
||||
static void verity_op_done(struct crypto_async_request *base, int err)
|
||||
{
|
||||
struct verity_result *res = (struct verity_result *)base->data;
|
||||
|
||||
if (err == -EINPROGRESS)
|
||||
return;
|
||||
|
||||
res->err = err;
|
||||
complete(&res->completion);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for async crypto API callback
|
||||
*/
|
||||
static inline int verity_complete_op(struct verity_result *res, int ret)
|
||||
{
|
||||
switch (ret) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case -EINPROGRESS:
|
||||
case -EBUSY:
|
||||
ret = wait_for_completion_interruptible(&res->completion);
|
||||
if (!ret)
|
||||
ret = res->err;
|
||||
reinit_completion(&res->completion);
|
||||
break;
|
||||
|
||||
default:
|
||||
DMERR("verity_wait_hash: crypto op submission failed: %d", ret);
|
||||
}
|
||||
|
||||
if (unlikely(ret < 0))
|
||||
DMERR("verity_wait_hash: crypto op failed: %d", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int verity_hash_update(struct dm_verity *v, struct ahash_request *req,
|
||||
const u8 *data, size_t len,
|
||||
struct verity_result *res)
|
||||
struct crypto_wait *wait)
|
||||
{
|
||||
struct scatterlist sg;
|
||||
|
||||
sg_init_one(&sg, data, len);
|
||||
ahash_request_set_crypt(req, &sg, NULL, len);
|
||||
|
||||
return verity_complete_op(res, crypto_ahash_update(req));
|
||||
return crypto_wait_req(crypto_ahash_update(req), wait);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper for crypto_ahash_init, which handles verity salting.
|
||||
*/
|
||||
static int verity_hash_init(struct dm_verity *v, struct ahash_request *req,
|
||||
struct verity_result *res)
|
||||
struct crypto_wait *wait)
|
||||
{
|
||||
int r;
|
||||
|
||||
ahash_request_set_tfm(req, v->tfm);
|
||||
ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
|
||||
CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
verity_op_done, (void *)res);
|
||||
init_completion(&res->completion);
|
||||
crypto_req_done, (void *)wait);
|
||||
crypto_init_wait(wait);
|
||||
|
||||
r = verity_complete_op(res, crypto_ahash_init(req));
|
||||
r = crypto_wait_req(crypto_ahash_init(req), wait);
|
||||
|
||||
if (unlikely(r < 0)) {
|
||||
DMERR("crypto_ahash_init failed: %d", r);
|
||||
@@ -167,18 +126,18 @@ static int verity_hash_init(struct dm_verity *v, struct ahash_request *req,
|
||||
}
|
||||
|
||||
if (likely(v->salt_size && (v->version >= 1)))
|
||||
r = verity_hash_update(v, req, v->salt, v->salt_size, res);
|
||||
r = verity_hash_update(v, req, v->salt, v->salt_size, wait);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int verity_hash_final(struct dm_verity *v, struct ahash_request *req,
|
||||
u8 *digest, struct verity_result *res)
|
||||
u8 *digest, struct crypto_wait *wait)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (unlikely(v->salt_size && (!v->version))) {
|
||||
r = verity_hash_update(v, req, v->salt, v->salt_size, res);
|
||||
r = verity_hash_update(v, req, v->salt, v->salt_size, wait);
|
||||
|
||||
if (r < 0) {
|
||||
DMERR("verity_hash_final failed updating salt: %d", r);
|
||||
@@ -187,7 +146,7 @@ static int verity_hash_final(struct dm_verity *v, struct ahash_request *req,
|
||||
}
|
||||
|
||||
ahash_request_set_crypt(req, NULL, digest, 0);
|
||||
r = verity_complete_op(res, crypto_ahash_final(req));
|
||||
r = crypto_wait_req(crypto_ahash_final(req), wait);
|
||||
out:
|
||||
return r;
|
||||
}
|
||||
@@ -196,17 +155,17 @@ int verity_hash(struct dm_verity *v, struct ahash_request *req,
|
||||
const u8 *data, size_t len, u8 *digest)
|
||||
{
|
||||
int r;
|
||||
struct verity_result res;
|
||||
struct crypto_wait wait;
|
||||
|
||||
r = verity_hash_init(v, req, &res);
|
||||
r = verity_hash_init(v, req, &wait);
|
||||
if (unlikely(r < 0))
|
||||
goto out;
|
||||
|
||||
r = verity_hash_update(v, req, data, len, &res);
|
||||
r = verity_hash_update(v, req, data, len, &wait);
|
||||
if (unlikely(r < 0))
|
||||
goto out;
|
||||
|
||||
r = verity_hash_final(v, req, digest, &res);
|
||||
r = verity_hash_final(v, req, digest, &wait);
|
||||
|
||||
out:
|
||||
return r;
|
||||
@@ -389,7 +348,7 @@ out:
|
||||
* Calculates the digest for the given bio
|
||||
*/
|
||||
int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io,
|
||||
struct bvec_iter *iter, struct verity_result *res)
|
||||
struct bvec_iter *iter, struct crypto_wait *wait)
|
||||
{
|
||||
unsigned int todo = 1 << v->data_dev_block_bits;
|
||||
struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
|
||||
@@ -414,7 +373,7 @@ int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io,
|
||||
*/
|
||||
sg_set_page(&sg, bv.bv_page, len, bv.bv_offset);
|
||||
ahash_request_set_crypt(req, &sg, NULL, len);
|
||||
r = verity_complete_op(res, crypto_ahash_update(req));
|
||||
r = crypto_wait_req(crypto_ahash_update(req), wait);
|
||||
|
||||
if (unlikely(r < 0)) {
|
||||
DMERR("verity_for_io_block crypto op failed: %d", r);
|
||||
@@ -482,7 +441,7 @@ static int verity_verify_io(struct dm_verity_io *io)
|
||||
struct dm_verity *v = io->v;
|
||||
struct bvec_iter start;
|
||||
unsigned b;
|
||||
struct verity_result res;
|
||||
struct crypto_wait wait;
|
||||
|
||||
for (b = 0; b < io->n_blocks; b++) {
|
||||
int r;
|
||||
@@ -507,17 +466,17 @@ static int verity_verify_io(struct dm_verity_io *io)
|
||||
continue;
|
||||
}
|
||||
|
||||
r = verity_hash_init(v, req, &res);
|
||||
r = verity_hash_init(v, req, &wait);
|
||||
if (unlikely(r < 0))
|
||||
return r;
|
||||
|
||||
start = io->iter;
|
||||
r = verity_for_io_block(v, io, &io->iter, &res);
|
||||
r = verity_for_io_block(v, io, &io->iter, &wait);
|
||||
if (unlikely(r < 0))
|
||||
return r;
|
||||
|
||||
r = verity_hash_final(v, req, verity_io_real_digest(v, io),
|
||||
&res);
|
||||
&wait);
|
||||
if (unlikely(r < 0))
|
||||
return r;
|
||||
|
||||
|
Reference in New Issue
Block a user