Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package grub2 for openSUSE:Factory checked in at 2025-09-08 13:05:03 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/grub2 (Old) and /work/SRC/openSUSE:Factory/.grub2.new.1977 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "grub2" Mon Sep 8 13:05:03 2025 rev:371 rq:1303110 version:2.12 Changes: -------- --- /work/SRC/openSUSE:Factory/grub2/grub2.changes 2025-08-15 21:51:02.765589682 +0200 +++ /work/SRC/openSUSE:Factory/.grub2.new.1977/grub2.changes 2025-09-08 13:05:07.820225869 +0200 @@ -1,0 +2,8 @@ +Tue Sep 2 07:46:46 UTC 2025 - Gary Ching-Pang Lin <[email protected]> + +- Optimize PBKDF2 to reduce the decryption time + * 0001-lib-crypto-Introduce-new-HMAC-functions-to-reuse-buf.patch + * 0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch + * 0001-kern-misc-Implement-faster-grub_memcpy-for-aligned-b.patch + +------------------------------------------------------------------- New: ---- 0001-kern-misc-Implement-faster-grub_memcpy-for-aligned-b.patch 0001-lib-crypto-Introduce-new-HMAC-functions-to-reuse-buf.patch 0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch ----------(New B)---------- New: * 0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch * 0001-kern-misc-Implement-faster-grub_memcpy-for-aligned-b.patch New:- Optimize PBKDF2 to reduce the decryption time * 0001-lib-crypto-Introduce-new-HMAC-functions-to-reuse-buf.patch * 0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch New: * 0001-lib-crypto-Introduce-new-HMAC-functions-to-reuse-buf.patch * 0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch * 0001-kern-misc-Implement-faster-grub_memcpy-for-aligned-b.patch ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ grub2.spec ++++++ --- /var/tmp/diff_new_pack.rXlvln/_old 2025-09-08 13:05:12.140407602 +0200 +++ /var/tmp/diff_new_pack.rXlvln/_new 2025-09-08 13:05:12.140407602 +0200 @@ -512,6 +512,9 @@ Patch336: 0002-linux-fallback-to-direct-PE-entry-boot-on-arm64.patch Patch337: 0003-efi-chainloader-fallback-to-direct-image-execution.patch Patch338: 0004-efi-chainloader-fix-missing-file_path-in-loaded_imag.patch +Patch339: 0001-lib-crypto-Introduce-new-HMAC-functions-to-reuse-buf.patch +Patch340: 0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch +Patch341: 0001-kern-misc-Implement-faster-grub_memcpy-for-aligned-b.patch %if 0%{?suse_version} < 1600 Requires: gettext-runtime ++++++ 0001-kern-misc-Implement-faster-grub_memcpy-for-aligned-b.patch ++++++ >From 1fbd2a278cfc645adc45c0e1357e58bcd1909f8d Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> Date: Thu, 28 Aug 2025 15:03:35 +0800 Subject: [PATCH] kern/misc: Implement faster grub_memcpy() for aligned buffers When both "dest" and "src" are aligned, copying the data in chunks (unsigned long) is more efficient than a byte-by-byte copy. Also tweak '__aeabi_memcpy()', '__aeabi_memcpy4()', and '__aeabi_memcpy8()', since 'grub_memcpy()' is not inline anymore. Signed-off-by: Gary Lin <[email protected]> --- grub-core/kern/compiler-rt.c | 8 ++++---- grub-core/kern/misc.c | 30 ++++++++++++++++++++++++++++++ include/grub/misc.h | 8 +------- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/grub-core/kern/compiler-rt.c b/grub-core/kern/compiler-rt.c index eda689a0c..8f3865e95 100644 --- a/grub-core/kern/compiler-rt.c +++ b/grub-core/kern/compiler-rt.c @@ -24,7 +24,7 @@ void * GRUB_BUILTIN_ATTR memcpy (void *dest, const void *src, grub_size_t n) { - return grub_memmove (dest, src, n); + return grub_memcpy (dest, src, n); } void * GRUB_BUILTIN_ATTR memmove (void *dest, const void *src, grub_size_t n) @@ -372,11 +372,11 @@ grub_int32_t __aeabi_idiv (grub_int32_t a, grub_int32_t b) __attribute__ ((alias ("__divsi3"))); void *__aeabi_memcpy (void *dest, const void *src, grub_size_t n) - __attribute__ ((alias ("grub_memcpy"))); + __attribute__ ((alias ("memcpy"))); void *__aeabi_memcpy4 (void *dest, const void *src, grub_size_t n) - __attribute__ ((alias ("grub_memcpy"))); + __attribute__ ((alias ("memcpy"))); void *__aeabi_memcpy8 (void *dest, const void *src, grub_size_t n) - __attribute__ ((alias ("grub_memcpy"))); + __attribute__ ((alias ("memcpy"))); void *__aeabi_memset (void *s, int c, grub_size_t n) __attribute__ ((alias ("memset"))); diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 2b7922393..016932583 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -99,6 +99,36 @@ grub_memmove (void *dest, const void *src, grub_size_t n) return dest; } +static void * +__memcpy_aligned (void *dest, const void *src, grub_size_t n) +{ + unsigned long *dw = (unsigned long *) dest; + const unsigned long *sw = (const unsigned long *) src; + grub_uint8_t *d; + const grub_uint8_t *s; + + for (; n >= sizeof (unsigned long); n -= sizeof (unsigned long)) + *dw++ = *sw++; + + d = (grub_uint8_t *) dw; + s = (const grub_uint8_t *) sw; + for (; n > 0; n--) + *d++ = *s++; + + return dest; +} + +void * +grub_memcpy (void *dest, const void *src, grub_size_t n) +{ + /* Check if 'dest' and 'src' are aligned */ + if (((grub_addr_t) dest & (sizeof (unsigned long) - 1)) == 0 && + ((grub_addr_t) src & (sizeof (unsigned long) - 1)) == 0) + return __memcpy_aligned (dest, src, n); + + return grub_memmove (dest, src, n); +} + char * grub_strcpy (char *dest, const char *src) { diff --git a/include/grub/misc.h b/include/grub/misc.h index e087e7b3e..b6b14ca55 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -38,6 +38,7 @@ #define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__) void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n); +void *EXPORT_FUNC(grub_memcpy) (void *dest, const void *src, grub_size_t n); char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src); static inline char * @@ -103,13 +104,6 @@ grub_strlcpy (char *dest, const char *src, grub_size_t size) return res; } -/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ -static inline void * -grub_memcpy (void *dest, const void *src, grub_size_t n) -{ - return grub_memmove (dest, src, n); -} - #if defined(__x86_64__) && !defined (GRUB_UTIL) #if defined (__MINGW32__) || defined (__CYGWIN__) || defined (__MINGW64__) #define GRUB_ASM_ATTR __attribute__ ((sysv_abi)) -- 2.51.0 ++++++ 0001-lib-crypto-Introduce-new-HMAC-functions-to-reuse-buf.patch ++++++ >From e98e880b67be178f3a5951fb345ded8c002eb6e5 Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> Date: Wed, 13 Aug 2025 11:43:40 +0800 Subject: [PATCH 1/2] lib/crypto: Introduce new HMAC functions to reuse buffers To enable more efficient buffer reuse for HMAC operations, three new functions have been introduced. This change prevents the need to reallocate memory for each HMAC operation. * grub_crypto_hmac_reset(): Reinitializes the hash contexts in the HMAC handle. * grub_crypto_hmac_final(): Provides the final HMAC result without freeing the handle, allowing it to be reused immediately. * grub_crypto_hmac_free(): Deallocates the HMAC handle and its associated memory. To further facilitate buffer reuse, 'ctx2' is now included within the HMAC handle struct, and the initialization of 'ctx2' is moved to grub_crypto_hmac_init(). The intermediate hash states ('ctx' and 'ctx2') for the inner and outer padded keys are now cached. grub_crypto_hmac_reset() restores these cached states for new operations, which avoids redundant hashing of the keys. Signed-off-by: Gary Lin <[email protected]> --- grub-core/disk/geli.c | 4 +- grub-core/lib/crypto.c | 91 ++++++++++++++++++++++++++++++------------ include/grub/crypto.h | 8 +++- 3 files changed, 74 insertions(+), 29 deletions(-) Index: grub-2.12/grub-core/disk/geli.c =================================================================== --- grub-2.12.orig/grub-core/disk/geli.c +++ grub-2.12/grub-core/disk/geli.c @@ -464,9 +464,7 @@ geli_recover_key (grub_disk_t source, gr grub_crypto_hmac_write (hnd, header.salt, sizeof (header.salt)); grub_crypto_hmac_write (hnd, cargs->key_data, cargs->key_len); - gcry_err = grub_crypto_hmac_fini (hnd, geomkey); - if (gcry_err) - return grub_crypto_gcry_error (gcry_err); + grub_crypto_hmac_fini (hnd, geomkey); } gcry_err = grub_crypto_hmac_buffer (dev->hash, geomkey, Index: grub-2.12/grub-core/lib/crypto.c =================================================================== --- grub-2.12.orig/grub-core/lib/crypto.c +++ grub-2.12/grub-core/lib/crypto.c @@ -31,7 +31,9 @@ struct grub_crypto_hmac_handle { const struct gcry_md_spec *md; void *ctx; - void *opad; + void *ctx2; + void *ctx_cache; + void *ctx2_cache; }; static gcry_cipher_spec_t *grub_ciphers = NULL; @@ -307,7 +309,8 @@ grub_crypto_hmac_init (const struct gcry { grub_uint8_t *helpkey = NULL; grub_uint8_t *ipad = NULL, *opad = NULL; - void *ctx = NULL; + void *ctx = NULL, *ctx2 = NULL; + void *ctx_cache = NULL, *ctx2_cache = NULL; struct grub_crypto_hmac_handle *ret = NULL; unsigned i; @@ -318,6 +321,18 @@ grub_crypto_hmac_init (const struct gcry if (!ctx) goto err; + ctx2 = grub_malloc (md->contextsize); + if (!ctx2) + goto err; + + ctx_cache = grub_malloc (md->contextsize); + if (!ctx_cache) + goto err; + + ctx2_cache = grub_malloc (md->contextsize); + if (!ctx2_cache) + goto err; + if ( keylen > md->blocksize ) { helpkey = grub_malloc (md->mdlen); @@ -347,26 +362,40 @@ grub_crypto_hmac_init (const struct gcry grub_free (helpkey); helpkey = NULL; + /* inner pad */ md->init (ctx); - - md->write (ctx, ipad, md->blocksize); /* inner pad */ + md->write (ctx, ipad, md->blocksize); + grub_memcpy (ctx_cache, ctx, md->contextsize); grub_memset (ipad, 0, md->blocksize); grub_free (ipad); ipad = NULL; + /* outer pad */ + md->init (ctx2); + md->write (ctx2, opad, md->blocksize); + grub_memcpy (ctx2_cache, ctx2, md->contextsize); + grub_memset (opad, 0, md->blocksize); + grub_free (opad); + opad = NULL; + ret = grub_malloc (sizeof (*ret)); if (!ret) goto err; ret->md = md; ret->ctx = ctx; - ret->opad = opad; + ret->ctx2 = ctx2; + ret->ctx_cache = ctx_cache; + ret->ctx2_cache = ctx2_cache; return ret; err: grub_free (helpkey); grub_free (ctx); + grub_free (ctx2); + grub_free (ctx_cache); + grub_free (ctx2_cache); grub_free (ipad); grub_free (opad); return NULL; @@ -380,37 +409,48 @@ grub_crypto_hmac_write (struct grub_cryp hnd->md->write (hnd->ctx, data, datalen); } -gcry_err_code_t +void grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out) { - grub_uint8_t *p; - grub_uint8_t *ctx2; + grub_crypto_hmac_final (hnd, out); + grub_crypto_hmac_free (hnd); +} - ctx2 = grub_malloc (hnd->md->contextsize); - if (!ctx2) - return GPG_ERR_OUT_OF_MEMORY; +void +grub_crypto_hmac_reset (struct grub_crypto_hmac_handle *hnd) +{ + grub_memcpy (hnd->ctx, hnd->ctx_cache, hnd->md->contextsize); + grub_memcpy (hnd->ctx2, hnd->ctx2_cache, hnd->md->contextsize); +} + +void +grub_crypto_hmac_final (struct grub_crypto_hmac_handle *hnd, void *out) +{ + grub_uint8_t *p; hnd->md->final (hnd->ctx); hnd->md->read (hnd->ctx); p = hnd->md->read (hnd->ctx); - hnd->md->init (ctx2); - hnd->md->write (ctx2, hnd->opad, hnd->md->blocksize); - hnd->md->write (ctx2, p, hnd->md->mdlen); - hnd->md->final (ctx2); - grub_memset (hnd->opad, 0, hnd->md->blocksize); - grub_free (hnd->opad); - grub_memset (hnd->ctx, 0, hnd->md->contextsize); - grub_free (hnd->ctx); + hnd->md->write (hnd->ctx2, p, hnd->md->mdlen); + hnd->md->final (hnd->ctx2); - grub_memcpy (out, hnd->md->read (ctx2), hnd->md->mdlen); - grub_memset (ctx2, 0, hnd->md->contextsize); - grub_free (ctx2); + grub_memcpy (out, hnd->md->read (hnd->ctx2), hnd->md->mdlen); +} +void +grub_crypto_hmac_free (struct grub_crypto_hmac_handle *hnd) +{ + grub_memset (hnd->ctx, 0, hnd->md->contextsize); + grub_free (hnd->ctx); + grub_memset (hnd->ctx2, 0, hnd->md->contextsize); + grub_free (hnd->ctx2); + grub_memset (hnd->ctx_cache, 0, hnd->md->contextsize); + grub_free (hnd->ctx_cache); + grub_memset (hnd->ctx2_cache, 0, hnd->md->contextsize); + grub_free (hnd->ctx2_cache); grub_memset (hnd, 0, sizeof (*hnd)); grub_free (hnd); - - return GPG_ERR_NO_ERROR; } gcry_err_code_t @@ -425,7 +465,8 @@ grub_crypto_hmac_buffer (const struct gc return GPG_ERR_OUT_OF_MEMORY; grub_crypto_hmac_write (hnd, data, datalen); - return grub_crypto_hmac_fini (hnd, out); + grub_crypto_hmac_fini (hnd, out); + return GPG_ERR_NO_ERROR; } Index: grub-2.12/include/grub/crypto.h =================================================================== --- grub-2.12.orig/include/grub/crypto.h +++ grub-2.12/include/grub/crypto.h @@ -358,8 +358,14 @@ void grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd, const void *data, grub_size_t datalen); -gcry_err_code_t +void grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out); +void +grub_crypto_hmac_reset (struct grub_crypto_hmac_handle *hnd); +void +grub_crypto_hmac_final (struct grub_crypto_hmac_handle *hnd, void *out); +void +grub_crypto_hmac_free (struct grub_crypto_hmac_handle *hnd); gcry_err_code_t grub_crypto_hmac_buffer (const struct gcry_md_spec *md, ++++++ 0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch ++++++ >From 7126da87f17ff41334b9fa6969ad032ff9940979 Mon Sep 17 00:00:00 2001 From: Gary Lin <[email protected]> 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 <[email protected]> --- 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
