mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-15 18:03:30 +00:00
178 lines
5.6 KiB
Diff
178 lines
5.6 KiB
Diff
From f39ee05bedc68cf80e76c69692f87b96bf5a3b51 Mon Sep 17 00:00:00 2001
|
|
From: Aviana Cruz <gwencroft@proton.me>
|
|
Date: Tue, 21 Jun 2022 10:47:10 +0800
|
|
Subject: [PATCH] crypto: use AES fallback for small requests
|
|
|
|
Signed-off-by: Aviana Cruz <gwencroft@proton.me>
|
|
---
|
|
crypto/mtk-eip93/eip93-aead.c | 2 -
|
|
crypto/mtk-eip93/eip93-cipher.c | 66 ++++++++++++++++++++++++++++++---
|
|
crypto/mtk-eip93/eip93-cipher.h | 3 ++
|
|
3 files changed, 63 insertions(+), 8 deletions(-)
|
|
|
|
--- a/crypto/mtk-eip93/eip93-aead.c
|
|
+++ b/crypto/mtk-eip93/eip93-aead.c
|
|
@@ -77,8 +77,6 @@ static int mtk_aead_cra_init(struct cryp
|
|
u32 flags = tmpl->flags;
|
|
char *alg_base;
|
|
|
|
- memset(ctx, 0, sizeof(*ctx));
|
|
-
|
|
crypto_aead_set_reqsize(__crypto_aead_cast(tfm),
|
|
sizeof(struct mtk_cipher_reqctx));
|
|
|
|
--- a/crypto/mtk-eip93/eip93-cipher.c
|
|
+++ b/crypto/mtk-eip93/eip93-cipher.c
|
|
@@ -31,6 +31,13 @@ void mtk_skcipher_handle_result(struct c
|
|
skcipher_request_complete(req, err);
|
|
}
|
|
|
|
+static inline bool mtk_skcipher_is_fallback(const struct crypto_tfm *tfm,
|
|
+ u32 flags)
|
|
+{
|
|
+ return (tfm->__crt_alg->cra_flags & CRYPTO_ALG_NEED_FALLBACK) &&
|
|
+ !IS_RFC3686(flags);
|
|
+}
|
|
+
|
|
static int mtk_skcipher_send_req(struct crypto_async_request *async)
|
|
{
|
|
struct skcipher_request *req = skcipher_request_cast(async);
|
|
@@ -53,11 +60,21 @@ static int mtk_skcipher_cra_init(struct
|
|
struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
|
|
struct mtk_alg_template *tmpl = container_of(tfm->__crt_alg,
|
|
struct mtk_alg_template, alg.skcipher.base);
|
|
+ bool fallback = mtk_skcipher_is_fallback(tfm, tmpl->flags);
|
|
+
|
|
+ if (fallback) {
|
|
+ ctx->fallback = crypto_alloc_skcipher(
|
|
+ crypto_tfm_alg_name(tfm), 0, CRYPTO_ALG_NEED_FALLBACK);
|
|
+ if (IS_ERR(ctx->fallback))
|
|
+ return PTR_ERR(ctx->fallback);
|
|
+ }
|
|
|
|
- crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm),
|
|
- sizeof(struct mtk_cipher_reqctx));
|
|
+ crypto_skcipher_set_reqsize(
|
|
+ __crypto_skcipher_cast(tfm),
|
|
+ sizeof(struct mtk_cipher_reqctx) +
|
|
+ (fallback ? crypto_skcipher_reqsize(ctx->fallback) :
|
|
+ 0));
|
|
|
|
- memset(ctx, 0, sizeof(*ctx));
|
|
ctx->mtk = tmpl->mtk;
|
|
|
|
ctx->sa_in = kzalloc(sizeof(struct saRecord_s), GFP_KERNEL);
|
|
@@ -86,6 +103,8 @@ static void mtk_skcipher_cra_exit(struct
|
|
sizeof(struct saRecord_s), DMA_TO_DEVICE);
|
|
kfree(ctx->sa_in);
|
|
kfree(ctx->sa_out);
|
|
+
|
|
+ crypto_free_skcipher(ctx->fallback);
|
|
}
|
|
|
|
static int mtk_skcipher_setkey(struct crypto_skcipher *ctfm, const u8 *key,
|
|
@@ -105,6 +124,8 @@ static int mtk_skcipher_setkey(struct cr
|
|
if (!key || !keylen)
|
|
return err;
|
|
|
|
+ ctx->keylen = keylen;
|
|
+
|
|
#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES)
|
|
if (IS_RFC3686(flags)) {
|
|
if (len < CTR_RFC3686_NONCE_SIZE)
|
|
@@ -128,6 +149,14 @@ static int mtk_skcipher_setkey(struct cr
|
|
#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES)
|
|
if (flags & MTK_ALG_AES) {
|
|
struct crypto_aes_ctx aes;
|
|
+ bool fallback = mtk_skcipher_is_fallback(tfm, flags);
|
|
+
|
|
+ if (fallback && !IS_RFC3686(flags)) {
|
|
+ err = crypto_skcipher_setkey(ctx->fallback, key,
|
|
+ keylen);
|
|
+ if (err)
|
|
+ return err;
|
|
+ }
|
|
|
|
ctx->blksize = AES_BLOCK_SIZE;
|
|
err = aes_expandkey(&aes, key, keylen);
|
|
@@ -160,16 +189,41 @@ static int mtk_skcipher_setkey(struct cr
|
|
return err;
|
|
}
|
|
|
|
-static int mtk_skcipher_crypt(struct skcipher_request *req)
|
|
+static int mtk_skcipher_crypt(struct skcipher_request *req, bool encrypt)
|
|
{
|
|
struct mtk_cipher_reqctx *rctx = skcipher_request_ctx(req);
|
|
struct crypto_async_request *async = &req->base;
|
|
struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
|
|
struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
|
|
+ bool fallback = mtk_skcipher_is_fallback(req->base.tfm, rctx->flags);
|
|
|
|
if (!req->cryptlen)
|
|
return 0;
|
|
|
|
+ /*
|
|
+ * ECB and CBC algorithms require message lengths to be
|
|
+ * multiples of block size.
|
|
+ */
|
|
+ if (IS_ECB(rctx->flags) || IS_CBC(rctx->flags))
|
|
+ if (!IS_ALIGNED(req->cryptlen,
|
|
+ crypto_skcipher_blocksize(skcipher)))
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (fallback &&
|
|
+ req->cryptlen <= (AES_KEYSIZE_128 ?
|
|
+ CONFIG_MTK_EIP93_AES_128_SW_MAX_LEN :
|
|
+ CONFIG_MTK_EIP93_GENERIC_SW_MAX_LEN)) {
|
|
+ skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback);
|
|
+ skcipher_request_set_callback(&rctx->fallback_req,
|
|
+ req->base.flags,
|
|
+ req->base.complete,
|
|
+ req->base.data);
|
|
+ skcipher_request_set_crypt(&rctx->fallback_req, req->src,
|
|
+ req->dst, req->cryptlen, req->iv);
|
|
+ return encrypt ? crypto_skcipher_encrypt(&rctx->fallback_req) :
|
|
+ crypto_skcipher_decrypt(&rctx->fallback_req);
|
|
+ }
|
|
+
|
|
rctx->assoclen = 0;
|
|
rctx->textsize = req->cryptlen;
|
|
rctx->authsize = 0;
|
|
@@ -195,7 +249,7 @@ static int mtk_skcipher_encrypt(struct s
|
|
rctx->flags |= MTK_ENCRYPT;
|
|
rctx->saRecord_base = ctx->sa_base_out;
|
|
|
|
- return mtk_skcipher_crypt(req);
|
|
+ return mtk_skcipher_crypt(req, true);
|
|
}
|
|
|
|
static int mtk_skcipher_decrypt(struct skcipher_request *req)
|
|
@@ -209,7 +263,7 @@ static int mtk_skcipher_decrypt(struct s
|
|
rctx->flags |= MTK_DECRYPT;
|
|
rctx->saRecord_base = ctx->sa_base_in;
|
|
|
|
- return mtk_skcipher_crypt(req);
|
|
+ return mtk_skcipher_crypt(req, false);
|
|
}
|
|
|
|
/* Available algorithms in this module */
|
|
--- a/crypto/mtk-eip93/eip93-cipher.h
|
|
+++ b/crypto/mtk-eip93/eip93-cipher.h
|
|
@@ -24,6 +24,8 @@ struct mtk_crypto_ctx {
|
|
bool in_first;
|
|
bool out_first;
|
|
struct crypto_shash *shash;
|
|
+ unsigned int keylen;
|
|
+ struct crypto_skcipher *fallback;
|
|
};
|
|
|
|
struct mtk_cipher_reqctx {
|
|
@@ -45,6 +47,7 @@ struct mtk_cipher_reqctx {
|
|
struct saState_s *saState_ctr;
|
|
dma_addr_t saState_base_ctr;
|
|
uint32_t saState_ctr_idx;
|
|
+ struct skcipher_request fallback_req; // keep at the end
|
|
};
|
|
|
|
int check_valid_request(struct mtk_cipher_reqctx *rctx);
|