From 7869f2591ca2dae30be6420d5810caa973a43cdf Mon Sep 17 00:00:00 2001 From: Lin Jinhan Date: Fri, 28 Mar 2025 17:44:26 +0800 Subject: [PATCH] crypto: rockchip: rkce: fix asym NULL point reference do_one_request cannot call crypto_finalize_akcipher_request, otherwise it will result in a null pointer reference. The asym algorithm needs to be changed to synchronous mode. Signed-off-by: Lin Jinhan Change-Id: I6615f113691a334b148da0364b7a1e3764d27739 --- drivers/crypto/rockchip/rkce/rkce_akcipher.c | 77 ++++++-------------- drivers/crypto/rockchip/rkce/rkce_dev.c | 7 +- drivers/crypto/rockchip/rkce/rkce_dev.h | 1 - 3 files changed, 25 insertions(+), 60 deletions(-) diff --git a/drivers/crypto/rockchip/rkce/rkce_akcipher.c b/drivers/crypto/rockchip/rkce/rkce_akcipher.c index 90066914ddad..b2b50f590831 100644 --- a/drivers/crypto/rockchip/rkce/rkce_akcipher.c +++ b/drivers/crypto/rockchip/rkce/rkce_akcipher.c @@ -22,6 +22,8 @@ #include "rkce_sm2signature.asn1.h" #include "rkce_ecdsasignature.asn1.h" +static DEFINE_MUTEX(akcipher_mutex); + static void rkce_rsa_adjust_rsa_key(struct rsa_key *key) { if (key->n_sz && key->n && !key->n[0]) { @@ -131,32 +133,8 @@ static int rkce_rsa_setprivkey(struct crypto_akcipher *tfm, const void *key, return rkce_rsa_setkey(tfm, key, keylen, true); } -static int rkce_rsa_handle_req(struct akcipher_request *req, bool encrypt) +static int rkce_rsa_calc(struct akcipher_request *req, bool encrypt) { - struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); - struct rkce_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); - struct crypto_engine *engine = ctx->algt->rk_dev->asym_engine; - - rk_trace("enter.\n"); - - ctx->is_enc = encrypt; - - return crypto_transfer_akcipher_request_to_engine(engine, req); -} - -static int rkce_rsa_enc(struct akcipher_request *req) -{ - return rkce_rsa_handle_req(req, true); -} - -static int rkce_rsa_dec(struct akcipher_request *req) -{ - return rkce_rsa_handle_req(req, false); -} - -static int rkce_rsa_run_req(struct crypto_engine *engine, void *async_req) -{ - struct akcipher_request *req = container_of(async_req, struct akcipher_request, base); struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct rkce_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct rkce_bignum *in = NULL, *out = NULL; @@ -169,7 +147,7 @@ static int rkce_rsa_run_req(struct crypto_engine *engine, void *async_req) if (unlikely(!ctx->n || !ctx->e)) goto exit; - if (!ctx->is_enc && !ctx->d) + if (!encrypt && !ctx->d) goto exit; key_byte_size = rkce_bn_get_size(ctx->n); @@ -211,11 +189,15 @@ static int rkce_rsa_run_req(struct crypto_engine *engine, void *async_req) if (ret) goto exit; - if (ctx->is_enc) + mutex_lock(&akcipher_mutex); + + if (encrypt) ret = rkce_pka_expt_mod(in, ctx->e, ctx->n, out); else ret = rkce_pka_expt_mod(in, ctx->d, ctx->n, out); + mutex_unlock(&akcipher_mutex); + if (ret) goto exit; @@ -232,8 +214,6 @@ static int rkce_rsa_run_req(struct crypto_engine *engine, void *async_req) req->dst_len = key_byte_size; exit: - crypto_finalize_akcipher_request(ctx->algt->rk_dev->asym_engine, req, ret); - kfree(tmp_buf); rkce_bn_free(in); @@ -244,6 +224,16 @@ exit: return ret; } +static int rkce_rsa_enc(struct akcipher_request *req) +{ + return rkce_rsa_calc(req, true); +} + +static int rkce_rsa_dec(struct akcipher_request *req) +{ + return rkce_rsa_calc(req, false); +} + static int rkce_rsa_init_tfm(struct crypto_akcipher *tfm) { struct rkce_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); @@ -258,7 +248,6 @@ static int rkce_rsa_init_tfm(struct crypto_akcipher *tfm) ctx->algt = algt; - ctx->enginectx.op.do_one_request = rkce_rsa_run_req; rkce_pka_set_crypto_base(algt->rk_dev->reg); @@ -343,27 +332,8 @@ int rkce_ecc_get_signature_s(void *context, size_t hdrlen, unsigned char tag, return rkce_bn_set_data(sig->y, tmp_value, vlen, RK_BG_BIG_ENDIAN); } -static int rkce_ecc_handle_req(struct akcipher_request *req, bool sign) -{ - struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); - struct rkce_ecc_ctx *ctx = akcipher_tfm_ctx(tfm); - struct crypto_engine *engine = ctx->algt->rk_dev->asym_engine; - - rk_trace("enter.\n"); - - ctx->is_sign = sign; - - return crypto_transfer_akcipher_request_to_engine(engine, req); -} - static int rkce_ec_verify(struct akcipher_request *req) { - return rkce_ecc_handle_req(req, false); -} - -static int rkce_ecc_run_req(struct crypto_engine *engine, void *async_req) -{ - struct akcipher_request *req = container_of(async_req, struct akcipher_request, base); struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct rkce_ecc_ctx *ctx = akcipher_tfm_ctx(tfm); size_t keylen = ctx->nbits / 8; @@ -412,10 +382,11 @@ static int rkce_ecc_run_req(struct crypto_engine *engine, void *async_req) memcpy(&rawhash, buffer + req->src_len, keylen); } - ret = rkce_ecc_verify(ctx->group_id, rawhash, keylen, ctx->point_Q, sig_point); -exit: - crypto_finalize_akcipher_request(ctx->algt->rk_dev->asym_engine, req, ret); + mutex_lock(&akcipher_mutex); + ret = rkce_ecc_verify(ctx->group_id, rawhash, keylen, ctx->point_Q, sig_point); + mutex_unlock(&akcipher_mutex); +exit: kfree(buffer); rkce_ecc_free_point(sig_point); @@ -489,8 +460,6 @@ static int rkce_ec_init_tfm(struct crypto_akcipher *tfm) ctx->algt = algt; - ctx->enginectx.op.do_one_request = rkce_ecc_run_req; - ctx->group_id = rkce_ecc_get_group_id(algt->algo); ctx->nbits = rkce_ecc_get_curve_nbits(ctx->group_id); ctx->point_Q = rkce_ecc_alloc_point_zero(RK_ECP_MAX_BYTES); diff --git a/drivers/crypto/rockchip/rkce/rkce_dev.c b/drivers/crypto/rockchip/rkce/rkce_dev.c index 533bb9f303b2..01e9eea45638 100644 --- a/drivers/crypto/rockchip/rkce/rkce_dev.c +++ b/drivers/crypto/rockchip/rkce/rkce_dev.c @@ -321,11 +321,8 @@ static int rkce_probe(struct platform_device *pdev) rk_dev->hash_engine = crypto_engine_alloc_init(&pdev->dev, true); crypto_engine_start(rk_dev->hash_engine); - rk_dev->asym_engine = crypto_engine_alloc_init(&pdev->dev, true); - crypto_engine_start(rk_dev->asym_engine); - - rk_debug("symm_engine = %p hash_engine = %p asym_engine = %p", - rk_dev->symm_engine, rk_dev->hash_engine, rk_dev->asym_engine); + rk_debug("symm_engine = %p hash_engine = %p", + rk_dev->symm_engine, rk_dev->hash_engine); rk_cryptodev_register_dev(dev, "RKCE multi"); diff --git a/drivers/crypto/rockchip/rkce/rkce_dev.h b/drivers/crypto/rockchip/rkce/rkce_dev.h index 743ed9daddd6..92238c62e08b 100644 --- a/drivers/crypto/rockchip/rkce/rkce_dev.h +++ b/drivers/crypto/rockchip/rkce/rkce_dev.h @@ -57,7 +57,6 @@ struct rkce_dev { spinlock_t lock; struct crypto_engine *symm_engine; struct crypto_engine *hash_engine; - struct crypto_engine *asym_engine; void *hardware; };