aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/apm821xx/patches-4.14/120-0005-crypto-crypto4xx-perform-aead-icv-check-in-the-drive.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/apm821xx/patches-4.14/120-0005-crypto-crypto4xx-perform-aead-icv-check-in-the-drive.patch')
-rw-r--r--target/linux/apm821xx/patches-4.14/120-0005-crypto-crypto4xx-perform-aead-icv-check-in-the-drive.patch146
1 files changed, 146 insertions, 0 deletions
diff --git a/target/linux/apm821xx/patches-4.14/120-0005-crypto-crypto4xx-perform-aead-icv-check-in-the-drive.patch b/target/linux/apm821xx/patches-4.14/120-0005-crypto-crypto4xx-perform-aead-icv-check-in-the-drive.patch
new file mode 100644
index 0000000000..0dbd924e3c
--- /dev/null
+++ b/target/linux/apm821xx/patches-4.14/120-0005-crypto-crypto4xx-perform-aead-icv-check-in-the-drive.patch
@@ -0,0 +1,146 @@
+From 5b3856d1d98e6f6a58b70c1c0d7da3fb5f042e9c Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@gmail.com>
+Date: Thu, 21 Dec 2017 16:00:01 +0100
+Subject: [PATCH 5/6] crypto: crypto4xx - perform aead icv check in the driver
+
+The ccm-aes-ppc4xx now fails one of testmgr's expected
+failure test cases as such:
+
+alg: aead: decryption failed on test 10 for ccm-aes-ppc4xx: ret was 0, expected -EBADMSG
+
+Upon closer inspection, it turned out that the hardware's
+crypto flags that would indicate an authentification failure
+are not set by the hardware. The original vendor source from
+which this was ported does not have any special code or notes
+about why this would happen or if there are any WAs.
+
+Hence, this patch converts the aead_done callback handler to
+perform the icv check in the driver. And this fixes the false
+negative and the ccm-aes-ppc4xx passes the selftests once again.
+
+|name : ccm(aes)
+|driver : ccm-aes-ppc4xx
+|module : crypto4xx
+|priority : 300
+|refcnt : 1
+|selftest : passed
+|internal : no
+|type : aead
+|async : yes
+|blocksize : 1
+|ivsize : 16
+|maxauthsize : 16
+|geniv : <none>
+
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+---
+ drivers/crypto/amcc/crypto4xx_alg.c | 6 +---
+ drivers/crypto/amcc/crypto4xx_core.c | 54 ++++++++++++++++++------------------
+ 2 files changed, 28 insertions(+), 32 deletions(-)
+
+--- a/drivers/crypto/amcc/crypto4xx_alg.c
++++ b/drivers/crypto/amcc/crypto4xx_alg.c
+@@ -256,10 +256,6 @@ static inline bool crypto4xx_aead_need_f
+ if (is_ccm && !(req->iv[0] == 1 || req->iv[0] == 3))
+ return true;
+
+- /* CCM - fix CBC MAC mismatch in special case */
+- if (is_ccm && decrypt && !req->assoclen)
+- return true;
+-
+ return false;
+ }
+
+@@ -330,7 +326,7 @@ int crypto4xx_setkey_aes_ccm(struct cryp
+ sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+ sa->sa_contents.w = SA_AES_CCM_CONTENTS | (keylen << 2);
+
+- set_dynamic_sa_command_0(sa, SA_NOT_SAVE_HASH, SA_NOT_SAVE_IV,
++ set_dynamic_sa_command_0(sa, SA_SAVE_HASH, SA_NOT_SAVE_IV,
+ SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE,
+ SA_NO_HEADER_PROC, SA_HASH_ALG_CBC_MAC,
+ SA_CIPHER_ALG_AES,
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -577,15 +577,14 @@ static void crypto4xx_aead_done(struct c
+ struct pd_uinfo *pd_uinfo,
+ struct ce_pd *pd)
+ {
+- struct aead_request *aead_req;
+- struct crypto4xx_ctx *ctx;
++ struct aead_request *aead_req = container_of(pd_uinfo->async_req,
++ struct aead_request, base);
+ struct scatterlist *dst = pd_uinfo->dest_va;
++ size_t cp_len = crypto_aead_authsize(
++ crypto_aead_reqtfm(aead_req));
++ u32 icv[cp_len];
+ int err = 0;
+
+- aead_req = container_of(pd_uinfo->async_req, struct aead_request,
+- base);
+- ctx = crypto_tfm_ctx(aead_req->base.tfm);
+-
+ if (pd_uinfo->using_sd) {
+ crypto4xx_copy_pkt_to_dst(dev, pd, pd_uinfo,
+ pd->pd_ctl_len.bf.pkt_len,
+@@ -597,38 +596,39 @@ static void crypto4xx_aead_done(struct c
+
+ if (pd_uinfo->sa_va->sa_command_0.bf.dir == DIR_OUTBOUND) {
+ /* append icv at the end */
+- size_t cp_len = crypto_aead_authsize(
+- crypto_aead_reqtfm(aead_req));
+- u32 icv[cp_len];
+-
+ crypto4xx_memcpy_from_le32(icv, pd_uinfo->sr_va->save_digest,
+ cp_len);
+
+ scatterwalk_map_and_copy(icv, dst, aead_req->cryptlen,
+ cp_len, 1);
++ } else {
++ /* check icv at the end */
++ scatterwalk_map_and_copy(icv, aead_req->src,
++ aead_req->assoclen + aead_req->cryptlen -
++ cp_len, cp_len, 0);
++
++ crypto4xx_memcpy_from_le32(icv, icv, cp_len);
++
++ if (crypto_memneq(icv, pd_uinfo->sr_va->save_digest, cp_len))
++ err = -EBADMSG;
+ }
+
+ crypto4xx_ret_sg_desc(dev, pd_uinfo);
+
+ if (pd->pd_ctl.bf.status & 0xff) {
+- if (pd->pd_ctl.bf.status & 0x1) {
+- /* authentication error */
+- err = -EBADMSG;
+- } else {
+- if (!__ratelimit(&dev->aead_ratelimit)) {
+- if (pd->pd_ctl.bf.status & 2)
+- pr_err("pad fail error\n");
+- if (pd->pd_ctl.bf.status & 4)
+- pr_err("seqnum fail\n");
+- if (pd->pd_ctl.bf.status & 8)
+- pr_err("error _notify\n");
+- pr_err("aead return err status = 0x%02x\n",
+- pd->pd_ctl.bf.status & 0xff);
+- pr_err("pd pad_ctl = 0x%08x\n",
+- pd->pd_ctl.bf.pd_pad_ctl);
+- }
+- err = -EINVAL;
++ if (!__ratelimit(&dev->aead_ratelimit)) {
++ if (pd->pd_ctl.bf.status & 2)
++ pr_err("pad fail error\n");
++ if (pd->pd_ctl.bf.status & 4)
++ pr_err("seqnum fail\n");
++ if (pd->pd_ctl.bf.status & 8)
++ pr_err("error _notify\n");
++ pr_err("aead return err status = 0x%02x\n",
++ pd->pd_ctl.bf.status & 0xff);
++ pr_err("pd pad_ctl = 0x%08x\n",
++ pd->pd_ctl.bf.pd_pad_ctl);
+ }
++ err = -EINVAL;
+ }
+
+ if (pd_uinfo->state & PD_ENTRY_BUSY)