File 0004-Add-test-code.patch of Package grub2

From d209a267333265af6d9da3dca9b2f0e827176722 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Tue, 6 Jun 2023 16:28:51 +0800
Subject: [PATCH 4/9] Add test code

---
 Makefile.util.def           |  16 +++
 Makefile.utilargon2.def     |   2 +
 util/grub-mkpasswd-argon2.c | 214 ++++++++++++++++++++++++++++++++++++
 3 files changed, 232 insertions(+)
 create mode 100644 util/grub-mkpasswd-argon2.c

diff --git a/Makefile.util.def b/Makefile.util.def
index a8c619132..ea1e5ecb0 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -300,6 +300,22 @@ program = {
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
 };
 
+program = {
+  name = grub-mkpasswd-argon2;
+
+  common = util/grub-mkpasswd-argon2.c;
+  common = grub-core/kern/emu/argp_common.c;
+  common = grub-core/osdep/random.c;
+  common = grub-core/osdep/init.c;
+
+  ldadd = libgrubmods.a;
+  ldadd = libgrubgcry.a;
+  ldadd = libgrubkern.a;
+  ldadd = libargon2.a;
+  ldadd = grub-core/lib/gnulib/libgnu.a;
+  ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
+};
+
 program = {
   name = grub-macho2img;
   mansection = 1;
diff --git a/Makefile.utilargon2.def b/Makefile.utilargon2.def
index a7954a674..ad603b6e6 100644
--- a/Makefile.utilargon2.def
+++ b/Makefile.utilargon2.def
@@ -7,4 +7,6 @@ library = {
 
   common = grub-core/lib/libgcrypt-argon2/cipher/blake2.c;
   common = grub-core/lib/libgcrypt-argon2/cipher/kdf.c;
+  common = grub-core/lib/libgcrypt_wrap/mem.c;
+  common = grub-core/lib/crypto.c;
 };
diff --git a/util/grub-mkpasswd-argon2.c b/util/grub-mkpasswd-argon2.c
new file mode 100644
index 000000000..6c92ce371
--- /dev/null
+++ b/util/grub-mkpasswd-argon2.c
@@ -0,0 +1,214 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1992-1999,2001,2003,2004,2005,2009 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 <config.h>
+
+#include <grub/types.h>
+#include <grub/crypto.h>
+#include <grub/auth.h>
+#include <grub/emu/misc.h>
+#include <grub/util/misc.h>
+#include <grub/i18n.h>
+#include <grub/misc.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define _GNU_SOURCE	1
+
+#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+#pragma GCC diagnostic ignored "-Wmissing-declarations"
+#include <argp.h>
+#pragma GCC diagnostic error "-Wmissing-prototypes"
+#pragma GCC diagnostic error "-Wmissing-declarations"
+
+#include "progname.h"
+
+/******************************
+ *                            *
+ *  Key Derivation Functions  *
+ *                            *
+ ******************************/
+
+/* Algorithm IDs for the KDFs.  */
+enum gcry_kdf_algos
+  {
+    GCRY_KDF_NONE = 0,
+    GCRY_KDF_SIMPLE_S2K = 16,
+    GCRY_KDF_SALTED_S2K = 17,
+    GCRY_KDF_ITERSALTED_S2K = 19,
+    GCRY_KDF_PBKDF1 = 33,
+    GCRY_KDF_PBKDF2 = 34,
+    GCRY_KDF_SCRYPT = 48,
+    GCRY_KDF_ARGON2   = 64,
+    GCRY_KDF_BALLOON  = 65
+  };
+
+enum gcry_kdf_subalgo_argon2
+  {
+    GCRY_KDF_ARGON2D  = 0,
+    GCRY_KDF_ARGON2I  = 1,
+    GCRY_KDF_ARGON2ID = 2
+  };
+
+/* Derive a key from a passphrase.  */
+gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen,
+                             int algo, int subalgo,
+                             const void *salt, size_t saltlen,
+                             unsigned long iterations,
+                             size_t keysize, void *keybuffer);
+
+/* Another API to derive a key from a passphrase.  */
+typedef struct gcry_kdf_handle *gcry_kdf_hd_t;
+
+typedef void (*gcry_kdf_job_fn_t) (void *priv);
+typedef int (*gcry_kdf_dispatch_job_fn_t) (void *jobs_context,
+                                           gcry_kdf_job_fn_t job_fn,
+                                           void *job_priv);
+typedef int (*gcry_kdf_wait_all_jobs_fn_t) (void *jobs_context);
+
+/* Exposed structure for KDF computation to decouple thread functionality.  */
+typedef struct gcry_kdf_thread_ops
+{
+  void *jobs_context;
+  gcry_kdf_dispatch_job_fn_t dispatch_job;
+  gcry_kdf_wait_all_jobs_fn_t wait_all_jobs;
+} gcry_kdf_thread_ops_t;
+
+gcry_error_t gcry_kdf_open (gcry_kdf_hd_t *hd, int algo, int subalgo,
+                            const unsigned long *param, unsigned int paramlen,
+                            const void *passphrase, size_t passphraselen,
+                            const void *salt, size_t saltlen,
+                            const void *key, size_t keylen,
+                            const void *ad, size_t adlen);
+gcry_error_t gcry_kdf_compute (gcry_kdf_hd_t h,
+                               const gcry_kdf_thread_ops_t *ops);
+gcry_error_t gcry_kdf_final (gcry_kdf_hd_t h, size_t resultlen, void *result);
+void gcry_kdf_close (gcry_kdf_hd_t h);
+
+static gcry_error_t
+my_kdf_derive (int parallel,
+               int algo, int subalgo,
+               const unsigned long *params, unsigned int paramslen,
+               const unsigned char *pass, size_t passlen,
+               const unsigned char *salt, size_t saltlen,
+               const unsigned char *key, size_t keylen,
+               const unsigned char *ad, size_t adlen,
+               size_t outlen, unsigned char *out)
+{
+  gcry_error_t err;
+  gcry_kdf_hd_t hd;
+
+  (void)parallel;
+
+  err = gcry_kdf_open (&hd, algo, subalgo, params, paramslen,
+                       pass, passlen, salt, saltlen, key, keylen,
+                       ad, adlen);
+  if (err)
+    return err;
+
+  err = gcry_kdf_compute (hd, NULL);
+
+  if (!err)
+    err = gcry_kdf_final (hd, outlen, out);
+
+  gcry_kdf_close (hd);
+  return err;
+}
+
+static void
+check_argon2 (void)
+{
+  gcry_error_t err;
+  int verbose = 0;
+  const unsigned long param[4] = { 32, 3, 32, 4 };
+  const unsigned char pass[32] = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+  };
+  const unsigned char salt[16] = {
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+  };
+  const unsigned char key[8] = { 3, 3, 3, 3, 3, 3, 3, 3 };
+  const unsigned char ad[12] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 };
+  unsigned char out[32];
+  unsigned char expected[3][32] = {
+    {  /* GCRY_KDF_ARGON2D */
+      0x51, 0x2b, 0x39, 0x1b, 0x6f, 0x11, 0x62, 0x97,
+      0x53, 0x71, 0xd3, 0x09, 0x19, 0x73, 0x42, 0x94,
+      0xf8, 0x68, 0xe3, 0xbe, 0x39, 0x84, 0xf3, 0xc1,
+      0xa1, 0x3a, 0x4d, 0xb9, 0xfa, 0xbe, 0x4a, 0xcb
+    },
+    { /* GCRY_KDF_ARGON2I */
+      0xc8, 0x14, 0xd9, 0xd1, 0xdc, 0x7f, 0x37, 0xaa,
+      0x13, 0xf0, 0xd7, 0x7f, 0x24, 0x94, 0xbd, 0xa1,
+      0xc8, 0xde, 0x6b, 0x01, 0x6d, 0xd3, 0x88, 0xd2,
+      0x99, 0x52, 0xa4, 0xc4, 0x67, 0x2b, 0x6c, 0xe8
+    },
+    { /* GCRY_KDF_ARGON2ID */
+      0x0d, 0x64, 0x0d, 0xf5, 0x8d, 0x78, 0x76, 0x6c,
+      0x08, 0xc0, 0x37, 0xa3, 0x4a, 0x8b, 0x53, 0xc9,
+      0xd0, 0x1e, 0xf0, 0x45, 0x2d, 0x75, 0xb6, 0x5e,
+      0xb5, 0x25, 0x20, 0xe9, 0x6b, 0x01, 0xe6, 0x59
+    }
+  };
+  int i;
+  int subalgo = GCRY_KDF_ARGON2D;
+  int count = 0;
+
+ again:
+
+  if (verbose)
+    fprintf (stderr, "checking ARGON2 test vector %d\n", count);
+
+  err = my_kdf_derive (0,
+                       GCRY_KDF_ARGON2, subalgo, param, 4,
+                       pass, 32, salt, 16, key, 8, ad, 12,
+                       32, out);
+  if (err)
+    fprintf (stderr, "argon2 test failed: \n");
+  else if (memcmp (out, expected[count], 32))
+    {
+      fprintf (stderr, "argon2 test failed: mismatch\n");
+      fputs ("got:", stderr);
+      for (i=0; i < 32; i++)
+        fprintf (stderr, " %02x", out[i]);
+      putc ('\n', stderr);
+    }
+
+  /* Next algo */
+  if (subalgo == GCRY_KDF_ARGON2D)
+    subalgo = GCRY_KDF_ARGON2I;
+  else if (subalgo == GCRY_KDF_ARGON2I)
+    subalgo = GCRY_KDF_ARGON2ID;
+
+  count++;
+  if (count < 3)
+    goto again;
+}
+
+int
+main (int argc, char *argv[])
+{
+  grub_util_host_init (&argc, &argv);
+  check_argon2 ();
+
+  return 0;
+}
-- 
2.40.1

openSUSE Build Service is sponsored by