@@ -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
225229decrypt :
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