File 0001-lib-crypto-Introduce-new-HMAC-functions-to-reuse-buf.patch of Package grub2
From e98e880b67be178f3a5951fb345ded8c002eb6e5 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
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 <glin@suse.com>
---
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,