mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
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 <troy.lin@rock-chips.com> Change-Id: I6615f113691a334b148da0364b7a1e3764d27739
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user