| From 438319ffe8f9be0e77417c22c7ae59acf77bce2f Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 27 Sep 2022 07:54:46 +0000 |
| Subject: crypto: rockchip - better handle cipher key |
| |
| From: Corentin Labbe <clabbe@baylibre.com> |
| |
| [ Upstream commit d6b23ccef82816050c2fd458c9dabfa0e0af09b9 ] |
| |
| The key should not be set in hardware too much in advance, this will |
| fail it 2 TFM with different keys generate alternative requests. |
| The key should be stored and used just before doing cipher operations. |
| |
| Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") |
| Reviewed-by: John Keeping <john@metanate.com> |
| Signed-off-by: Corentin Labbe <clabbe@baylibre.com> |
| Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/crypto/rockchip/rk3288_crypto.h | 1 + |
| drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 10 +++++++--- |
| 2 files changed, 8 insertions(+), 3 deletions(-) |
| |
| diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h |
| index dfff0e2a83e4..665cc0bb2264 100644 |
| --- a/drivers/crypto/rockchip/rk3288_crypto.h |
| +++ b/drivers/crypto/rockchip/rk3288_crypto.h |
| @@ -245,6 +245,7 @@ struct rk_ahash_rctx { |
| struct rk_cipher_ctx { |
| struct rk_crypto_info *dev; |
| unsigned int keylen; |
| + u8 key[AES_MAX_KEY_SIZE]; |
| u8 iv[AES_BLOCK_SIZE]; |
| struct crypto_skcipher *fallback_tfm; |
| }; |
| diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c |
| index eac5bba66e25..1ef94f8db2c5 100644 |
| --- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c |
| +++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c |
| @@ -95,7 +95,7 @@ static int rk_aes_setkey(struct crypto_skcipher *cipher, |
| keylen != AES_KEYSIZE_256) |
| return -EINVAL; |
| ctx->keylen = keylen; |
| - memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen); |
| + memcpy(ctx->key, key, keylen); |
| |
| return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); |
| } |
| @@ -111,7 +111,7 @@ static int rk_des_setkey(struct crypto_skcipher *cipher, |
| return err; |
| |
| ctx->keylen = keylen; |
| - memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); |
| + memcpy(ctx->key, key, keylen); |
| |
| return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); |
| } |
| @@ -127,7 +127,8 @@ static int rk_tdes_setkey(struct crypto_skcipher *cipher, |
| return err; |
| |
| ctx->keylen = keylen; |
| - memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); |
| + memcpy(ctx->key, key, keylen); |
| + |
| return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); |
| } |
| |
| @@ -283,6 +284,7 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev) |
| RK_CRYPTO_TDES_BYTESWAP_IV; |
| CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode); |
| memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize); |
| + memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen); |
| conf_reg = RK_CRYPTO_DESSEL; |
| } else { |
| rctx->mode |= RK_CRYPTO_AES_FIFO_MODE | |
| @@ -295,6 +297,7 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev) |
| rctx->mode |= RK_CRYPTO_AES_256BIT_key; |
| CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode); |
| memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize); |
| + memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen); |
| } |
| conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO | |
| RK_CRYPTO_BYTESWAP_BRFIFO; |
| @@ -484,6 +487,7 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm) |
| { |
| struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); |
| |
| + memzero_explicit(ctx->key, ctx->keylen); |
| free_page((unsigned long)ctx->dev->addr_vir); |
| crypto_free_skcipher(ctx->fallback_tfm); |
| } |
| -- |
| 2.35.1 |
| |