]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.31/crypto-rockchip-update-new-iv-to-device-in-multiple-operations.patch
Linux 4.19.31
[thirdparty/kernel/stable-queue.git] / releases / 4.19.31 / crypto-rockchip-update-new-iv-to-device-in-multiple-operations.patch
CommitLineData
eedc2696
GKH
1From c1c214adcb56d36433480c8fedf772498e7e539c Mon Sep 17 00:00:00 2001
2From: Zhang Zhijie <zhangzj@rock-chips.com>
3Date: Wed, 13 Feb 2019 16:24:39 +0800
4Subject: crypto: rockchip - update new iv to device in multiple operations
5
6From: Zhang Zhijie <zhangzj@rock-chips.com>
7
8commit c1c214adcb56d36433480c8fedf772498e7e539c upstream.
9
10For chain mode in cipher(eg. AES-CBC/DES-CBC), the iv is continuously
11updated in the operation. The new iv value should be written to device
12register by software.
13
14Reported-by: Eric Biggers <ebiggers@google.com>
15Fixes: 433cd2c617bf ("crypto: rockchip - add crypto driver for rk3288")
16Cc: <stable@vger.kernel.org> # v4.5+
17Signed-off-by: Zhang Zhijie <zhangzj@rock-chips.com>
18Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
19Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
20
21---
22 drivers/crypto/rockchip/rk3288_crypto.h | 1
23 drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 34 +++++++++++++++++++++
24 2 files changed, 35 insertions(+)
25
26--- a/drivers/crypto/rockchip/rk3288_crypto.h
27+++ b/drivers/crypto/rockchip/rk3288_crypto.h
28@@ -245,6 +245,7 @@ struct rk_cipher_ctx {
29 struct rk_crypto_info *dev;
30 unsigned int keylen;
31 u32 mode;
32+ u8 iv[AES_BLOCK_SIZE];
33 };
34
35 enum alg_type {
36--- a/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c
37+++ b/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c
38@@ -242,6 +242,17 @@ static void crypto_dma_start(struct rk_c
39 static int rk_set_data_start(struct rk_crypto_info *dev)
40 {
41 int err;
42+ struct ablkcipher_request *req =
43+ ablkcipher_request_cast(dev->async_req);
44+ struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
45+ struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm);
46+ u32 ivsize = crypto_ablkcipher_ivsize(tfm);
47+ u8 *src_last_blk = page_address(sg_page(dev->sg_src)) +
48+ dev->sg_src->offset + dev->sg_src->length - ivsize;
49+
50+ /* store the iv that need to be updated in chain mode */
51+ if (ctx->mode & RK_CRYPTO_DEC)
52+ memcpy(ctx->iv, src_last_blk, ivsize);
53
54 err = dev->load_data(dev, dev->sg_src, dev->sg_dst);
55 if (!err)
56@@ -286,6 +297,28 @@ static void rk_iv_copyback(struct rk_cry
57 memcpy_fromio(req->info, dev->reg + RK_CRYPTO_AES_IV_0, ivsize);
58 }
59
60+static void rk_update_iv(struct rk_crypto_info *dev)
61+{
62+ struct ablkcipher_request *req =
63+ ablkcipher_request_cast(dev->async_req);
64+ struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
65+ struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm);
66+ u32 ivsize = crypto_ablkcipher_ivsize(tfm);
67+ u8 *new_iv = NULL;
68+
69+ if (ctx->mode & RK_CRYPTO_DEC) {
70+ new_iv = ctx->iv;
71+ } else {
72+ new_iv = page_address(sg_page(dev->sg_dst)) +
73+ dev->sg_dst->offset + dev->sg_dst->length - ivsize;
74+ }
75+
76+ if (ivsize == DES_BLOCK_SIZE)
77+ memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, new_iv, ivsize);
78+ else if (ivsize == AES_BLOCK_SIZE)
79+ memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, new_iv, ivsize);
80+}
81+
82 /* return:
83 * true some err was occurred
84 * fault no err, continue
85@@ -307,6 +340,7 @@ static int rk_ablk_rx(struct rk_crypto_i
86 }
87 }
88 if (dev->left_bytes) {
89+ rk_update_iv(dev);
90 if (dev->aligned) {
91 if (sg_is_last(dev->sg_src)) {
92 dev_err(dev->dev, "[%s:%d] Lack of data\n",