This patch set introduces support for using the in-tree (mainline) EIP93 crypto driver for kernel 6.18 and later, along with additional improvements and fixes: - Conditional Kconfig/Makefile handling for crypto-hw-eip93 to enable use of the mainline driver with kernel 6.18+. - Patch 926: Use software AES fallback for small requests in the EIP93 driver. - Patch 927: Add `mediatek,mtk-eip93` compatible string for upstream kernel device trees. Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com> Link: https://github.com/openwrt/openwrt/pull/21078 Signed-off-by: Robert Marko <robimarko@gmail.com>
171 lines
5.7 KiB
Diff
171 lines
5.7 KiB
Diff
From 46d673033b7f6974d0bf5696ff8365fd412cd646 Mon Sep 17 00:00:00 2001
|
|
From: Aviana Cruz <gwencroft@proton.me>
|
|
Date: Mon, 20 Jun 2022 21:55:45 +0800
|
|
Subject: [PATCH] crypto: eip93 - use AES fallback for small requests
|
|
|
|
For data blocks smaller than 1024, software crypto is faster.
|
|
|
|
Signed-off-by: Aviana Cruz <gwencroft@proton.me>
|
|
---
|
|
|
|
--- a/drivers/crypto/inside-secure/eip93/Kconfig
|
|
+++ b/drivers/crypto/inside-secure/eip93/Kconfig
|
|
@@ -18,3 +18,19 @@ config CRYPTO_DEV_EIP93
|
|
CTR crypto. Also provide DES and 3DES ECB and CBC.
|
|
|
|
Also provide AEAD authenc(hmac(x), cipher(y)) for supported algo.
|
|
+
|
|
+config CRYPTO_DEV_EIP93_GENERIC_SW_MAX_LEN
|
|
+ int "Max skcipher software fallback length"
|
|
+ depends on CRYPTO_DEV_EIP93
|
|
+ default 256
|
|
+ help
|
|
+ Max length of crypt request which
|
|
+ will fallback to software crypt of skcipher *except* AES-128.
|
|
+
|
|
+config CRYPTO_DEV_EIP93_AES_128_SW_MAX_LEN
|
|
+ int "Max AES-128 skcipher software fallback length"
|
|
+ depends on CRYPTO_DEV_EIP93
|
|
+ default 512
|
|
+ help
|
|
+ Max length of crypt request which
|
|
+ will fallback to software crypt of AES-128 skcipher.
|
|
--- a/drivers/crypto/inside-secure/eip93/eip93-cipher.c
|
|
+++ b/drivers/crypto/inside-secure/eip93/eip93-cipher.c
|
|
@@ -30,6 +30,13 @@ void eip93_skcipher_handle_result(struct
|
|
skcipher_request_complete(req, err);
|
|
}
|
|
|
|
+static inline bool eip93_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 eip93_skcipher_send_req(struct crypto_async_request *async)
|
|
{
|
|
struct skcipher_request *req = skcipher_request_cast(async);
|
|
@@ -52,12 +59,21 @@ static int eip93_skcipher_cra_init(struc
|
|
struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
|
|
struct eip93_alg_template *tmpl = container_of(tfm->__crt_alg,
|
|
struct eip93_alg_template, alg.skcipher.base);
|
|
-
|
|
- crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm),
|
|
- sizeof(struct eip93_cipher_reqctx));
|
|
+ bool fallback = eip93_skcipher_is_fallback(tfm, tmpl->flags);
|
|
|
|
memset(ctx, 0, sizeof(*ctx));
|
|
|
|
+ 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 eip93_cipher_reqctx) + (fallback ?
|
|
+ crypto_skcipher_reqsize(ctx->fallback) : 0));
|
|
+
|
|
ctx->eip93 = tmpl->eip93;
|
|
ctx->type = tmpl->type;
|
|
|
|
@@ -75,6 +91,8 @@ static void eip93_skcipher_cra_exit(stru
|
|
dma_unmap_single(ctx->eip93->dev, ctx->sa_record_base,
|
|
sizeof(*ctx->sa_record), DMA_TO_DEVICE);
|
|
kfree(ctx->sa_record);
|
|
+
|
|
+ crypto_free_skcipher(ctx->fallback);
|
|
}
|
|
|
|
static int eip93_skcipher_setkey(struct crypto_skcipher *ctfm, const u8 *key,
|
|
@@ -117,6 +135,14 @@ static int eip93_skcipher_setkey(struct
|
|
|
|
if (flags & EIP93_ALG_AES) {
|
|
struct crypto_aes_ctx aes;
|
|
+ bool fallback = eip93_skcipher_is_fallback(tfm, flags);
|
|
+
|
|
+ if (fallback && !IS_RFC3686(flags)) {
|
|
+ ret = crypto_skcipher_setkey(ctx->fallback, key,
|
|
+ keylen);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
|
|
ctx->blksize = AES_BLOCK_SIZE;
|
|
ret = aes_expandkey(&aes, key, keylen);
|
|
@@ -133,12 +159,13 @@ static int eip93_skcipher_setkey(struct
|
|
return 0;
|
|
}
|
|
|
|
-static int eip93_skcipher_crypt(struct skcipher_request *req)
|
|
+static int eip93_skcipher_crypt(struct skcipher_request *req, bool encrypt)
|
|
{
|
|
struct eip93_cipher_reqctx *rctx = skcipher_request_ctx(req);
|
|
struct crypto_async_request *async = &req->base;
|
|
struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
|
|
struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
|
|
+ bool fallback = eip93_skcipher_is_fallback(req->base.tfm, rctx->flags);
|
|
int ret;
|
|
|
|
if (!req->cryptlen)
|
|
@@ -153,6 +180,21 @@ static int eip93_skcipher_crypt(struct s
|
|
crypto_skcipher_blocksize(skcipher)))
|
|
return -EINVAL;
|
|
|
|
+ if (fallback &&
|
|
+ req->cryptlen <= (AES_KEYSIZE_128 ?
|
|
+ CONFIG_CRYPTO_DEV_EIP93_AES_128_SW_MAX_LEN :
|
|
+ CONFIG_CRYPTO_DEV_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);
|
|
+ }
|
|
+
|
|
ctx->sa_record_base = dma_map_single(ctx->eip93->dev, ctx->sa_record,
|
|
sizeof(*ctx->sa_record), DMA_TO_DEVICE);
|
|
ret = dma_mapping_error(ctx->eip93->dev, ctx->sa_record_base);
|
|
@@ -181,7 +223,7 @@ static int eip93_skcipher_encrypt(struct
|
|
rctx->flags = tmpl->flags;
|
|
rctx->flags |= EIP93_ENCRYPT;
|
|
|
|
- return eip93_skcipher_crypt(req);
|
|
+ return eip93_skcipher_crypt(req, true);
|
|
}
|
|
|
|
static int eip93_skcipher_decrypt(struct skcipher_request *req)
|
|
@@ -196,7 +238,7 @@ static int eip93_skcipher_decrypt(struct
|
|
rctx->flags = tmpl->flags;
|
|
rctx->flags |= EIP93_DECRYPT;
|
|
|
|
- return eip93_skcipher_crypt(req);
|
|
+ return eip93_skcipher_crypt(req, false);
|
|
}
|
|
|
|
/* Available algorithms in this module */
|
|
--- a/drivers/crypto/inside-secure/eip93/eip93-cipher.h
|
|
+++ b/drivers/crypto/inside-secure/eip93/eip93-cipher.h
|
|
@@ -22,6 +22,7 @@ struct eip93_crypto_ctx {
|
|
unsigned int assoclen;
|
|
bool set_assoc;
|
|
enum eip93_alg_type type;
|
|
+ struct crypto_skcipher *fallback;
|
|
};
|
|
|
|
struct eip93_cipher_reqctx {
|
|
@@ -42,6 +43,7 @@ struct eip93_cipher_reqctx {
|
|
int dst_nents;
|
|
struct sa_state *sa_state_ctr;
|
|
dma_addr_t sa_state_ctr_base;
|
|
+ struct skcipher_request fallback_req;
|
|
};
|
|
|
|
int check_valid_request(struct eip93_cipher_reqctx *rctx);
|