From 4cef2fc7308b2132317ad166939994f098b41561 Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Tue, 9 Sep 2025 14:23:14 +0100 Subject: [PATCH] CVE-2024-56738 Backport an algorithmic change to grub_crypto_memcmp() so that it completes in constant time and thus isn't susceptible to side-channel attacks. This is a partial backport of grub 0739d24cd ("libgcrypt: Adjust import script, definitions and API users for libgcrypt 1.11") CVE: CVE-2024-56738 Upstream-Status: Backport [0739d24cd] Signed-off-by: Ross Burton --- grub-core/lib/crypto.c | 23 ++++++++++++++++------- include/grub/crypto.h | 2 +- 2 files changed, 17 insertions(+), 8 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 diff --git a/include/grub/crypto.h b/include/grub/crypto.h index 31c87c302..20ad4c5f7 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -393,7 +393,7 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md, grub_uint8_t *DK, grub_size_t dkLen); 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); int grub_password_get (char buf[], unsigned buf_size); -- 2.43.0