crypto: rockchip - better handle cipher key
authorCorentin Labbe <clabbe@baylibre.com>
Tue, 27 Sep 2022 07:54:46 +0000 (07:54 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 31 Dec 2022 12:32:30 +0000 (13:32 +0100)
[ 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
drivers/crypto/rockchip/rk3288_crypto_skcipher.c

index dfff0e2..665cc0b 100644 (file)
@@ -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;
 };
index eac5bba..1ef94f8 100644 (file)
@@ -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);
 }