Skip to content

Commit b3aac24

Browse files
herbertxopsiff
authored andcommitted
crypto: authencesn - Do not place hiseq at end of dst for out-of-place decryption
mainline inclusion from mainline-v7.0-rc7 category: bugfix When decrypting data that is not in-place (src != dst), there is no need to save the high-order sequence bits in dst as it could simply be re-copied from the source. However, the data to be hashed need to be rearranged accordingly. Reported-by: Taeyang Lee <0wn@theori.io> Fixes: 104880a ("crypto: authencesn - Convert to new AEAD interface") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Thanks, Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> (cherry picked from commit e02494114ebf7c8b42777c6cd6982f113bfdbec7) Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
1 parent 54c7d29 commit b3aac24

1 file changed

Lines changed: 29 additions & 19 deletions

File tree

crypto/authencesn.c

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -212,30 +212,35 @@ static int crypto_authenc_esn_decrypt_tail(struct aead_request *req,
212212
crypto_ahash_alignmask(auth) + 1);
213213
unsigned int cryptlen = req->cryptlen - authsize;
214214
unsigned int assoclen = req->assoclen;
215+
struct scatterlist *src = req->src;
215216
struct scatterlist *dst = req->dst;
216217
u8 *ihash = ohash + crypto_ahash_digestsize(auth);
217218
u32 tmp[2];
218219

219220
if (!authsize)
220221
goto decrypt;
221222

222-
/* Move high-order bits of sequence number back. */
223-
scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
224-
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
225-
scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
223+
if (src == dst) {
224+
/* Move high-order bits of sequence number back. */
225+
scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
226+
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
227+
scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
228+
} else
229+
memcpy_sglist(dst, src, assoclen);
226230

227231
if (crypto_memneq(ihash, ohash, authsize))
228232
return -EBADMSG;
229233

230234
decrypt:
231235

232-
sg_init_table(areq_ctx->dst, 2);
236+
if (src != dst)
237+
src = scatterwalk_ffwd(areq_ctx->src, src, assoclen);
233238
dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen);
234239

235240
skcipher_request_set_tfm(skreq, ctx->enc);
236241
skcipher_request_set_callback(skreq, flags,
237242
req->base.complete, req->base.data);
238-
skcipher_request_set_crypt(skreq, dst, dst, cryptlen, req->iv);
243+
skcipher_request_set_crypt(skreq, src, dst, cryptlen, req->iv);
239244

240245
return crypto_skcipher_decrypt(skreq);
241246
}
@@ -261,31 +266,36 @@ static int crypto_authenc_esn_decrypt(struct aead_request *req)
261266
unsigned int assoclen = req->assoclen;
262267
unsigned int cryptlen = req->cryptlen;
263268
u8 *ihash = ohash + crypto_ahash_digestsize(auth);
269+
struct scatterlist *src = req->src;
264270
struct scatterlist *dst = req->dst;
265271
u32 tmp[2];
266272
int err;
267273

268274
if (assoclen < 8)
269275
return -EINVAL;
270276

271-
cryptlen -= authsize;
272-
273-
if (req->src != dst)
274-
memcpy_sglist(dst, req->src, assoclen + cryptlen);
277+
if (!authsize)
278+
goto tail;
275279

280+
cryptlen -= authsize;
276281
scatterwalk_map_and_copy(ihash, req->src, assoclen + cryptlen,
277282
authsize, 0);
278283

279-
if (!authsize)
280-
goto tail;
281-
282284
/* Move high-order bits of sequence number to the end. */
283-
scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);
284-
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
285-
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
286-
287-
sg_init_table(areq_ctx->dst, 2);
288-
dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
285+
scatterwalk_map_and_copy(tmp, src, 0, 8, 0);
286+
if (src == dst) {
287+
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
288+
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
289+
dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
290+
} else {
291+
scatterwalk_map_and_copy(tmp, dst, 0, 4, 1);
292+
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen - 4, 4, 1);
293+
294+
src = scatterwalk_ffwd(areq_ctx->src, src, 8);
295+
dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
296+
memcpy_sglist(dst, src, assoclen + cryptlen - 8);
297+
dst = req->dst;
298+
}
289299

290300
ahash_request_set_tfm(ahreq, auth);
291301
ahash_request_set_crypt(ahreq, dst, ohash, assoclen + cryptlen);

0 commit comments

Comments
 (0)