Skip to content

Commit e024941

Browse files
committed
crypto: authencesn - Do not place hiseq at end of dst for out-of-place decryption
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>
1 parent a664bf3 commit e024941

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
@@ -207,30 +207,35 @@ static int crypto_authenc_esn_decrypt_tail(struct aead_request *req,
207207
u8 *ohash = areq_ctx->tail;
208208
unsigned int cryptlen = req->cryptlen - authsize;
209209
unsigned int assoclen = req->assoclen;
210+
struct scatterlist *src = req->src;
210211
struct scatterlist *dst = req->dst;
211212
u8 *ihash = ohash + crypto_ahash_digestsize(auth);
212213
u32 tmp[2];
213214

214215
if (!authsize)
215216
goto decrypt;
216217

217-
/* Move high-order bits of sequence number back. */
218-
scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
219-
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
220-
scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
218+
if (src == dst) {
219+
/* Move high-order bits of sequence number back. */
220+
scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
221+
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
222+
scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
223+
} else
224+
memcpy_sglist(dst, src, assoclen);
221225

222226
if (crypto_memneq(ihash, ohash, authsize))
223227
return -EBADMSG;
224228

225229
decrypt:
226230

227-
sg_init_table(areq_ctx->dst, 2);
231+
if (src != dst)
232+
src = scatterwalk_ffwd(areq_ctx->src, src, assoclen);
228233
dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen);
229234

230235
skcipher_request_set_tfm(skreq, ctx->enc);
231236
skcipher_request_set_callback(skreq, flags,
232237
req->base.complete, req->base.data);
233-
skcipher_request_set_crypt(skreq, dst, dst, cryptlen, req->iv);
238+
skcipher_request_set_crypt(skreq, src, dst, cryptlen, req->iv);
234239

235240
return crypto_skcipher_decrypt(skreq);
236241
}
@@ -255,31 +260,36 @@ static int crypto_authenc_esn_decrypt(struct aead_request *req)
255260
unsigned int assoclen = req->assoclen;
256261
unsigned int cryptlen = req->cryptlen;
257262
u8 *ihash = ohash + crypto_ahash_digestsize(auth);
263+
struct scatterlist *src = req->src;
258264
struct scatterlist *dst = req->dst;
259265
u32 tmp[2];
260266
int err;
261267

262268
if (assoclen < 8)
263269
return -EINVAL;
264270

265-
cryptlen -= authsize;
266-
267-
if (req->src != dst)
268-
memcpy_sglist(dst, req->src, assoclen + cryptlen);
271+
if (!authsize)
272+
goto tail;
269273

274+
cryptlen -= authsize;
270275
scatterwalk_map_and_copy(ihash, req->src, assoclen + cryptlen,
271276
authsize, 0);
272277

273-
if (!authsize)
274-
goto tail;
275-
276278
/* Move high-order bits of sequence number to the end. */
277-
scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);
278-
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
279-
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
280-
281-
sg_init_table(areq_ctx->dst, 2);
282-
dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
279+
scatterwalk_map_and_copy(tmp, src, 0, 8, 0);
280+
if (src == dst) {
281+
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
282+
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
283+
dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
284+
} else {
285+
scatterwalk_map_and_copy(tmp, dst, 0, 4, 1);
286+
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen - 4, 4, 1);
287+
288+
src = scatterwalk_ffwd(areq_ctx->src, src, 8);
289+
dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
290+
memcpy_sglist(dst, src, assoclen + cryptlen - 8);
291+
dst = req->dst;
292+
}
283293

284294
ahash_request_set_tfm(ahreq, auth);
285295
ahash_request_set_crypt(ahreq, dst, ohash, assoclen + cryptlen);

0 commit comments

Comments
 (0)