apm821xx: backport and reassign crypto4xx patches
[openwrt/openwrt.git] / target / linux / apm821xx / patches-4.14 / 022-0007-crypto-crypto4xx-extend-aead-fallback-checks.patch
1 From 584201f1895d915c1aa523bc86afdc126e94beca Mon Sep 17 00:00:00 2001
2 From: Christian Lamparter <chunkeey@gmail.com>
3 Date: Thu, 19 Apr 2018 18:41:56 +0200
4 Subject: [PATCH 7/8] crypto: crypto4xx - extend aead fallback checks
5
6 1020 bytes is the limit for associated data. Any more
7 and it will no longer fit into hash_crypto_offset anymore.
8
9 The hardware will not process aead requests with plaintext
10 that have less than AES_BLOCK_SIZE bytes. When decrypting
11 aead requests the authsize has to be taken in account as
12 well, as it is part of the cryptlen. Otherwise the hardware
13 will think it has been misconfigured and will return:
14
15 aead return err status = 0x98
16
17 For rtc4543(gcm(aes)), the hardware has a dedicated GMAC
18 mode as part of the hash function set.
19
20 Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
21 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
22 ---
23 drivers/crypto/amcc/crypto4xx_alg.c | 30 +++++++++++++++--------------
24 1 file changed, 16 insertions(+), 14 deletions(-)
25
26 --- a/drivers/crypto/amcc/crypto4xx_alg.c
27 +++ b/drivers/crypto/amcc/crypto4xx_alg.c
28 @@ -321,6 +321,7 @@ int crypto4xx_decrypt_ctr(struct skciphe
29 }
30
31 static inline bool crypto4xx_aead_need_fallback(struct aead_request *req,
32 + unsigned int len,
33 bool is_ccm, bool decrypt)
34 {
35 struct crypto_aead *aead = crypto_aead_reqtfm(req);
36 @@ -330,14 +331,14 @@ static inline bool crypto4xx_aead_need_f
37 return true;
38
39 /*
40 - * hardware does not handle cases where cryptlen
41 - * is less than a block
42 + * hardware does not handle cases where plaintext
43 + * is less than a block.
44 */
45 - if (req->cryptlen < AES_BLOCK_SIZE)
46 + if (len < AES_BLOCK_SIZE)
47 return true;
48
49 - /* assoc len needs to be a multiple of 4 */
50 - if (req->assoclen & 0x3)
51 + /* assoc len needs to be a multiple of 4 and <= 1020 */
52 + if (req->assoclen & 0x3 || req->assoclen > 1020)
53 return true;
54
55 /* CCM supports only counter field length of 2 and 4 bytes */
56 @@ -449,17 +450,17 @@ static int crypto4xx_crypt_aes_ccm(struc
57 {
58 struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
59 struct crypto_aead *aead = crypto_aead_reqtfm(req);
60 - unsigned int len = req->cryptlen;
61 __le32 iv[16];
62 u32 tmp_sa[SA_AES128_CCM_LEN + 4];
63 struct dynamic_sa_ctl *sa = (struct dynamic_sa_ctl *)tmp_sa;
64 -
65 - if (crypto4xx_aead_need_fallback(req, true, decrypt))
66 - return crypto4xx_aead_fallback(req, ctx, decrypt);
67 + unsigned int len = req->cryptlen;
68
69 if (decrypt)
70 len -= crypto_aead_authsize(aead);
71
72 + if (crypto4xx_aead_need_fallback(req, len, true, decrypt))
73 + return crypto4xx_aead_fallback(req, ctx, decrypt);
74 +
75 memcpy(tmp_sa, decrypt ? ctx->sa_in : ctx->sa_out, ctx->sa_len * 4);
76 sa->sa_command_0.bf.digest_len = crypto_aead_authsize(aead) >> 2;
77
78 @@ -605,18 +606,19 @@ static inline int crypto4xx_crypt_aes_gc
79 bool decrypt)
80 {
81 struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
82 - unsigned int len = req->cryptlen;
83 + struct crypto4xx_aead_reqctx *rctx = aead_request_ctx(req);
84 __le32 iv[4];
85 + unsigned int len = req->cryptlen;
86 +
87 + if (decrypt)
88 + len -= crypto_aead_authsize(crypto_aead_reqtfm(req));
89
90 - if (crypto4xx_aead_need_fallback(req, false, decrypt))
91 + if (crypto4xx_aead_need_fallback(req, len, false, decrypt))
92 return crypto4xx_aead_fallback(req, ctx, decrypt);
93
94 crypto4xx_memcpy_to_le32(iv, req->iv, GCM_AES_IV_SIZE);
95 iv[3] = cpu_to_le32(1);
96
97 - if (decrypt)
98 - len -= crypto_aead_authsize(crypto_aead_reqtfm(req));
99 -
100 return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
101 len, iv, sizeof(iv),
102 decrypt ? ctx->sa_in : ctx->sa_out,