From 4bbd6ae38efc7c0ae9ffd343157b7f3f37bd729c Mon Sep 17 00:00:00 2001 From: Gary Lin Date: Fri, 25 Jul 2025 13:50:23 +0800 Subject: [PATCH] Constant-time grub_crypto_memcmp() Use the constant-time algorithm to compare the given memory blocks. The code is extracted from the upstream commit: 0739d24cd1648531d0708d1079ff6bbfa6140268 Fix: bsc#1234959 CVE: CVE-2024-56738 Signed-off-by: Gary Lin Upstream: not submitted upstream, as upstream has switched to gcrypt Taken-from: https://build.opensuse.org/projects/SUSE:SLE-15-SP5:Update/packages/grub2.39923/files/grub2-constant-time-grub_crypto_memcmp.patch?expand=0 Fixes: https://www.cve.org/CVERecord?id=CVE-2024-56738 Signed-off-by: Thomas Petazzoni --- grub-core/lib/crypto.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index 396f76410..19db7870a 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -433,19 +433,28 @@ grub_crypto_gcry_error (gcry_err_code_t in) return GRUB_ACCESS_DENIED; } +/* + * Compare byte arrays of length LEN, return 1 if it's not same, + * 0, otherwise. + */ int -grub_crypto_memcmp (const void *a, const void *b, grub_size_t n) +grub_crypto_memcmp (const void *b1, const void *b2, grub_size_t len) { - register grub_size_t counter = 0; - const grub_uint8_t *pa, *pb; + const grub_uint8_t *a = b1; + const grub_uint8_t *b = b2; + int ab, ba; + grub_size_t i; - for (pa = a, pb = b; n; pa++, pb++, n--) + /* Constant-time compare. */ + for (i = 0, ab = 0, ba = 0; i < len; i++) { - if (*pa != *pb) - counter++; + /* If a[i] != b[i], either ab or ba will be negative. */ + ab |= a[i] - b[i]; + ba |= b[i] - a[i]; } - return !!counter; + /* 'ab | ba' is negative when buffers are not equal, extract sign bit. */ + return ((unsigned int)(ab | ba) >> (sizeof(unsigned int) * 8 - 1)) & 1; } #ifndef GRUB_UTIL -- 2.50.1