The previous PBKDF2 implementation used grub_crypto_hmac_buffer(), which allocates and frees an HMAC handle on every call. This approach caused significant performance overhead, slowing down the boot process considerably.
This commit refactors the PBKDF2 code to use the new HMAC functions, allowing the HMAC handle and its buffers to be allocated once and reused across multiple operations. This change significantly reduces disk unlocking time. In a QEMU/OVMF test environment, this patch reduced the time to unlock a LUKS2(*) partition from approximately 15 seconds to 4 seconds. (*) PBKDF2 SHA256 with 3454944 iterations Signed-off-by: Gary Lin <g...@suse.com> --- grub-core/lib/pbkdf2.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/grub-core/lib/pbkdf2.c b/grub-core/lib/pbkdf2.c index 28aa96c46..410eff580 100644 --- a/grub-core/lib/pbkdf2.c +++ b/grub-core/lib/pbkdf2.c @@ -39,6 +39,7 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md, unsigned int c, grub_uint8_t *DK, grub_size_t dkLen) { + struct grub_crypto_hmac_handle *hnd = NULL; unsigned int hLen = md->mdlen; grub_uint8_t U[GRUB_CRYPTO_MAX_MDLEN]; grub_uint8_t T[GRUB_CRYPTO_MAX_MDLEN]; @@ -47,7 +48,6 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md, unsigned int r; unsigned int i; unsigned int k; - gcry_err_code_t rc; grub_uint8_t *tmp; grub_size_t tmplen = Slen + 4; @@ -72,6 +72,13 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md, grub_memcpy (tmp, S, Slen); + hnd = grub_crypto_hmac_init (md, P, Plen); + if (hnd == NULL) + { + grub_free (tmp); + return GPG_ERR_OUT_OF_MEMORY; + } + for (i = 1; i - 1 < l; i++) { grub_memset (T, 0, hLen); @@ -85,16 +92,13 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md, tmp[Slen + 2] = (i & 0x0000ff00) >> 8; tmp[Slen + 3] = (i & 0x000000ff) >> 0; - rc = grub_crypto_hmac_buffer (md, P, Plen, tmp, tmplen, U); + grub_crypto_hmac_write (hnd, tmp, tmplen); } else - rc = grub_crypto_hmac_buffer (md, P, Plen, U, hLen, U); + grub_crypto_hmac_write (hnd, U, hLen); - if (rc != GPG_ERR_NO_ERROR) - { - grub_free (tmp); - return rc; - } + grub_crypto_hmac_final (hnd, U); + grub_crypto_hmac_reset (hnd); for (k = 0; k < hLen; k++) T[k] ^= U[k]; @@ -103,6 +107,7 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md, grub_memcpy (DK + (i - 1) * hLen, T, i == l ? r : hLen); } + grub_crypto_hmac_free (hnd); grub_free (tmp); return GPG_ERR_NO_ERROR; -- 2.43.0 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel