From 6ad785b40f01bbc1ce52c751c98f846031d7ae8f Mon Sep 17 00:00:00 2001 From: Lin Jinhan Date: Mon, 23 Aug 2021 16:49:42 +0800 Subject: [PATCH] crypto: rockchip: v1&v2: switch ablkcipher to skcipher API Signed-off-by: Lin Jinhan Change-Id: I2936c26d1a9600ecbdb86ab2821a502371e9c2bc --- drivers/crypto/Kconfig | 8 + drivers/crypto/rockchip/Makefile | 11 +- drivers/crypto/rockchip/rk_crypto_core.c | 27 ++-- drivers/crypto/rockchip/rk_crypto_core.h | 81 +++++----- ...1_ablkcipher.c => rk_crypto_v1_skcipher.c} | 134 ++++++++--------- drivers/crypto/rockchip/rk_crypto_v2_ahash.c | 2 - drivers/crypto/rockchip/rk_crypto_v2_pka.c | 17 +++ ...2_ablkcipher.c => rk_crypto_v2_skcipher.c} | 140 +++++++++--------- 8 files changed, 224 insertions(+), 196 deletions(-) rename drivers/crypto/rockchip/{rk_crypto_v1_ablkcipher.c => rk_crypto_v1_skcipher.c} (73%) rename drivers/crypto/rockchip/{rk_crypto_v2_ablkcipher.c => rk_crypto_v2_skcipher.c} (80%) diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index ff5e85eefbf6..6fc61f506e7b 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -750,12 +750,20 @@ config CRYPTO_DEV_ROCKCHIP tristate "Rockchip's Cryptographic Engine driver" depends on OF && ARCH_ROCKCHIP select CRYPTO_AES + select CRYPTO_ECB + select CRYPTO_CBC + select CRYPTO_XTS + select CRYPTO_CFB + select CRYPTO_CTR select CRYPTO_LIB_DES select CRYPTO_MD5 select CRYPTO_SHA1 + select CRYPTO_SM3 + select CRYPTO_SM4 select CRYPTO_SHA256 select CRYPTO_HASH select CRYPTO_SKCIPHER + select CRYPTO_RSA help This driver interfaces with the hardware crypto accelerator. diff --git a/drivers/crypto/rockchip/Makefile b/drivers/crypto/rockchip/Makefile index 785277aca71e..91fc402ee679 100644 --- a/drivers/crypto/rockchip/Makefile +++ b/drivers/crypto/rockchip/Makefile @@ -1,5 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rk_crypto.o -rk_crypto-objs := rk3288_crypto.o \ - rk3288_crypto_skcipher.o \ - rk3288_crypto_ahash.o +rk_crypto-objs := rk_crypto_core.o \ + rk_crypto_v1_ahash.o \ + rk_crypto_v1_skcipher.o \ + rk_crypto_v2_skcipher.o \ + rk_crypto_v2_ahash.o \ + rk_crypto_v2_akcipher.o \ + rk_crypto_v2_pka.o \ + rk_crypto_bignum.o diff --git a/drivers/crypto/rockchip/rk_crypto_core.c b/drivers/crypto/rockchip/rk_crypto_core.c index 5e6cc2ec7b84..98361997ad8f 100644 --- a/drivers/crypto/rockchip/rk_crypto_core.c +++ b/drivers/crypto/rockchip/rk_crypto_core.c @@ -51,9 +51,16 @@ .default_pka_offset = 0x0480,\ } +static struct rk_alg_ctx *rk_alg_ctx_cast(struct crypto_async_request *async_req) +{ + struct rk_cipher_ctx *ctx = crypto_tfm_ctx(async_req->tfm); + + return &ctx->algs_ctx; +} + static void dump_alg_ctx(struct crypto_async_request *async_req) { - struct rk_alg_ctx *alg_ctx = crypto_tfm_ctx(async_req->tfm); + struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(async_req); struct scatterlist *cur_sg = NULL; unsigned int i; @@ -127,7 +134,7 @@ static int rk_load_data(struct rk_crypto_dev *rk_dev, int ret = -EINVAL; unsigned int count; struct device *dev = rk_dev->dev; - struct rk_alg_ctx *alg_ctx = crypto_tfm_ctx(rk_dev->async_req->tfm); + struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(rk_dev->async_req); mutex_lock(&rk_dev->mutex); @@ -209,7 +216,7 @@ static int rk_unload_data(struct rk_crypto_dev *rk_dev) { int ret = 0; struct scatterlist *sg_in, *sg_out; - struct rk_alg_ctx *alg_ctx = crypto_tfm_ctx(rk_dev->async_req->tfm); + struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(rk_dev->async_req); CRYPTO_TRACE("aligned = %d, total = %u, left_bytes = %u\n", alg_ctx->aligned, alg_ctx->total, alg_ctx->left_bytes); @@ -240,7 +247,7 @@ exit: static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) { struct rk_crypto_dev *rk_dev = platform_get_drvdata(dev_id); - struct rk_alg_ctx *alg_ctx = crypto_tfm_ctx(rk_dev->async_req->tfm); + struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(rk_dev->async_req); spin_lock(&rk_dev->lock); @@ -297,7 +304,7 @@ static void rk_crypto_queue_task_cb(unsigned long data) backlog = NULL; } - alg_ctx = crypto_tfm_ctx(async_req->tfm); + alg_ctx = rk_alg_ctx_cast(async_req); rk_dev->async_req = async_req; err = alg_ctx->ops.start(rk_dev); @@ -310,7 +317,7 @@ static void rk_crypto_queue_task_cb(unsigned long data) static void rk_crypto_done_task_cb(unsigned long data) { struct rk_crypto_dev *rk_dev = (struct rk_crypto_dev *)data; - struct rk_alg_ctx *alg_ctx = crypto_tfm_ctx(rk_dev->async_req->tfm); + struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(rk_dev->async_req); if (rk_dev->err) { alg_ctx->ops.complete(rk_dev->async_req, rk_dev->err); @@ -369,9 +376,9 @@ static int rk_crypto_register(struct rk_crypto_dev *rk_dev) if (tmp_algs->algo == CIPHER_ALGO_AES && tmp_algs->mode != CIPHER_MODE_XTS && soc_data->use_soft_aes192) - tmp_algs->alg.crypto.cra_flags |= CRYPTO_ALG_NEED_FALLBACK; + tmp_algs->alg.crypto.base.cra_flags |= CRYPTO_ALG_NEED_FALLBACK; - err = crypto_register_alg(&tmp_algs->alg.crypto); + err = crypto_register_skcipher(&tmp_algs->alg.crypto); } else if (tmp_algs->type == ALG_TYPE_HASH || tmp_algs->type == ALG_TYPE_HMAC) { err = crypto_register_ahash(&tmp_algs->alg.hash); } else if (tmp_algs->type == ALG_TYPE_ASYM) { @@ -393,7 +400,7 @@ err_cipher_algs: for (k = 0; k < i; k++, algs_name++) { tmp_algs = rk_crypto_find_algs(rk_dev, *algs_name); if (tmp_algs->type == ALG_TYPE_CIPHER) - crypto_unregister_alg(&tmp_algs->alg.crypto); + crypto_unregister_skcipher(&tmp_algs->alg.crypto); else if (tmp_algs->type == ALG_TYPE_HASH || tmp_algs->type == ALG_TYPE_HMAC) crypto_unregister_ahash(&tmp_algs->alg.hash); else if (tmp_algs->type == ALG_TYPE_ASYM) @@ -413,7 +420,7 @@ static void rk_crypto_unregister(struct rk_crypto_dev *rk_dev) for (i = 0; i < rk_dev->soc_data->valid_algs_num; i++, algs_name++) { tmp_algs = rk_crypto_find_algs(rk_dev, *algs_name); if (tmp_algs->type == ALG_TYPE_CIPHER) - crypto_unregister_alg(&tmp_algs->alg.crypto); + crypto_unregister_skcipher(&tmp_algs->alg.crypto); else if (tmp_algs->type == ALG_TYPE_HASH || tmp_algs->type == ALG_TYPE_HMAC) crypto_unregister_ahash(&tmp_algs->alg.hash); else if (tmp_algs->type == ALG_TYPE_ASYM) diff --git a/drivers/crypto/rockchip/rk_crypto_core.h b/drivers/crypto/rockchip/rk_crypto_core.h index 3dc2f0c57498..ea82090a5a4c 100644 --- a/drivers/crypto/rockchip/rk_crypto_core.h +++ b/drivers/crypto/rockchip/rk_crypto_core.h @@ -12,13 +12,19 @@ #include #include #include +#include #include #include #include +#include #include + #include #include #include +#include +#include +#include #include "rk_crypto_bignum.h" @@ -128,6 +134,7 @@ struct rk_cipher_ctx { /* for fallback */ struct crypto_skcipher *fallback_tfm; + struct skcipher_request fallback_req; // keep at the end }; struct rk_rsa_ctx { @@ -149,7 +156,7 @@ enum alg_type { struct rk_crypto_algt { struct rk_crypto_dev *rk_dev; union { - struct crypto_alg crypto; + struct skcipher_alg crypto; struct ahash_alg hash; struct akcipher_alg asym; } alg; @@ -198,26 +205,22 @@ enum rk_cipher_mode { .algo = CIPHER_ALGO_##cipher_algo,\ .mode = CIPHER_MODE_##cipher_mode,\ .alg.crypto = {\ - .cra_name = #algo_name,\ - .cra_driver_name = #driver_name,\ - .cra_priority = RK_CRYPTO_PRIORITY,\ - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |\ - CRYPTO_ALG_ASYNC,\ - .cra_blocksize = cipher_algo##_BLOCK_SIZE,\ - .cra_ctxsize = sizeof(struct rk_cipher_ctx),\ - .cra_alignmask = 0x07,\ - .cra_type = &crypto_ablkcipher_type,\ - .cra_module = THIS_MODULE,\ - .cra_init = rk_ablk_cra_init,\ - .cra_exit = rk_ablk_cra_exit,\ - .cra_u.ablkcipher = {\ - .min_keysize = cipher_algo##_MIN_KEY_SIZE,\ - .max_keysize = cipher_algo##_MAX_KEY_SIZE,\ - .ivsize = cipher_algo##_BLOCK_SIZE,\ - .setkey = rk_cipher_setkey,\ - .encrypt = rk_cipher_encrypt,\ - .decrypt = rk_cipher_decrypt,\ - } \ + .base.cra_name = #algo_name,\ + .base.cra_driver_name = #driver_name,\ + .base.cra_priority = RK_CRYPTO_PRIORITY,\ + .base.cra_flags = CRYPTO_ALG_ASYNC,\ + .base.cra_blocksize = cipher_algo##_BLOCK_SIZE,\ + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx),\ + .base.cra_alignmask = 0x07,\ + .base.cra_module = THIS_MODULE,\ + .init = rk_ablk_init_tfm,\ + .exit = rk_ablk_exit_tfm,\ + .min_keysize = cipher_algo##_MIN_KEY_SIZE,\ + .max_keysize = cipher_algo##_MAX_KEY_SIZE,\ + .ivsize = cipher_algo##_BLOCK_SIZE,\ + .setkey = rk_cipher_setkey,\ + .encrypt = rk_cipher_encrypt,\ + .decrypt = rk_cipher_decrypt,\ } \ } @@ -227,26 +230,22 @@ enum rk_cipher_mode { .algo = CIPHER_ALGO_##cipher_algo,\ .mode = CIPHER_MODE_XTS,\ .alg.crypto = {\ - .cra_name = #algo_name,\ - .cra_driver_name = #driver_name,\ - .cra_priority = RK_CRYPTO_PRIORITY,\ - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |\ - CRYPTO_ALG_ASYNC,\ - .cra_blocksize = cipher_algo##_BLOCK_SIZE,\ - .cra_ctxsize = sizeof(struct rk_cipher_ctx),\ - .cra_alignmask = 0x07,\ - .cra_type = &crypto_ablkcipher_type,\ - .cra_module = THIS_MODULE,\ - .cra_init = rk_ablk_cra_init,\ - .cra_exit = rk_ablk_cra_exit,\ - .cra_u.ablkcipher = {\ - .min_keysize = cipher_algo##_MAX_KEY_SIZE,\ - .max_keysize = cipher_algo##_MAX_KEY_SIZE * 2,\ - .ivsize = cipher_algo##_BLOCK_SIZE,\ - .setkey = rk_cipher_setkey,\ - .encrypt = rk_cipher_encrypt,\ - .decrypt = rk_cipher_decrypt,\ - } \ + .base.cra_name = #algo_name,\ + .base.cra_driver_name = #driver_name,\ + .base.cra_priority = RK_CRYPTO_PRIORITY,\ + .base.cra_flags = CRYPTO_ALG_ASYNC,\ + .base.cra_blocksize = cipher_algo##_BLOCK_SIZE,\ + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx),\ + .base.cra_alignmask = 0x07,\ + .base.cra_module = THIS_MODULE,\ + .init = rk_ablk_init_tfm,\ + .exit = rk_ablk_exit_tfm,\ + .min_keysize = cipher_algo##_MAX_KEY_SIZE,\ + .max_keysize = cipher_algo##_MAX_KEY_SIZE * 2,\ + .ivsize = cipher_algo##_BLOCK_SIZE,\ + .setkey = rk_cipher_setkey,\ + .encrypt = rk_cipher_encrypt,\ + .decrypt = rk_cipher_decrypt,\ } \ } diff --git a/drivers/crypto/rockchip/rk_crypto_v1_ablkcipher.c b/drivers/crypto/rockchip/rk_crypto_v1_skcipher.c similarity index 73% rename from drivers/crypto/rockchip/rk_crypto_v1_ablkcipher.c rename to drivers/crypto/rockchip/rk_crypto_v1_skcipher.c index d684c466f930..ed3be60bcdf2 100644 --- a/drivers/crypto/rockchip/rk_crypto_v1_ablkcipher.c +++ b/drivers/crypto/rockchip/rk_crypto_v1_skcipher.c @@ -17,10 +17,10 @@ static struct rk_alg_ctx *rk_alg_ctx_cast( struct rk_crypto_dev *rk_dev) { - struct ablkcipher_request *req = - ablkcipher_request_cast(rk_dev->async_req); - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct skcipher_request *req = + skcipher_request_cast(rk_dev->async_req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); return &ctx->algs_ctx; } @@ -48,11 +48,11 @@ static void rk_crypto_complete(struct crypto_async_request *base, int err) } static int rk_handle_req(struct rk_crypto_dev *rk_dev, - struct ablkcipher_request *req) + struct skcipher_request *req) { struct rk_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); - if (!IS_ALIGNED(req->nbytes, ctx->algs_ctx.align_size)) + if (!IS_ALIGNED(req->cryptlen, ctx->algs_ctx.align_size)) return -EINVAL; else return rk_dev->enqueue(rk_dev, &req->base); @@ -92,14 +92,13 @@ error: return -EINVAL; } -static int rk_cipher_setkey(struct crypto_ablkcipher *cipher, +static int rk_cipher_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int keylen) { - struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); - struct rk_cipher_ctx *ctx = crypto_tfm_ctx(tfm); - struct crypto_alg *alg = tfm->__crt_alg; + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); + struct skcipher_alg *alg = crypto_skcipher_alg(cipher); struct rk_crypto_algt *algt; - u32 tmp[DES_EXPKEY_WORDS]; + int err; algt = container_of(alg, struct rk_crypto_algt, alg.crypto); @@ -111,14 +110,14 @@ static int rk_cipher_setkey(struct crypto_ablkcipher *cipher, if (keylen != DES_KEY_SIZE) goto error; - if (!des_ekey(tmp, key) && - (tfm->crt_flags & CRYPTO_TFM_REQ_WEAK_KEY)) { - tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY; - return -EINVAL; - } + err = verify_skcipher_des_key(cipher, key); + if (err) + goto error; + break; case CIPHER_ALGO_DES3_EDE: - if (keylen != DES3_EDE_KEY_SIZE) + err = verify_skcipher_des3_key(cipher, key); + if (err) goto error; break; case CIPHER_ALGO_AES: @@ -137,16 +136,15 @@ static int rk_cipher_setkey(struct crypto_ablkcipher *cipher, return 0; error: - crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); return -EINVAL; } -static int rk_cipher_encrypt(struct ablkcipher_request *req) +static int rk_cipher_encrypt(struct skcipher_request *req) { - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm); - struct crypto_alg *alg = tfm->base.__crt_alg; + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct skcipher_alg *alg = crypto_skcipher_alg(tfm); struct rk_crypto_dev *rk_dev = ctx->rk_dev; struct rk_crypto_algt *algt; int ret; @@ -162,11 +160,11 @@ static int rk_cipher_encrypt(struct ablkcipher_request *req) return rk_handle_req(rk_dev, req); } -static int rk_cipher_decrypt(struct ablkcipher_request *req) +static int rk_cipher_decrypt(struct skcipher_request *req) { - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm); - struct crypto_alg *alg = tfm->base.__crt_alg; + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct skcipher_alg *alg = crypto_skcipher_alg(tfm); struct rk_crypto_dev *rk_dev = ctx->rk_dev; struct rk_crypto_algt *algt; int ret; @@ -186,15 +184,15 @@ static int rk_cipher_decrypt(struct ablkcipher_request *req) static void rk_ablk_hw_init(struct rk_crypto_dev *rk_dev) { - struct ablkcipher_request *req = - ablkcipher_request_cast(rk_dev->async_req); - struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); - struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); - struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(cipher); + struct skcipher_request *req = + skcipher_request_cast(rk_dev->async_req); + struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); + struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); u32 ivsize, block, conf_reg = 0; block = crypto_tfm_alg_blocksize(tfm); - ivsize = crypto_ablkcipher_ivsize(cipher); + ivsize = crypto_skcipher_ivsize(cipher); if (block == DES_BLOCK_SIZE) { memcpy_toio(ctx->rk_dev->reg + RK_CRYPTO_TDES_KEY1_0, @@ -204,7 +202,7 @@ static void rk_ablk_hw_init(struct rk_crypto_dev *rk_dev) RK_CRYPTO_TDES_BYTESWAP_IV; CRYPTO_WRITE(rk_dev, RK_CRYPTO_TDES_CTRL, ctx->mode); memcpy_toio(rk_dev->reg + RK_CRYPTO_TDES_IV_0, - req->info, ivsize); + req->iv, ivsize); conf_reg = RK_CRYPTO_DESSEL; } else { memcpy_toio(ctx->rk_dev->reg + RK_CRYPTO_AES_KEY_0, @@ -219,7 +217,7 @@ static void rk_ablk_hw_init(struct rk_crypto_dev *rk_dev) ctx->mode |= RK_CRYPTO_AES_256BIT_key; CRYPTO_WRITE(rk_dev, RK_CRYPTO_AES_CTRL, ctx->mode); memcpy_toio(rk_dev->reg + RK_CRYPTO_AES_IV_0, - req->info, ivsize); + req->iv, ivsize); } conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO | RK_CRYPTO_BYTESWAP_BRFIFO; @@ -242,12 +240,12 @@ static void crypto_dma_start(struct rk_crypto_dev *rk_dev) static int rk_set_data_start(struct rk_crypto_dev *rk_dev) { int err; - struct ablkcipher_request *req = - ablkcipher_request_cast(rk_dev->async_req); - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct skcipher_request *req = + skcipher_request_cast(rk_dev->async_req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(rk_dev); - u32 ivsize = crypto_ablkcipher_ivsize(tfm); + u32 ivsize = crypto_skcipher_ivsize(tfm); u8 *src_last_blk = page_address(sg_page(alg_ctx->sg_src)) + alg_ctx->sg_src->offset + alg_ctx->sg_src->length - ivsize; @@ -257,7 +255,7 @@ static int rk_set_data_start(struct rk_crypto_dev *rk_dev) if (ctx->mode & RK_CRYPTO_DEC) { memcpy(ctx->iv, src_last_blk, ivsize); sg_pcopy_to_buffer(alg_ctx->req_src, alg_ctx->src_nents, - req->info, ivsize, alg_ctx->total - ivsize); + req->iv, ivsize, alg_ctx->total - ivsize); } err = rk_dev->load_data(rk_dev, alg_ctx->sg_src, alg_ctx->sg_dst); @@ -268,20 +266,20 @@ static int rk_set_data_start(struct rk_crypto_dev *rk_dev) static int rk_ablk_start(struct rk_crypto_dev *rk_dev) { - struct ablkcipher_request *req = - ablkcipher_request_cast(rk_dev->async_req); + struct skcipher_request *req = + skcipher_request_cast(rk_dev->async_req); struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(rk_dev); unsigned long flags; int err = 0; - alg_ctx->left_bytes = req->nbytes; - alg_ctx->total = req->nbytes; + alg_ctx->left_bytes = req->cryptlen; + alg_ctx->total = req->cryptlen; alg_ctx->sg_src = req->src; alg_ctx->req_src = req->src; - alg_ctx->src_nents = sg_nents_for_len(req->src, req->nbytes); + alg_ctx->src_nents = sg_nents_for_len(req->src, req->cryptlen); alg_ctx->sg_dst = req->dst; alg_ctx->req_dst = req->dst; - alg_ctx->dst_nents = sg_nents_for_len(req->dst, req->nbytes); + alg_ctx->dst_nents = sg_nents_for_len(req->dst, req->cryptlen); spin_lock_irqsave(&rk_dev->lock, flags); rk_ablk_hw_init(rk_dev); @@ -292,20 +290,20 @@ static int rk_ablk_start(struct rk_crypto_dev *rk_dev) static void rk_iv_copyback(struct rk_crypto_dev *rk_dev) { - struct ablkcipher_request *req = - ablkcipher_request_cast(rk_dev->async_req); - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct skcipher_request *req = + skcipher_request_cast(rk_dev->async_req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(rk_dev); - u32 ivsize = crypto_ablkcipher_ivsize(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) && req->info) { + if (!(ctx->mode & RK_CRYPTO_DEC) && req->iv) { if (alg_ctx->aligned) { - memcpy(req->info, sg_virt(alg_ctx->sg_dst) + + memcpy(req->iv, sg_virt(alg_ctx->sg_dst) + alg_ctx->sg_dst->length - ivsize, ivsize); } else { - memcpy(req->info, rk_dev->addr_vir + + memcpy(req->iv, rk_dev->addr_vir + alg_ctx->count - ivsize, ivsize); } } @@ -313,12 +311,12 @@ static void rk_iv_copyback(struct rk_crypto_dev *rk_dev) static void rk_update_iv(struct rk_crypto_dev *rk_dev) { - struct ablkcipher_request *req = - ablkcipher_request_cast(rk_dev->async_req); - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct skcipher_request *req = + skcipher_request_cast(rk_dev->async_req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(rk_dev); - u32 ivsize = crypto_ablkcipher_ivsize(tfm); + u32 ivsize = crypto_skcipher_ivsize(tfm); u8 *new_iv = NULL; if (ctx->mode & RK_CRYPTO_DEC) { @@ -373,13 +371,14 @@ out_rx: return err; } -static int rk_ablk_cra_init(struct crypto_tfm *tfm) +static int rk_ablk_init_tfm(struct crypto_skcipher *tfm) { - struct rk_cipher_ctx *ctx = crypto_tfm_ctx(tfm); - struct crypto_alg *alg = tfm->__crt_alg; + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct skcipher_alg *alg = crypto_skcipher_alg(tfm); struct rk_alg_ctx *alg_ctx = &ctx->algs_ctx; struct rk_crypto_algt *algt; struct rk_crypto_dev *rk_dev; + const char *alg_name = crypto_tfm_alg_name(crypto_skcipher_tfm(tfm)); algt = container_of(alg, struct rk_crypto_algt, alg.crypto); rk_dev = algt->rk_dev; @@ -389,9 +388,9 @@ static int rk_ablk_cra_init(struct crypto_tfm *tfm) if (!rk_dev->request_crypto) return -EFAULT; - rk_dev->request_crypto(rk_dev, crypto_tfm_alg_name(tfm)); + rk_dev->request_crypto(rk_dev, alg_name); - alg_ctx->align_size = crypto_tfm_alg_alignmask(tfm) + 1; + alg_ctx->align_size = crypto_skcipher_alignmask(tfm) + 1; alg_ctx->ops.start = rk_ablk_start; alg_ctx->ops.update = rk_ablk_rx; @@ -403,11 +402,12 @@ static int rk_ablk_cra_init(struct crypto_tfm *tfm) return 0; } -static void rk_ablk_cra_exit(struct crypto_tfm *tfm) +static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm) { - struct rk_cipher_ctx *ctx = crypto_tfm_ctx(tfm); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + const char *alg_name = crypto_tfm_alg_name(crypto_skcipher_tfm(tfm)); - ctx->rk_dev->release_crypto(ctx->rk_dev, crypto_tfm_alg_name(tfm)); + ctx->rk_dev->release_crypto(ctx->rk_dev, alg_name); } int rk_hw_crypto_v1_init(struct device *dev, void *hw_info) diff --git a/drivers/crypto/rockchip/rk_crypto_v2_ahash.c b/drivers/crypto/rockchip/rk_crypto_v2_ahash.c index d02117b498e5..47ce1fb6e90d 100644 --- a/drivers/crypto/rockchip/rk_crypto_v2_ahash.c +++ b/drivers/crypto/rockchip/rk_crypto_v2_ahash.c @@ -402,8 +402,6 @@ static int rk_ahash_hmac_setkey(struct crypto_ahash *tfm, const u8 *key, } exit: - if (ret) - crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); return ret; } diff --git a/drivers/crypto/rockchip/rk_crypto_v2_pka.c b/drivers/crypto/rockchip/rk_crypto_v2_pka.c index 15d8ae59db67..f773bab96759 100644 --- a/drivers/crypto/rockchip/rk_crypto_v2_pka.c +++ b/drivers/crypto/rockchip/rk_crypto_v2_pka.c @@ -150,6 +150,17 @@ enum pka_opcode { /********************* Private Variable Definition ***************************/ static void __iomem *pka_base; +/* + * Turn off clang optimization temporarily. Pka_word_memcpy will be optimized + * to memcpy, but the SRAM area of PKA can only be accessed in word, so memcpy + * will cause panic. + */ +#if defined(__clang__) + +#pragma clang optimize off + +#endif + static void pka_word_memcpy(u32 *dst, u32 *src, u32 size) { u32 i; @@ -166,6 +177,12 @@ static void pka_word_memset(u32 *buff, u32 val, u32 size) buff[i] = val; } +#if defined(__clang__) + +#pragma clang optimize on + +#endif + static int pka_wait_pipe_rdy(void) { u32 reg_val = 0; diff --git a/drivers/crypto/rockchip/rk_crypto_v2_ablkcipher.c b/drivers/crypto/rockchip/rk_crypto_v2_skcipher.c similarity index 80% rename from drivers/crypto/rockchip/rk_crypto_v2_ablkcipher.c rename to drivers/crypto/rockchip/rk_crypto_v2_skcipher.c index 44b1acd6ebb9..7cca1ba7a1c0 100644 --- a/drivers/crypto/rockchip/rk_crypto_v2_ablkcipher.c +++ b/drivers/crypto/rockchip/rk_crypto_v2_skcipher.c @@ -38,10 +38,10 @@ static const u32 cipher_mode2bc[] = { static struct rk_alg_ctx *rk_alg_ctx_cast( struct rk_crypto_dev *rk_dev) { - struct ablkcipher_request *req = - ablkcipher_request_cast(rk_dev->async_req); - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct skcipher_request *req = + skcipher_request_cast(rk_dev->async_req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); return &ctx->algs_ctx; } @@ -159,9 +159,9 @@ static void write_tkey_reg(struct rk_crypto_dev *rk_dev, const u8 *key, } } -static struct rk_crypto_algt *rk_cipher_get_algt(struct crypto_ablkcipher *tfm) +static struct rk_crypto_algt *rk_cipher_get_algt(struct crypto_skcipher *tfm) { - struct crypto_alg *alg = tfm->base.__crt_alg; + struct skcipher_alg *alg = crypto_skcipher_alg(tfm); return container_of(alg, struct rk_crypto_algt, alg.crypto); } @@ -171,9 +171,9 @@ static bool is_use_fallback(struct rk_cipher_ctx *ctx) return ctx->keylen == AES_KEYSIZE_192 && ctx->fallback_tfm; } -static bool is_no_multi_blocksize(struct ablkcipher_request *req) +static bool is_no_multi_blocksize(struct skcipher_request *req) { - struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); + struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); struct rk_crypto_algt *algt = rk_cipher_get_algt(cipher); return (algt->mode == CIPHER_MODE_CFB || @@ -188,24 +188,22 @@ static void rk_crypto_complete(struct crypto_async_request *base, int err) } static int rk_handle_req(struct rk_crypto_dev *rk_dev, - struct ablkcipher_request *req) + struct skcipher_request *req) { struct rk_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); - if (!IS_ALIGNED(req->nbytes, ctx->algs_ctx.align_size) && + if (!IS_ALIGNED(req->cryptlen, ctx->algs_ctx.align_size) && !is_no_multi_blocksize(req)) return -EINVAL; else return rk_dev->enqueue(rk_dev, &req->base); } -static int rk_cipher_setkey(struct crypto_ablkcipher *cipher, +static int rk_cipher_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int keylen) { - struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); struct rk_crypto_algt *algt = rk_cipher_get_algt(cipher); - struct rk_cipher_ctx *ctx = crypto_tfm_ctx(tfm); - u32 tmp[DES_EXPKEY_WORDS]; + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); int ret = -EINVAL; CRYPTO_MSG("algo = %x, mode = %x, key_len = %d\n", @@ -213,17 +211,13 @@ static int rk_cipher_setkey(struct crypto_ablkcipher *cipher, switch (algt->algo) { case CIPHER_ALGO_DES: - if (keylen != DES_KEY_SIZE) + ret = verify_skcipher_des_key(cipher, key); + if (ret) goto error; - - if (!des_ekey(tmp, key) && - (tfm->crt_flags & CRYPTO_TFM_REQ_WEAK_KEY)) { - tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY; - return -EINVAL; - } break; case CIPHER_ALGO_DES3_EDE: - if (keylen != DES3_EDE_KEY_SIZE) + ret = verify_skcipher_des3_key(cipher, key); + if (ret) goto error; break; case CIPHER_ALGO_AES: @@ -269,41 +263,41 @@ static int rk_cipher_setkey(struct crypto_ablkcipher *cipher, return 0; error: - crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); return ret; } -static int rk_cipher_fallback(struct ablkcipher_request *req, +static int rk_cipher_fallback(struct skcipher_request *req, struct rk_cipher_ctx *ctx, bool encrypt) { int ret; - SKCIPHER_REQUEST_ON_STACK(subreq, ctx->fallback_tfm); - CRYPTO_MSG("use fallback tfm"); - skcipher_request_set_tfm(subreq, ctx->fallback_tfm); - skcipher_request_set_callback(subreq, req->base.flags, - NULL, NULL); - skcipher_request_set_crypt(subreq, req->src, req->dst, - req->nbytes, req->info); - ret = encrypt ? crypto_skcipher_encrypt(subreq) : - crypto_skcipher_decrypt(subreq); - skcipher_request_zero(subreq); + skcipher_request_set_tfm(&ctx->fallback_req, ctx->fallback_tfm); + skcipher_request_set_callback(&ctx->fallback_req, + req->base.flags, + req->base.complete, + req->base.data); + + skcipher_request_set_crypt(&ctx->fallback_req, req->src, + req->dst, req->cryptlen, req->iv); + + ret = encrypt ? crypto_skcipher_encrypt(&ctx->fallback_req) : + crypto_skcipher_decrypt(&ctx->fallback_req); return ret; } -static int rk_cipher_crypt(struct ablkcipher_request *req, bool encrypt) +static int rk_cipher_crypt(struct skcipher_request *req, bool encrypt) { - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); struct rk_crypto_algt *algt = rk_cipher_get_algt(tfm); int ret = -EINVAL; CRYPTO_TRACE("%s total = %u", - encrypt ? "encrypt" : "decrypt", req->nbytes); + encrypt ? "encrypt" : "decrypt", req->cryptlen); if (is_use_fallback(ctx)) { ret = rk_cipher_fallback(req, ctx, encrypt); @@ -320,29 +314,29 @@ static int rk_cipher_crypt(struct ablkcipher_request *req, bool encrypt) return ret; } -static int rk_cipher_encrypt(struct ablkcipher_request *req) +static int rk_cipher_encrypt(struct skcipher_request *req) { return rk_cipher_crypt(req, true); } -static int rk_cipher_decrypt(struct ablkcipher_request *req) +static int rk_cipher_decrypt(struct skcipher_request *req) { return rk_cipher_crypt(req, false); } static void rk_ablk_hw_init(struct rk_crypto_dev *rk_dev) { - struct ablkcipher_request *req = - ablkcipher_request_cast(rk_dev->async_req); - struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); - struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); - struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(cipher); + struct skcipher_request *req = + skcipher_request_cast(rk_dev->async_req); + struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); + struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); u32 ivsize, block; CRYPTO_WRITE(rk_dev, CRYPTO_BC_CTL, 0x00010000); block = crypto_tfm_alg_blocksize(tfm); - ivsize = crypto_ablkcipher_ivsize(cipher); + ivsize = crypto_skcipher_ivsize(cipher); write_key_reg(ctx->rk_dev, ctx->key, ctx->keylen); if (MASK_BC_MODE(ctx->mode) == CRYPTO_BC_XTS) @@ -350,7 +344,7 @@ static void rk_ablk_hw_init(struct rk_crypto_dev *rk_dev) ctx->key + ctx->keylen, ctx->keylen); if (MASK_BC_MODE(ctx->mode) != CRYPTO_BC_ECB) - set_iv_reg(rk_dev, req->info, ivsize); + set_iv_reg(rk_dev, req->iv, ivsize); if (block != DES_BLOCK_SIZE) { if (ctx->keylen == AES_KEYSIZE_128) @@ -374,8 +368,8 @@ static void crypto_dma_start(struct rk_crypto_dev *rk_dev) { struct rk_hw_crypto_v2_info *hw_info = (struct rk_hw_crypto_v2_info *)rk_dev->hw_info; - struct ablkcipher_request *req = - ablkcipher_request_cast(rk_dev->async_req); + struct skcipher_request *req = + skcipher_request_cast(rk_dev->async_req); struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(rk_dev); u32 calc_len = alg_ctx->count; @@ -415,20 +409,20 @@ static int rk_set_data_start(struct rk_crypto_dev *rk_dev) static int rk_ablk_start(struct rk_crypto_dev *rk_dev) { - struct ablkcipher_request *req = - ablkcipher_request_cast(rk_dev->async_req); + struct skcipher_request *req = + skcipher_request_cast(rk_dev->async_req); struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(rk_dev); unsigned long flags; int err = 0; - alg_ctx->left_bytes = req->nbytes; - alg_ctx->total = req->nbytes; + alg_ctx->left_bytes = req->cryptlen; + alg_ctx->total = req->cryptlen; alg_ctx->sg_src = req->src; alg_ctx->req_src = req->src; - alg_ctx->src_nents = sg_nents_for_len(req->src, req->nbytes); + alg_ctx->src_nents = sg_nents_for_len(req->src, req->cryptlen); alg_ctx->sg_dst = req->dst; alg_ctx->req_dst = req->dst; - alg_ctx->dst_nents = sg_nents_for_len(req->dst, req->nbytes); + alg_ctx->dst_nents = sg_nents_for_len(req->dst, req->cryptlen); CRYPTO_TRACE("total = %u", alg_ctx->total); @@ -441,21 +435,21 @@ static int rk_ablk_start(struct rk_crypto_dev *rk_dev) static void rk_iv_copyback(struct rk_crypto_dev *rk_dev) { - struct ablkcipher_request *req = - ablkcipher_request_cast(rk_dev->async_req); - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); - struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct skcipher_request *req = + skcipher_request_cast(rk_dev->async_req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); struct rk_alg_ctx *alg_ctx = rk_alg_ctx_cast(rk_dev); - u32 ivsize = crypto_ablkcipher_ivsize(tfm); + u32 ivsize = crypto_skcipher_ivsize(tfm); /* Update the IV buffer to contain the next IV for encryption mode. */ - if (!IS_BC_DECRYPT(ctx->mode) && req->info) { + if (!IS_BC_DECRYPT(ctx->mode) && req->iv) { if (alg_ctx->aligned) { - memcpy(req->info, sg_virt(alg_ctx->sg_dst) + + memcpy(req->iv, sg_virt(alg_ctx->sg_dst) + alg_ctx->count - ivsize, ivsize); } else { - memcpy(req->info, rk_dev->addr_vir + + memcpy(req->iv, rk_dev->addr_vir + alg_ctx->count - ivsize, ivsize); } } @@ -499,12 +493,11 @@ out_rx: return err; } -static int rk_ablk_cra_init(struct crypto_tfm *tfm) +static int rk_ablk_init_tfm(struct crypto_skcipher *tfm) { - struct rk_crypto_algt *algt = - rk_cipher_get_algt(__crypto_ablkcipher_cast(tfm)); - struct rk_cipher_ctx *ctx = crypto_tfm_ctx(tfm); - const char *alg_name = crypto_tfm_alg_name(tfm); + struct rk_crypto_algt *algt = rk_cipher_get_algt(tfm); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + const char *alg_name = crypto_tfm_alg_name(crypto_skcipher_tfm(tfm)); struct rk_crypto_dev *rk_dev = algt->rk_dev; struct rk_alg_ctx *alg_ctx = &ctx->algs_ctx; @@ -517,7 +510,7 @@ static int rk_ablk_cra_init(struct crypto_tfm *tfm) rk_dev->request_crypto(rk_dev, alg_name); - alg_ctx->align_size = crypto_tfm_alg_blocksize(tfm); + alg_ctx->align_size = crypto_skcipher_blocksize(tfm); alg_ctx->ops.start = rk_ablk_start; alg_ctx->ops.update = rk_ablk_rx; @@ -526,7 +519,7 @@ static int rk_ablk_cra_init(struct crypto_tfm *tfm) ctx->rk_dev = rk_dev; - if (algt->alg.crypto.cra_flags & CRYPTO_ALG_NEED_FALLBACK) { + if (algt->alg.crypto.base.cra_flags & CRYPTO_ALG_NEED_FALLBACK) { CRYPTO_MSG("alloc fallback tfm, name = %s", alg_name); ctx->fallback_tfm = crypto_alloc_skcipher(alg_name, 0, CRYPTO_ALG_ASYNC | @@ -541,9 +534,10 @@ static int rk_ablk_cra_init(struct crypto_tfm *tfm) return 0; } -static void rk_ablk_cra_exit(struct crypto_tfm *tfm) +static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm) { - struct rk_cipher_ctx *ctx = crypto_tfm_ctx(tfm); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + const char *alg_name = crypto_tfm_alg_name(crypto_skcipher_tfm(tfm)); CRYPTO_TRACE(); @@ -552,7 +546,7 @@ static void rk_ablk_cra_exit(struct crypto_tfm *tfm) crypto_free_skcipher(ctx->fallback_tfm); } - ctx->rk_dev->release_crypto(ctx->rk_dev, crypto_tfm_alg_name(tfm)); + ctx->rk_dev->release_crypto(ctx->rk_dev, alg_name); } int rk_hw_crypto_v2_init(struct device *dev, void *hw_info)