/branches/gl-inet/target/linux/apm821xx/patches-4.14/022-0002-crypto-crypto4xx-performance-optimizations.patch |
@@ -0,0 +1,159 @@ |
From a8d79d7bfb14f471914017103ee2329a74e5e89d Mon Sep 17 00:00:00 2001 |
From: Christian Lamparter <chunkeey@gmail.com> |
Date: Thu, 19 Apr 2018 18:41:51 +0200 |
Subject: crypto: crypto4xx - performance optimizations |
|
This patch provides a cheap 2MiB/s+ (~ 6%) performance |
improvement over the current code. This is because the |
compiler can now optimize several endian swap memcpy. |
|
Signed-off-by: Christian Lamparter <chunkeey@gmail.com> |
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> |
--- |
drivers/crypto/amcc/crypto4xx_alg.c | 32 +++++++++++++++++++------------- |
drivers/crypto/amcc/crypto4xx_core.c | 22 +++++++++++----------- |
drivers/crypto/amcc/crypto4xx_core.h | 6 ++++-- |
3 files changed, 34 insertions(+), 26 deletions(-) |
|
--- a/drivers/crypto/amcc/crypto4xx_alg.c |
+++ b/drivers/crypto/amcc/crypto4xx_alg.c |
@@ -74,32 +74,38 @@ static void set_dynamic_sa_command_1(str |
sa->sa_command_1.bf.copy_hdr = cp_hdr; |
} |
|
-int crypto4xx_encrypt(struct ablkcipher_request *req) |
+static inline int crypto4xx_crypt(struct ablkcipher_request *req, |
+ const unsigned int ivlen, bool decrypt) |
{ |
struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm); |
- unsigned int ivlen = crypto_ablkcipher_ivsize( |
- crypto_ablkcipher_reqtfm(req)); |
__le32 iv[ivlen]; |
|
if (ivlen) |
crypto4xx_memcpy_to_le32(iv, req->info, ivlen); |
|
return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst, |
- req->nbytes, iv, ivlen, ctx->sa_out, ctx->sa_len, 0); |
+ req->nbytes, iv, ivlen, decrypt ? ctx->sa_in : ctx->sa_out, |
+ ctx->sa_len, 0); |
} |
|
-int crypto4xx_decrypt(struct ablkcipher_request *req) |
+int crypto4xx_encrypt_noiv(struct ablkcipher_request *req) |
{ |
- struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm); |
- unsigned int ivlen = crypto_ablkcipher_ivsize( |
- crypto_ablkcipher_reqtfm(req)); |
- __le32 iv[ivlen]; |
+ return crypto4xx_crypt(req, 0, false); |
+} |
|
- if (ivlen) |
- crypto4xx_memcpy_to_le32(iv, req->info, ivlen); |
+int crypto4xx_encrypt_iv(struct ablkcipher_request *req) |
+{ |
+ return crypto4xx_crypt(req, AES_IV_SIZE, false); |
+} |
|
- return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst, |
- req->nbytes, iv, ivlen, ctx->sa_in, ctx->sa_len, 0); |
+int crypto4xx_decrypt_noiv(struct ablkcipher_request *req) |
+{ |
+ return crypto4xx_crypt(req, 0, true); |
+} |
+ |
+int crypto4xx_decrypt_iv(struct ablkcipher_request *req) |
+{ |
+ return crypto4xx_crypt(req, AES_IV_SIZE, true); |
} |
|
/** |
--- a/drivers/crypto/amcc/crypto4xx_core.c |
+++ b/drivers/crypto/amcc/crypto4xx_core.c |
@@ -580,7 +580,7 @@ static void crypto4xx_aead_done(struct c |
struct scatterlist *dst = pd_uinfo->dest_va; |
size_t cp_len = crypto_aead_authsize( |
crypto_aead_reqtfm(aead_req)); |
- u32 icv[cp_len]; |
+ u32 icv[AES_BLOCK_SIZE]; |
int err = 0; |
|
if (pd_uinfo->using_sd) { |
@@ -595,7 +595,7 @@ static void crypto4xx_aead_done(struct c |
if (pd_uinfo->sa_va->sa_command_0.bf.dir == DIR_OUTBOUND) { |
/* append icv at the end */ |
crypto4xx_memcpy_from_le32(icv, pd_uinfo->sr_va->save_digest, |
- cp_len); |
+ sizeof(icv)); |
|
scatterwalk_map_and_copy(icv, dst, aead_req->cryptlen, |
cp_len, 1); |
@@ -605,7 +605,7 @@ static void crypto4xx_aead_done(struct c |
aead_req->assoclen + aead_req->cryptlen - |
cp_len, cp_len, 0); |
|
- crypto4xx_memcpy_from_le32(icv, icv, cp_len); |
+ crypto4xx_memcpy_from_le32(icv, icv, sizeof(icv)); |
|
if (crypto_memneq(icv, pd_uinfo->sr_va->save_digest, cp_len)) |
err = -EBADMSG; |
@@ -1122,8 +1122,8 @@ static struct crypto4xx_alg_common crypt |
.max_keysize = AES_MAX_KEY_SIZE, |
.ivsize = AES_IV_SIZE, |
.setkey = crypto4xx_setkey_aes_cbc, |
- .encrypt = crypto4xx_encrypt, |
- .decrypt = crypto4xx_decrypt, |
+ .encrypt = crypto4xx_encrypt_iv, |
+ .decrypt = crypto4xx_decrypt_iv, |
} |
} |
}}, |
@@ -1146,8 +1146,8 @@ static struct crypto4xx_alg_common crypt |
.max_keysize = AES_MAX_KEY_SIZE, |
.ivsize = AES_IV_SIZE, |
.setkey = crypto4xx_setkey_aes_cfb, |
- .encrypt = crypto4xx_encrypt, |
- .decrypt = crypto4xx_decrypt, |
+ .encrypt = crypto4xx_encrypt_iv, |
+ .decrypt = crypto4xx_decrypt_iv, |
} |
} |
} }, |
@@ -1195,8 +1195,8 @@ static struct crypto4xx_alg_common crypt |
.min_keysize = AES_MIN_KEY_SIZE, |
.max_keysize = AES_MAX_KEY_SIZE, |
.setkey = crypto4xx_setkey_aes_ecb, |
- .encrypt = crypto4xx_encrypt, |
- .decrypt = crypto4xx_decrypt, |
+ .encrypt = crypto4xx_encrypt_noiv, |
+ .decrypt = crypto4xx_decrypt_noiv, |
} |
} |
} }, |
@@ -1219,8 +1219,8 @@ static struct crypto4xx_alg_common crypt |
.max_keysize = AES_MAX_KEY_SIZE, |
.ivsize = AES_IV_SIZE, |
.setkey = crypto4xx_setkey_aes_ofb, |
- .encrypt = crypto4xx_encrypt, |
- .decrypt = crypto4xx_decrypt, |
+ .encrypt = crypto4xx_encrypt_iv, |
+ .decrypt = crypto4xx_decrypt_iv, |
} |
} |
} }, |
--- a/drivers/crypto/amcc/crypto4xx_core.h |
+++ b/drivers/crypto/amcc/crypto4xx_core.h |
@@ -168,8 +168,10 @@ int crypto4xx_setkey_aes_ofb(struct cryp |
const u8 *key, unsigned int keylen); |
int crypto4xx_setkey_rfc3686(struct crypto_ablkcipher *cipher, |
const u8 *key, unsigned int keylen); |
-int crypto4xx_encrypt(struct ablkcipher_request *req); |
-int crypto4xx_decrypt(struct ablkcipher_request *req); |
+int crypto4xx_encrypt_iv(struct ablkcipher_request *req); |
+int crypto4xx_decrypt_iv(struct ablkcipher_request *req); |
+int crypto4xx_encrypt_noiv(struct ablkcipher_request *req); |
+int crypto4xx_decrypt_noiv(struct ablkcipher_request *req); |
int crypto4xx_rfc3686_encrypt(struct ablkcipher_request *req); |
int crypto4xx_rfc3686_decrypt(struct ablkcipher_request *req); |
int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm); |