File 0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch of Package grub2

From 7126da87f17ff41334b9fa6969ad032ff9940979 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Wed, 13 Aug 2025 09:57:04 +0800
Subject: [PATCH 2/2] lib/pbkdf2: Optimize PBKDF2 by reusing HMAC handle

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 <glin@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.51.0

openSUSE Build Service is sponsored by