mirror of https://github.com/hak5/openwrt.git
147 lines
4.6 KiB
Diff
147 lines
4.6 KiB
Diff
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
|
|
@@ -257,10 +257,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;
|
|
}
|
|
|
|
@@ -331,7 +327,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
|
|
@@ -586,15 +586,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,
|
|
@@ -606,38 +605,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)
|