crypto: rockchip - do not store mode globally

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: ce0183cb64 ("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>
This commit is contained in:
Corentin Labbe 2022-09-27 07:54:43 +00:00 committed by Herbert Xu
parent 6d11c93878
commit 87e356c496
2 changed files with 41 additions and 22 deletions

View 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,

View 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)) +