This commit introduces grub_crypto_argon2() which leverages the
'_gcry_kdf_*' functions from libgcrypt to provide Argon2 support.

Due to the dependency of the '_gcry_kdf_*' functions, the order of
'ldadd' entries have to be tweaked in Makefile.util.def so that the
linker can discover those functions.

Signed-off-by: Gary Lin <g...@suse.com>
---
 Makefile.util.def           | 19 +++++++-------
 grub-core/Makefile.core.def |  5 ++++
 grub-core/lib/argon2.c      | 52 +++++++++++++++++++++++++++++++++++++
 include/grub/crypto.h       |  9 +++++++
 4 files changed, 76 insertions(+), 9 deletions(-)
 create mode 100644 grub-core/lib/argon2.c

diff --git a/Makefile.util.def b/Makefile.util.def
index 038253b37..820897bff 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -43,6 +43,7 @@ library = {
   common = grub-core/disk/key_protector.c;
   common = grub-core/disk/cryptodisk.c;
   common = grub-core/disk/AFSplitter.c;
+  common = grub-core/lib/argon2.c;
   common = grub-core/lib/pbkdf2.c;
   common = grub-core/commands/extcmd.c;
   common = grub-core/lib/arg.c;
@@ -225,8 +226,8 @@ program = {
   cflags = '-I$(srcdir)/grub-core/lib/tss2 
-I$(srcdir)/grub-core/commands/tpm2_key_protector';
 
   ldadd = libgrubmods.a;
-  ldadd = libgrubgcry.a;
   ldadd = libgrubkern.a;
+  ldadd = libgrubgcry.a;
   ldadd = grub-core/lib/gnulib/libgnu.a;
   ldadd = '$(LIBTASN1)';
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) 
$(LIBGEOM)';
@@ -323,8 +324,8 @@ program = {
   common = grub-core/osdep/init.c;
 
   ldadd = libgrubmods.a;
-  ldadd = libgrubgcry.a;
   ldadd = libgrubkern.a;
+  ldadd = libgrubgcry.a;
   ldadd = grub-core/lib/gnulib/libgnu.a;
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) 
$(LIBGEOM)';
 };
@@ -378,8 +379,8 @@ program = {
   common = grub-core/osdep/init.c;
 
   ldadd = libgrubmods.a;
-  ldadd = libgrubgcry.a;
   ldadd = libgrubkern.a;
+  ldadd = libgrubgcry.a;
   ldadd = grub-core/lib/gnulib/libgnu.a;
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) 
$(LIBGEOM)';
 };
@@ -466,8 +467,8 @@ program = {
   common = grub-core/kern/emu/argp_common.c;
 
   ldadd = libgrubmods.a;
-  ldadd = libgrubgcry.a;
   ldadd = libgrubkern.a;
+  ldadd = libgrubgcry.a;
   ldadd = grub-core/lib/gnulib/libgnu.a;
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) 
$(LIBGEOM)';
 };
@@ -605,8 +606,8 @@ program = {
 
   ldadd = '$(LIBLZMA)';
   ldadd = libgrubmods.a;
-  ldadd = libgrubgcry.a;
   ldadd = libgrubkern.a;
+  ldadd = libgrubgcry.a;
   ldadd = grub-core/lib/gnulib/libgnu.a;
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) 
$(LIBGEOM)';
 
@@ -691,8 +692,8 @@ program = {
 
   ldadd = '$(LIBLZMA)';
   ldadd = libgrubmods.a;
-  ldadd = libgrubgcry.a;
   ldadd = libgrubkern.a;
+  ldadd = libgrubgcry.a;
   ldadd = grub-core/lib/gnulib/libgnu.a;
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) 
$(LIBGEOM)';
 };
@@ -1400,8 +1401,8 @@ program = {
   common = grub-core/kern/emu/argp_common.c;
 
   ldadd = libgrubmods.a;
-  ldadd = libgrubgcry.a;
   ldadd = libgrubkern.a;
+  ldadd = libgrubgcry.a;
   ldadd = grub-core/lib/gnulib/libgnu.a;
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
 };
@@ -1434,8 +1435,8 @@ program = {
   common = grub-core/osdep/init.c;
 
   ldadd = libgrubmods.a;
-  ldadd = libgrubgcry.a;
   ldadd = libgrubkern.a;
+  ldadd = libgrubgcry.a;
   ldadd = grub-core/lib/gnulib/libgnu.a;
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
 };
@@ -1463,8 +1464,8 @@ program = {
   common = grub-core/osdep/init.c;
 
   ldadd = libgrubmods.a;
-  ldadd = libgrubgcry.a;
   ldadd = libgrubkern.a;
+  ldadd = libgrubgcry.a;
   ldadd = grub-core/lib/gnulib/libgnu.a;
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
 };
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index b3f71196a..16166b1ed 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1694,6 +1694,11 @@ module = {
   common = lib/pbkdf2.c;
 };
 
+module = {
+  name = argon2;
+  common = lib/argon2.c;
+};
+
 module = {
   name = relocator;
   common = lib/relocator.c;
diff --git a/grub-core/lib/argon2.c b/grub-core/lib/argon2.c
new file mode 100644
index 000000000..12ad7ad1c
--- /dev/null
+++ b/grub-core/lib/argon2.c
@@ -0,0 +1,52 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2025  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/crypto.h>
+#include <grub/dl.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+gcry_err_code_t
+grub_crypto_argon2 (int subalgo,
+                   const unsigned long *param, unsigned int paramlen,
+                   const void *password, grub_size_t passwordlen,
+                   const void *salt, grub_size_t saltlen,
+                   const void *key, grub_size_t keylen,
+                   const void *ad, grub_size_t adlen,
+                   grub_size_t resultlen, void *result)
+{
+  gcry_kdf_hd_t hd = {0};
+  gpg_err_code_t err;
+
+  if (saltlen == 0)
+    return GPG_ERR_INV_VALUE;
+
+  err = _gcry_kdf_open (&hd, GRUB_GCRY_KDF_ARGON2, subalgo, param, paramlen,
+                       password, passwordlen, salt, saltlen, key, keylen,
+                       ad, adlen);
+  if (err != GPG_ERR_NO_ERROR)
+    return err;
+
+  err = _gcry_kdf_compute (hd, NULL);
+  if (err == GPG_ERR_NO_ERROR)
+    err = _gcry_kdf_final (hd, resultlen, result);
+
+  _gcry_kdf_close (hd);
+
+  return err;
+}
diff --git a/include/grub/crypto.h b/include/grub/crypto.h
index d323f00ce..c6eb8b2d2 100644
--- a/include/grub/crypto.h
+++ b/include/grub/crypto.h
@@ -573,6 +573,15 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
                    unsigned int c,
                    grub_uint8_t *DK, grub_size_t dkLen);
 
+gcry_err_code_t
+grub_crypto_argon2 (int subalgo,
+                   const unsigned long *param, unsigned int paramlen,
+                   const void *password, grub_size_t passwordlen,
+                   const void *salt, grub_size_t saltlen,
+                   const void *key, grub_size_t keylen,
+                   const void *ad, grub_size_t adlen,
+                   grub_size_t resultlen, void *result);
+
 int
 grub_crypto_memcmp (const void *a, const void *b, grub_size_t n);
 
-- 
2.43.0


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to