1*74a43a2cSHerbert Xu /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*74a43a2cSHerbert Xu /* 3*74a43a2cSHerbert Xu * Handle partial blocks for block hash. 4*74a43a2cSHerbert Xu * 5*74a43a2cSHerbert Xu * Copyright (c) 2015 Linaro Ltd <ard.biesheuvel@linaro.org> 6*74a43a2cSHerbert Xu * Copyright (c) 2025 Herbert Xu <herbert@gondor.apana.org.au> 7*74a43a2cSHerbert Xu */ 8*74a43a2cSHerbert Xu 9*74a43a2cSHerbert Xu #ifndef _CRYPTO_INTERNAL_BLOCKHASH_H 10*74a43a2cSHerbert Xu #define _CRYPTO_INTERNAL_BLOCKHASH_H 11*74a43a2cSHerbert Xu 12*74a43a2cSHerbert Xu #include <linux/string.h> 13*74a43a2cSHerbert Xu #include <linux/types.h> 14*74a43a2cSHerbert Xu 15*74a43a2cSHerbert Xu #define BLOCK_HASH_UPDATE_BASE(block_fn, state, src, nbytes, bs, dv, \ 16*74a43a2cSHerbert Xu buf, buflen) \ 17*74a43a2cSHerbert Xu ({ \ 18*74a43a2cSHerbert Xu typeof(block_fn) *_block_fn = &(block_fn); \ 19*74a43a2cSHerbert Xu typeof(state + 0) _state = (state); \ 20*74a43a2cSHerbert Xu unsigned int _buflen = (buflen); \ 21*74a43a2cSHerbert Xu size_t _nbytes = (nbytes); \ 22*74a43a2cSHerbert Xu unsigned int _bs = (bs); \ 23*74a43a2cSHerbert Xu const u8 *_src = (src); \ 24*74a43a2cSHerbert Xu u8 *_buf = (buf); \ 25*74a43a2cSHerbert Xu while ((_buflen + _nbytes) >= _bs) { \ 26*74a43a2cSHerbert Xu const u8 *data = _src; \ 27*74a43a2cSHerbert Xu size_t len = _nbytes; \ 28*74a43a2cSHerbert Xu size_t blocks; \ 29*74a43a2cSHerbert Xu int remain; \ 30*74a43a2cSHerbert Xu if (_buflen) { \ 31*74a43a2cSHerbert Xu remain = _bs - _buflen; \ 32*74a43a2cSHerbert Xu memcpy(_buf + _buflen, _src, remain); \ 33*74a43a2cSHerbert Xu data = _buf; \ 34*74a43a2cSHerbert Xu len = _bs; \ 35*74a43a2cSHerbert Xu } \ 36*74a43a2cSHerbert Xu remain = len % bs; \ 37*74a43a2cSHerbert Xu blocks = (len - remain) / (dv); \ 38*74a43a2cSHerbert Xu (*_block_fn)(_state, data, blocks); \ 39*74a43a2cSHerbert Xu _src += len - remain - _buflen; \ 40*74a43a2cSHerbert Xu _nbytes -= len - remain - _buflen; \ 41*74a43a2cSHerbert Xu _buflen = 0; \ 42*74a43a2cSHerbert Xu } \ 43*74a43a2cSHerbert Xu memcpy(_buf + _buflen, _src, _nbytes); \ 44*74a43a2cSHerbert Xu _buflen += _nbytes; \ 45*74a43a2cSHerbert Xu }) 46*74a43a2cSHerbert Xu 47*74a43a2cSHerbert Xu #define BLOCK_HASH_UPDATE(block, state, src, nbytes, bs, buf, buflen) \ 48*74a43a2cSHerbert Xu BLOCK_HASH_UPDATE_BASE(block, state, src, nbytes, bs, 1, buf, buflen) 49*74a43a2cSHerbert Xu #define BLOCK_HASH_UPDATE_BLOCKS(block, state, src, nbytes, bs, buf, buflen) \ 50*74a43a2cSHerbert Xu BLOCK_HASH_UPDATE_BASE(block, state, src, nbytes, bs, bs, buf, buflen) 51*74a43a2cSHerbert Xu 52*74a43a2cSHerbert Xu #endif /* _CRYPTO_INTERNAL_BLOCKHASH_H */ 53