File 0002-Add-blake2-message-digest.patch of Package grub2

From 12eacf80a63734c6681b8678d3e02dc60179e646 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Thu, 1 Jun 2023 20:04:20 +0800
Subject: [PATCH 2/9] Add blake2 message digest

---
 Makefile.utilargon2.def                       |    9 +
 autogen.sh                                    |    4 +-
 conf/Makefile.common                          |    5 +-
 conf/Makefile.extra-dist                      |    2 +
 grub-core/Makefile.argon2.def                 |    9 +
 .../lib/libgcrypt-argon2/cipher/bithelp.h     |   57 +
 .../lib/libgcrypt-argon2/cipher/blake2.c      | 1051 ++++++++++
 .../lib/libgcrypt-argon2/cipher/bufhelp.h     |  435 ++++
 .../lib/libgcrypt-argon2/cipher/cipher.h      |    1 +
 .../lib/libgcrypt-argon2/cipher/g10lib.h      |    1 +
 .../lib/libgcrypt-argon2/cipher/hash-common.h |   36 +
 .../lib/libgcrypt-argon2/src/cipher-proto.h   |  100 +
 grub-core/lib/libgcrypt-argon2/src/cipher.h   |  182 ++
 grub-core/lib/libgcrypt-argon2/src/g10lib.h   |  302 +++
 .../lib/libgcrypt-argon2/src/gcrypt-module.h  |    0
 grub-core/lib/libgcrypt-argon2/src/gcrypt.h   | 1754 +++++++++++++++++
 grub-core/lib/libgcrypt-argon2/src/types.h    |  128 ++
 .../lib/libgcrypt-argon2/src/visibility.h     |    1 +
 grub-core/lib/libgcrypt_wrap/cipher_wrap.h    |    5 +
 include/grub/crypto110.h                      |  510 +++++
 include/grub/gcrypt/gpg-error.h               |    5 +
 21 files changed, 4593 insertions(+), 4 deletions(-)
 create mode 100644 Makefile.utilargon2.def
 create mode 100644 grub-core/Makefile.argon2.def
 create mode 100644 grub-core/lib/libgcrypt-argon2/cipher/bithelp.h
 create mode 100644 grub-core/lib/libgcrypt-argon2/cipher/blake2.c
 create mode 100644 grub-core/lib/libgcrypt-argon2/cipher/bufhelp.h
 create mode 100644 grub-core/lib/libgcrypt-argon2/cipher/cipher.h
 create mode 100644 grub-core/lib/libgcrypt-argon2/cipher/g10lib.h
 create mode 100644 grub-core/lib/libgcrypt-argon2/cipher/hash-common.h
 create mode 100644 grub-core/lib/libgcrypt-argon2/src/cipher-proto.h
 create mode 100644 grub-core/lib/libgcrypt-argon2/src/cipher.h
 create mode 100644 grub-core/lib/libgcrypt-argon2/src/g10lib.h
 create mode 100644 grub-core/lib/libgcrypt-argon2/src/gcrypt-module.h
 create mode 100644 grub-core/lib/libgcrypt-argon2/src/gcrypt.h
 create mode 100644 grub-core/lib/libgcrypt-argon2/src/types.h
 create mode 100644 grub-core/lib/libgcrypt-argon2/src/visibility.h
 create mode 100644 include/grub/crypto110.h

diff --git a/Makefile.utilargon2.def b/Makefile.utilargon2.def
new file mode 100644
index 000000000..2ee7d6513
--- /dev/null
+++ b/Makefile.utilargon2.def
@@ -0,0 +1,9 @@
+AutoGen definitions Makefile.tpl;
+
+library = {
+  name = libargon2.a;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_ARGON2)';
+
+  common = grub-core/lib/libgcrypt-argon2/cipher/blake2.c;
+};
diff --git a/autogen.sh b/autogen.sh
index 31b0ced7e..606e204d0 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -47,8 +47,8 @@ if [ "x${GRUB_CONTRIB}" != x ]; then
   [ "${GRUB_CONTRIB}" = grub-core/contrib ] || ln -s ../contrib grub-core/contrib
 fi
 
-UTIL_DEFS='Makefile.util.def Makefile.utilgcry.def'
-CORE_DEFS='grub-core/Makefile.core.def grub-core/Makefile.gcry.def'
+UTIL_DEFS='Makefile.util.def Makefile.utilgcry.def Makefile.utilargon2.def'
+CORE_DEFS='grub-core/Makefile.core.def grub-core/Makefile.gcry.def grub-core/Makefile.argon2.def'
 
 for extra in contrib/*/Makefile.util.def; do
   if test -e "$extra"; then
diff --git a/conf/Makefile.common b/conf/Makefile.common
index cf95fc291..f14f82457 100644
--- a/conf/Makefile.common
+++ b/conf/Makefile.common
@@ -72,6 +72,7 @@ CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap
 
 CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers -Wno-redundant-decls -Wno-undef $(CFLAGS_POSIX)
 CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt-grub/src -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap $(CPPFLAGS_POSIX) -D_GCRYPT_IN_LIBGCRYPT=1 -I$(top_srcdir)/include/grub/gcrypt
+CPPFLAGS_ARGON2 = -I$(top_srcdir)/grub-core/lib/libgcrypt-argon2/src -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap $(CPPFLAGS_POSIX) -D_GCRYPT110=1 -D_GCRYPT_IN_LIBGCRYPT=1 -I$(top_srcdir)/include/grub/gcrypt
 
 CPPFLAGS_EFIEMU = -I$(top_srcdir)/grub-core/efiemu/runtime
 
@@ -128,12 +129,12 @@ BUILT_SOURCES =
 # Rules for Automake input
 
 .PRECIOUS: $(top_srcdir)/Makefile.util.am
-$(top_srcdir)/Makefile.util.am: $(top_srcdir)/gentpl.py $(top_srcdir)/Makefile.util.def $(top_srcdir)/Makefile.utilgcry.def
+$(top_srcdir)/Makefile.util.am: $(top_srcdir)/gentpl.py $(top_srcdir)/Makefile.util.def $(top_srcdir)/Makefile.utilgcry.def $(top_srcdir)/Makefile.utilargon2.def
 	$(PYTHON) $^ > $@.new || (rm -f $@.new; exit 1)
 	mv $@.new $@
 
 .PRECIOUS: $(top_srcdir)/grub-core/Makefile.core.am
-$(top_srcdir)/grub-core/Makefile.core.am: $(top_srcdir)/gentpl.py $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def
+$(top_srcdir)/grub-core/Makefile.core.am: $(top_srcdir)/gentpl.py $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def $(top_srcdir)/grub-core/Makefile.argon2.def
 	if [ "x$$GRUB_CONTRIB" != x ]; then echo "You need to run ./bootstrap manually." >&2; exit 1; fi
 	$(PYTHON) $^ > $@.new || (rm -f $@.new; exit 1)
 	mv $@.new $@
diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist
index 8f1485d52..e7dee39be 100644
--- a/conf/Makefile.extra-dist
+++ b/conf/Makefile.extra-dist
@@ -4,6 +4,7 @@ EXTRA_DIST += geninit.sh
 EXTRA_DIST += gentpl.py
 EXTRA_DIST += Makefile.util.def
 EXTRA_DIST += Makefile.utilgcry.def
+EXTRA_DIST += Makefile.utilargon2.def
 
 EXTRA_DIST += asm-tests
 EXTRA_DIST += unicode
@@ -20,6 +21,7 @@ EXTRA_DIST += conf/i386-cygwin-img-ld.sc
 
 EXTRA_DIST += grub-core/Makefile.core.def
 EXTRA_DIST += grub-core/Makefile.gcry.def
+EXTRA_DIST += grub-core/Makefile.argon2.def
 
 EXTRA_DIST += grub-core/genmoddep.awk
 EXTRA_DIST += grub-core/genmod.sh.in
diff --git a/grub-core/Makefile.argon2.def b/grub-core/Makefile.argon2.def
new file mode 100644
index 000000000..e9f493785
--- /dev/null
+++ b/grub-core/Makefile.argon2.def
@@ -0,0 +1,9 @@
+AutoGen definitions Makefile.tpl;
+
+module = {
+  name = gcry_blake2;
+  common = lib/libgcrypt-argon2/cipher/blake2.c;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_ARGON2)';
+};
+
diff --git a/grub-core/lib/libgcrypt-argon2/cipher/bithelp.h b/grub-core/lib/libgcrypt-argon2/cipher/bithelp.h
new file mode 100644
index 000000000..e957b4eac
--- /dev/null
+++ b/grub-core/lib/libgcrypt-argon2/cipher/bithelp.h
@@ -0,0 +1,57 @@
+/* This file was automatically imported with 
+   import_gcry.py. Please don't modify it */
+#include <grub/dl.h>
+/* bithelp.h  -  Some bit manipulation helpers
+ *	Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef G10_BITHELP_H
+#define G10_BITHELP_H
+
+
+/****************
+ * Rotate the 32 bit unsigned integer X by N bits left/right
+ */
+#if defined(__GNUC__) && defined(__i386__)
+static inline u32
+rol( u32 x, int n)
+{
+	__asm__("roll %%cl,%0"
+		:"=r" (x)
+		:"0" (x),"c" (n));
+	return x;
+}
+#else
+#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
+#endif
+
+#if defined(__GNUC__) && defined(__i386__)
+static inline u32
+ror(u32 x, int n)
+{
+	__asm__("rorl %%cl,%0"
+		:"=r" (x)
+		:"0" (x),"c" (n));
+	return x;
+}
+#else
+#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
+#endif
+
+
+#endif /*G10_BITHELP_H*/
diff --git a/grub-core/lib/libgcrypt-argon2/cipher/blake2.c b/grub-core/lib/libgcrypt-argon2/cipher/blake2.c
new file mode 100644
index 000000000..0345b65df
--- /dev/null
+++ b/grub-core/lib/libgcrypt-argon2/cipher/blake2.c
@@ -0,0 +1,1051 @@
+/* blake2.c - BLAKE2b and BLAKE2s hash functions (RFC 7693)
+ * Copyright (C) 2017  Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The code is based on public-domain/CC0 BLAKE2 reference implementation
+ * by Samual Neves, at https://github.com/BLAKE2/BLAKE2/tree/master/ref
+ * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
+ */
+
+#include <grub/dl.h>
+GRUB_MOD_LICENSE ("GPLv3+");
+
+#include "g10lib.h"
+#include "bithelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+#include "bufhelp.h"
+#if 0
+#include "cipher-proto.h"
+#endif
+
+#define _gcry_get_hw_features() 0
+
+/* USE_AVX indicates whether to compile with Intel AVX code. */
+#undef USE_AVX
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
+    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AVX 1
+#endif
+
+/* USE_AVX2 indicates whether to compile with Intel AVX2 code. */
+#undef USE_AVX2
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX2) && \
+    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AVX2 1
+#endif
+
+/* AMD64 assembly implementations use SystemV ABI, ABI conversion and additional
+ * stack to store XMM6-XMM15 needed on Win64. */
+#undef ASM_FUNC_ABI
+#undef ASM_EXTRA_STACK
+#if defined(USE_AVX2) && defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)
+# define ASM_FUNC_ABI __attribute__((sysv_abi))
+# define ASM_EXTRA_STACK (10 * 16)
+#else
+# define ASM_FUNC_ABI
+# define ASM_EXTRA_STACK 0
+#endif
+
+#define BLAKE2B_BLOCKBYTES 128
+#define BLAKE2B_OUTBYTES 64
+#define BLAKE2B_KEYBYTES 64
+
+#define BLAKE2S_BLOCKBYTES 64
+#define BLAKE2S_OUTBYTES 32
+#define BLAKE2S_KEYBYTES 32
+
+typedef struct
+{
+  u64 h[8];
+  u64 t[2];
+  u64 f[2];
+} BLAKE2B_STATE;
+
+struct blake2b_param_s
+{
+  byte digest_length;
+  byte key_length;
+  byte fanout;
+  byte depth;
+  byte leaf_length[4];
+  byte node_offset[4];
+  byte xof_length[4];
+  byte node_depth;
+  byte inner_length;
+  byte reserved[14];
+  byte salt[16];
+  byte personal[16];
+};
+
+typedef struct BLAKE2B_CONTEXT_S
+{
+  BLAKE2B_STATE state;
+  byte buf[BLAKE2B_BLOCKBYTES];
+  size_t buflen;
+  size_t outlen;
+#ifdef USE_AVX2
+  unsigned int use_avx2:1;
+#endif
+} BLAKE2B_CONTEXT;
+
+typedef struct
+{
+  u32 h[8];
+  u32 t[2];
+  u32 f[2];
+} BLAKE2S_STATE;
+
+struct blake2s_param_s
+{
+  byte digest_length;
+  byte key_length;
+  byte fanout;
+  byte depth;
+  byte leaf_length[4];
+  byte node_offset[4];
+  byte xof_length[2];
+  byte node_depth;
+  byte inner_length;
+  /* byte reserved[0]; */
+  byte salt[8];
+  byte personal[8];
+};
+
+typedef struct BLAKE2S_CONTEXT_S
+{
+  BLAKE2S_STATE state;
+  byte buf[BLAKE2S_BLOCKBYTES];
+  size_t buflen;
+  size_t outlen;
+#ifdef USE_AVX
+  unsigned int use_avx:1;
+#endif
+} BLAKE2S_CONTEXT;
+
+typedef unsigned int (*blake2_transform_t)(void *S, const void *inblk,
+					   size_t nblks);
+
+
+static const u64 blake2b_IV[8] =
+{
+  U64_C(0x6a09e667f3bcc908), U64_C(0xbb67ae8584caa73b),
+  U64_C(0x3c6ef372fe94f82b), U64_C(0xa54ff53a5f1d36f1),
+  U64_C(0x510e527fade682d1), U64_C(0x9b05688c2b3e6c1f),
+  U64_C(0x1f83d9abfb41bd6b), U64_C(0x5be0cd19137e2179)
+};
+
+static const u32 blake2s_IV[8] =
+{
+  0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
+  0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
+};
+
+static byte zero_block[BLAKE2B_BLOCKBYTES] = { 0, };
+
+
+static void blake2_write(void *S, const void *inbuf, size_t inlen,
+			 byte *tmpbuf, size_t *tmpbuflen, size_t blkbytes,
+			 blake2_transform_t transform_fn)
+{
+  const byte* in = inbuf;
+  unsigned int burn = 0;
+
+  if (inlen > 0)
+    {
+      size_t left = *tmpbuflen;
+      size_t fill = blkbytes - left;
+      size_t nblks;
+
+      if (inlen > fill)
+	{
+	  if (fill > 0)
+	    buf_cpy (tmpbuf + left, in, fill); /* Fill buffer */
+	  left = 0;
+
+	  burn = transform_fn (S, tmpbuf, 1); /* Increment counter + Compress */
+
+	  in += fill;
+	  inlen -= fill;
+
+	  nblks = inlen / blkbytes - !(inlen % blkbytes);
+	  if (nblks)
+	    {
+	      burn = transform_fn(S, in, nblks);
+	      in += blkbytes * nblks;
+	      inlen -= blkbytes * nblks;
+	    }
+	}
+
+      gcry_assert (inlen > 0);
+
+      buf_cpy (tmpbuf + left, in, inlen);
+      *tmpbuflen = left + inlen;
+    }
+
+  if (burn)
+    _gcry_burn_stack (burn);
+
+  return;
+}
+
+
+static inline void blake2b_set_lastblock(BLAKE2B_STATE *S)
+{
+  S->f[0] = U64_C(0xffffffffffffffff);
+}
+
+static inline int blake2b_is_lastblock(const BLAKE2B_STATE *S)
+{
+  return S->f[0] != 0;
+}
+
+static inline void blake2b_increment_counter(BLAKE2B_STATE *S, const int inc)
+{
+  S->t[0] += (u64)inc;
+  S->t[1] += (S->t[0] < (u64)inc) - (inc < 0);
+}
+
+static inline u64 rotr64(u64 x, u64 n)
+{
+  return ((x >> (n & 63)) | (x << ((64 - n) & 63)));
+}
+
+static unsigned int blake2b_transform_generic(BLAKE2B_STATE *S,
+                                              const void *inblks,
+                                              size_t nblks)
+{
+  static const byte blake2b_sigma[12][16] =
+  {
+    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 },
+    { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 },
+    { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 },
+    {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 },
+    {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 },
+    {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 },
+    { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 },
+    { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 },
+    {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 },
+    { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 },
+    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 },
+    { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 }
+  };
+  const byte* in = inblks;
+  u64 m[16];
+  u64 v[16];
+
+  while (nblks--)
+    {
+      /* Increment counter */
+      blake2b_increment_counter (S, BLAKE2B_BLOCKBYTES);
+
+      /* Compress */
+      m[0] = buf_get_le64 (in + 0 * sizeof(m[0]));
+      m[1] = buf_get_le64 (in + 1 * sizeof(m[0]));
+      m[2] = buf_get_le64 (in + 2 * sizeof(m[0]));
+      m[3] = buf_get_le64 (in + 3 * sizeof(m[0]));
+      m[4] = buf_get_le64 (in + 4 * sizeof(m[0]));
+      m[5] = buf_get_le64 (in + 5 * sizeof(m[0]));
+      m[6] = buf_get_le64 (in + 6 * sizeof(m[0]));
+      m[7] = buf_get_le64 (in + 7 * sizeof(m[0]));
+      m[8] = buf_get_le64 (in + 8 * sizeof(m[0]));
+      m[9] = buf_get_le64 (in + 9 * sizeof(m[0]));
+      m[10] = buf_get_le64 (in + 10 * sizeof(m[0]));
+      m[11] = buf_get_le64 (in + 11 * sizeof(m[0]));
+      m[12] = buf_get_le64 (in + 12 * sizeof(m[0]));
+      m[13] = buf_get_le64 (in + 13 * sizeof(m[0]));
+      m[14] = buf_get_le64 (in + 14 * sizeof(m[0]));
+      m[15] = buf_get_le64 (in + 15 * sizeof(m[0]));
+
+      v[ 0] = S->h[0];
+      v[ 1] = S->h[1];
+      v[ 2] = S->h[2];
+      v[ 3] = S->h[3];
+      v[ 4] = S->h[4];
+      v[ 5] = S->h[5];
+      v[ 6] = S->h[6];
+      v[ 7] = S->h[7];
+      v[ 8] = blake2b_IV[0];
+      v[ 9] = blake2b_IV[1];
+      v[10] = blake2b_IV[2];
+      v[11] = blake2b_IV[3];
+      v[12] = blake2b_IV[4] ^ S->t[0];
+      v[13] = blake2b_IV[5] ^ S->t[1];
+      v[14] = blake2b_IV[6] ^ S->f[0];
+      v[15] = blake2b_IV[7] ^ S->f[1];
+
+#define G(r,i,a,b,c,d)                      \
+  do {                                      \
+    a = a + b + m[blake2b_sigma[r][2*i+0]]; \
+    d = rotr64(d ^ a, 32);                  \
+    c = c + d;                              \
+    b = rotr64(b ^ c, 24);                  \
+    a = a + b + m[blake2b_sigma[r][2*i+1]]; \
+    d = rotr64(d ^ a, 16);                  \
+    c = c + d;                              \
+    b = rotr64(b ^ c, 63);                  \
+  } while(0)
+
+#define ROUND(r)                    \
+  do {                              \
+    G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
+    G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
+    G(r,2,v[ 2],v[ 6],v[10],v[14]); \
+    G(r,3,v[ 3],v[ 7],v[11],v[15]); \
+    G(r,4,v[ 0],v[ 5],v[10],v[15]); \
+    G(r,5,v[ 1],v[ 6],v[11],v[12]); \
+    G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
+    G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
+  } while(0)
+
+      ROUND(0);
+      ROUND(1);
+      ROUND(2);
+      ROUND(3);
+      ROUND(4);
+      ROUND(5);
+      ROUND(6);
+      ROUND(7);
+      ROUND(8);
+      ROUND(9);
+      ROUND(10);
+      ROUND(11);
+
+#undef G
+#undef ROUND
+
+      S->h[0] = S->h[0] ^ v[0] ^ v[0 + 8];
+      S->h[1] = S->h[1] ^ v[1] ^ v[1 + 8];
+      S->h[2] = S->h[2] ^ v[2] ^ v[2 + 8];
+      S->h[3] = S->h[3] ^ v[3] ^ v[3 + 8];
+      S->h[4] = S->h[4] ^ v[4] ^ v[4 + 8];
+      S->h[5] = S->h[5] ^ v[5] ^ v[5 + 8];
+      S->h[6] = S->h[6] ^ v[6] ^ v[6 + 8];
+      S->h[7] = S->h[7] ^ v[7] ^ v[7 + 8];
+
+      in += BLAKE2B_BLOCKBYTES;
+    }
+
+  return sizeof(void *) * 4 + sizeof(u64) * 16 * 2;
+}
+
+#ifdef USE_AVX2
+unsigned int _gcry_blake2b_transform_amd64_avx2(BLAKE2B_STATE *S,
+                                                const void *inblks,
+                                                size_t nblks) ASM_FUNC_ABI;
+#endif
+
+static unsigned int blake2b_transform(void *ctx, const void *inblks,
+                                      size_t nblks)
+{
+  BLAKE2B_CONTEXT *c = ctx;
+  unsigned int nburn;
+
+  if (0)
+    {}
+#ifdef USE_AVX2
+  if (c->use_avx2)
+    nburn = _gcry_blake2b_transform_amd64_avx2(&c->state, inblks, nblks);
+#endif
+  else
+    nburn = blake2b_transform_generic(&c->state, inblks, nblks);
+
+  if (nburn)
+    nburn += ASM_EXTRA_STACK;
+
+  return nburn;
+}
+
+static void blake2b_final(void *ctx)
+{
+  BLAKE2B_CONTEXT *c = ctx;
+  BLAKE2B_STATE *S = &c->state;
+  unsigned int burn;
+  size_t i;
+
+  gcry_assert (sizeof(c->buf) >= c->outlen);
+  if (blake2b_is_lastblock(S))
+    return;
+
+  if (c->buflen < BLAKE2B_BLOCKBYTES)
+    memset (c->buf + c->buflen, 0, BLAKE2B_BLOCKBYTES - c->buflen); /* Padding */
+  blake2b_set_lastblock (S);
+  blake2b_increment_counter (S, (int)c->buflen - BLAKE2B_BLOCKBYTES);
+  burn = blake2b_transform (ctx, c->buf, 1);
+
+  /* Output full hash to buffer */
+  for (i = 0; i < 8; ++i)
+    buf_put_le64 (c->buf + sizeof(S->h[i]) * i, S->h[i]);
+
+  /* Zero out extra buffer bytes. */
+  if (c->outlen < sizeof(c->buf))
+    memset (c->buf + c->outlen, 0, sizeof(c->buf) - c->outlen);
+
+  if (burn)
+    _gcry_burn_stack (burn);
+}
+
+static byte *blake2b_read(void *ctx)
+{
+  BLAKE2B_CONTEXT *c = ctx;
+  return c->buf;
+}
+
+static void blake2b_write(void *ctx, const void *inbuf, size_t inlen)
+{
+  BLAKE2B_CONTEXT *c = ctx;
+  BLAKE2B_STATE *S = &c->state;
+  blake2_write(S, inbuf, inlen, c->buf, &c->buflen, BLAKE2B_BLOCKBYTES,
+	       blake2b_transform);
+}
+
+static inline void blake2b_init_param(BLAKE2B_STATE *S,
+				      const struct blake2b_param_s *P)
+{
+  const byte *p = (const byte *)P;
+  size_t i;
+
+  /* init xors IV with input parameter block */
+
+  /* IV XOR ParamBlock */
+  for (i = 0; i < 8; ++i)
+    S->h[i] = blake2b_IV[i] ^ buf_get_le64(p + sizeof(S->h[i]) * i);
+}
+
+static inline gcry_err_code_t blake2b_init(BLAKE2B_CONTEXT *ctx,
+					   const byte *key, size_t keylen)
+{
+  struct blake2b_param_s P[1] = { { 0, } };
+  BLAKE2B_STATE *S = &ctx->state;
+
+  if (!ctx->outlen || ctx->outlen > BLAKE2B_OUTBYTES)
+    return GPG_ERR_INV_ARG;
+  if (sizeof(P[0]) != sizeof(u64) * 8)
+    return GPG_ERR_INTERNAL;
+  if (keylen && (!key || keylen > BLAKE2B_KEYBYTES))
+    return GPG_ERR_INV_KEYLEN;
+
+  P->digest_length = ctx->outlen;
+  P->key_length = keylen;
+  P->fanout = 1;
+  P->depth = 1;
+
+  blake2b_init_param (S, P);
+  wipememory (P, sizeof(P));
+
+  if (key)
+    {
+      blake2b_write (ctx, key, keylen);
+      blake2b_write (ctx, zero_block, BLAKE2B_BLOCKBYTES - keylen);
+    }
+
+  return 0;
+}
+
+static gcry_err_code_t blake2b_init_ctx(void *ctx, unsigned int flags,
+					const byte *key, size_t keylen,
+					unsigned int dbits)
+{
+  BLAKE2B_CONTEXT *c = ctx;
+  unsigned int features = _gcry_get_hw_features ();
+
+  (void)features;
+  (void)flags;
+
+  memset (c, 0, sizeof (*c));
+
+#ifdef USE_AVX2
+  c->use_avx2 = !!(features & HWF_INTEL_AVX2);
+#endif
+
+  c->outlen = dbits / 8;
+  c->buflen = 0;
+  return blake2b_init(c, key, keylen);
+}
+
+/* Variable-length Hash Function H'.  */
+gcry_err_code_t
+blake2b_vl_hash (const void *in, size_t inlen, size_t outputlen, void *output)
+{
+  gcry_err_code_t ec;
+  BLAKE2B_CONTEXT ctx;
+  unsigned char buf[4];
+
+  ec = blake2b_init_ctx (&ctx, 0, NULL, 0,
+                         (outputlen < 64 ? outputlen: 64)*8);
+  if (ec)
+    return ec;
+
+  buf_put_le32 (buf, outputlen);
+  blake2b_write (&ctx, buf, 4);
+  blake2b_write (&ctx, in, inlen);
+  blake2b_final (&ctx);
+
+  if (outputlen <= 64)
+    memcpy (output, ctx.buf, outputlen);
+  else
+    {
+      int r = (outputlen-1)/32 - 1;
+      unsigned int remained = outputlen - 32*r;
+      int i;
+      unsigned char d[64];
+
+      i = 0;
+      while (1)
+        {
+          memcpy (d, ctx.buf, 64);
+          memcpy ((unsigned char *)output+i*32, d, 32);
+
+          if (++i >= r)
+            break;
+
+          ec = blake2b_init_ctx (&ctx, 0, NULL, 0, 64*8);
+          if (ec)
+            return ec;
+
+          blake2b_write (&ctx, d, 64);
+          blake2b_final (&ctx);
+        }
+
+      ec = blake2b_init_ctx (&ctx, 0, NULL, 0, remained*8);
+      if (ec)
+        return ec;
+
+      blake2b_write (&ctx, d, 64);
+      blake2b_final (&ctx);
+
+      memcpy ((unsigned char *)output+r*32, ctx.buf, remained);
+    }
+
+  wipememory (buf, sizeof (buf));
+  wipememory (&ctx, sizeof (ctx));
+  return 0;
+}
+
+static inline void blake2s_set_lastblock(BLAKE2S_STATE *S)
+{
+  S->f[0] = 0xFFFFFFFFUL;
+}
+
+static inline int blake2s_is_lastblock(BLAKE2S_STATE *S)
+{
+  return S->f[0] != 0;
+}
+
+static inline void blake2s_increment_counter(BLAKE2S_STATE *S, const int inc)
+{
+  S->t[0] += (u32)inc;
+  S->t[1] += (S->t[0] < (u32)inc) - (inc < 0);
+}
+
+static unsigned int blake2s_transform_generic(BLAKE2S_STATE *S,
+                                              const void *inblks,
+                                              size_t nblks)
+{
+  static const byte blake2s_sigma[10][16] =
+  {
+    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 },
+    { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 },
+    { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 },
+    {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 },
+    {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 },
+    {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 },
+    { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 },
+    { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 },
+    {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 },
+    { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 },
+  };
+  unsigned int burn = 0;
+  const byte* in = inblks;
+  u32 m[16];
+  u32 v[16];
+
+  while (nblks--)
+    {
+      /* Increment counter */
+      blake2s_increment_counter (S, BLAKE2S_BLOCKBYTES);
+
+      /* Compress */
+      m[0] = buf_get_le32 (in + 0 * sizeof(m[0]));
+      m[1] = buf_get_le32 (in + 1 * sizeof(m[0]));
+      m[2] = buf_get_le32 (in + 2 * sizeof(m[0]));
+      m[3] = buf_get_le32 (in + 3 * sizeof(m[0]));
+      m[4] = buf_get_le32 (in + 4 * sizeof(m[0]));
+      m[5] = buf_get_le32 (in + 5 * sizeof(m[0]));
+      m[6] = buf_get_le32 (in + 6 * sizeof(m[0]));
+      m[7] = buf_get_le32 (in + 7 * sizeof(m[0]));
+      m[8] = buf_get_le32 (in + 8 * sizeof(m[0]));
+      m[9] = buf_get_le32 (in + 9 * sizeof(m[0]));
+      m[10] = buf_get_le32 (in + 10 * sizeof(m[0]));
+      m[11] = buf_get_le32 (in + 11 * sizeof(m[0]));
+      m[12] = buf_get_le32 (in + 12 * sizeof(m[0]));
+      m[13] = buf_get_le32 (in + 13 * sizeof(m[0]));
+      m[14] = buf_get_le32 (in + 14 * sizeof(m[0]));
+      m[15] = buf_get_le32 (in + 15 * sizeof(m[0]));
+
+      v[ 0] = S->h[0];
+      v[ 1] = S->h[1];
+      v[ 2] = S->h[2];
+      v[ 3] = S->h[3];
+      v[ 4] = S->h[4];
+      v[ 5] = S->h[5];
+      v[ 6] = S->h[6];
+      v[ 7] = S->h[7];
+      v[ 8] = blake2s_IV[0];
+      v[ 9] = blake2s_IV[1];
+      v[10] = blake2s_IV[2];
+      v[11] = blake2s_IV[3];
+      v[12] = S->t[0] ^ blake2s_IV[4];
+      v[13] = S->t[1] ^ blake2s_IV[5];
+      v[14] = S->f[0] ^ blake2s_IV[6];
+      v[15] = S->f[1] ^ blake2s_IV[7];
+
+#define G(r,i,a,b,c,d)                      \
+  do {                                      \
+    a = a + b + m[blake2s_sigma[r][2*i+0]]; \
+    d = ror(d ^ a, 16);                     \
+    c = c + d;                              \
+    b = ror(b ^ c, 12);                     \
+    a = a + b + m[blake2s_sigma[r][2*i+1]]; \
+    d = ror(d ^ a, 8);                      \
+    c = c + d;                              \
+    b = ror(b ^ c, 7);                      \
+  } while(0)
+
+#define ROUND(r)                    \
+  do {                              \
+    G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
+    G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
+    G(r,2,v[ 2],v[ 6],v[10],v[14]); \
+    G(r,3,v[ 3],v[ 7],v[11],v[15]); \
+    G(r,4,v[ 0],v[ 5],v[10],v[15]); \
+    G(r,5,v[ 1],v[ 6],v[11],v[12]); \
+    G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
+    G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
+  } while(0)
+
+      ROUND(0);
+      ROUND(1);
+      ROUND(2);
+      ROUND(3);
+      ROUND(4);
+      ROUND(5);
+      ROUND(6);
+      ROUND(7);
+      ROUND(8);
+      ROUND(9);
+
+#undef G
+#undef ROUND
+
+      S->h[0] = S->h[0] ^ v[0] ^ v[0 + 8];
+      S->h[1] = S->h[1] ^ v[1] ^ v[1 + 8];
+      S->h[2] = S->h[2] ^ v[2] ^ v[2 + 8];
+      S->h[3] = S->h[3] ^ v[3] ^ v[3 + 8];
+      S->h[4] = S->h[4] ^ v[4] ^ v[4 + 8];
+      S->h[5] = S->h[5] ^ v[5] ^ v[5 + 8];
+      S->h[6] = S->h[6] ^ v[6] ^ v[6 + 8];
+      S->h[7] = S->h[7] ^ v[7] ^ v[7 + 8];
+
+      in += BLAKE2S_BLOCKBYTES;
+    }
+
+  return burn;
+}
+
+#ifdef USE_AVX
+unsigned int _gcry_blake2s_transform_amd64_avx(BLAKE2S_STATE *S,
+                                               const void *inblks,
+                                               size_t nblks) ASM_FUNC_ABI;
+#endif
+
+static unsigned int blake2s_transform(void *ctx, const void *inblks,
+                                      size_t nblks)
+{
+  BLAKE2S_CONTEXT *c = ctx;
+  unsigned int nburn;
+
+  if (0)
+    {}
+#ifdef USE_AVX
+  if (c->use_avx)
+    nburn = _gcry_blake2s_transform_amd64_avx(&c->state, inblks, nblks);
+#endif
+  else
+    nburn = blake2s_transform_generic(&c->state, inblks, nblks);
+
+  if (nburn)
+    nburn += ASM_EXTRA_STACK;
+
+  return nburn;
+}
+
+static void blake2s_final(void *ctx)
+{
+  BLAKE2S_CONTEXT *c = ctx;
+  BLAKE2S_STATE *S = &c->state;
+  unsigned int burn;
+  size_t i;
+
+  gcry_assert (sizeof(c->buf) >= c->outlen);
+  if (blake2s_is_lastblock(S))
+    return;
+
+  if (c->buflen < BLAKE2S_BLOCKBYTES)
+    memset (c->buf + c->buflen, 0, BLAKE2S_BLOCKBYTES - c->buflen); /* Padding */
+  blake2s_set_lastblock (S);
+  blake2s_increment_counter (S, (int)c->buflen - BLAKE2S_BLOCKBYTES);
+  burn = blake2s_transform (ctx, c->buf, 1);
+
+  /* Output full hash to buffer */
+  for (i = 0; i < 8; ++i)
+    buf_put_le32 (c->buf + sizeof(S->h[i]) * i, S->h[i]);
+
+  /* Zero out extra buffer bytes. */
+  if (c->outlen < sizeof(c->buf))
+    memset (c->buf + c->outlen, 0, sizeof(c->buf) - c->outlen);
+
+  if (burn)
+    _gcry_burn_stack (burn);
+}
+
+static byte *blake2s_read(void *ctx)
+{
+  BLAKE2S_CONTEXT *c = ctx;
+  return c->buf;
+}
+
+static void blake2s_write(void *ctx, const void *inbuf, size_t inlen)
+{
+  BLAKE2S_CONTEXT *c = ctx;
+  BLAKE2S_STATE *S = &c->state;
+  blake2_write(S, inbuf, inlen, c->buf, &c->buflen, BLAKE2S_BLOCKBYTES,
+	       blake2s_transform);
+}
+
+static inline void blake2s_init_param(BLAKE2S_STATE *S,
+				      const struct blake2s_param_s *P)
+{
+  const byte *p = (const byte *)P;
+  size_t i;
+
+  /* init2 xors IV with input parameter block */
+
+  /* IV XOR ParamBlock */
+  for (i = 0; i < 8; ++i)
+    S->h[i] ^= blake2s_IV[i] ^ buf_get_le32(&p[i * 4]);
+}
+
+static inline gcry_err_code_t blake2s_init(BLAKE2S_CONTEXT *ctx,
+					   const byte *key, size_t keylen)
+{
+  struct blake2s_param_s P[1] = { { 0, } };
+  BLAKE2S_STATE *S = &ctx->state;
+
+  if (!ctx->outlen || ctx->outlen > BLAKE2S_OUTBYTES)
+    return GPG_ERR_INV_ARG;
+  if (sizeof(P[0]) != sizeof(u32) * 8)
+    return GPG_ERR_INTERNAL;
+  if (keylen && (!key || keylen > BLAKE2S_KEYBYTES))
+    return GPG_ERR_INV_KEYLEN;
+
+  P->digest_length = ctx->outlen;
+  P->key_length = keylen;
+  P->fanout = 1;
+  P->depth = 1;
+
+  blake2s_init_param (S, P);
+  wipememory (P, sizeof(P));
+
+  if (key)
+    {
+      blake2s_write (ctx, key, keylen);
+      blake2s_write (ctx, zero_block, BLAKE2S_BLOCKBYTES - keylen);
+    }
+
+  return 0;
+}
+
+static gcry_err_code_t blake2s_init_ctx(void *ctx, unsigned int flags,
+					const byte *key, size_t keylen,
+					unsigned int dbits)
+{
+  BLAKE2S_CONTEXT *c = ctx;
+  unsigned int features = _gcry_get_hw_features ();
+
+  (void)features;
+  (void)flags;
+
+  memset (c, 0, sizeof (*c));
+
+#ifdef USE_AVX
+  c->use_avx = !!(features & HWF_INTEL_AVX);
+#endif
+
+  c->outlen = dbits / 8;
+  c->buflen = 0;
+  return blake2s_init(c, key, keylen);
+}
+
+/* Selftests from "RFC 7693, Appendix E. BLAKE2b and BLAKE2s Self-Test
+ * Module C Source". */
+static void selftest_seq(byte *out, size_t len, u32 seed)
+{
+  size_t i;
+  u32 t, a, b;
+
+  a = 0xDEAD4BAD * seed;
+  b = 1;
+
+  for (i = 0; i < len; i++)
+    {
+      t = a + b;
+      a = b;
+      b = t;
+      out[i] = (t >> 24) & 0xFF;
+    }
+}
+
+static gpg_err_code_t
+selftests_blake2b (int algo, int extended, selftest_report_func_t report)
+{
+  static const byte blake2b_res[32] =
+  {
+    0xC2, 0x3A, 0x78, 0x00, 0xD9, 0x81, 0x23, 0xBD,
+    0x10, 0xF5, 0x06, 0xC6, 0x1E, 0x29, 0xDA, 0x56,
+    0x03, 0xD7, 0x63, 0xB8, 0xBB, 0xAD, 0x2E, 0x73,
+    0x7F, 0x5E, 0x76, 0x5A, 0x7B, 0xCC, 0xD4, 0x75
+  };
+  static const size_t b2b_md_len[4] = { 20, 32, 48, 64 };
+  static const size_t b2b_in_len[6] = { 0, 3, 128, 129, 255, 1024 };
+  size_t i, j, outlen, inlen;
+  byte in[1024], key[64];
+  BLAKE2B_CONTEXT ctx;
+  BLAKE2B_CONTEXT ctx2;
+  const char *what;
+  const char *errtxt;
+
+  (void)extended;
+
+  what = "rfc7693 BLAKE2b selftest";
+
+  /* 256-bit hash for testing */
+  if (blake2b_init_ctx(&ctx, 0, NULL, 0, 32 * 8))
+    {
+      errtxt = "init failed";
+      goto failed;
+    }
+
+  for (i = 0; i < 4; i++)
+    {
+      outlen = b2b_md_len[i];
+      for (j = 0; j < 6; j++)
+	{
+	  inlen = b2b_in_len[j];
+
+	  selftest_seq(in, inlen, inlen); /* unkeyed hash */
+	  blake2b_init_ctx(&ctx2, 0, NULL, 0, outlen * 8);
+	  blake2b_write(&ctx2, in, inlen);
+	  blake2b_final(&ctx2);
+	  blake2b_write(&ctx, ctx2.buf, outlen); /* hash the hash */
+
+	  selftest_seq(key, outlen, outlen); /* keyed hash */
+	  blake2b_init_ctx(&ctx2, 0, key, outlen, outlen * 8);
+	  blake2b_write(&ctx2, in, inlen);
+	  blake2b_final(&ctx2);
+	  blake2b_write(&ctx, ctx2.buf, outlen); /* hash the hash */
+	}
+    }
+
+  /* compute and compare the hash of hashes */
+  blake2b_final(&ctx);
+  for (i = 0; i < 32; i++)
+    {
+      if (ctx.buf[i] != blake2b_res[i])
+	{
+	  errtxt = "digest mismatch";
+	  goto failed;
+	}
+    }
+
+  return 0;
+
+failed:
+  if (report)
+    report ("digest", algo, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+static gpg_err_code_t
+selftests_blake2s (int algo, int extended, selftest_report_func_t report)
+{
+  static const byte blake2s_res[32] =
+  {
+    0x6A, 0x41, 0x1F, 0x08, 0xCE, 0x25, 0xAD, 0xCD,
+    0xFB, 0x02, 0xAB, 0xA6, 0x41, 0x45, 0x1C, 0xEC,
+    0x53, 0xC5, 0x98, 0xB2, 0x4F, 0x4F, 0xC7, 0x87,
+    0xFB, 0xDC, 0x88, 0x79, 0x7F, 0x4C, 0x1D, 0xFE
+  };
+  static const size_t b2s_md_len[4] = { 16, 20, 28, 32 };
+  static const size_t b2s_in_len[6] = { 0, 3, 64, 65, 255, 1024 };
+  size_t i, j, outlen, inlen;
+  byte in[1024], key[32];
+  BLAKE2S_CONTEXT ctx;
+  BLAKE2S_CONTEXT ctx2;
+  const char *what;
+  const char *errtxt;
+
+  (void)extended;
+
+  what = "rfc7693 BLAKE2s selftest";
+
+  /* 256-bit hash for testing */
+  if (blake2s_init_ctx(&ctx, 0, NULL, 0, 32 * 8))
+    {
+      errtxt = "init failed";
+      goto failed;
+    }
+
+  for (i = 0; i < 4; i++)
+    {
+      outlen = b2s_md_len[i];
+      for (j = 0; j < 6; j++)
+	{
+	  inlen = b2s_in_len[j];
+
+	  selftest_seq(in, inlen, inlen); /* unkeyed hash */
+	  blake2s_init_ctx(&ctx2, 0, NULL, 0, outlen * 8);
+	  blake2s_write(&ctx2, in, inlen);
+	  blake2s_final(&ctx2);
+	  blake2s_write(&ctx, ctx2.buf, outlen); /* hash the hash */
+
+	  selftest_seq(key, outlen, outlen); /* keyed hash */
+	  blake2s_init_ctx(&ctx2, 0, key, outlen, outlen * 8);
+	  blake2s_write(&ctx2, in, inlen);
+	  blake2s_final(&ctx2);
+	  blake2s_write(&ctx, ctx2.buf, outlen); /* hash the hash */
+	}
+    }
+
+  /* compute and compare the hash of hashes */
+  blake2s_final(&ctx);
+  for (i = 0; i < 32; i++)
+    {
+      if (ctx.buf[i] != blake2s_res[i])
+	{
+	  errtxt = "digest mismatch";
+	  goto failed;
+	}
+    }
+
+  return 0;
+
+failed:
+  if (report)
+    report ("digest", algo, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+gcry_err_code_t _gcry_blake2_init_with_key(void *ctx, unsigned int flags,
+					   const unsigned char *key,
+					   size_t keylen, int algo)
+{
+  gcry_err_code_t rc;
+  switch (algo)
+    {
+    case GCRY_MD_BLAKE2B_512:
+      rc = blake2b_init_ctx (ctx, flags, key, keylen, 512);
+      break;
+    case GCRY_MD_BLAKE2B_384:
+      rc = blake2b_init_ctx (ctx, flags, key, keylen, 384);
+      break;
+    case GCRY_MD_BLAKE2B_256:
+      rc = blake2b_init_ctx (ctx, flags, key, keylen, 256);
+      break;
+    case GCRY_MD_BLAKE2B_160:
+      rc = blake2b_init_ctx (ctx, flags, key, keylen, 160);
+      break;
+    case GCRY_MD_BLAKE2S_256:
+      rc = blake2s_init_ctx (ctx, flags, key, keylen, 256);
+      break;
+    case GCRY_MD_BLAKE2S_224:
+      rc = blake2s_init_ctx (ctx, flags, key, keylen, 224);
+      break;
+    case GCRY_MD_BLAKE2S_160:
+      rc = blake2s_init_ctx (ctx, flags, key, keylen, 160);
+      break;
+    case GCRY_MD_BLAKE2S_128:
+      rc = blake2s_init_ctx (ctx, flags, key, keylen, 128);
+      break;
+    default:
+      rc = GPG_ERR_DIGEST_ALGO;
+      break;
+    }
+
+  return rc;
+}
+
+
+#define DEFINE_BLAKE2_VARIANT(bs, BS, dbits, oid_branch) \
+  static void blake2##bs##_##dbits##_init(void *ctx, unsigned int flags) \
+  { \
+    int err = blake2##bs##_init_ctx (ctx, flags, NULL, 0, dbits); \
+    gcry_assert (err == 0); \
+  } \
+  static void \
+  _gcry_blake2##bs##_##dbits##_hash_buffers(void *outbuf, size_t nbytes, \
+        const gcry_buffer_t *iov, int iovcnt) \
+  { \
+    BLAKE2##BS##_CONTEXT hd; \
+    (void)nbytes; \
+    blake2##bs##_##dbits##_init (&hd, 0); \
+    for (;iovcnt > 0; iov++, iovcnt--) \
+      blake2##bs##_write (&hd, (const char*)iov[0].data + iov[0].off, \
+                          iov[0].len); \
+    blake2##bs##_final (&hd); \
+    memcpy (outbuf, blake2##bs##_read (&hd), dbits / 8); \
+  } \
+  static const byte blake2##bs##_##dbits##_asn[] = { 0x30 }; \
+  static const gcry_md_oid_spec_t oid_spec_blake2##bs##_##dbits[] = \
+    { \
+      { " 1.3.6.1.4.1.1722.12.2." oid_branch }, \
+      { NULL } \
+    }; \
+  const gcry_md_spec_t _gcry_digest_spec_blake2##bs##_##dbits = \
+    { \
+      GCRY_MD_BLAKE2##BS##_##dbits, {0, 0}, \
+      "BLAKE2" #BS "_" #dbits, blake2##bs##_##dbits##_asn, \
+      DIM (blake2##bs##_##dbits##_asn), oid_spec_blake2##bs##_##dbits, \
+      dbits / 8, blake2##bs##_##dbits##_init, blake2##bs##_write, \
+      blake2##bs##_final, blake2##bs##_read, NULL, \
+      _gcry_blake2##bs##_##dbits##_hash_buffers, \
+      sizeof (BLAKE2##BS##_CONTEXT), selftests_blake2##bs \
+    };
+
+DEFINE_BLAKE2_VARIANT(b, B, 512, "1.16")
+DEFINE_BLAKE2_VARIANT(b, B, 384, "1.12")
+DEFINE_BLAKE2_VARIANT(b, B, 256, "1.8")
+DEFINE_BLAKE2_VARIANT(b, B, 160, "1.5")
+
+DEFINE_BLAKE2_VARIANT(s, S, 256, "2.8")
+DEFINE_BLAKE2_VARIANT(s, S, 224, "2.7")
+DEFINE_BLAKE2_VARIANT(s, S, 160, "2.5")
+DEFINE_BLAKE2_VARIANT(s, S, 128, "2.4")
diff --git a/grub-core/lib/libgcrypt-argon2/cipher/bufhelp.h b/grub-core/lib/libgcrypt-argon2/cipher/bufhelp.h
new file mode 100644
index 000000000..89471e65f
--- /dev/null
+++ b/grub-core/lib/libgcrypt-argon2/cipher/bufhelp.h
@@ -0,0 +1,435 @@
+/* This file was automatically imported with 
+   import_gcry.py. Please don't modify it */
+#include <grub/dl.h>
+/* bufhelp.h  -  Some buffer manipulation helpers
+ * Copyright (C) 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef GCRYPT_BUFHELP_H
+#define GCRYPT_BUFHELP_H
+
+
+#include "bithelp.h"
+
+
+#undef BUFHELP_FAST_UNALIGNED_ACCESS
+#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \
+    defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \
+    (defined(__i386__) || defined(__x86_64__) || \
+     (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \
+     defined(__aarch64__))
+/* These architectures are able of unaligned memory accesses and can
+   handle those fast.
+ */
+# define BUFHELP_FAST_UNALIGNED_ACCESS 1
+#endif
+
+
+#ifdef BUFHELP_FAST_UNALIGNED_ACCESS
+/* Define type with one-byte alignment on architectures with fast unaligned
+   memory accesses.
+ */
+typedef struct bufhelp_int_s
+{
+  uintptr_t a;
+} __attribute__((packed, aligned(1))) bufhelp_int_t;
+#else
+/* Define type with default alignment for other architectures (unaligned
+   accessed handled in per byte loops).
+ */
+typedef struct bufhelp_int_s
+{
+  uintptr_t a;
+} bufhelp_int_t;
+#endif
+
+
+/* Optimized function for small buffer copying */
+static inline void
+buf_cpy(void *_dst, const void *_src, size_t len)
+{
+#if __GNUC__ >= 4 && (defined(__x86_64__) || defined(__i386__))
+  /* For AMD64 and i386, memcpy is faster.  */
+  memcpy(_dst, _src, len);
+#else
+  byte *dst = _dst;
+  const byte *src = _src;
+  bufhelp_int_t *ldst;
+  const bufhelp_int_t *lsrc;
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
+
+  /* Skip fast processing if buffers are unaligned.  */
+  if (((uintptr_t)dst | (uintptr_t)src) & longmask)
+    goto do_bytes;
+#endif
+
+  ldst = (bufhelp_int_t *)(void *)dst;
+  lsrc = (const bufhelp_int_t *)(const void *)src;
+
+  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
+    (ldst++)->a = (lsrc++)->a;
+
+  dst = (byte *)ldst;
+  src = (const byte *)lsrc;
+
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+do_bytes:
+#endif
+  /* Handle tail.  */
+  for (; len; len--)
+    *dst++ = *src++;
+#endif /*__GNUC__ >= 4 && (__x86_64__ || __i386__)*/
+}
+
+
+/* Optimized function for buffer xoring */
+static inline void
+buf_xor(void *_dst, const void *_src1, const void *_src2, size_t len)
+{
+  byte *dst = _dst;
+  const byte *src1 = _src1;
+  const byte *src2 = _src2;
+  bufhelp_int_t *ldst;
+  const bufhelp_int_t *lsrc1, *lsrc2;
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
+
+  /* Skip fast processing if buffers are unaligned.  */
+  if (((uintptr_t)dst | (uintptr_t)src1 | (uintptr_t)src2) & longmask)
+    goto do_bytes;
+#endif
+
+  ldst = (bufhelp_int_t *)(void *)dst;
+  lsrc1 = (const bufhelp_int_t *)(const void *)src1;
+  lsrc2 = (const bufhelp_int_t *)(const void *)src2;
+
+  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
+    (ldst++)->a = (lsrc1++)->a ^ (lsrc2++)->a;
+
+  dst = (byte *)ldst;
+  src1 = (const byte *)lsrc1;
+  src2 = (const byte *)lsrc2;
+
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+do_bytes:
+#endif
+  /* Handle tail.  */
+  for (; len; len--)
+    *dst++ = *src1++ ^ *src2++;
+}
+
+
+/* Optimized function for in-place buffer xoring. */
+static inline void
+buf_xor_1(void *_dst, const void *_src, size_t len)
+{
+  byte *dst = _dst;
+  const byte *src = _src;
+  bufhelp_int_t *ldst;
+  const bufhelp_int_t *lsrc;
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
+
+  /* Skip fast processing if buffers are unaligned.  */
+  if (((uintptr_t)dst | (uintptr_t)src) & longmask)
+    goto do_bytes;
+#endif
+
+  ldst = (bufhelp_int_t *)(void *)dst;
+  lsrc = (const bufhelp_int_t *)(const void *)src;
+
+  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
+    (ldst++)->a ^= (lsrc++)->a;
+
+  dst = (byte *)ldst;
+  src = (const byte *)lsrc;
+
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+do_bytes:
+#endif
+  /* Handle tail.  */
+  for (; len; len--)
+    *dst++ ^= *src++;
+}
+
+
+/* Optimized function for buffer xoring with two destination buffers.  Used
+   mainly by CFB mode encryption.  */
+static inline void
+buf_xor_2dst(void *_dst1, void *_dst2, const void *_src, size_t len)
+{
+  byte *dst1 = _dst1;
+  byte *dst2 = _dst2;
+  const byte *src = _src;
+  bufhelp_int_t *ldst1, *ldst2;
+  const bufhelp_int_t *lsrc;
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
+
+  /* Skip fast processing if buffers are unaligned.  */
+  if (((uintptr_t)src | (uintptr_t)dst1 | (uintptr_t)dst2) & longmask)
+    goto do_bytes;
+#endif
+
+  ldst1 = (bufhelp_int_t *)(void *)dst1;
+  ldst2 = (bufhelp_int_t *)(void *)dst2;
+  lsrc = (const bufhelp_int_t *)(const void *)src;
+
+  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
+    (ldst1++)->a = ((ldst2++)->a ^= (lsrc++)->a);
+
+  dst1 = (byte *)ldst1;
+  dst2 = (byte *)ldst2;
+  src = (const byte *)lsrc;
+
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+do_bytes:
+#endif
+  /* Handle tail.  */
+  for (; len; len--)
+    *dst1++ = (*dst2++ ^= *src++);
+}
+
+
+/* Optimized function for combined buffer xoring and copying.  Used by mainly
+   CBC mode decryption.  */
+static inline void
+buf_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy,
+		 const void *_src_cpy, size_t len)
+{
+  byte *dst_xor = _dst_xor;
+  byte *srcdst_cpy = _srcdst_cpy;
+  const byte *src_xor = _src_xor;
+  const byte *src_cpy = _src_cpy;
+  byte temp;
+  bufhelp_int_t *ldst_xor, *lsrcdst_cpy;
+  const bufhelp_int_t *lsrc_cpy, *lsrc_xor;
+  uintptr_t ltemp;
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+  const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
+
+  /* Skip fast processing if buffers are unaligned.  */
+  if (((uintptr_t)src_cpy | (uintptr_t)src_xor | (uintptr_t)dst_xor |
+       (uintptr_t)srcdst_cpy) & longmask)
+    goto do_bytes;
+#endif
+
+  ldst_xor = (bufhelp_int_t *)(void *)dst_xor;
+  lsrc_xor = (const bufhelp_int_t *)(void *)src_xor;
+  lsrcdst_cpy = (bufhelp_int_t *)(void *)srcdst_cpy;
+  lsrc_cpy = (const bufhelp_int_t *)(const void *)src_cpy;
+
+  for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t))
+    {
+      ltemp = (lsrc_cpy++)->a;
+      (ldst_xor++)->a = (lsrcdst_cpy)->a ^ (lsrc_xor++)->a;
+      (lsrcdst_cpy++)->a = ltemp;
+    }
+
+  dst_xor = (byte *)ldst_xor;
+  src_xor = (const byte *)lsrc_xor;
+  srcdst_cpy = (byte *)lsrcdst_cpy;
+  src_cpy = (const byte *)lsrc_cpy;
+
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+do_bytes:
+#endif
+  /* Handle tail.  */
+  for (; len; len--)
+    {
+      temp = *src_cpy++;
+      *dst_xor++ = *srcdst_cpy ^ *src_xor++;
+      *srcdst_cpy++ = temp;
+    }
+}
+
+
+/* Optimized function for combined buffer xoring and copying.  Used by mainly
+   CFB mode decryption.  */
+static inline void
+buf_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src, size_t len)
+{
+  buf_xor_n_copy_2(_dst_xor, _src, _srcdst_cpy, _src, len);
+}
+
+
+/* Constant-time compare of two buffers.  Returns 1 if buffers are equal,
+   and 0 if buffers differ.  */
+static inline int
+buf_eq_const(const void *_a, const void *_b, size_t len)
+{
+  const byte *a = _a;
+  const byte *b = _b;
+  size_t diff, i;
+
+  /* Constant-time compare. */
+  for (i = 0, diff = 0; i < len; i++)
+    diff -= !!(a[i] - b[i]);
+
+  return !diff;
+}
+
+
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+
+/* Functions for loading and storing unaligned u32 values of different
+   endianness.  */
+static inline u32 buf_get_be32(const void *_buf)
+{
+  const byte *in = _buf;
+  return ((u32)in[0] << 24) | ((u32)in[1] << 16) | \
+         ((u32)in[2] << 8) | (u32)in[3];
+}
+
+static inline u32 buf_get_le32(const void *_buf)
+{
+  const byte *in = _buf;
+  return ((u32)in[3] << 24) | ((u32)in[2] << 16) | \
+         ((u32)in[1] << 8) | (u32)in[0];
+}
+
+static inline void buf_put_be32(void *_buf, u32 val)
+{
+  byte *out = _buf;
+  out[0] = val >> 24;
+  out[1] = val >> 16;
+  out[2] = val >> 8;
+  out[3] = val;
+}
+
+static inline void buf_put_le32(void *_buf, u32 val)
+{
+  byte *out = _buf;
+  out[3] = val >> 24;
+  out[2] = val >> 16;
+  out[1] = val >> 8;
+  out[0] = val;
+}
+
+
+/* Functions for loading and storing unaligned u64 values of different
+   endianness.  */
+static inline u64 buf_get_be64(const void *_buf)
+{
+  const byte *in = _buf;
+  return ((u64)in[0] << 56) | ((u64)in[1] << 48) | \
+         ((u64)in[2] << 40) | ((u64)in[3] << 32) | \
+         ((u64)in[4] << 24) | ((u64)in[5] << 16) | \
+         ((u64)in[6] << 8) | (u64)in[7];
+}
+
+static inline u64 buf_get_le64(const void *_buf)
+{
+  const byte *in = _buf;
+  return ((u64)in[7] << 56) | ((u64)in[6] << 48) | \
+         ((u64)in[5] << 40) | ((u64)in[4] << 32) | \
+         ((u64)in[3] << 24) | ((u64)in[2] << 16) | \
+         ((u64)in[1] << 8) | (u64)in[0];
+}
+
+static inline void buf_put_be64(void *_buf, u64 val)
+{
+  byte *out = _buf;
+  out[0] = val >> 56;
+  out[1] = val >> 48;
+  out[2] = val >> 40;
+  out[3] = val >> 32;
+  out[4] = val >> 24;
+  out[5] = val >> 16;
+  out[6] = val >> 8;
+  out[7] = val;
+}
+
+static inline void buf_put_le64(void *_buf, u64 val)
+{
+  byte *out = _buf;
+  out[7] = val >> 56;
+  out[6] = val >> 48;
+  out[5] = val >> 40;
+  out[4] = val >> 32;
+  out[3] = val >> 24;
+  out[2] = val >> 16;
+  out[1] = val >> 8;
+  out[0] = val;
+}
+
+#else /*BUFHELP_FAST_UNALIGNED_ACCESS*/
+
+typedef struct bufhelp_u32_s
+{
+  u32 a;
+} __attribute__((packed, aligned(1))) bufhelp_u32_t;
+
+/* Functions for loading and storing unaligned u32 values of different
+   endianness.  */
+static inline u32 buf_get_be32(const void *_buf)
+{
+  return be_bswap32(((const bufhelp_u32_t *)_buf)->a);
+}
+
+static inline u32 buf_get_le32(const void *_buf)
+{
+  return le_bswap32(((const bufhelp_u32_t *)_buf)->a);
+}
+
+static inline void buf_put_be32(void *_buf, u32 val)
+{
+  bufhelp_u32_t *out = _buf;
+  out->a = be_bswap32(val);
+}
+
+static inline void buf_put_le32(void *_buf, u32 val)
+{
+  bufhelp_u32_t *out = _buf;
+  out->a = le_bswap32(val);
+}
+
+
+typedef struct bufhelp_u64_s
+{
+  u64 a;
+} __attribute__((packed, aligned(1))) bufhelp_u64_t;
+
+/* Functions for loading and storing unaligned u64 values of different
+   endianness.  */
+static inline u64 buf_get_be64(const void *_buf)
+{
+  return be_bswap64(((const bufhelp_u64_t *)_buf)->a);
+}
+
+static inline u64 buf_get_le64(const void *_buf)
+{
+  return le_bswap64(((const bufhelp_u64_t *)_buf)->a);
+}
+
+static inline void buf_put_be64(void *_buf, u64 val)
+{
+  bufhelp_u64_t *out = _buf;
+  out->a = be_bswap64(val);
+}
+
+static inline void buf_put_le64(void *_buf, u64 val)
+{
+  bufhelp_u64_t *out = _buf;
+  out->a = le_bswap64(val);
+}
+
+
+#endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/
+
+#endif /*GCRYPT_BUFHELP_H*/
diff --git a/grub-core/lib/libgcrypt-argon2/cipher/cipher.h b/grub-core/lib/libgcrypt-argon2/cipher/cipher.h
new file mode 100644
index 000000000..49cc16a2a
--- /dev/null
+++ b/grub-core/lib/libgcrypt-argon2/cipher/cipher.h
@@ -0,0 +1 @@
+#include <cipher_wrap.h>
diff --git a/grub-core/lib/libgcrypt-argon2/cipher/g10lib.h b/grub-core/lib/libgcrypt-argon2/cipher/g10lib.h
new file mode 100644
index 000000000..49cc16a2a
--- /dev/null
+++ b/grub-core/lib/libgcrypt-argon2/cipher/g10lib.h
@@ -0,0 +1 @@
+#include <cipher_wrap.h>
diff --git a/grub-core/lib/libgcrypt-argon2/cipher/hash-common.h b/grub-core/lib/libgcrypt-argon2/cipher/hash-common.h
new file mode 100644
index 000000000..79d36759f
--- /dev/null
+++ b/grub-core/lib/libgcrypt-argon2/cipher/hash-common.h
@@ -0,0 +1,36 @@
+/* This file was automatically imported with 
+   import_gcry.py. Please don't modify it */
+#include <grub/dl.h>
+/* hash-common.h - Declarations of common code for hash algorithms.
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_HASH_COMMON_H
+#define GCRY_HASH_COMMON_H
+
+
+const char * _gcry_hash_selftest_check_one
+/**/         (int algo,
+              int datamode, const void *data, size_t datalen,
+              const void *expect, size_t expectlen);
+
+
+
+
+
+#endif /*GCRY_HASH_COMMON_H*/
diff --git a/grub-core/lib/libgcrypt-argon2/src/cipher-proto.h b/grub-core/lib/libgcrypt-argon2/src/cipher-proto.h
new file mode 100644
index 000000000..80202fe77
--- /dev/null
+++ b/grub-core/lib/libgcrypt-argon2/src/cipher-proto.h
@@ -0,0 +1,100 @@
+/* cipher-proto.h - Internal declarations
+ *	Copyright (C) 2008, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This file has been factored out from cipher.h so that it can be
+   used standalone in visibility.c . */
+
+#ifndef G10_CIPHER_PROTO_H
+#define G10_CIPHER_PROTO_H
+
+/* Definition of a function used to report selftest failures.
+   DOMAIN is a string describing the function block:
+          "cipher", "digest", "pubkey or "random",
+   ALGO   is the algorithm under test,
+   WHAT   is a string describing what has been tested,
+   DESC   is a string describing the error. */
+typedef void (*selftest_report_func_t)(const char *domain,
+                                       int algo,
+                                       const char *what,
+                                       const char *errdesc);
+
+/* Definition of the selftest functions.  */
+typedef gpg_err_code_t (*selftest_func_t)
+     (int algo, int extended, selftest_report_func_t report);
+
+/*
+ *
+ * Message digest related definitions.
+ *
+ */
+
+/* Type for the md_init function.  */
+typedef void (*gcry_md_init_t) (void *c, unsigned int flags);
+
+/* Type for the md_write function.  */
+typedef void (*gcry_md_write_t) (void *c, const void *buf, size_t nbytes);
+
+/* Type for the md_final function.  */
+typedef void (*gcry_md_final_t) (void *c);
+
+/* Type for the md_read function.  */
+typedef unsigned char *(*gcry_md_read_t) (void *c);
+
+/* Type for the md_extract function.  */
+typedef void (*gcry_md_extract_t) (void *c, void *outbuf, size_t nbytes);
+
+/* Type for the md_hash_buffers function. */
+typedef void (*gcry_md_hash_buffers_t) (void *outbuf, size_t nbytes,
+					const gcry_buffer_t *iov,
+					int iovcnt);
+
+typedef struct gcry_md_oid_spec
+{
+  const char *oidstring;
+} gcry_md_oid_spec_t;
+
+/* Module specification structure for message digests.  */
+typedef struct gcry_md_spec
+{
+  int algo;
+  struct {
+    unsigned int disabled:1;
+    unsigned int fips:1;
+  } flags;
+  const char *name;
+  const unsigned char *asnoid;
+  int asnlen;
+  const gcry_md_oid_spec_t *oids;
+  int mdlen;
+  gcry_md_init_t init;
+  gcry_md_write_t write;
+  gcry_md_final_t final;
+  gcry_md_read_t read;
+  gcry_md_extract_t extract;
+  gcry_md_hash_buffers_t hash_buffers;
+  size_t contextsize; /* allocate this amount of context */
+  selftest_func_t selftest;
+} gcry_md_spec_t;
+
+
+/* The selftest functions.  */
+gcry_error_t _gcry_md_selftest (int algo, int extended,
+                                selftest_report_func_t report);
+
+#endif /*G10_CIPHER_PROTO_H*/
diff --git a/grub-core/lib/libgcrypt-argon2/src/cipher.h b/grub-core/lib/libgcrypt-argon2/src/cipher.h
new file mode 100644
index 000000000..48eeeda5e
--- /dev/null
+++ b/grub-core/lib/libgcrypt-argon2/src/cipher.h
@@ -0,0 +1,182 @@
+/* cipher.h
+ *	Copyright (C) 1998, 2002, 2003, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef G10_CIPHER_H
+#define G10_CIPHER_H
+
+#include <gcrypt.h>
+
+#define DBG_CIPHER _gcry_get_debug_flag( 1 )
+
+#include "../random/random.h"
+
+#define PUBKEY_FLAG_NO_BLINDING    (1 << 0)
+
+enum pk_operation
+  {
+    PUBKEY_OP_ENCRYPT,
+    PUBKEY_OP_DECRYPT,
+    PUBKEY_OP_SIGN,
+    PUBKEY_OP_VERIFY
+  };
+
+enum pk_encoding
+  {
+    PUBKEY_ENC_RAW,
+    PUBKEY_ENC_PKCS1,
+    PUBKEY_ENC_OAEP,
+    PUBKEY_ENC_PSS,
+    PUBKEY_ENC_UNKNOWN
+  };
+
+struct pk_encoding_ctx
+{
+  enum pk_operation op;
+  unsigned int nbits;
+
+  enum pk_encoding encoding;
+  int flags;
+
+  int hash_algo;
+
+  /* for OAEP */
+  unsigned char *label;
+  size_t labellen;
+
+  /* for PSS */
+  size_t saltlen;
+
+  int (* verify_cmp) (void *opaque, gcry_mpi_t tmp);
+  void *verify_arg;
+};
+
+#define CIPHER_INFO_NO_WEAK_KEY    1
+
+#include "cipher-proto.h"
+
+
+/*-- rmd160.c --*/
+void _gcry_rmd160_hash_buffer (void *outbuf,
+                               const void *buffer, size_t length);
+/*-- sha1.c --*/
+void _gcry_sha1_hash_buffer (void *outbuf,
+                             const void *buffer, size_t length);
+
+/*-- rijndael.c --*/
+void _gcry_aes_cfb_enc (void *context, unsigned char *iv,
+                        void *outbuf, const void *inbuf,
+                        unsigned int nblocks);
+void _gcry_aes_cfb_dec (void *context, unsigned char *iv,
+                        void *outbuf_arg, const void *inbuf_arg,
+                        unsigned int nblocks);
+void _gcry_aes_cbc_enc (void *context, unsigned char *iv,
+                        void *outbuf_arg, const void *inbuf_arg,
+                        unsigned int nblocks, int cbc_mac);
+void _gcry_aes_cbc_dec (void *context, unsigned char *iv,
+                        void *outbuf_arg, const void *inbuf_arg,
+                        unsigned int nblocks);
+void _gcry_aes_ctr_enc (void *context, unsigned char *ctr,
+                        void *outbuf_arg, const void *inbuf_arg,
+                        unsigned int nblocks);
+
+
+/*-- dsa.c --*/
+void _gcry_register_pk_dsa_progress (gcry_handler_progress_t cbc, void *cb_data);
+
+/*-- elgamal.c --*/
+void _gcry_register_pk_elg_progress (gcry_handler_progress_t cb,
+                                     void *cb_data);
+
+
+/*-- ecc.c --*/
+void _gcry_register_pk_ecc_progress (gcry_handler_progress_t cbc,
+                                     void *cb_data);
+
+
+/*-- primegen.c --*/
+void _gcry_register_primegen_progress (gcry_handler_progress_t cb,
+                                       void *cb_data);
+
+/*-- pubkey.c --*/
+const char * _gcry_pk_aliased_algo_name (int algorithm);
+
+/* Declarations for the cipher specifications.  */
+extern gcry_cipher_spec_t _gcry_cipher_spec_blowfish;
+extern gcry_cipher_spec_t _gcry_cipher_spec_des;
+extern gcry_cipher_spec_t _gcry_cipher_spec_tripledes;
+extern gcry_cipher_spec_t _gcry_cipher_spec_arcfour;
+extern gcry_cipher_spec_t _gcry_cipher_spec_cast5;
+extern gcry_cipher_spec_t _gcry_cipher_spec_aes;
+extern gcry_cipher_spec_t _gcry_cipher_spec_aes192;
+extern gcry_cipher_spec_t _gcry_cipher_spec_aes256;
+extern gcry_cipher_spec_t _gcry_cipher_spec_twofish;
+extern gcry_cipher_spec_t _gcry_cipher_spec_twofish128;
+extern gcry_cipher_spec_t _gcry_cipher_spec_serpent128;
+extern gcry_cipher_spec_t _gcry_cipher_spec_serpent192;
+extern gcry_cipher_spec_t _gcry_cipher_spec_serpent256;
+extern gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40;
+extern gcry_cipher_spec_t _gcry_cipher_spec_seed;
+extern gcry_cipher_spec_t _gcry_cipher_spec_camellia128;
+extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192;
+extern gcry_cipher_spec_t _gcry_cipher_spec_camellia256;
+extern gcry_cipher_spec_t _gcry_cipher_spec_idea;
+
+extern cipher_extra_spec_t _gcry_cipher_extraspec_tripledes;
+extern cipher_extra_spec_t _gcry_cipher_extraspec_aes;
+extern cipher_extra_spec_t _gcry_cipher_extraspec_aes192;
+extern cipher_extra_spec_t _gcry_cipher_extraspec_aes256;
+
+
+/* Declarations for the digest specifications.  */
+extern gcry_md_spec_t _gcry_digest_spec_crc32;
+extern gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510;
+extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440;
+extern gcry_md_spec_t _gcry_digest_spec_md4;
+extern gcry_md_spec_t _gcry_digest_spec_md5;
+extern gcry_md_spec_t _gcry_digest_spec_rmd160;
+extern gcry_md_spec_t _gcry_digest_spec_sha1;
+extern gcry_md_spec_t _gcry_digest_spec_sha224;
+extern gcry_md_spec_t _gcry_digest_spec_sha256;
+extern gcry_md_spec_t _gcry_digest_spec_sha512;
+extern gcry_md_spec_t _gcry_digest_spec_sha384;
+extern gcry_md_spec_t _gcry_digest_spec_tiger;
+extern gcry_md_spec_t _gcry_digest_spec_tiger1;
+extern gcry_md_spec_t _gcry_digest_spec_tiger2;
+extern gcry_md_spec_t _gcry_digest_spec_whirlpool;
+
+extern md_extra_spec_t _gcry_digest_extraspec_sha1;
+extern md_extra_spec_t _gcry_digest_extraspec_sha224;
+extern md_extra_spec_t _gcry_digest_extraspec_sha256;
+extern md_extra_spec_t _gcry_digest_extraspec_sha384;
+extern md_extra_spec_t _gcry_digest_extraspec_sha512;
+
+/* Declarations for the pubkey cipher specifications.  */
+extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
+extern gcry_pk_spec_t _gcry_pubkey_spec_elg;
+extern gcry_pk_spec_t _gcry_pubkey_spec_dsa;
+extern gcry_pk_spec_t _gcry_pubkey_spec_ecdsa;
+extern gcry_pk_spec_t _gcry_pubkey_spec_ecdh;
+
+extern pk_extra_spec_t _gcry_pubkey_extraspec_rsa;
+extern pk_extra_spec_t _gcry_pubkey_extraspec_dsa;
+extern pk_extra_spec_t _gcry_pubkey_extraspec_elg;
+extern pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa;
+
+
+#endif /*G10_CIPHER_H*/
diff --git a/grub-core/lib/libgcrypt-argon2/src/g10lib.h b/grub-core/lib/libgcrypt-argon2/src/g10lib.h
new file mode 100644
index 000000000..85a51beea
--- /dev/null
+++ b/grub-core/lib/libgcrypt-argon2/src/g10lib.h
@@ -0,0 +1,302 @@
+/* g10lib.h - Internal definitions for libgcrypt
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005
+ *               2007, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This header is to be used inside of libgcrypt in place of gcrypt.h.
+   This way we can better distinguish between internal and external
+   usage of gcrypt.h. */
+
+#ifndef G10LIB_H
+#define G10LIB_H 1
+
+#ifdef _GCRYPT_H
+#error  gcrypt.h already included
+#endif
+
+#ifndef _GCRYPT_IN_LIBGCRYPT
+#error something is wrong with config.h
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "visibility.h"
+#include "types.h"
+
+
+
+
+/* Attribute handling macros.  */
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
+#define JNLIB_GCC_M_FUNCTION 1
+#define JNLIB_GCC_A_NR 	     __attribute__ ((noreturn))
+#define JNLIB_GCC_A_PRINTF( f, a )  __attribute__ ((format (__printf__,f,a)))
+#define JNLIB_GCC_A_NR_PRINTF( f, a ) \
+			    __attribute__ ((noreturn, format (__printf__,f,a)))
+#define GCC_ATTR_NORETURN  __attribute__ ((__noreturn__))
+#else
+#define JNLIB_GCC_A_NR
+#define JNLIB_GCC_A_PRINTF( f, a )
+#define JNLIB_GCC_A_NR_PRINTF( f, a )
+#define GCC_ATTR_NORETURN
+#endif
+
+#if __GNUC__ >= 3
+/* According to glibc this attribute is available since 2.8 however we
+   better play safe and use it only with gcc 3 or newer. */
+#define GCC_ATTR_FORMAT_ARG(a)  __attribute__ ((format_arg (a)))
+#else
+#define GCC_ATTR_FORMAT_ARG(a)
+#endif
+
+
+/* Gettext macros.  */
+
+/* Some handy macros */
+#ifndef STR
+#define STR(v) #v
+#endif
+#define STR2(v) STR(v)
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#define DIMof(type,member)   DIM(((type *)0)->member)
+
+
+
+/*-- src/global.c -*/
+int _gcry_global_is_operational (void);
+gcry_error_t _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr);
+void  _gcry_check_heap (const void *a);
+int _gcry_get_debug_flag (unsigned int mask);
+
+
+/*-- src/misc.c --*/
+
+#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L
+void _gcry_bug (const char *file, int line,
+                const char *func) GCC_ATTR_NORETURN;
+void _gcry_assert_failed (const char *expr, const char *file, int line,
+                          const char *func) GCC_ATTR_NORETURN;
+#else
+void _gcry_bug (const char *file, int line);
+void _gcry_assert_failed (const char *expr, const char *file, int line);
+#endif
+
+const char *_gcry_gettext (const char *key) GCC_ATTR_FORMAT_ARG(1);
+void _gcry_fatal_error(int rc, const char *text ) JNLIB_GCC_A_NR;
+void _gcry_log( int level, const char *fmt, ... ) JNLIB_GCC_A_PRINTF(2,3);
+void _gcry_log_bug( const char *fmt, ... )   JNLIB_GCC_A_NR_PRINTF(1,2);
+void _gcry_log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
+void _gcry_log_error( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void _gcry_log_info( const char *fmt, ... )  JNLIB_GCC_A_PRINTF(1,2);
+int  _gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... )
+                                             JNLIB_GCC_A_PRINTF(2,3);
+void _gcry_log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void _gcry_log_printf ( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void _gcry_log_printhex (const char *text, const void *buffer, size_t length);
+
+void _gcry_set_log_verbosity( int level );
+int _gcry_log_verbosity( int level );
+
+#ifdef JNLIB_GCC_M_FUNCTION
+#define BUG() _gcry_bug( __FILE__ , __LINE__, __FUNCTION__ )
+#define gcry_assert(expr) ((expr)? (void)0 \
+         : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __FUNCTION__))
+#elif __STDC_VERSION__ >= 199901L
+#define BUG() _gcry_bug( __FILE__ , __LINE__, __func__ )
+#define gcry_assert(expr) ((expr)? (void)0 \
+         : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __func__))
+#else
+#define BUG() _gcry_bug( __FILE__ , __LINE__ )
+#define gcry_assert(expr) ((expr)? (void)0 \
+         : _gcry_assert_failed (STR(expr), __FILE__, __LINE__))
+#endif
+
+
+#define log_bug     _gcry_log_bug
+#define log_fatal   _gcry_log_fatal
+#define log_error   _gcry_log_error
+#define log_info    _gcry_log_info
+#define log_debug   _gcry_log_debug
+#define log_printf  _gcry_log_printf
+#define log_printhex _gcry_log_printhex
+
+
+/*-- src/hwfeatures.c --*/
+/* (Do not change these values unless synced with the asm code.)  */
+#define HWF_PADLOCK_RNG  1
+#define HWF_PADLOCK_AES  2
+#define HWF_PADLOCK_SHA  4
+#define HWF_PADLOCK_MMUL 8
+
+#define HWF_INTEL_AESNI  256
+
+
+unsigned int _gcry_get_hw_features (void);
+void _gcry_detect_hw_features (unsigned int);
+
+
+/*-- mpi/mpiutil.c --*/
+const char *_gcry_mpi_get_hw_config (void);
+
+
+/*-- cipher/pubkey.c --*/
+
+/* FIXME: shouldn't this go into mpi.h?  */
+#ifndef mpi_powm
+#define mpi_powm(w,b,e,m)   gcry_mpi_powm( (w), (b), (e), (m) )
+#endif
+
+/*-- primegen.c --*/
+gcry_mpi_t _gcry_generate_secret_prime (unsigned int nbits,
+                                 gcry_random_level_t random_level,
+                                 int (*extra_check)(void*, gcry_mpi_t),
+                                 void *extra_check_arg);
+gcry_mpi_t _gcry_generate_public_prime (unsigned int nbits,
+                                 gcry_random_level_t random_level,
+                                 int (*extra_check)(void*, gcry_mpi_t),
+                                 void *extra_check_arg);
+gcry_mpi_t _gcry_generate_elg_prime (int mode,
+                                     unsigned int pbits, unsigned int qbits,
+                                     gcry_mpi_t g, gcry_mpi_t **factors);
+gcry_mpi_t _gcry_derive_x931_prime (const gcry_mpi_t xp,
+                                    const gcry_mpi_t xp1, const gcry_mpi_t xp2,
+                                    const gcry_mpi_t e,
+                                    gcry_mpi_t *r_p1, gcry_mpi_t *r_p2);
+gpg_err_code_t _gcry_generate_fips186_2_prime
+                 (unsigned int pbits, unsigned int qbits,
+                  const void *seed, size_t seedlen,
+                  gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+                  int *r_counter,
+                  void **r_seed, size_t *r_seedlen);
+gpg_err_code_t _gcry_generate_fips186_3_prime
+                 (unsigned int pbits, unsigned int qbits,
+                  const void *seed, size_t seedlen,
+                  gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+                  int *r_counter,
+                  void **r_seed, size_t *r_seedlen, int *r_hashalgo);
+
+
+/* Replacements of missing functions (missing-string.c).  */
+#ifndef HAVE_STPCPY
+char *stpcpy (char *a, const char *b);
+#endif
+#ifndef HAVE_STRCASECMP
+int strcasecmp (const char *a, const char *b) _GCRY_GCC_ATTR_PURE;
+#endif
+
+
+/* Macros used to rename missing functions.  */
+#ifndef HAVE_STRTOUL
+#define strtoul(a,b,c)  ((unsigned long)strtol((a),(b),(c)))
+#endif
+#ifndef HAVE_MEMMOVE
+#define memmove(d, s, n) bcopy((s), (d), (n))
+#endif
+#ifndef HAVE_STRICMP
+#define stricmp(a,b)	 strcasecmp( (a), (b) )
+#endif
+#ifndef HAVE_ATEXIT
+#define atexit(a)    (on_exit((a),0))
+#endif
+#ifndef HAVE_RAISE
+#define raise(a) kill(getpid(), (a))
+#endif
+
+
+/* Stack burning.  */
+
+void _gcry_burn_stack (int bytes);
+
+
+/* To avoid that a compiler optimizes certain memset calls away, these
+   macros may be used instead. */
+#define wipememory2(_ptr,_set,_len) do { \
+              volatile char *_vptr=(volatile char *)(_ptr); \
+              size_t _vlen=(_len); \
+              while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
+                  } while(0)
+#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
+
+
+
+/* Digit predicates.  */
+
+#define digitp(p)   (*(p) >= '0' && *(p) <= '9')
+#define octdigitp(p) (*(p) >= '0' && *(p) <= '7')
+#define alphap(a)    (   (*(a) >= 'A' && *(a) <= 'Z')  \
+                      || (*(a) >= 'a' && *(a) <= 'z'))
+#define hexdigitp(a) (digitp (a)                     \
+                      || (*(a) >= 'A' && *(a) <= 'F')  \
+                      || (*(a) >= 'a' && *(a) <= 'f'))
+
+
+/*-- sexp.c --*/
+gcry_error_t _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
+                                const char *format, va_list arg_ptr);
+char *_gcry_sexp_nth_string (const gcry_sexp_t list, int number);
+
+
+/*-- fips.c --*/
+
+void _gcry_initialize_fips_mode (int force);
+
+int _gcry_fips_mode (void);
+#define fips_mode() _gcry_fips_mode ()
+
+int _gcry_enforced_fips_mode (void);
+
+void _gcry_set_enforced_fips_mode (void);
+
+void _gcry_inactivate_fips_mode (const char *text);
+int _gcry_is_fips_mode_inactive (void);
+
+
+void _gcry_fips_signal_error (const char *srcfile,
+                              int srcline,
+                              const char *srcfunc,
+                              int is_fatal,
+                              const char *description);
+#ifdef JNLIB_GCC_M_FUNCTION
+# define fips_signal_error(a) \
+           _gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 0, (a))
+# define fips_signal_fatal_error(a) \
+           _gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 1, (a))
+#else
+# define fips_signal_error(a) \
+           _gcry_fips_signal_error (__FILE__, __LINE__, NULL, 0, (a))
+# define fips_signal_fatal_error(a) \
+           _gcry_fips_signal_error (__FILE__, __LINE__, NULL, 1, (a))
+#endif
+
+int _gcry_fips_is_operational (void);
+#define fips_is_operational()   (_gcry_global_is_operational ())
+#define fips_not_operational()  (GCRY_GPG_ERR_NOT_OPERATIONAL)
+
+int _gcry_fips_test_operational (void);
+int _gcry_fips_test_error_or_operational (void);
+
+gpg_err_code_t _gcry_fips_run_selftests (int extended);
+
+void _gcry_fips_noreturn (void);
+#define fips_noreturn()  (_gcry_fips_noreturn ())
+
+
+
+#endif /* G10LIB_H */
diff --git a/grub-core/lib/libgcrypt-argon2/src/gcrypt-module.h b/grub-core/lib/libgcrypt-argon2/src/gcrypt-module.h
new file mode 100644
index 000000000..e69de29bb
diff --git a/grub-core/lib/libgcrypt-argon2/src/gcrypt.h b/grub-core/lib/libgcrypt-argon2/src/gcrypt.h
new file mode 100644
index 000000000..cd1bc03a4
--- /dev/null
+++ b/grub-core/lib/libgcrypt-argon2/src/gcrypt.h
@@ -0,0 +1,1754 @@
+/* gcrypt.h -  GNU Cryptographic Library Interface              -*- c -*-
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
+                 2007, 2008, 2009, 2010, 2011,
+                 2012  Free Software Foundation, Inc.
+   Copyright (C) 2012, 2013  g10 Code GmbH
+
+   This file is part of Libgcrypt.
+
+   Libgcrypt is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+
+   Libgcrypt 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+   File: @configure_input@ */
+
+#ifndef _GCRYPT_H
+#define _GCRYPT_H
+
+#include <stdarg.h>
+
+#include <grub/gcrypt/gpg-error.h>
+
+#include <sys/types.h>
+
+#if defined _WIN32 || defined __WIN32__
+# ifndef __GNUC__
+# endif /*!__GNUC__*/
+#else
+#endif /*!_WIN32*/
+
+
+/* This is required for error code compatibility. */
+#define _GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT
+
+#ifdef __cplusplus
+extern "C" {
+#if 0 /* (Keep Emacsens' auto-indent happy.) */
+}
+#endif
+#endif
+
+/* The version of this header should match the one of the library. It
+   should not be used by a program because gcry_check_version() should
+   return the same version.  The purpose of this macro is to let
+   autoconf (using the AM_PATH_GCRYPT macro) check that this header
+   matches the installed library.  */
+#define GCRYPT_VERSION "@VERSION@"
+
+/* The version number of this header.  It may be used to handle minor
+   API incompatibilities.  */
+#define GCRYPT_VERSION_NUMBER @VERSION_NUMBER@
+
+
+/* Internal: We can't use the convenience macros for the multi
+   precision integer functions when building this library. */
+#ifdef _GCRYPT_IN_LIBGCRYPT
+#ifndef GCRYPT_NO_MPI_MACROS
+#define GCRYPT_NO_MPI_MACROS 1
+#endif
+#endif
+
+/* We want to use gcc attributes when possible.  Warning: Don't use
+   these macros in your programs: As indicated by the leading
+   underscore they are subject to change without notice. */
+#ifdef __GNUC__
+
+#define _GCRY_GCC_VERSION (__GNUC__ * 10000 \
+                             + __GNUC_MINOR__ * 100 \
+                             + __GNUC_PATCHLEVEL__)
+
+#if _GCRY_GCC_VERSION >= 30100
+#define _GCRY_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#if _GCRY_GCC_VERSION >= 29600
+#define _GCRY_GCC_ATTR_PURE  __attribute__ ((__pure__))
+#endif
+
+#if _GCRY_GCC_VERSION >= 30200
+#define _GCRY_GCC_ATTR_MALLOC  __attribute__ ((__malloc__))
+#endif
+
+#endif /*__GNUC__*/
+
+#ifndef _GCRY_GCC_ATTR_DEPRECATED
+#define _GCRY_GCC_ATTR_DEPRECATED
+#endif
+#ifndef _GCRY_GCC_ATTR_PURE
+#define _GCRY_GCC_ATTR_PURE
+#endif
+#ifndef _GCRY_GCC_ATTR_MALLOC
+#define _GCRY_GCC_ATTR_MALLOC
+#endif
+
+/* Make up an attribute to mark functions and types as deprecated but
+   allow internal use by Libgcrypt.  */
+#ifdef _GCRYPT_IN_LIBGCRYPT
+#define _GCRY_ATTR_INTERNAL
+#else
+#define _GCRY_ATTR_INTERNAL	_GCRY_GCC_ATTR_DEPRECATED
+#endif
+
+/* Wrappers for the libgpg-error library.  */
+
+typedef gpg_err_source_t gcry_err_source_t;
+
+static GPG_ERR_INLINE gcry_error_t
+gcry_err_make (gcry_err_source_t source, gcry_err_code_t code)
+{
+  return gpg_err_make (source, code);
+}
+
+/* The user can define GPG_ERR_SOURCE_DEFAULT before including this
+   file to specify a default source for gpg_error.  */
+#ifndef GCRY_ERR_SOURCE_DEFAULT
+#define GCRY_ERR_SOURCE_DEFAULT  GPG_ERR_SOURCE_USER_1
+#endif
+
+static GPG_ERR_INLINE gcry_error_t
+gcry_error (gcry_err_code_t code)
+{
+  return gcry_err_make (GCRY_ERR_SOURCE_DEFAULT, code);
+}
+
+static GPG_ERR_INLINE gcry_err_code_t
+gcry_err_code (gcry_error_t err)
+{
+  return gpg_err_code (err);
+}
+
+
+static GPG_ERR_INLINE gcry_err_source_t
+gcry_err_source (gcry_error_t err)
+{
+  return gpg_err_source (err);
+}
+
+/* Return a pointer to a string containing a description of the error
+   code in the error value ERR.  */
+const char *gcry_strerror (gcry_error_t err);
+
+/* Return a pointer to a string containing a description of the error
+   source in the error value ERR.  */
+const char *gcry_strsource (gcry_error_t err);
+
+/* Retrieve the error code for the system error ERR.  This returns
+   GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
+   this).  */
+gcry_err_code_t gcry_err_code_from_errno (int err);
+
+/* Retrieve the system error for the error code CODE.  This returns 0
+   if CODE is not a system error code.  */
+int gcry_err_code_to_errno (gcry_err_code_t code);
+
+/* Return an error value with the error source SOURCE and the system
+   error ERR.  */
+gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err);
+
+/* Return an error value with the system error ERR.  */
+gcry_err_code_t gcry_error_from_errno (int err);
+
+
+/* The data object used to hold a multi precision integer.  */
+struct gcry_mpi;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_mpi *GCRY_MPI _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_mpi *GcryMPI _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+
+
+/* Check that the library fulfills the version requirement.  */
+const char *gcry_check_version (const char *req_version);
+
+/* Codes for function dispatchers.  */
+
+/* Codes used with the gcry_control function. */
+enum gcry_ctl_cmds
+  {
+    GCRYCTL_SET_KEY  = 1,
+    GCRYCTL_SET_IV   = 2,
+    GCRYCTL_CFB_SYNC = 3,
+    GCRYCTL_RESET    = 4,   /* e.g. for MDs */
+    GCRYCTL_FINALIZE = 5,
+    GCRYCTL_GET_KEYLEN = 6,
+    GCRYCTL_GET_BLKLEN = 7,
+    GCRYCTL_TEST_ALGO = 8,
+    GCRYCTL_IS_SECURE = 9,
+    GCRYCTL_GET_ASNOID = 10,
+    GCRYCTL_ENABLE_ALGO = 11,
+    GCRYCTL_DISABLE_ALGO = 12,
+    GCRYCTL_DUMP_RANDOM_STATS = 13,
+    GCRYCTL_DUMP_SECMEM_STATS = 14,
+    GCRYCTL_GET_ALGO_NPKEY    = 15,
+    GCRYCTL_GET_ALGO_NSKEY    = 16,
+    GCRYCTL_GET_ALGO_NSIGN    = 17,
+    GCRYCTL_GET_ALGO_NENCR    = 18,
+    GCRYCTL_SET_VERBOSITY     = 19,
+    GCRYCTL_SET_DEBUG_FLAGS   = 20,
+    GCRYCTL_CLEAR_DEBUG_FLAGS = 21,
+    GCRYCTL_USE_SECURE_RNDPOOL= 22,
+    GCRYCTL_DUMP_MEMORY_STATS = 23,
+    GCRYCTL_INIT_SECMEM       = 24,
+    GCRYCTL_TERM_SECMEM       = 25,
+    GCRYCTL_DISABLE_SECMEM_WARN = 27,
+    GCRYCTL_SUSPEND_SECMEM_WARN = 28,
+    GCRYCTL_RESUME_SECMEM_WARN  = 29,
+    GCRYCTL_DROP_PRIVS          = 30,
+    GCRYCTL_ENABLE_M_GUARD      = 31,
+    GCRYCTL_START_DUMP          = 32,
+    GCRYCTL_STOP_DUMP           = 33,
+    GCRYCTL_GET_ALGO_USAGE      = 34,
+    GCRYCTL_IS_ALGO_ENABLED     = 35,
+    GCRYCTL_DISABLE_INTERNAL_LOCKING = 36,
+    GCRYCTL_DISABLE_SECMEM      = 37,
+    GCRYCTL_INITIALIZATION_FINISHED = 38,
+    GCRYCTL_INITIALIZATION_FINISHED_P = 39,
+    GCRYCTL_ANY_INITIALIZATION_P = 40,
+    GCRYCTL_SET_CBC_CTS = 41,
+    GCRYCTL_SET_CBC_MAC = 42,
+    GCRYCTL_SET_CTR = 43,
+    GCRYCTL_ENABLE_QUICK_RANDOM = 44,
+    GCRYCTL_SET_RANDOM_SEED_FILE = 45,
+    GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46,
+    GCRYCTL_SET_THREAD_CBS = 47,
+    GCRYCTL_FAST_POLL = 48,
+    GCRYCTL_SET_RANDOM_DAEMON_SOCKET = 49,
+    GCRYCTL_USE_RANDOM_DAEMON = 50,
+    GCRYCTL_FAKED_RANDOM_P = 51,
+    GCRYCTL_SET_RNDEGD_SOCKET = 52,
+    GCRYCTL_PRINT_CONFIG = 53,
+    GCRYCTL_OPERATIONAL_P = 54,
+    GCRYCTL_FIPS_MODE_P = 55,
+    GCRYCTL_FORCE_FIPS_MODE = 56,
+    GCRYCTL_SELFTEST = 57,
+    /* Note: 58 .. 62 are used internally.  */
+    GCRYCTL_DISABLE_HWF = 63,
+    GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64
+  };
+
+/* Perform various operations defined by CMD. */
+gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...);
+
+
+/* S-expression management. */
+
+/* The object to represent an S-expression as used with the public key
+   functions.  */
+struct gcry_sexp;
+typedef struct gcry_sexp *gcry_sexp_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_sexp *GCRY_SEXP _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_sexp *GcrySexp _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* The possible values for the S-expression format. */
+enum gcry_sexp_format
+  {
+    GCRYSEXP_FMT_DEFAULT   = 0,
+    GCRYSEXP_FMT_CANON     = 1,
+    GCRYSEXP_FMT_BASE64    = 2,
+    GCRYSEXP_FMT_ADVANCED  = 3
+  };
+
+/* Create an new S-expression object from BUFFER of size LENGTH and
+   return it in RETSEXP.  With AUTODETECT set to 0 the data in BUFFER
+   is expected to be in canonized format.  */
+gcry_error_t gcry_sexp_new (gcry_sexp_t *retsexp,
+                            const void *buffer, size_t length,
+                            int autodetect);
+
+ /* Same as gcry_sexp_new but allows to pass a FREEFNC which has the
+    effect to transfer ownership of BUFFER to the created object.  */
+gcry_error_t gcry_sexp_create (gcry_sexp_t *retsexp,
+                               void *buffer, size_t length,
+                               int autodetect, void (*freefnc) (void *));
+
+/* Scan BUFFER and return a new S-expression object in RETSEXP.  This
+   function expects a printf like string in BUFFER.  */
+gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+                              const char *buffer, size_t length);
+
+/* Same as gcry_sexp_sscan but expects a string in FORMAT and can thus
+   only be used for certain encodings.  */
+gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff,
+                              const char *format, ...);
+
+/* Like gcry_sexp_build, but uses an array instead of variable
+   function arguments.  */
+gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+				    const char *format, void **arg_list);
+
+/* Release the S-expression object SEXP */
+void gcry_sexp_release (gcry_sexp_t sexp);
+
+/* Calculate the length of an canonized S-expresion in BUFFER and
+   check for a valid encoding. */
+size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+                            size_t *erroff, gcry_error_t *errcode);
+
+/* Copies the S-expression object SEXP into BUFFER using the format
+   specified in MODE.  */
+size_t gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer,
+                         size_t maxlength);
+
+/* Dumps the S-expression object A in a format suitable for debugging
+   to Libgcrypt's logging stream.  */
+void gcry_sexp_dump (const gcry_sexp_t a);
+
+gcry_sexp_t gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b);
+gcry_sexp_t gcry_sexp_alist (const gcry_sexp_t *array);
+gcry_sexp_t gcry_sexp_vlist (const gcry_sexp_t a, ...);
+gcry_sexp_t gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n);
+gcry_sexp_t gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n);
+
+/* Scan the S-expression for a sublist with a type (the car of the
+   list) matching the string TOKEN.  If TOKLEN is not 0, the token is
+   assumed to be raw memory of this length.  The function returns a
+   newly allocated S-expression consisting of the found sublist or
+   `NULL' when not found.  */
+gcry_sexp_t gcry_sexp_find_token (gcry_sexp_t list,
+                                const char *tok, size_t toklen);
+/* Return the length of the LIST.  For a valid S-expression this
+   should be at least 1.  */
+int gcry_sexp_length (const gcry_sexp_t list);
+
+/* Create and return a new S-expression from the element with index
+   NUMBER in LIST.  Note that the first element has the index 0.  If
+   there is no such element, `NULL' is returned.  */
+gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t list, int number);
+
+/* Create and return a new S-expression from the first element in
+   LIST; this called the "type" and should always exist and be a
+   string. `NULL' is returned in case of a problem.  */
+gcry_sexp_t gcry_sexp_car (const gcry_sexp_t list);
+
+/* Create and return a new list form all elements except for the first
+   one.  Note, that this function may return an invalid S-expression
+   because it is not guaranteed, that the type exists and is a string.
+   However, for parsing a complex S-expression it might be useful for
+   intermediate lists.  Returns `NULL' on error.  */
+gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t list);
+
+gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list);
+
+
+/* This function is used to get data from a LIST.  A pointer to the
+   actual data with index NUMBER is returned and the length of this
+   data will be stored to DATALEN.  If there is no data at the given
+   index or the index represents another list, `NULL' is returned.
+   *Note:* The returned pointer is valid as long as LIST is not
+   modified or released.  */
+const char *gcry_sexp_nth_data (const gcry_sexp_t list, int number,
+                                size_t *datalen);
+
+/* This function is used to get and convert data from a LIST.  The
+   data is assumed to be a Nul terminated string.  The caller must
+   release the returned value using `gcry_free'.  If there is no data
+   at the given index, the index represents a list or the value can't
+   be converted to a string, `NULL' is returned.  */
+char *gcry_sexp_nth_string (gcry_sexp_t list, int number);
+
+/* This function is used to get and convert data from a LIST. This
+   data is assumed to be an MPI stored in the format described by
+   MPIFMT and returned as a standard Libgcrypt MPI.  The caller must
+   release this returned value using `gcry_mpi_release'.  If there is
+   no data at the given index, the index represents a list or the
+   value can't be converted to an MPI, `NULL' is returned.  */
+gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt);
+
+
+
+/*******************************************
+ *                                         *
+ *  Multi Precision Integer Functions      *
+ *                                         *
+ *******************************************/
+
+/* Different formats of external big integer representation. */
+enum gcry_mpi_format
+  {
+    GCRYMPI_FMT_NONE= 0,
+    GCRYMPI_FMT_STD = 1,    /* Twos complement stored without length.  */
+    GCRYMPI_FMT_PGP = 2,    /* As used by OpenPGP (unsigned only).  */
+    GCRYMPI_FMT_SSH = 3,    /* As used by SSH (like STD but with length).  */
+    GCRYMPI_FMT_HEX = 4,    /* Hex format. */
+    GCRYMPI_FMT_USG = 5     /* Like STD but unsigned. */
+  };
+
+/* Flags used for creating big integers.  */
+enum gcry_mpi_flag
+  {
+    GCRYMPI_FLAG_SECURE = 1,  /* Allocate the number in "secure" memory.  */
+    GCRYMPI_FLAG_OPAQUE = 2   /* The number is not a real one but just
+                                 a way to store some bytes.  This is
+                                 useful for encrypted big integers.  */
+  };
+
+
+/* Allocate a new big integer object, initialize it with 0 and
+   initially allocate memory for a number of at least NBITS. */
+gcry_mpi_t gcry_mpi_new (unsigned int nbits);
+
+/* Same as gcry_mpi_new() but allocate in "secure" memory. */
+gcry_mpi_t gcry_mpi_snew (unsigned int nbits);
+
+/* Release the number A and free all associated resources. */
+void gcry_mpi_release (gcry_mpi_t a);
+
+/* Create a new number with the same value as A. */
+gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a);
+
+/* Store the big integer value U in W. */
+gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u);
+
+/* Store the unsigned integer value U in W. */
+gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u);
+
+/* Swap the values of A and B. */
+void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b);
+
+/* Compare the big integer number U and V returning 0 for equality, a
+   positive value for U > V and a negative for U < V. */
+int gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v);
+
+/* Compare the big integer number U with the unsigned integer V
+   returning 0 for equality, a positive value for U > V and a negative
+   for U < V. */
+int gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v);
+
+/* Convert the external representation of an integer stored in BUFFER
+   with a length of BUFLEN into a newly create MPI returned in
+   RET_MPI.  If NSCANNED is not NULL, it will receive the number of
+   bytes actually scanned after a successful operation. */
+gcry_error_t gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
+                            const void *buffer, size_t buflen,
+                            size_t *nscanned);
+
+/* Convert the big integer A into the external representation
+   described by FORMAT and store it in the provided BUFFER which has
+   been allocated by the user with a size of BUFLEN bytes.  NWRITTEN
+   receives the actual length of the external representation unless it
+   has been passed as NULL. */
+gcry_error_t gcry_mpi_print (enum gcry_mpi_format format,
+                             unsigned char *buffer, size_t buflen,
+                             size_t *nwritten,
+                             const gcry_mpi_t a);
+
+/* Convert the big integer A int the external representation described
+   by FORMAT and store it in a newly allocated buffer which address
+   will be put into BUFFER.  NWRITTEN receives the actual lengths of the
+   external representation. */
+gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format,
+                              unsigned char **buffer, size_t *nwritten,
+                              const gcry_mpi_t a);
+
+/* Dump the value of A in a format suitable for debugging to
+   Libgcrypt's logging stream.  Note that one leading space but no
+   trailing space or linefeed will be printed.  It is okay to pass
+   NULL for A. */
+void gcry_mpi_dump (const gcry_mpi_t a);
+
+
+/* W = U + V.  */
+void gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U + V.  V is an unsigned integer. */
+void gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v);
+
+/* W = U + V mod M. */
+void gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U - V. */
+void gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U - V.  V is an unsigned integer. */
+void gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+
+/* W = U - V mod M */
+void gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U * V. */
+void gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U * V.  V is an unsigned integer. */
+void gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+
+/* W = U * V mod M. */
+void gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U * (2 ^ CNT). */
+void gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt);
+
+/* Q = DIVIDEND / DIVISOR, R = DIVIDEND % DIVISOR,
+   Q or R may be passed as NULL.  ROUND should be negative or 0. */
+void gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r,
+                   gcry_mpi_t dividend, gcry_mpi_t divisor, int round);
+
+/* R = DIVIDEND % DIVISOR */
+void gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
+
+/* W = B ^ E mod M. */
+void gcry_mpi_powm (gcry_mpi_t w,
+                    const gcry_mpi_t b, const gcry_mpi_t e,
+                    const gcry_mpi_t m);
+
+/* Set G to the greatest common divisor of A and B.
+   Return true if the G is 1. */
+int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b);
+
+/* Set X to the multiplicative inverse of A mod M.
+   Return true if the value exists. */
+int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m);
+
+
+/* Return the number of bits required to represent A. */
+unsigned int gcry_mpi_get_nbits (gcry_mpi_t a);
+
+/* Return true when bit number N (counting from 0) is set in A. */
+int      gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n);
+
+/* Set bit number N in A. */
+void     gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n);
+
+/* Clear bit number N in A. */
+void     gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n);
+
+/* Set bit number N in A and clear all bits greater than N. */
+void     gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n);
+
+/* Clear bit number N in A and all bits greater than N. */
+void     gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n);
+
+/* Shift the value of A by N bits to the right and store the result in X. */
+void     gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+
+/* Shift the value of A by N bits to the left and store the result in X. */
+void     gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+
+/* Store NBITS of the value P points to in A and mark A as an opaque
+   value.  WARNING: Never use an opaque MPI for anything thing else then
+   gcry_mpi_release, gcry_mpi_get_opaque. */
+gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits);
+
+/* Return a pointer to an opaque value stored in A and return its size
+   in NBITS.  Note that the returned pointer is still owned by A and
+   that the function should never be used for an non-opaque MPI. */
+void *gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits);
+
+/* Set the FLAG for the big integer A.  Currently only the flag
+   GCRYMPI_FLAG_SECURE is allowed to convert A into an big intger
+   stored in "secure" memory. */
+void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Clear FLAG for the big integer A.  Note that this function is
+   currently useless as no flags are allowed. */
+void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Return true when the FLAG is set for A. */
+int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Unless the GCRYPT_NO_MPI_MACROS is used, provide a couple of
+   convenience macros for the big integer functions. */
+#ifndef GCRYPT_NO_MPI_MACROS
+#define mpi_new(n)          gcry_mpi_new( (n) )
+#define mpi_secure_new( n ) gcry_mpi_snew( (n) )
+#define mpi_release(a)      \
+  do \
+    { \
+      gcry_mpi_release ((a)); \
+      (a) = NULL; \
+    } \
+  while (0)
+
+#define mpi_copy( a )          gcry_mpi_copy( (a) )
+#define mpi_set( w, u)         gcry_mpi_set( (w), (u) )
+#define mpi_set_ui( w, u)      gcry_mpi_set_ui( (w), (u) )
+#define mpi_cmp( u, v )        gcry_mpi_cmp( (u), (v) )
+#define mpi_cmp_ui( u, v )     gcry_mpi_cmp_ui( (u), (v) )
+
+#define mpi_add_ui(w,u,v)      gcry_mpi_add_ui((w),(u),(v))
+#define mpi_add(w,u,v)         gcry_mpi_add ((w),(u),(v))
+#define mpi_addm(w,u,v,m)      gcry_mpi_addm ((w),(u),(v),(m))
+#define mpi_sub_ui(w,u,v)      gcry_mpi_sub_ui ((w),(u),(v))
+#define mpi_sub(w,u,v)         gcry_mpi_sub ((w),(u),(v))
+#define mpi_subm(w,u,v,m)      gcry_mpi_subm ((w),(u),(v),(m))
+#define mpi_mul_ui(w,u,v)      gcry_mpi_mul_ui ((w),(u),(v))
+#define mpi_mul_2exp(w,u,v)    gcry_mpi_mul_2exp ((w),(u),(v))
+#define mpi_mul(w,u,v)         gcry_mpi_mul ((w),(u),(v))
+#define mpi_mulm(w,u,v,m)      gcry_mpi_mulm ((w),(u),(v),(m))
+#define mpi_powm(w,b,e,m)      gcry_mpi_powm ( (w), (b), (e), (m) )
+#define mpi_tdiv(q,r,a,m)      gcry_mpi_div ( (q), (r), (a), (m), 0)
+#define mpi_fdiv(q,r,a,m)      gcry_mpi_div ( (q), (r), (a), (m), -1)
+#define mpi_mod(r,a,m)         gcry_mpi_mod ((r), (a), (m))
+#define mpi_gcd(g,a,b)         gcry_mpi_gcd ( (g), (a), (b) )
+#define mpi_invm(g,a,b)        gcry_mpi_invm ( (g), (a), (b) )
+
+#define mpi_get_nbits(a)       gcry_mpi_get_nbits ((a))
+#define mpi_test_bit(a,b)      gcry_mpi_test_bit ((a),(b))
+#define mpi_set_bit(a,b)       gcry_mpi_set_bit ((a),(b))
+#define mpi_set_highbit(a,b)   gcry_mpi_set_highbit ((a),(b))
+#define mpi_clear_bit(a,b)     gcry_mpi_clear_bit ((a),(b))
+#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b))
+#define mpi_rshift(a,b,c)      gcry_mpi_rshift ((a),(b),(c))
+#define mpi_lshift(a,b,c)      gcry_mpi_lshift ((a),(b),(c))
+
+#define mpi_set_opaque(a,b,c)  gcry_mpi_set_opaque( (a), (b), (c) )
+#define mpi_get_opaque(a,b)    gcry_mpi_get_opaque( (a), (b) )
+#endif /* GCRYPT_NO_MPI_MACROS */
+
+
+
+/************************************
+ *                                  *
+ *   Symmetric Cipher Functions     *
+ *                                  *
+ ************************************/
+
+/* The data object used to hold a handle to an encryption object.  */
+struct gcry_cipher_handle;
+typedef struct gcry_cipher_handle *gcry_cipher_hd_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_cipher_handle *GCRY_CIPHER_HD _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_cipher_handle *GcryCipherHd _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* All symmetric encryption algorithms are identified by their IDs.
+   More IDs may be registered at runtime. */
+enum gcry_cipher_algos
+  {
+    GCRY_CIPHER_NONE        = 0,
+    GCRY_CIPHER_IDEA        = 1,
+    GCRY_CIPHER_3DES        = 2,
+    GCRY_CIPHER_CAST5       = 3,
+    GCRY_CIPHER_BLOWFISH    = 4,
+    GCRY_CIPHER_SAFER_SK128 = 5,
+    GCRY_CIPHER_DES_SK      = 6,
+    GCRY_CIPHER_AES         = 7,
+    GCRY_CIPHER_AES192      = 8,
+    GCRY_CIPHER_AES256      = 9,
+    GCRY_CIPHER_TWOFISH     = 10,
+
+    /* Other cipher numbers are above 300 for OpenPGP reasons. */
+    GCRY_CIPHER_ARCFOUR     = 301,  /* Fully compatible with RSA's RC4 (tm). */
+    GCRY_CIPHER_DES         = 302,  /* Yes, this is single key 56 bit DES. */
+    GCRY_CIPHER_TWOFISH128  = 303,
+    GCRY_CIPHER_SERPENT128  = 304,
+    GCRY_CIPHER_SERPENT192  = 305,
+    GCRY_CIPHER_SERPENT256  = 306,
+    GCRY_CIPHER_RFC2268_40  = 307,  /* Ron's Cipher 2 (40 bit). */
+    GCRY_CIPHER_RFC2268_128 = 308,  /* Ron's Cipher 2 (128 bit). */
+    GCRY_CIPHER_SEED        = 309,  /* 128 bit cipher described in RFC4269. */
+    GCRY_CIPHER_CAMELLIA128 = 310,
+    GCRY_CIPHER_CAMELLIA192 = 311,
+    GCRY_CIPHER_CAMELLIA256 = 312
+  };
+
+/* The Rijndael algorithm is basically AES, so provide some macros. */
+#define GCRY_CIPHER_AES128      GCRY_CIPHER_AES
+#define GCRY_CIPHER_RIJNDAEL    GCRY_CIPHER_AES
+#define GCRY_CIPHER_RIJNDAEL128 GCRY_CIPHER_AES128
+#define GCRY_CIPHER_RIJNDAEL192 GCRY_CIPHER_AES192
+#define GCRY_CIPHER_RIJNDAEL256 GCRY_CIPHER_AES256
+
+/* The supported encryption modes.  Note that not all of them are
+   supported for each algorithm. */
+enum gcry_cipher_modes
+  {
+    GCRY_CIPHER_MODE_NONE   = 0,  /* Not yet specified. */
+    GCRY_CIPHER_MODE_ECB    = 1,  /* Electronic codebook. */
+    GCRY_CIPHER_MODE_CFB    = 2,  /* Cipher feedback. */
+    GCRY_CIPHER_MODE_CBC    = 3,  /* Cipher block chaining. */
+    GCRY_CIPHER_MODE_STREAM = 4,  /* Used with stream ciphers. */
+    GCRY_CIPHER_MODE_OFB    = 5,  /* Outer feedback. */
+    GCRY_CIPHER_MODE_CTR    = 6,  /* Counter. */
+    GCRY_CIPHER_MODE_AESWRAP= 7   /* AES-WRAP algorithm.  */
+  };
+
+/* Flags used with the open function. */
+enum gcry_cipher_flags
+  {
+    GCRY_CIPHER_SECURE      = 1,  /* Allocate in secure memory. */
+    GCRY_CIPHER_ENABLE_SYNC = 2,  /* Enable CFB sync mode. */
+    GCRY_CIPHER_CBC_CTS     = 4,  /* Enable CBC cipher text stealing (CTS). */
+    GCRY_CIPHER_CBC_MAC     = 8   /* Enable CBC message auth. code (MAC). */
+  };
+
+
+/* Create a handle for algorithm ALGO to be used in MODE.  FLAGS may
+   be given as an bitwise OR of the gcry_cipher_flags values. */
+gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle,
+                              int algo, int mode, unsigned int flags);
+
+/* Close the cioher handle H and release all resource. */
+void gcry_cipher_close (gcry_cipher_hd_t h);
+
+/* Perform various operations on the cipher object H. */
+gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer,
+                             size_t buflen);
+
+/* Retrieve various information about the cipher object H. */
+gcry_error_t gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer,
+                              size_t *nbytes);
+
+/* Retrieve various information about the cipher algorithm ALGO. */
+gcry_error_t gcry_cipher_algo_info (int algo, int what, void *buffer,
+                                   size_t *nbytes);
+
+/* Map the cipher algorithm whose ID is contained in ALGORITHM to a
+   string representation of the algorithm name.  For unknown algorithm
+   IDs this function returns "?".  */
+const char *gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm name NAME to an cipher algorithm ID.  Return 0 if
+   the algorithm name is not known. */
+int gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE;
+
+/* Given an ASN.1 object identifier in standard IETF dotted decimal
+   format in STRING, return the encryption mode associated with that
+   OID or 0 if not known or applicable. */
+int gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE;
+
+/* Encrypt the plaintext of size INLEN in IN using the cipher handle H
+   into the buffer OUT which has an allocated length of OUTSIZE.  For
+   most algorithms it is possible to pass NULL for in and 0 for INLEN
+   and do a in-place decryption of the data provided in OUT.  */
+gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h,
+                                  void *out, size_t outsize,
+                                  const void *in, size_t inlen);
+
+/* The counterpart to gcry_cipher_encrypt.  */
+gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t h,
+                                  void *out, size_t outsize,
+                                  const void *in, size_t inlen);
+
+/* Set KEY of length KEYLEN bytes for the cipher handle HD.  */
+gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd,
+                                 const void *key, size_t keylen);
+
+
+/* Set initialization vector IV of length IVLEN for the cipher handle HD. */
+gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd,
+                                const void *iv, size_t ivlen);
+
+
+/* Reset the handle to the state after open.  */
+#define gcry_cipher_reset(h)  gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0)
+
+/* Perform the OpenPGP sync operation if this is enabled for the
+   cipher handle H. */
+#define gcry_cipher_sync(h)  gcry_cipher_ctl( (h), GCRYCTL_CFB_SYNC, NULL, 0)
+
+/* Enable or disable CTS in future calls to gcry_encrypt(). CBC mode only. */
+#define gcry_cipher_cts(h,on)  gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \
+                                                                   NULL, on )
+
+/* Set counter for CTR mode.  (CTR,CTRLEN) must denote a buffer of
+   block size length, or (NULL,0) to set the CTR to the all-zero block. */
+gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd,
+                                const void *ctr, size_t ctrlen);
+
+/* Retrieve the key length in bytes used with algorithm A. */
+size_t gcry_cipher_get_algo_keylen (int algo);
+
+/* Retrieve the block length in bytes used with algorithm A. */
+size_t gcry_cipher_get_algo_blklen (int algo);
+
+/* Return 0 if the algorithm A is available for use. */
+#define gcry_cipher_test_algo(a) \
+            gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+/* Get a list consisting of the IDs of the loaded cipher modules.  If
+   LIST is zero, write the number of loaded cipher modules to
+   LIST_LENGTH and return.  If LIST is non-zero, the first
+   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+   according size.  In case there are less cipher modules than
+   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
+gcry_error_t gcry_cipher_list (int *list, int *list_length);
+
+
+/************************************
+ *                                  *
+ *    Asymmetric Cipher Functions   *
+ *                                  *
+ ************************************/
+
+/* The algorithms and their IDs we support. */
+enum gcry_pk_algos
+  {
+    GCRY_PK_RSA   = 1,
+    GCRY_PK_RSA_E = 2,      /* (deprecated) */
+    GCRY_PK_RSA_S = 3,      /* (deprecated) */
+    GCRY_PK_ELG_E = 16,
+    GCRY_PK_DSA   = 17,
+    GCRY_PK_ELG   = 20,
+    GCRY_PK_ECDSA = 301,
+    GCRY_PK_ECDH  = 302
+  };
+
+/* Flags describing usage capabilities of a PK algorithm. */
+#define GCRY_PK_USAGE_SIGN 1   /* Good for signatures. */
+#define GCRY_PK_USAGE_ENCR 2   /* Good for encryption. */
+#define GCRY_PK_USAGE_CERT 4   /* Good to certify other keys. */
+#define GCRY_PK_USAGE_AUTH 8   /* Good for authentication. */
+#define GCRY_PK_USAGE_UNKN 128 /* Unknown usage flag. */
+
+/* Encrypt the DATA using the public key PKEY and store the result as
+   a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_encrypt (gcry_sexp_t *result,
+                              gcry_sexp_t data, gcry_sexp_t pkey);
+
+/* Decrypt the DATA using the private key SKEY and store the result as
+   a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result,
+                              gcry_sexp_t data, gcry_sexp_t skey);
+
+/* Sign the DATA using the private key SKEY and store the result as
+   a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_sign (gcry_sexp_t *result,
+                           gcry_sexp_t data, gcry_sexp_t skey);
+
+/* Check the signature SIGVAL on DATA using the public key PKEY. */
+gcry_error_t gcry_pk_verify (gcry_sexp_t sigval,
+                             gcry_sexp_t data, gcry_sexp_t pkey);
+
+/* Check that private KEY is sane. */
+gcry_error_t gcry_pk_testkey (gcry_sexp_t key);
+
+/* Generate a new key pair according to the parameters given in
+   S_PARMS.  The new key pair is returned in as an S-expression in
+   R_KEY. */
+gcry_error_t gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms);
+
+/* Catch all function for miscellaneous operations. */
+gcry_error_t gcry_pk_ctl (int cmd, void *buffer, size_t buflen);
+
+/* Retrieve information about the public key algorithm ALGO. */
+gcry_error_t gcry_pk_algo_info (int algo, int what,
+                                void *buffer, size_t *nbytes);
+
+/* Map the public key algorithm whose ID is contained in ALGORITHM to
+   a string representation of the algorithm name.  For unknown
+   algorithm IDs this functions returns "?". */
+const char *gcry_pk_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm NAME to a public key algorithm Id.  Return 0 if
+   the algorithm name is not known. */
+int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+
+/* Return what is commonly referred as the key length for the given
+   public or private KEY.  */
+unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE;
+
+/* Please note that keygrip is still experimental and should not be
+   used without contacting the author. */
+unsigned char *gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array);
+
+/* Return the name of the curve matching KEY.  */
+const char *gcry_pk_get_curve (gcry_sexp_t key, int iterator,
+                               unsigned int *r_nbits);
+
+/* Return an S-expression with the parameters of the named ECC curve
+   NAME.  ALGO must be set to an ECC algorithm.  */
+gcry_sexp_t gcry_pk_get_param (int algo, const char *name);
+
+/* Return 0 if the public key algorithm A is available for use. */
+#define gcry_pk_test_algo(a) \
+            gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+/* Get a list consisting of the IDs of the loaded pubkey modules.  If
+   LIST is zero, write the number of loaded pubkey modules to
+   LIST_LENGTH and return.  If LIST is non-zero, the first
+   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+   according size.  In case there are less pubkey modules than
+   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
+gcry_error_t gcry_pk_list (int *list, int *list_length);
+
+
+
+/************************************
+ *                                  *
+ *   Cryptograhic Hash Functions    *
+ *                                  *
+ ************************************/
+
+/* Algorithm IDs for the hash functions we know about. Not all of them
+   are implemnted. */
+enum gcry_md_algos
+  {
+    GCRY_MD_NONE    = 0,
+    GCRY_MD_MD5     = 1,
+    GCRY_MD_SHA1    = 2,
+    GCRY_MD_RMD160  = 3,
+    GCRY_MD_MD2     = 5,
+    GCRY_MD_TIGER   = 6,   /* TIGER/192 as used by gpg <= 1.3.2. */
+    GCRY_MD_HAVAL   = 7,   /* HAVAL, 5 pass, 160 bit. */
+    GCRY_MD_SHA256  = 8,
+    GCRY_MD_SHA384  = 9,
+    GCRY_MD_SHA512  = 10,
+    GCRY_MD_SHA224  = 11,
+    GCRY_MD_MD4     = 301,
+    GCRY_MD_CRC32         = 302,
+    GCRY_MD_CRC32_RFC1510 = 303,
+    GCRY_MD_CRC24_RFC2440 = 304,
+    GCRY_MD_WHIRLPOOL = 305,
+    GCRY_MD_TIGER1  = 306, /* TIGER fixed.  */
+    GCRY_MD_TIGER2  = 307, /* TIGER2 variant.   */
+    GCRY_MD_BLAKE2B_512   = 318,
+    GCRY_MD_BLAKE2B_384   = 319,
+    GCRY_MD_BLAKE2B_256   = 320,
+    GCRY_MD_BLAKE2B_160   = 321,
+    GCRY_MD_BLAKE2S_256   = 322,
+    GCRY_MD_BLAKE2S_224   = 323,
+    GCRY_MD_BLAKE2S_160   = 324,
+    GCRY_MD_BLAKE2S_128   = 325,
+  };
+
+/* Flags used with the open function.  */
+enum gcry_md_flags
+  {
+    GCRY_MD_FLAG_SECURE = 1,  /* Allocate all buffers in "secure" memory.  */
+    GCRY_MD_FLAG_HMAC   = 2   /* Make an HMAC out of this algorithm.  */
+  };
+
+/* (Forward declaration.)  */
+struct gcry_md_context;
+
+/* This object is used to hold a handle to a message digest object.
+   This structure is private - only to be used by the public gcry_md_*
+   macros.  */
+typedef struct gcry_md_handle
+{
+  /* Actual context.  */
+  struct gcry_md_context *ctx;
+
+  /* Buffer management.  */
+  int  bufpos;
+  int  bufsize;
+  unsigned char buf[1];
+} *gcry_md_hd_t;
+
+/* Compatibility types, do not use them.  */
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_md_handle *GCRY_MD_HD _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_md_handle *GcryMDHd _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* Create a message digest object for algorithm ALGO.  FLAGS may be
+   given as an bitwise OR of the gcry_md_flags values.  ALGO may be
+   given as 0 if the algorithms to be used are later set using
+   gcry_md_enable.  */
+gcry_error_t gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags);
+
+/* Release the message digest object HD.  */
+void gcry_md_close (gcry_md_hd_t hd);
+
+/* Add the message digest algorithm ALGO to the digest object HD.  */
+gcry_error_t gcry_md_enable (gcry_md_hd_t hd, int algo);
+
+/* Create a new digest object as an exact copy of the object HD.  */
+gcry_error_t gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd);
+
+/* Reset the digest object HD to its initial state.  */
+void gcry_md_reset (gcry_md_hd_t hd);
+
+/* Perform various operations on the digest object HD. */
+gcry_error_t gcry_md_ctl (gcry_md_hd_t hd, int cmd,
+                          void *buffer, size_t buflen);
+
+/* Pass LENGTH bytes of data in BUFFER to the digest object HD so that
+   it can update the digest values.  This is the actual hash
+   function. */
+void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length);
+
+/* Read out the final digest from HD return the digest value for
+   algorithm ALGO. */
+unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo);
+
+/* Convenience function to calculate the hash from the data in BUFFER
+   of size LENGTH using the algorithm ALGO avoiding the creating of a
+   hash object.  The hash is returned in the caller provided buffer
+   DIGEST which must be large enough to hold the digest of the given
+   algorithm. */
+void gcry_md_hash_buffer (int algo, void *digest,
+                          const void *buffer, size_t length);
+
+/* Retrieve the algorithm used with HD.  This does not work reliable
+   if more than one algorithm is enabled in HD. */
+int gcry_md_get_algo (gcry_md_hd_t hd);
+
+/* Retrieve the length in bytes of the digest yielded by algorithm
+   ALGO. */
+unsigned int gcry_md_get_algo_dlen (int algo);
+
+/* Return true if the the algorithm ALGO is enabled in the digest
+   object A. */
+int gcry_md_is_enabled (gcry_md_hd_t a, int algo);
+
+/* Return true if the digest object A is allocated in "secure" memory. */
+int gcry_md_is_secure (gcry_md_hd_t a);
+
+/* Retrieve various information about the object H.  */
+gcry_error_t gcry_md_info (gcry_md_hd_t h, int what, void *buffer,
+                          size_t *nbytes);
+
+/* Retrieve various information about the algorithm ALGO.  */
+gcry_error_t gcry_md_algo_info (int algo, int what, void *buffer,
+                               size_t *nbytes);
+
+/* Map the digest algorithm id ALGO to a string representation of the
+   algorithm name.  For unknown algorithms this function returns
+   "?". */
+const char *gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm NAME to a digest algorithm Id.  Return 0 if
+   the algorithm name is not known. */
+int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+
+/* For use with the HMAC feature, the set MAC key to the KEY of
+   KEYLEN bytes. */
+gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen);
+
+/* Start or stop debugging for digest handle HD; i.e. create a file
+   named dbgmd-<n>.<suffix> while hashing.  If SUFFIX is NULL,
+   debugging stops and the file will be closed. */
+void gcry_md_debug (gcry_md_hd_t hd, const char *suffix);
+
+
+/* Update the hash(s) of H with the character C.  This is a buffered
+   version of the gcry_md_write function. */
+#define gcry_md_putc(h,c)  \
+            do {                                          \
+                gcry_md_hd_t h__ = (h);                   \
+                if( (h__)->bufpos == (h__)->bufsize )     \
+                    gcry_md_write( (h__), NULL, 0 );      \
+                (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \
+            } while(0)
+
+/* Finalize the digest calculation.  This is not really needed because
+   gcry_md_read() does this implicitly. */
+#define gcry_md_final(a) \
+            gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0)
+
+/* Return 0 if the algorithm A is available for use. */
+#define gcry_md_test_algo(a) \
+            gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+/* Return an DER encoded ASN.1 OID for the algorithm A in buffer B. N
+   must point to size_t variable with the available size of buffer B.
+   After return it will receive the actual size of the returned
+   OID. */
+#define gcry_md_get_asnoid(a,b,n) \
+            gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n))
+
+/* Enable debugging for digest object A; i.e. create files named
+   dbgmd-<n>.<string> while hashing.  B is a string used as the suffix
+   for the filename.  This macro is deprecated, use gcry_md_debug. */
+#ifndef GCRYPT_NO_DEPRECATED
+#define gcry_md_start_debug(a,b) \
+            gcry_md_ctl( (a), GCRYCTL_START_DUMP, (b), 0 )
+
+/* Disable the debugging of A.  This macro is deprecated, use
+   gcry_md_debug.  */
+#define gcry_md_stop_debug(a,b) \
+            gcry_md_ctl( (a), GCRYCTL_STOP_DUMP, (b), 0 )
+#endif
+
+/* Get a list consisting of the IDs of the loaded message digest
+   modules.  If LIST is zero, write the number of loaded message
+   digest modules to LIST_LENGTH and return.  If LIST is non-zero, the
+   first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
+   of according size.  In case there are less message digest modules
+   than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
+   number.  */
+gcry_error_t gcry_md_list (int *list, int *list_length);
+
+
+#if !defined(GCRYPT_NO_DEPRECATED) || defined(_GCRYPT_IN_LIBGCRYPT)
+/* Alternative interface for asymmetric cryptography.  This interface
+   is deprecated.  */
+
+/* The algorithm IDs. */
+typedef enum gcry_ac_id
+  {
+    GCRY_AC_RSA = 1,
+    GCRY_AC_DSA = 17,
+    GCRY_AC_ELG = 20,
+    GCRY_AC_ELG_E = 16
+  }
+gcry_ac_id_t _GCRY_ATTR_INTERNAL;
+
+/* Key types.  */
+typedef enum gcry_ac_key_type
+  {
+    GCRY_AC_KEY_SECRET,
+    GCRY_AC_KEY_PUBLIC
+  }
+gcry_ac_key_type_t _GCRY_ATTR_INTERNAL;
+
+/* Encoding methods.  */
+typedef enum gcry_ac_em
+  {
+    GCRY_AC_EME_PKCS_V1_5,
+    GCRY_AC_EMSA_PKCS_V1_5
+  }
+gcry_ac_em_t _GCRY_ATTR_INTERNAL;
+
+/* Encryption and Signature schemes.  */
+typedef enum gcry_ac_scheme
+  {
+    GCRY_AC_ES_PKCS_V1_5,
+    GCRY_AC_SSA_PKCS_V1_5
+  }
+gcry_ac_scheme_t _GCRY_ATTR_INTERNAL;
+
+/* AC data.  */
+#define GCRY_AC_FLAG_DEALLOC     (1 << 0)
+#define GCRY_AC_FLAG_COPY        (1 << 1)
+#define GCRY_AC_FLAG_NO_BLINDING (1 << 2)
+
+/* This type represents a `data set'.  */
+typedef struct gcry_ac_data *gcry_ac_data_t _GCRY_ATTR_INTERNAL;
+
+/* This type represents a single `key', either a secret one or a
+   public one.  */
+typedef struct gcry_ac_key *gcry_ac_key_t _GCRY_ATTR_INTERNAL;
+
+/* This type represents a `key pair' containing a secret and a public
+   key.  */
+typedef struct gcry_ac_key_pair *gcry_ac_key_pair_t _GCRY_ATTR_INTERNAL;
+
+/* This type represents a `handle' that is needed by functions
+   performing cryptographic operations.  */
+typedef struct gcry_ac_handle *gcry_ac_handle_t _GCRY_ATTR_INTERNAL;
+
+typedef gpg_error_t (*gcry_ac_data_read_cb_t) (void *opaque,
+					       unsigned char *buffer,
+					       size_t *buffer_n)
+  /* */  _GCRY_ATTR_INTERNAL;
+
+typedef gpg_error_t (*gcry_ac_data_write_cb_t) (void *opaque,
+						unsigned char *buffer,
+						size_t buffer_n)
+  /* */  _GCRY_ATTR_INTERNAL;
+
+typedef enum
+  {
+    GCRY_AC_IO_READABLE,
+    GCRY_AC_IO_WRITABLE
+  }
+gcry_ac_io_mode_t _GCRY_ATTR_INTERNAL;
+
+typedef enum
+  {
+    GCRY_AC_IO_STRING,
+    GCRY_AC_IO_CALLBACK
+  }
+gcry_ac_io_type_t _GCRY_ATTR_INTERNAL;
+
+typedef struct gcry_ac_io
+{
+  /* This is an INTERNAL structure, do NOT use manually.  */
+  gcry_ac_io_mode_t mode _GCRY_ATTR_INTERNAL;
+  gcry_ac_io_type_t type _GCRY_ATTR_INTERNAL;
+  union
+  {
+    union
+    {
+      struct
+      {
+	gcry_ac_data_read_cb_t cb;
+	void *opaque;
+      } callback;
+      struct
+      {
+	unsigned char *data;
+	size_t data_n;
+      } string;
+      void *opaque;
+    } readable;
+    union
+    {
+      struct
+      {
+	gcry_ac_data_write_cb_t cb;
+	void *opaque;
+      } callback;
+      struct
+      {
+	unsigned char **data;
+	size_t *data_n;
+      } string;
+      void *opaque;
+    } writable;
+  } io _GCRY_ATTR_INTERNAL;
+}
+gcry_ac_io_t _GCRY_ATTR_INTERNAL;
+
+/* The caller of gcry_ac_key_pair_generate can provide one of these
+   structures in order to influence the key generation process in an
+   algorithm-specific way.  */
+typedef struct gcry_ac_key_spec_rsa
+{
+  gcry_mpi_t e;                 /* E to use.  */
+} gcry_ac_key_spec_rsa_t _GCRY_ATTR_INTERNAL;
+
+/* Structure used for passing data to the implementation of the
+   `EME-PKCS-V1_5' encoding method.  */
+typedef struct gcry_ac_eme_pkcs_v1_5
+{
+  size_t key_size;
+} gcry_ac_eme_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+
+typedef enum gcry_md_algos gcry_md_algo_t _GCRY_ATTR_INTERNAL;
+
+/* Structure used for passing data to the implementation of the
+   `EMSA-PKCS-V1_5' encoding method.  */
+typedef struct gcry_ac_emsa_pkcs_v1_5
+{
+  gcry_md_algo_t md;
+  size_t em_n;
+} gcry_ac_emsa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+
+/* Structure used for passing data to the implementation of the
+   `SSA-PKCS-V1_5' signature scheme.  */
+typedef struct gcry_ac_ssa_pkcs_v1_5
+{
+  gcry_md_algo_t md;
+} gcry_ac_ssa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+#endif /* !GCRYPT_NO_DEPRECATED || !_GCRYPT_IN_LIBGCRYPT */
+
+
+#ifndef GCRYPT_NO_DEPRECATED
+/* Returns a new, empty data set in DATA.  */
+gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data)
+  /* */                       _GCRY_ATTR_INTERNAL;
+
+/* Destroy the data set DATA.  */
+void gcry_ac_data_destroy (gcry_ac_data_t data)
+  /* */                       _GCRY_ATTR_INTERNAL;
+
+/* Create a copy of the data set DATA and store it in DATA_CP.  */
+gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp,
+                                gcry_ac_data_t data)
+  /* */                       _GCRY_ATTR_INTERNAL;
+
+/* Return the number of named MPI values inside of the data set
+   DATA.  */
+unsigned int gcry_ac_data_length (gcry_ac_data_t data)
+  /* */                       _GCRY_ATTR_INTERNAL;
+
+/* Destroy any values contained in the data set DATA.  */
+void gcry_ac_data_clear (gcry_ac_data_t data)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Add the value MPI to DATA with the label NAME.  If FLAGS contains
+   GCRY_AC_FLAG_DATA_COPY, the data set will contain copies of NAME
+   and MPI.  If FLAGS contains GCRY_AC_FLAG_DATA_DEALLOC or
+   GCRY_AC_FLAG_DATA_COPY, the values contained in the data set will
+   be deallocated when they are to be removed from the data set.  */
+gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
+                               const char *name, gcry_mpi_t mpi)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Store the value labelled with NAME found in DATA in MPI.  If FLAGS
+   contains GCRY_AC_FLAG_COPY, store a copy of the MPI value contained
+   in the data set.  MPI may be NULL.  */
+gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
+                                    const char *name, gcry_mpi_t *mpi)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Stores in NAME and MPI the named MPI value contained in the data
+   set DATA with the index IDX.  If FLAGS contains GCRY_AC_FLAG_COPY,
+   store copies of the values contained in the data set. NAME or MPI
+   may be NULL.  */
+gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
+                                     unsigned int idx,
+                                     const char **name, gcry_mpi_t *mpi)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Convert the data set DATA into a new S-Expression, which is to be
+   stored in SEXP, according to the identifiers contained in
+   IDENTIFIERS.  */
+gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
+				   const char **identifiers)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Create a new data set, which is to be stored in DATA_SET, from the
+   S-Expression SEXP, according to the identifiers contained in
+   IDENTIFIERS.  */
+gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
+				     const char **identifiers)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Initialize AC_IO according to MODE, TYPE and the variable list of
+   arguments.  The list of variable arguments to specify depends on
+   the given TYPE.  */
+void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+		      gcry_ac_io_type_t type, ...)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Initialize AC_IO according to MODE, TYPE and the variable list of
+   arguments AP.  The list of variable arguments to specify depends on
+   the given TYPE.  */
+void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+			 gcry_ac_io_type_t type, va_list ap)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Create a new ac handle.  */
+gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle,
+                           gcry_ac_id_t algorithm, unsigned int flags)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy an ac handle.  */
+void gcry_ac_close (gcry_ac_handle_t handle)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Initialize a key from a given data set.  */
+gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
+                               gcry_ac_key_type_t type, gcry_ac_data_t data)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Generates a new key pair via the handle HANDLE of NBITS bits and
+   stores it in KEY_PAIR.  In case non-standard settings are wanted, a
+   pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
+   matching the selected algorithm, can be given as KEY_SPEC.
+   MISC_DATA is not used yet.  */
+gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
+                                        unsigned int nbits, void *spec,
+                                        gcry_ac_key_pair_t *key_pair,
+                                        gcry_mpi_t **misc_data)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Returns the key of type WHICH out of the key pair KEY_PAIR.  */
+gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
+                                        gcry_ac_key_type_t which)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Returns the data set contained in the key KEY.  */
+gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Verifies that the key KEY is sane via HANDLE.  */
+gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Stores the number of bits of the key KEY in NBITS via HANDLE.  */
+gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
+                                    gcry_ac_key_t key, unsigned int *nbits)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
+   HANDLE.  */
+gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
+                                   unsigned char *key_grip)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy a key.  */
+void gcry_ac_key_destroy (gcry_ac_key_t key)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy a key pair.  */
+void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Encodes a message according to the encoding method METHOD.  OPTIONS
+   must be a pointer to a method-specific structure
+   (gcry_ac_em*_t).  */
+gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method,
+				  unsigned int flags, void *options,
+				  gcry_ac_io_t *io_read,
+				  gcry_ac_io_t *io_write)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Decodes a message according to the encoding method METHOD.  OPTIONS
+   must be a pointer to a method-specific structure
+   (gcry_ac_em*_t).  */
+gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method,
+				  unsigned int flags, void *options,
+				  gcry_ac_io_t *io_read,
+				  gcry_ac_io_t *io_write)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Encrypt the plain text MPI value DATA_PLAIN with the key KEY under
+   the control of the flags FLAGS and store the resulting data set
+   into DATA_ENCRYPTED.  */
+gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle,
+                                   unsigned int flags,
+                                   gcry_ac_key_t key,
+                                   gcry_mpi_t data_plain,
+                                   gcry_ac_data_t *data_encrypted)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Decrypt the decrypted data contained in the data set DATA_ENCRYPTED
+   with the key KEY under the control of the flags FLAGS and store the
+   resulting plain text MPI value in DATA_PLAIN.  */
+gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle,
+                                   unsigned int flags,
+                                   gcry_ac_key_t key,
+                                   gcry_mpi_t *data_plain,
+                                   gcry_ac_data_t data_encrypted)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Sign the data contained in DATA with the key KEY and store the
+   resulting signature in the data set DATA_SIGNATURE.  */
+gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle,
+                                gcry_ac_key_t key,
+                                gcry_mpi_t data,
+                                gcry_ac_data_t *data_signature)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Verify that the signature contained in the data set DATA_SIGNATURE
+   is indeed the result of signing the data contained in DATA with the
+   secret key belonging to the public key KEY.  */
+gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle,
+                                  gcry_ac_key_t key,
+                                  gcry_mpi_t data,
+                                  gcry_ac_data_t data_signature)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Encrypts the plain text readable from IO_MESSAGE through HANDLE
+   with the public key KEY according to SCHEME, FLAGS and OPTS.  If
+   OPTS is not NULL, it has to be a pointer to a structure specific to
+   the chosen scheme (gcry_ac_es_*_t).  The encrypted message is
+   written to IO_CIPHER. */
+gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
+					  gcry_ac_scheme_t scheme,
+					  unsigned int flags, void *opts,
+					  gcry_ac_key_t key,
+					  gcry_ac_io_t *io_message,
+					  gcry_ac_io_t *io_cipher)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Decrypts the cipher text readable from IO_CIPHER through HANDLE
+   with the secret key KEY according to SCHEME, @var{flags} and OPTS.
+   If OPTS is not NULL, it has to be a pointer to a structure specific
+   to the chosen scheme (gcry_ac_es_*_t).  The decrypted message is
+   written to IO_MESSAGE.  */
+gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
+					  gcry_ac_scheme_t scheme,
+					  unsigned int flags, void *opts,
+					  gcry_ac_key_t key,
+					  gcry_ac_io_t *io_cipher,
+					  gcry_ac_io_t *io_message)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Signs the message readable from IO_MESSAGE through HANDLE with the
+   secret key KEY according to SCHEME, FLAGS and OPTS.  If OPTS is not
+   NULL, it has to be a pointer to a structure specific to the chosen
+   scheme (gcry_ac_ssa_*_t).  The signature is written to
+   IO_SIGNATURE.  */
+gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
+				       gcry_ac_scheme_t scheme,
+				       unsigned int flags, void *opts,
+				       gcry_ac_key_t key,
+				       gcry_ac_io_t *io_message,
+				       gcry_ac_io_t *io_signature)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Verifies through HANDLE that the signature readable from
+   IO_SIGNATURE is indeed the result of signing the message readable
+   from IO_MESSAGE with the secret key belonging to the public key KEY
+   according to SCHEME and OPTS.  If OPTS is not NULL, it has to be an
+   anonymous structure (gcry_ac_ssa_*_t) specific to the chosen
+   scheme.  */
+gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
+					 gcry_ac_scheme_t scheme,
+					 unsigned int flags, void *opts,
+					 gcry_ac_key_t key,
+					 gcry_ac_io_t *io_message,
+					 gcry_ac_io_t *io_signature)
+  /* */ _GCRY_ATTR_INTERNAL;
+
+/* Store the textual representation of the algorithm whose id is given
+   in ALGORITHM in NAME.  This function is deprecated; use
+   gcry_pk_algo_name. */
+gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm,
+                                 const char **name)
+     /* */                      _GCRY_GCC_ATTR_DEPRECATED;
+/* Store the numeric ID of the algorithm whose textual representation
+   is contained in NAME in ALGORITHM.  This function is deprecated;
+   use gcry_pk_map_name. */
+gcry_error_t gcry_ac_name_to_id (const char *name,
+                                 gcry_ac_id_t *algorithm)
+     /* */                      _GCRY_GCC_ATTR_DEPRECATED;
+#endif /*GCRYPT_NO_DEPRECATED*/
+
+
+/******************************
+ *                            *
+ *  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
+  };
+
+/* 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);
+
+
+
+
+/************************************
+ *                                  *
+ *   Random Generating Functions    *
+ *                                  *
+ ************************************/
+
+/* The possible values for the random quality.  The rule of thumb is
+   to use STRONG for session keys and VERY_STRONG for key material.
+   WEAK is usually an alias for STRONG and should not be used anymore
+   (except with gcry_mpi_randomize); use gcry_create_nonce instead. */
+typedef enum gcry_random_level
+  {
+    GCRY_WEAK_RANDOM = 0,
+    GCRY_STRONG_RANDOM = 1,
+    GCRY_VERY_STRONG_RANDOM = 2
+  }
+gcry_random_level_t;
+
+/* Fill BUFFER with LENGTH bytes of random, using random numbers of
+   quality LEVEL. */
+void gcry_randomize (void *buffer, size_t length,
+                     enum gcry_random_level level);
+
+/* Add the external random from BUFFER with LENGTH bytes into the
+   pool. QUALITY should either be -1 for unknown or in the range of 0
+   to 100 */
+gcry_error_t gcry_random_add_bytes (const void *buffer, size_t length,
+                                    int quality);
+
+/* If random numbers are used in an application, this macro should be
+   called from time to time so that new stuff gets added to the
+   internal pool of the RNG.  */
+#define gcry_fast_random_poll()  gcry_control (GCRYCTL_FAST_POLL, NULL)
+
+
+/* Return NBYTES of allocated random using a random numbers of quality
+   LEVEL. */
+void *gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
+                         _GCRY_GCC_ATTR_MALLOC;
+
+/* Return NBYTES of allocated random using a random numbers of quality
+   LEVEL.  The random numbers are created returned in "secure"
+   memory. */
+void *gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
+                                _GCRY_GCC_ATTR_MALLOC;
+
+
+/* Set the big integer W to a random value of NBITS using a random
+   generator with quality LEVEL.  Note that by using a level of
+   GCRY_WEAK_RANDOM gcry_create_nonce is used internally. */
+void gcry_mpi_randomize (gcry_mpi_t w,
+                         unsigned int nbits, enum gcry_random_level level);
+
+
+/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
+void gcry_create_nonce (void *buffer, size_t length);
+
+
+
+
+
+/*******************************/
+/*                             */
+/*    Prime Number Functions   */
+/*                             */
+/*******************************/
+
+/* Mode values passed to a gcry_prime_check_func_t. */
+#define GCRY_PRIME_CHECK_AT_FINISH      0
+#define GCRY_PRIME_CHECK_AT_GOT_PRIME   1
+#define GCRY_PRIME_CHECK_AT_MAYBE_PRIME 2
+
+/* The function should return 1 if the operation shall continue, 0 to
+   reject the prime candidate. */
+typedef int (*gcry_prime_check_func_t) (void *arg, int mode,
+                                        gcry_mpi_t candidate);
+
+/* Flags for gcry_prime_generate():  */
+
+/* Allocate prime numbers and factors in secure memory.  */
+#define GCRY_PRIME_FLAG_SECRET         (1 << 0)
+
+/* Make sure that at least one prime factor is of size
+   `FACTOR_BITS'.  */
+#define GCRY_PRIME_FLAG_SPECIAL_FACTOR (1 << 1)
+
+/* Generate a new prime number of PRIME_BITS bits and store it in
+   PRIME.  If FACTOR_BITS is non-zero, one of the prime factors of
+   (prime - 1) / 2 must be FACTOR_BITS bits long.  If FACTORS is
+   non-zero, allocate a new, NULL-terminated array holding the prime
+   factors and store it in FACTORS.  FLAGS might be used to influence
+   the prime number generation process.  */
+gcry_error_t gcry_prime_generate (gcry_mpi_t *prime,
+                                  unsigned int prime_bits,
+                                  unsigned int factor_bits,
+                                  gcry_mpi_t **factors,
+                                  gcry_prime_check_func_t cb_func,
+                                  void *cb_arg,
+                                  gcry_random_level_t random_level,
+                                  unsigned int flags);
+
+/* Find a generator for PRIME where the factorization of (prime-1) is
+   in the NULL terminated array FACTORS. Return the generator as a
+   newly allocated MPI in R_G.  If START_G is not NULL, use this as
+   teh start for the search. */
+gcry_error_t gcry_prime_group_generator (gcry_mpi_t *r_g,
+                                         gcry_mpi_t prime,
+                                         gcry_mpi_t *factors,
+                                         gcry_mpi_t start_g);
+
+
+/* Convenience function to release the FACTORS array. */
+void gcry_prime_release_factors (gcry_mpi_t *factors);
+
+
+/* Check wether the number X is prime.  */
+gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags);
+
+
+
+/************************************
+ *                                  *
+ *     Miscellaneous Stuff          *
+ *                                  *
+ ************************************/
+
+/* Log levels used by the internal logging facility. */
+enum gcry_log_levels
+  {
+    GCRY_LOG_CONT   = 0,    /* (Continue the last log line.) */
+    GCRY_LOG_INFO   = 10,
+    GCRY_LOG_WARN   = 20,
+    GCRY_LOG_ERROR  = 30,
+    GCRY_LOG_FATAL  = 40,
+    GCRY_LOG_BUG    = 50,
+    GCRY_LOG_DEBUG  = 100
+  };
+
+/* Type for progress handlers.  */
+typedef void (*gcry_handler_progress_t) (void *, const char *, int, int, int);
+
+/* Type for memory allocation handlers.  */
+typedef void *(*gcry_handler_alloc_t) (size_t n);
+
+/* Type for secure memory check handlers.  */
+typedef int (*gcry_handler_secure_check_t) (const void *);
+
+/* Type for memory reallocation handlers.  */
+typedef void *(*gcry_handler_realloc_t) (void *p, size_t n);
+
+/* Type for memory free handlers.  */
+typedef void (*gcry_handler_free_t) (void *);
+
+/* Type for out-of-memory handlers.  */
+typedef int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int);
+
+/* Type for fatal error handlers.  */
+typedef void (*gcry_handler_error_t) (void *, int, const char *);
+
+/* Type for logging handlers.  */
+typedef void (*gcry_handler_log_t) (void *, int, const char *, va_list);
+
+/* Certain operations can provide progress information.  This function
+   is used to register a handler for retrieving these information. */
+void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data);
+
+
+/* Register a custom memory allocation functions. */
+void gcry_set_allocation_handler (
+                             gcry_handler_alloc_t func_alloc,
+                             gcry_handler_alloc_t func_alloc_secure,
+                             gcry_handler_secure_check_t func_secure_check,
+                             gcry_handler_realloc_t func_realloc,
+                             gcry_handler_free_t func_free);
+
+/* Register a function used instead of the internal out of memory
+   handler. */
+void gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque);
+
+/* Register a function used instead of the internal fatal error
+   handler. */
+void gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque);
+
+/* Register a function used instead of the internal logging
+   facility. */
+void gcry_set_log_handler (gcry_handler_log_t f, void *opaque);
+
+/* Reserved for future use. */
+void gcry_set_gettext_handler (const char *(*f)(const char*));
+
+/* Libgcrypt uses its own memory allocation.  It is important to use
+   gcry_free () to release memory allocated by libgcrypt. */
+void *gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_calloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_realloc (void *a, size_t n);
+char *gcry_strdup (const char *string) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xmalloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xcalloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xmalloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xcalloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xrealloc (void *a, size_t n);
+char *gcry_xstrdup (const char * a) _GCRY_GCC_ATTR_MALLOC;
+void  gcry_free (void *a);
+
+/* Return true if A is allocated in "secure" memory. */
+int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE;
+
+/* Return true if Libgcrypt is in FIPS mode.  */
+#define gcry_fips_mode_active()  !!gcry_control (GCRYCTL_FIPS_MODE_P, 0)
+
+
+/* Include support for Libgcrypt modules.  */
+#include <gcrypt-module.h>
+
+#if 0 /* (Keep Emacsens' auto-indent happy.) */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif /* _GCRYPT_H */
+/*
+@emacs_local_vars_begin@
+@emacs_local_vars_read_only@
+@emacs_local_vars_end@
+*/
diff --git a/grub-core/lib/libgcrypt-argon2/src/types.h b/grub-core/lib/libgcrypt-argon2/src/types.h
new file mode 100644
index 000000000..f2c0abf93
--- /dev/null
+++ b/grub-core/lib/libgcrypt-argon2/src/types.h
@@ -0,0 +1,128 @@
+/* types.h - some common typedefs
+ *	Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef GCRYPT_TYPES_H
+#define GCRYPT_TYPES_H
+
+
+/* The AC_CHECK_SIZEOF() in configure fails for some machines.
+ * we provide some fallback values here */
+#if !SIZEOF_UNSIGNED_SHORT
+#undef SIZEOF_UNSIGNED_SHORT
+#define SIZEOF_UNSIGNED_SHORT 2
+#endif
+#if !SIZEOF_UNSIGNED_INT
+#undef SIZEOF_UNSIGNED_INT
+#define SIZEOF_UNSIGNED_INT 4
+#endif
+#if !SIZEOF_UNSIGNED_LONG
+#undef SIZEOF_UNSIGNED_LONG
+#define SIZEOF_UNSIGNED_LONG 4
+#endif
+
+
+#include <sys/types.h>
+
+
+#ifndef HAVE_BYTE_TYPEDEF
+#undef byte	    /* maybe there is a macro with this name */
+/* Windows typedefs byte in the rpc headers.  Avoid warning about
+   double definition.  */
+#if !(defined(_WIN32) && defined(cbNDRContext))
+  typedef unsigned char byte;
+#endif
+#define HAVE_BYTE_TYPEDEF
+#endif
+
+#ifndef HAVE_USHORT_TYPEDEF
+#undef ushort     /* maybe there is a macro with this name */
+  typedef unsigned short ushort;
+#define HAVE_USHORT_TYPEDEF
+#endif
+
+#ifndef HAVE_ULONG_TYPEDEF
+#undef ulong	    /* maybe there is a macro with this name */
+  typedef unsigned long ulong;
+#define HAVE_ULONG_TYPEDEF
+#endif
+
+#ifndef HAVE_U16_TYPEDEF
+#undef u16	    /* maybe there is a macro with this name */
+#if SIZEOF_UNSIGNED_INT == 2
+    typedef unsigned int   u16;
+#elif SIZEOF_UNSIGNED_SHORT == 2
+    typedef unsigned short u16;
+#else
+#error no typedef for u16
+#endif
+#define HAVE_U16_TYPEDEF
+#endif
+
+#ifndef HAVE_U32_TYPEDEF
+#undef u32	    /* maybe there is a macro with this name */
+#if SIZEOF_UNSIGNED_INT == 4
+    typedef unsigned int u32;
+#elif SIZEOF_UNSIGNED_LONG == 4
+    typedef unsigned long u32;
+#else
+#error no typedef for u32
+#endif
+#define HAVE_U32_TYPEDEF
+#endif
+
+/****************
+ * Warning: Some systems segfault when this u64 typedef and
+ * the dummy code in cipher/md.c is not available.  Examples are
+ * Solaris and IRIX.
+ */
+#ifndef HAVE_U64_TYPEDEF
+#undef u64	    /* maybe there is a macro with this name */
+#if SIZEOF_UNSIGNED_INT == 8
+    typedef unsigned int u64;
+#define U64_C(c) (c ## U)
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UNSIGNED_LONG == 8
+    typedef unsigned long u64;
+#define U64_C(c) (c ## UL)
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UNSIGNED_LONG_LONG == 8
+    typedef unsigned long long u64;
+#define U64_C(c) (c ## ULL)
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UINT64_T == 8
+    typedef uint64_t u64;
+#define U64_C(c) (UINT64_C(c))
+#define HAVE_U64_TYPEDEF
+#endif
+#endif
+
+typedef union {
+    int a;
+    short b;
+    char c[1];
+    long d;
+#ifdef HAVE_U64_TYPEDEF
+    u64 e;
+#endif
+    
+    
+} PROPERLY_ALIGNED_TYPE;
+
+#endif /*GCRYPT_TYPES_H*/
diff --git a/grub-core/lib/libgcrypt-argon2/src/visibility.h b/grub-core/lib/libgcrypt-argon2/src/visibility.h
new file mode 100644
index 000000000..66a858c4c
--- /dev/null
+++ b/grub-core/lib/libgcrypt-argon2/src/visibility.h
@@ -0,0 +1 @@
+# include <gcrypt.h>
diff --git a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h
index 42835493d..bc528fcd1 100644
--- a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h
+++ b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h
@@ -23,7 +23,12 @@
 #include <grub/mm.h>
 #include <grub/misc.h>
 #include <grub/dl.h>
+#ifdef _GCRYPT110
+#include <grub/crypto110.h>
+#else
 #include <grub/crypto.h>
+#endif
+
 
 #include <sys/types.h>
 
diff --git a/include/grub/crypto110.h b/include/grub/crypto110.h
new file mode 100644
index 000000000..2a9038a70
--- /dev/null
+++ b/include/grub/crypto110.h
@@ -0,0 +1,510 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
+ *                2007, 2008, 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/>.
+ */
+
+/* Contains elements based on gcrypt-module.h and gcrypt.h.in.
+   If it's changed please update this file.  */
+
+#ifndef GRUB_CRYPTO_HEADER
+#define GRUB_CRYPTO_HEADER 1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+
+typedef enum 
+  {
+    GPG_ERR_NO_ERROR,
+    GPG_ERR_BAD_MPI,
+    GPG_ERR_BAD_SECKEY,
+    GPG_ERR_BAD_SIGNATURE,
+    GPG_ERR_CIPHER_ALGO,
+    GPG_ERR_CONFLICT,
+    GPG_ERR_DECRYPT_FAILED,
+    GPG_ERR_DIGEST_ALGO,
+    GPG_ERR_GENERAL,
+    GPG_ERR_INTERNAL,
+    GPG_ERR_INV_ARG,
+    GPG_ERR_INV_CIPHER_MODE,
+    GPG_ERR_INV_FLAG,
+    GPG_ERR_INV_KEYLEN,
+    GPG_ERR_INV_OBJ,
+    GPG_ERR_INV_OP,
+    GPG_ERR_INV_SEXP,
+    GPG_ERR_INV_VALUE,
+    GPG_ERR_MISSING_VALUE,
+    GPG_ERR_NO_ENCRYPTION_SCHEME,
+    GPG_ERR_NO_OBJ,
+    GPG_ERR_NO_PRIME,
+    GPG_ERR_NO_SIGNATURE_SCHEME,
+    GPG_ERR_NOT_FOUND,
+    GPG_ERR_NOT_IMPLEMENTED,
+    GPG_ERR_NOT_SUPPORTED,
+    GPG_ERR_PUBKEY_ALGO,
+    GPG_ERR_SELFTEST_FAILED,
+    GPG_ERR_TOO_SHORT,
+    GPG_ERR_UNSUPPORTED,
+    GPG_ERR_WEAK_KEY,
+    GPG_ERR_WRONG_KEY_USAGE,
+    GPG_ERR_WRONG_PUBKEY_ALGO,
+    GPG_ERR_OUT_OF_MEMORY,
+    GPG_ERR_TOO_LARGE,
+    GPG_ERR_ENOMEM
+  } gpg_err_code_t;
+typedef gpg_err_code_t gpg_error_t;
+typedef gpg_error_t gcry_error_t;
+typedef gpg_err_code_t gcry_err_code_t;
+#define gcry_error_t gcry_err_code_t
+#if 0
+enum gcry_cipher_modes 
+  {
+    GCRY_CIPHER_MODE_NONE   = 0,  /* Not yet specified. */
+    GCRY_CIPHER_MODE_ECB    = 1,  /* Electronic codebook. */
+    GCRY_CIPHER_MODE_CFB    = 2,  /* Cipher feedback. */
+    GCRY_CIPHER_MODE_CBC    = 3,  /* Cipher block chaining. */
+    GCRY_CIPHER_MODE_STREAM = 4,  /* Used with stream ciphers. */
+    GCRY_CIPHER_MODE_OFB    = 5,  /* Outer feedback. */
+    GCRY_CIPHER_MODE_CTR    = 6   /* Counter. */
+  };
+#endif
+
+/* Don't rely on this. Check!  */
+#define GRUB_CRYPTO_MAX_MDLEN 64
+#define GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE 16
+#define GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE 256
+
+/* Type for the cipher_setkey function.  */
+typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c,
+						 const unsigned char *key,
+						 unsigned keylen);
+
+/* Type for the cipher_encrypt function.  */
+typedef void (*gcry_cipher_encrypt_t) (void *c,
+				       unsigned char *outbuf,
+				       const unsigned char *inbuf);
+
+/* Type for the cipher_decrypt function.  */
+typedef void (*gcry_cipher_decrypt_t) (void *c,
+				       unsigned char *outbuf,
+				       const unsigned char *inbuf);
+
+/* Type for the cipher_stencrypt function.  */
+typedef void (*gcry_cipher_stencrypt_t) (void *c,
+					 unsigned char *outbuf,
+					 const unsigned char *inbuf,
+					 unsigned int n);
+
+/* Type for the cipher_stdecrypt function.  */
+typedef void (*gcry_cipher_stdecrypt_t) (void *c,
+					 unsigned char *outbuf,
+					 const unsigned char *inbuf,
+					 unsigned int n);
+
+typedef struct gcry_cipher_oid_spec
+{
+  const char *oid;
+  int mode;
+} gcry_cipher_oid_spec_t;
+
+/* Module specification structure for ciphers.  */
+typedef struct gcry_cipher_spec
+{
+  const char *name;
+  const char **aliases;
+  gcry_cipher_oid_spec_t *oids;
+  grub_size_t blocksize;
+  grub_size_t keylen;
+  grub_size_t contextsize;
+  gcry_cipher_setkey_t setkey;
+  gcry_cipher_encrypt_t encrypt;
+  gcry_cipher_decrypt_t decrypt;
+  gcry_cipher_stencrypt_t stencrypt;
+  gcry_cipher_stdecrypt_t stdecrypt;
+#ifdef GRUB_UTIL
+  const char *modname;
+#endif
+  struct gcry_cipher_spec *next;
+} gcry_cipher_spec_t;
+
+#if 0 /* HACK: Not needed by Argon2 ? */
+/* Type for the md_init function.  */
+typedef void (*gcry_md_init_t) (void *c);
+
+/* Type for the md_write function.  */
+typedef void (*gcry_md_write_t) (void *c, const void *buf, grub_size_t nbytes);
+
+/* Type for the md_final function.  */
+typedef void (*gcry_md_final_t) (void *c);
+
+/* Type for the md_read function.  */
+typedef unsigned char *(*gcry_md_read_t) (void *c);
+
+typedef struct gcry_md_oid_spec
+{
+  const char *oidstring;
+} gcry_md_oid_spec_t;
+
+/* Module specification structure for message digests.  */
+typedef struct gcry_md_spec
+{
+  const char *name;
+  unsigned char *asnoid;
+  int asnlen;
+  gcry_md_oid_spec_t *oids;
+  grub_size_t mdlen;
+  gcry_md_init_t init;
+  gcry_md_write_t write;
+  gcry_md_final_t final;
+  gcry_md_read_t read;
+  grub_size_t contextsize; /* allocate this amount of context */
+  /* Block size, needed for HMAC.  */
+  grub_size_t blocksize;
+#ifdef GRUB_UTIL
+  const char *modname;
+#endif
+  struct gcry_md_spec *next;
+} gcry_md_spec_t;
+#else
+
+/* A structure used for scatter gather hashing.  */
+typedef struct
+{
+  grub_size_t size;  /* The allocated size of the buffer or 0.  */
+  grub_size_t off;   /* Offset into the buffer.  */
+  grub_size_t len;   /* The used length of the buffer.  */
+  void *data;   /* The buffer.  */
+} gcry_buffer_t;
+
+/* Definition of a function used to report selftest failures.
+   DOMAIN is a string describing the function block:
+          "cipher", "digest", "pubkey or "random",
+   ALGO   is the algorithm under test,
+   WHAT   is a string describing what has been tested,
+   DESC   is a string describing the error. */
+typedef void (*selftest_report_func_t)(const char *domain,
+                                       int algo,
+                                       const char *what,
+                                       const char *errdesc);
+
+/* Definition of the selftest functions.  */
+typedef gpg_err_code_t (*selftest_func_t)
+     (int algo, int extended, selftest_report_func_t report);
+
+/*
+ *
+ * Message digest related definitions.
+ *
+ */
+
+/* Type for the md_init function.  */
+typedef void (*gcry_md_init_t) (void *c, unsigned int flags);
+
+/* Type for the md_write function.  */
+typedef void (*gcry_md_write_t) (void *c, const void *buf, grub_size_t nbytes);
+
+/* Type for the md_final function.  */
+typedef void (*gcry_md_final_t) (void *c);
+
+/* Type for the md_read function.  */
+typedef unsigned char *(*gcry_md_read_t) (void *c);
+
+/* Type for the md_extract function.  */
+typedef void (*gcry_md_extract_t) (void *c, void *outbuf, grub_size_t nbytes);
+
+/* Type for the md_hash_buffers function. */
+typedef void (*gcry_md_hash_buffers_t) (void *outbuf, grub_size_t nbytes,
+					const gcry_buffer_t *iov,
+					int iovcnt);
+
+typedef struct gcry_md_oid_spec
+{
+  const char *oidstring;
+} gcry_md_oid_spec_t;
+
+/* Module specification structure for message digests.  */
+typedef struct gcry_md_spec
+{
+  int algo;
+  struct {
+    unsigned int disabled:1;
+    unsigned int fips:1;
+  } flags;
+  const char *name;
+  const unsigned char *asnoid;
+  int asnlen;
+  const gcry_md_oid_spec_t *oids;
+  int mdlen;
+  gcry_md_init_t init;
+  gcry_md_write_t write;
+  gcry_md_final_t final;
+  gcry_md_read_t read;
+  gcry_md_extract_t extract;
+  gcry_md_hash_buffers_t hash_buffers;
+  grub_size_t contextsize; /* allocate this amount of context */
+  selftest_func_t selftest;
+} gcry_md_spec_t;
+
+
+/* The selftest functions.  */
+gcry_error_t _gcry_md_selftest (int algo, int extended,
+                                selftest_report_func_t report);
+
+#endif /* HACK: Not needed by Argon2 ? */
+
+struct gcry_mpi;
+typedef struct gcry_mpi *gcry_mpi_t;
+
+
+/* Type for the pk_generate function.  */
+typedef gcry_err_code_t (*gcry_pk_generate_t) (int algo,
+					       unsigned int nbits,
+					       unsigned long use_e,
+					       gcry_mpi_t *skey,
+					       gcry_mpi_t **retfactors);
+
+/* Type for the pk_check_secret_key function.  */
+typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
+						       gcry_mpi_t *skey);
+
+/* Type for the pk_encrypt function.  */
+typedef gcry_err_code_t (*gcry_pk_encrypt_t) (int algo,
+					      gcry_mpi_t *resarr,
+					      gcry_mpi_t data,
+					      gcry_mpi_t *pkey,
+					      int flags);
+
+/* Type for the pk_decrypt function.  */
+typedef gcry_err_code_t (*gcry_pk_decrypt_t) (int algo,
+					      gcry_mpi_t *result,
+					      gcry_mpi_t *data,
+					      gcry_mpi_t *skey,
+					      int flags);
+
+/* Type for the pk_sign function.  */
+typedef gcry_err_code_t (*gcry_pk_sign_t) (int algo,
+					   gcry_mpi_t *resarr,
+					   gcry_mpi_t data,
+					   gcry_mpi_t *skey);
+
+/* Type for the pk_verify function.  */
+typedef gcry_err_code_t (*gcry_pk_verify_t) (int algo,
+					     gcry_mpi_t hash,
+					     gcry_mpi_t *data,
+					     gcry_mpi_t *pkey,
+					     int (*cmp) (void *, gcry_mpi_t),
+					     void *opaquev);
+
+/* Type for the pk_get_nbits function.  */
+typedef unsigned (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey);
+
+/* Module specification structure for message digests.  */
+typedef struct gcry_pk_spec
+{
+  const char *name;
+  const char **aliases;
+  const char *elements_pkey;
+  const char *elements_skey;
+  const char *elements_enc;
+  const char *elements_sig;
+  const char *elements_grip;
+  int use;
+  gcry_pk_generate_t generate;
+  gcry_pk_check_secret_key_t check_secret_key;
+  gcry_pk_encrypt_t encrypt;
+  gcry_pk_decrypt_t decrypt;
+  gcry_pk_sign_t sign;
+  gcry_pk_verify_t verify;
+  gcry_pk_get_nbits_t get_nbits;
+#ifdef GRUB_UTIL
+  const char *modname;
+#endif
+} gcry_pk_spec_t;
+
+struct grub_crypto_cipher_handle
+{
+  const struct gcry_cipher_spec *cipher;
+  char ctx[0];
+};
+
+typedef struct grub_crypto_cipher_handle *grub_crypto_cipher_handle_t;
+
+struct grub_crypto_hmac_handle;
+
+const gcry_cipher_spec_t *
+grub_crypto_lookup_cipher_by_name (const char *name);
+
+grub_crypto_cipher_handle_t
+grub_crypto_cipher_open (const struct gcry_cipher_spec *cipher);
+
+gcry_err_code_t
+grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher,
+			    const unsigned char *key,
+			    unsigned keylen);
+
+static inline void
+grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher)
+{
+  grub_free (cipher);
+}
+
+static inline void
+grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size)
+{
+  const grub_uint8_t *in1ptr = in1, *in2ptr = in2;
+  grub_uint8_t *outptr = out;
+  while (size && (((grub_addr_t) in1ptr & (sizeof (grub_uint64_t) - 1))
+		  || ((grub_addr_t) in2ptr & (sizeof (grub_uint64_t) - 1))
+		  || ((grub_addr_t) outptr & (sizeof (grub_uint64_t) - 1))))
+    {
+      *outptr = *in1ptr ^ *in2ptr;
+      in1ptr++;
+      in2ptr++;
+      outptr++;
+      size--;
+    }
+  while (size >= sizeof (grub_uint64_t))
+    {
+      /* We've already checked that all pointers are aligned.  */
+      *(grub_uint64_t *) (void *) outptr
+	= (*(const grub_uint64_t *) (const void *) in1ptr
+	   ^ *(const grub_uint64_t *) (const void *) in2ptr);
+      in1ptr += sizeof (grub_uint64_t);
+      in2ptr += sizeof (grub_uint64_t);
+      outptr += sizeof (grub_uint64_t);
+      size -= sizeof (grub_uint64_t);
+    }
+  while (size)
+    {
+      *outptr = *in1ptr ^ *in2ptr;
+      in1ptr++;
+      in2ptr++;
+      outptr++;
+      size--;
+    }
+}
+
+gcry_err_code_t
+grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
+			 void *out, const void *in, grub_size_t size);
+
+gcry_err_code_t
+grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
+			 void *out, const void *in, grub_size_t size);
+gcry_err_code_t
+grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher,
+			 void *out, const void *in, grub_size_t size,
+			 void *iv_in);
+gcry_err_code_t
+grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher,
+			 void *out, const void *in, grub_size_t size,
+			 void *iv);
+void 
+grub_cipher_register (gcry_cipher_spec_t *cipher);
+void
+grub_cipher_unregister (gcry_cipher_spec_t *cipher);
+void 
+grub_md_register (gcry_md_spec_t *digest);
+void 
+grub_md_unregister (gcry_md_spec_t *cipher);
+
+extern struct gcry_pk_spec *grub_crypto_pk_dsa;
+extern struct gcry_pk_spec *grub_crypto_pk_ecdsa;
+extern struct gcry_pk_spec *grub_crypto_pk_ecdh;
+extern struct gcry_pk_spec *grub_crypto_pk_rsa;
+
+void
+grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in,
+		  grub_size_t inlen);
+const gcry_md_spec_t *
+grub_crypto_lookup_md_by_name (const char *name);
+
+grub_err_t
+grub_crypto_gcry_error (gcry_err_code_t in);
+
+void grub_burn_stack (grub_size_t size);
+
+struct grub_crypto_hmac_handle *
+grub_crypto_hmac_init (const struct gcry_md_spec *md,
+		       const void *key, grub_size_t keylen);
+void
+grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd,
+			const void *data,
+			grub_size_t datalen);
+gcry_err_code_t
+grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out);
+
+gcry_err_code_t
+grub_crypto_hmac_buffer (const struct gcry_md_spec *md,
+			 const void *key, grub_size_t keylen,
+			 const void *data, grub_size_t datalen, void *out);
+
+extern gcry_md_spec_t _gcry_digest_spec_md5;
+extern gcry_md_spec_t _gcry_digest_spec_sha1;
+extern gcry_md_spec_t _gcry_digest_spec_sha256;
+extern gcry_md_spec_t _gcry_digest_spec_sha512;
+extern gcry_md_spec_t _gcry_digest_spec_crc32;
+extern gcry_cipher_spec_t _gcry_cipher_spec_aes;
+#define GRUB_MD_MD5 ((const gcry_md_spec_t *) &_gcry_digest_spec_md5)
+#define GRUB_MD_SHA1 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha1)
+#define GRUB_MD_SHA256 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha256)
+#define GRUB_MD_SHA512 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha512)
+#define GRUB_MD_CRC32 ((const gcry_md_spec_t *) &_gcry_digest_spec_crc32)
+#define GRUB_CIPHER_AES ((const gcry_cipher_spec_t *) &_gcry_cipher_spec_aes)
+
+/* Implement PKCS#5 PBKDF2 as per RFC 2898.  The PRF to use is HMAC variant
+   of digest supplied by MD.  Inputs are the password P of length PLEN,
+   the salt S of length SLEN, the iteration counter C (> 0), and the
+   desired derived output length DKLEN.  Output buffer is DK which
+   must have room for at least DKLEN octets.  The output buffer will
+   be filled with the derived data.  */
+gcry_err_code_t
+grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
+		    const grub_uint8_t *P, grub_size_t Plen,
+		    const grub_uint8_t *S, grub_size_t Slen,
+		    unsigned int c,
+		    grub_uint8_t *DK, grub_size_t dkLen);
+
+int
+grub_crypto_memcmp (const void *a, const void *b, grub_size_t n);
+
+int
+grub_password_get (char buf[], unsigned buf_size);
+
+/* For indistinguishibility.  */
+#define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, N_("access denied"))
+
+extern void (*grub_crypto_autoload_hook) (const char *name);
+
+void _gcry_assert_failed (const char *expr, const char *file, int line,
+                          const char *func) __attribute__ ((noreturn));
+
+void _gcry_burn_stack (int bytes);
+void _gcry_log_error( const char *fmt, ... )  __attribute__ ((format (__printf__, 1, 2)));
+
+
+#ifdef GRUB_UTIL
+void grub_gcry_init_all (void);
+void grub_gcry_fini_all (void);
+
+int
+grub_get_random (void *out, grub_size_t len);
+
+#endif
+
+#endif
diff --git a/include/grub/gcrypt/gpg-error.h b/include/grub/gcrypt/gpg-error.h
index 1e4250284..51b8e99a0 100644
--- a/include/grub/gcrypt/gpg-error.h
+++ b/include/grub/gcrypt/gpg-error.h
@@ -1,7 +1,12 @@
 #ifndef GRUB_GPG_ERROR_H
 #define GRUB_GPG_ERROR_H 1
 
+#ifdef _GCRYPT110
+#include <grub/crypto110.h>
+#else
 #include <grub/crypto.h>
+#endif
+
 typedef enum
   {
     GPG_ERR_SOURCE_USER_1
-- 
2.40.1

openSUSE Build Service is sponsored by