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;
 }
 
        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,
 
                                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,
 
        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)