Skip to content

Commit

Permalink
crypto: rockchip - update IV buffer to contain the next IV
Browse files Browse the repository at this point in the history
The Kernel Crypto API request output the next IV data to
IV buffer for CBC implementation. So the last block data of
ciphertext should be copid into assigned IV buffer.

Reported-by: Eric Biggers <[email protected]>
Fixes: 433cd2c ("crypto: rockchip - add crypto driver for rk3288")
Cc: <[email protected]> # v4.5+
Signed-off-by: Zhang Zhijie <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
ElonZhang0328 authored and herbertx committed Apr 18, 2019
1 parent c4741b2 commit f0cfd57
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,14 @@ static int rk_set_data_start(struct rk_crypto_info *dev)
u8 *src_last_blk = page_address(sg_page(dev->sg_src)) +
dev->sg_src->offset + dev->sg_src->length - ivsize;

/* store the iv that need to be updated in chain mode */
if (ctx->mode & RK_CRYPTO_DEC)
/* Store the iv that need to be updated in chain mode.
* And update the IV buffer to contain the next IV for decryption mode.
*/
if (ctx->mode & RK_CRYPTO_DEC) {
memcpy(ctx->iv, src_last_blk, ivsize);
sg_pcopy_to_buffer(dev->first, dev->src_nents, req->info,
ivsize, dev->total - ivsize);
}

err = dev->load_data(dev, dev->sg_src, dev->sg_dst);
if (!err)
Expand Down Expand Up @@ -300,13 +305,19 @@ static void rk_iv_copyback(struct rk_crypto_info *dev)
struct ablkcipher_request *req =
ablkcipher_request_cast(dev->async_req);
struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm);
u32 ivsize = crypto_ablkcipher_ivsize(tfm);

if (ivsize == DES_BLOCK_SIZE)
memcpy_fromio(req->info, dev->reg + RK_CRYPTO_TDES_IV_0,
ivsize);
else if (ivsize == AES_BLOCK_SIZE)
memcpy_fromio(req->info, dev->reg + RK_CRYPTO_AES_IV_0, ivsize);
/* Update the IV buffer to contain the next IV for encryption mode. */
if (!(ctx->mode & RK_CRYPTO_DEC)) {
if (dev->aligned) {
memcpy(req->info, sg_virt(dev->sg_dst) +
dev->sg_dst->length - ivsize, ivsize);
} else {
memcpy(req->info, dev->addr_vir +
dev->count - ivsize, ivsize);
}
}
}

static void rk_update_iv(struct rk_crypto_info *dev)
Expand Down

0 comments on commit f0cfd57

Please sign in to comment.