crypto: rockchip - do not store mode globally
authorCorentin Labbe <clabbe@baylibre.com>
Tue, 27 Sep 2022 07:54:43 +0000 (07:54 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 31 Dec 2022 12:32:30 +0000 (13:32 +0100)
[ Upstream commit 87e356c4966444866186f68f05832fdcc0f351a3 ]

Storing the mode globally does not work if 2 requests are handled in the
same time.
We should store it in a request context.

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 2fa7131..3e60e3d 100644 (file)
@@ -245,10 +245,13 @@ struct rk_ahash_rctx {
 struct rk_cipher_ctx {
        struct rk_crypto_info           *dev;
        unsigned int                    keylen;
-       u32                             mode;
        u8                              iv[AES_BLOCK_SIZE];
 };
 
+struct rk_cipher_rctx {
+       u32                             mode;
+};
+
 enum alg_type {
        ALG_TYPE_HASH,
        ALG_TYPE_CIPHER,
index 8c44a19..bbd0bf5 100644 (file)
@@ -76,9 +76,10 @@ static int rk_aes_ecb_encrypt(struct skcipher_request *req)
 {
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_crypto_info *dev = ctx->dev;
 
-       ctx->mode = RK_CRYPTO_AES_ECB_MODE;
+       rctx->mode = RK_CRYPTO_AES_ECB_MODE;
        return rk_handle_req(dev, req);
 }
 
@@ -86,9 +87,10 @@ static int rk_aes_ecb_decrypt(struct skcipher_request *req)
 {
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_crypto_info *dev = ctx->dev;
 
-       ctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
+       rctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
        return rk_handle_req(dev, req);
 }
 
@@ -96,9 +98,10 @@ static int rk_aes_cbc_encrypt(struct skcipher_request *req)
 {
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_crypto_info *dev = ctx->dev;
 
-       ctx->mode = RK_CRYPTO_AES_CBC_MODE;
+       rctx->mode = RK_CRYPTO_AES_CBC_MODE;
        return rk_handle_req(dev, req);
 }
 
@@ -106,9 +109,10 @@ static int rk_aes_cbc_decrypt(struct skcipher_request *req)
 {
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_crypto_info *dev = ctx->dev;
 
-       ctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
+       rctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
        return rk_handle_req(dev, req);
 }
 
@@ -116,9 +120,10 @@ static int rk_des_ecb_encrypt(struct skcipher_request *req)
 {
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_crypto_info *dev = ctx->dev;
 
-       ctx->mode = 0;
+       rctx->mode = 0;
        return rk_handle_req(dev, req);
 }
 
@@ -126,9 +131,10 @@ static int rk_des_ecb_decrypt(struct skcipher_request *req)
 {
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_crypto_info *dev = ctx->dev;
 
-       ctx->mode = RK_CRYPTO_DEC;
+       rctx->mode = RK_CRYPTO_DEC;
        return rk_handle_req(dev, req);
 }
 
@@ -136,9 +142,10 @@ static int rk_des_cbc_encrypt(struct skcipher_request *req)
 {
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_crypto_info *dev = ctx->dev;
 
-       ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
+       rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
        return rk_handle_req(dev, req);
 }
 
@@ -146,9 +153,10 @@ static int rk_des_cbc_decrypt(struct skcipher_request *req)
 {
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_crypto_info *dev = ctx->dev;
 
-       ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
+       rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
        return rk_handle_req(dev, req);
 }
 
@@ -156,9 +164,10 @@ static int rk_des3_ede_ecb_encrypt(struct skcipher_request *req)
 {
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_crypto_info *dev = ctx->dev;
 
-       ctx->mode = RK_CRYPTO_TDES_SELECT;
+       rctx->mode = RK_CRYPTO_TDES_SELECT;
        return rk_handle_req(dev, req);
 }
 
@@ -166,9 +175,10 @@ static int rk_des3_ede_ecb_decrypt(struct skcipher_request *req)
 {
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_crypto_info *dev = ctx->dev;
 
-       ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
+       rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
        return rk_handle_req(dev, req);
 }
 
@@ -176,9 +186,10 @@ static int rk_des3_ede_cbc_encrypt(struct skcipher_request *req)
 {
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_crypto_info *dev = ctx->dev;
 
-       ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
+       rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
        return rk_handle_req(dev, req);
 }
 
@@ -186,9 +197,10 @@ static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req)
 {
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_crypto_info *dev = ctx->dev;
 
-       ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
+       rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
                    RK_CRYPTO_DEC;
        return rk_handle_req(dev, req);
 }
@@ -199,6 +211,7 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
                skcipher_request_cast(dev->async_req);
        struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
        struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
        u32 ivsize, block, conf_reg = 0;
 
@@ -206,22 +219,22 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
        ivsize = crypto_skcipher_ivsize(cipher);
 
        if (block == DES_BLOCK_SIZE) {
-               ctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
+               rctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
                             RK_CRYPTO_TDES_BYTESWAP_KEY |
                             RK_CRYPTO_TDES_BYTESWAP_IV;
-               CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, ctx->mode);
+               CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode);
                memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize);
                conf_reg = RK_CRYPTO_DESSEL;
        } else {
-               ctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
+               rctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
                             RK_CRYPTO_AES_KEY_CHANGE |
                             RK_CRYPTO_AES_BYTESWAP_KEY |
                             RK_CRYPTO_AES_BYTESWAP_IV;
                if (ctx->keylen == AES_KEYSIZE_192)
-                       ctx->mode |= RK_CRYPTO_AES_192BIT_key;
+                       rctx->mode |= RK_CRYPTO_AES_192BIT_key;
                else if (ctx->keylen == AES_KEYSIZE_256)
-                       ctx->mode |= RK_CRYPTO_AES_256BIT_key;
-               CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, ctx->mode);
+                       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);
        }
        conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO |
@@ -246,6 +259,7 @@ static int rk_set_data_start(struct rk_crypto_info *dev)
        struct skcipher_request *req =
                skcipher_request_cast(dev->async_req);
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
        u32 ivsize = crypto_skcipher_ivsize(tfm);
        u8 *src_last_blk = page_address(sg_page(dev->sg_src)) +
@@ -254,7 +268,7 @@ static int rk_set_data_start(struct rk_crypto_info *dev)
        /* 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) {
+       if (rctx->mode & RK_CRYPTO_DEC) {
                memcpy(ctx->iv, src_last_blk, ivsize);
                sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv,
                                   ivsize, dev->total - ivsize);
@@ -294,11 +308,12 @@ static void rk_iv_copyback(struct rk_crypto_info *dev)
        struct skcipher_request *req =
                skcipher_request_cast(dev->async_req);
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
        u32 ivsize = crypto_skcipher_ivsize(tfm);
 
        /* Update the IV buffer to contain the next IV for encryption mode. */
-       if (!(ctx->mode & RK_CRYPTO_DEC)) {
+       if (!(rctx->mode & RK_CRYPTO_DEC)) {
                if (dev->aligned) {
                        memcpy(req->iv, sg_virt(dev->sg_dst) +
                                dev->sg_dst->length - ivsize, ivsize);
@@ -314,11 +329,12 @@ static void rk_update_iv(struct rk_crypto_info *dev)
        struct skcipher_request *req =
                skcipher_request_cast(dev->async_req);
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
        struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
        u32 ivsize = crypto_skcipher_ivsize(tfm);
        u8 *new_iv = NULL;
 
-       if (ctx->mode & RK_CRYPTO_DEC) {
+       if (rctx->mode & RK_CRYPTO_DEC) {
                new_iv = ctx->iv;
        } else {
                new_iv = page_address(sg_page(dev->sg_dst)) +