Commit f0cfd57b authored by Zhang Zhijie's avatar Zhang Zhijie Committed by Herbert Xu

crypto: rockchip - update IV buffer to contain the next IV

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: default avatarEric Biggers <ebiggers@google.com>
Fixes: 433cd2c6 ("crypto: rockchip - add crypto driver for rk3288")
Cc: <stable@vger.kernel.org> # v4.5+
Signed-off-by: default avatarZhang Zhijie <zhangzj@rock-chips.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent c4741b23
...@@ -262,9 +262,14 @@ static int rk_set_data_start(struct rk_crypto_info *dev) ...@@ -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)) + u8 *src_last_blk = page_address(sg_page(dev->sg_src)) +
dev->sg_src->offset + dev->sg_src->length - ivsize; dev->sg_src->offset + dev->sg_src->length - ivsize;
/* store the iv that need to be updated in chain mode */ /* Store the iv that need to be updated in chain mode.
if (ctx->mode & RK_CRYPTO_DEC) * 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); 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); err = dev->load_data(dev, dev->sg_src, dev->sg_dst);
if (!err) if (!err)
...@@ -300,13 +305,19 @@ static void rk_iv_copyback(struct rk_crypto_info *dev) ...@@ -300,13 +305,19 @@ static void rk_iv_copyback(struct rk_crypto_info *dev)
struct ablkcipher_request *req = struct ablkcipher_request *req =
ablkcipher_request_cast(dev->async_req); ablkcipher_request_cast(dev->async_req);
struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm);
u32 ivsize = crypto_ablkcipher_ivsize(tfm); u32 ivsize = crypto_ablkcipher_ivsize(tfm);
if (ivsize == DES_BLOCK_SIZE) /* Update the IV buffer to contain the next IV for encryption mode. */
memcpy_fromio(req->info, dev->reg + RK_CRYPTO_TDES_IV_0, if (!(ctx->mode & RK_CRYPTO_DEC)) {
ivsize); if (dev->aligned) {
else if (ivsize == AES_BLOCK_SIZE) memcpy(req->info, sg_virt(dev->sg_dst) +
memcpy_fromio(req->info, dev->reg + RK_CRYPTO_AES_IV_0, ivsize); 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) static void rk_update_iv(struct rk_crypto_info *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment