Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: adiantum - Use scatter_walk API instead of sg_miter

Make adiantum_hash_message() use the scatter_walk API instead of
sg_miter. scatter_walk is a bit simpler and also more efficient. For
example, unlike sg_miter, scatter_walk doesn't require that the number
of scatterlist entries be calculated up-front.

Link: https://lore.kernel.org/r/20251211011846.8179-8-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>

+15 -18
+15 -18
crypto/adiantum.c
··· 369 369 * property; NH is used for performance since it's much faster than Poly1305. 370 370 */ 371 371 static void adiantum_hash_message(struct skcipher_request *req, 372 - struct scatterlist *sgl, unsigned int nents, 373 - le128 *out) 372 + struct scatterlist *sgl, le128 *out) 374 373 { 375 374 struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 376 375 const struct adiantum_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); 377 376 struct adiantum_request_ctx *rctx = skcipher_request_ctx(req); 378 - const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE; 379 - struct sg_mapping_iter miter; 380 - unsigned int i, n; 377 + unsigned int len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE; 378 + struct scatter_walk walk; 381 379 382 380 nhpoly1305_init(&rctx->u.hash_ctx); 381 + scatterwalk_start(&walk, sgl); 382 + while (len) { 383 + unsigned int n = scatterwalk_next(&walk, len); 383 384 384 - sg_miter_start(&miter, sgl, nents, SG_MITER_FROM_SG | SG_MITER_ATOMIC); 385 - for (i = 0; i < bulk_len; i += n) { 386 - sg_miter_next(&miter); 387 - n = min_t(unsigned int, miter.length, bulk_len - i); 388 - nhpoly1305_update(&rctx->u.hash_ctx, tctx, miter.addr, n); 385 + nhpoly1305_update(&rctx->u.hash_ctx, tctx, walk.addr, n); 386 + scatterwalk_done_src(&walk, n); 387 + len -= n; 389 388 } 390 - sg_miter_stop(&miter); 391 - 392 389 nhpoly1305_final(&rctx->u.hash_ctx, tctx, out); 393 390 } 394 391 ··· 397 400 struct adiantum_request_ctx *rctx = skcipher_request_ctx(req); 398 401 const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE; 399 402 struct scatterlist *dst = req->dst; 400 - const unsigned int dst_nents = sg_nents(dst); 401 403 le128 digest; 402 404 403 405 /* If decrypting, decrypt C_M with the block cipher to get P_M */ ··· 410 414 * dec: P_R = P_M - H_{K_H}(T, P_L) 411 415 */ 412 416 le128_sub(&rctx->rbuf.bignum, &rctx->rbuf.bignum, &rctx->header_hash); 413 - if (dst_nents == 1 && dst->offset + req->cryptlen <= PAGE_SIZE) { 417 + if (dst->length >= req->cryptlen && 418 + dst->offset + req->cryptlen <= PAGE_SIZE) { 414 419 /* Fast path for single-page destination */ 415 420 struct page *page = sg_page(dst); 416 421 void *virt = kmap_local_page(page) + dst->offset; ··· 425 428 kunmap_local(virt); 426 429 } else { 427 430 /* Slow path that works for any destination scatterlist */ 428 - adiantum_hash_message(req, dst, dst_nents, &digest); 431 + adiantum_hash_message(req, dst, &digest); 429 432 le128_sub(&rctx->rbuf.bignum, &rctx->rbuf.bignum, &digest); 430 433 scatterwalk_map_and_copy(&rctx->rbuf.bignum, dst, 431 434 bulk_len, sizeof(le128), 1); ··· 450 453 struct adiantum_request_ctx *rctx = skcipher_request_ctx(req); 451 454 const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE; 452 455 struct scatterlist *src = req->src; 453 - const unsigned int src_nents = sg_nents(src); 454 456 unsigned int stream_len; 455 457 le128 digest; 456 458 ··· 464 468 * dec: C_M = C_R + H_{K_H}(T, C_L) 465 469 */ 466 470 adiantum_hash_header(req); 467 - if (src_nents == 1 && src->offset + req->cryptlen <= PAGE_SIZE) { 471 + if (src->length >= req->cryptlen && 472 + src->offset + req->cryptlen <= PAGE_SIZE) { 468 473 /* Fast path for single-page source */ 469 474 void *virt = kmap_local_page(sg_page(src)) + src->offset; 470 475 ··· 476 479 kunmap_local(virt); 477 480 } else { 478 481 /* Slow path that works for any source scatterlist */ 479 - adiantum_hash_message(req, src, src_nents, &digest); 482 + adiantum_hash_message(req, src, &digest); 480 483 scatterwalk_map_and_copy(&rctx->rbuf.bignum, src, 481 484 bulk_len, sizeof(le128), 0); 482 485 }