]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
nettle: vendor-in SIV-GCM implementation
authorDaiki Ueno <ueno@gnu.org>
Wed, 6 Sep 2023 04:34:27 +0000 (13:34 +0900)
committerDaiki Ueno <ueno@gnu.org>
Thu, 7 Sep 2023 21:09:13 +0000 (06:09 +0900)
This imports SIV-GCM implementation from Nettle 3.9.1, while still
assuming Nettle 3.6 as the baseline.  As such, only non-optimized
implementation is imported.  Performance critical applications are
advised to build GnuTLS with Nettle 3.9.1 or later.

Signed-off-by: Daiki Ueno <ueno@gnu.org>
configure.ac
devel/import-from-nettle.sh
lib/nettle/Makefile.am
lib/nettle/int/nettle-internal.h [new file with mode: 0644]

index 8961c0eebaae77f85e9f828cd31ee19076f0b25b..f81d93edc0af3f6d1d797896abbed54bb050a234 100644 (file)
@@ -778,6 +778,13 @@ LIBS="$LIBS $NETTLE_LIBS"
 AC_CHECK_FUNCS(nettle_cmac_kuznyechik_update)
 LIBS=$save_LIBS
 
+# Check for SIV-GCM
+save_LIBS=$LIBS
+LIBS="$LIBS $NETTLE_LIBS"
+AC_CHECK_FUNCS(nettle_siv_gcm_encrypt_message)
+LIBS=$save_LIBS
+AM_CONDITIONAL([NEED_SIV_GCM], [test "$ac_cv_func_nettle_siv_gcm_encrypt_message" != yes])
+
 # Check sonames of the linked libraries needed for FIPS selftests.
 save_LIBS=$LIBS
 LIBS="$LIBS $GMP_LIBS"
index 0a1e68df97d312e1ed520a6a0f1786a9891398a7..ac3dd5fbff7ad3c46db01fb182fb507f6ae0f614 100755 (executable)
@@ -11,6 +11,19 @@ DST=$srcdir/lib/nettle/backport
 
 IMPORTS="
 block-internal.h
+bswap-internal.h
+ctr-internal.h
+ctr.h
+ctr16.c
+ghash-internal.h
+ghash-set-key.c
+ghash-update.c
+siv-gcm-aes128.c
+siv-gcm-aes256.c
+siv-gcm.c
+siv-gcm.h
+siv-ghash-set-key.c
+siv-ghash-update.c
 "
 
 PUBLIC="
@@ -20,6 +33,7 @@ ctr.h
 des.h
 ecc-curve.h
 ecc.h
+gcm.h
 macros.h
 memops.h
 memxor.h
@@ -83,6 +97,14 @@ for f in $IMPORTS; do
          $dst > $dst-t && mv $dst-t $dst
        ;;
     esac
+    # Avoid -Wcast-align=strict warnings
+    case $dst in
+      */ctr16.c)
+       sed \
+         -e 's/\((union nettle_block16 \*) \)\(dst\)/\1(void *) \2/' \
+         $dst > $dst-t && mv $dst-t $dst
+       ;;
+    esac
   else
     echo "Error: $src not found" 1>&2
     exit 1
index bea7c7eda92efc58af7e8ea54ff15c8fbd401c47..d644a0cbfcaf3504d9f197c228eb23721f14a798 100644 (file)
@@ -47,7 +47,7 @@ libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c \
        int/ecdsa-compute-k.c int/ecdsa-compute-k.h \
        int/mpn-base256.c int/mpn-base256.h \
        int/block8.h backport/block-internal.h \
-       int/rsa-pad.c
+       int/rsa-pad.c int/nettle-internal.h
 
 if WINDOWS
 if HAVE_BCRYPT
@@ -95,3 +95,21 @@ libcrypto_la_SOURCES += \
        gost/acpkm.c gost/acpkm.h \
        gost/cmac.h gost/cmac-magma.c gost/cmac-kuznyechik.c
 endif
+
+if NEED_SIV_GCM
+libcrypto_la_SOURCES += \
+       backport/bswap-internal.h \
+       backport/ctr-internal.h \
+       backport/ctr.h \
+       backport/ctr16.c \
+       backport/ghash-internal.h \
+       backport/ghash-set-key.c \
+       backport/ghash-update.c \
+       backport/siv-gcm-aes128.c \
+       backport/siv-gcm-aes256.c \
+       backport/siv-gcm.c \
+       backport/siv-gcm.h \
+       backport/siv-ghash-set-key.c \
+       backport/siv-ghash-update.c \
+       $(NULL)
+endif
diff --git a/lib/nettle/int/nettle-internal.h b/lib/nettle/int/nettle-internal.h
new file mode 100644 (file)
index 0000000..c3aefb8
--- /dev/null
@@ -0,0 +1,76 @@
+/* nettle-internal.h
+
+   Things that are used only by the testsuite and benchmark, and
+   not included in the library.
+
+   Copyright (C) 2002, 2014 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+*/
+
+#ifndef GNUTLS_NETTLE_INT_NETTLE_INTERNAL_H_INCLUDED
+#define GNUTLS_NETTLE_INT_NETTLE_INTERNAL_H_INCLUDED
+
+#include <assert.h>
+/* Needed for alloca on bsd systems. */
+#include <stdlib.h>
+
+/* Temporary allocation, for systems that don't support alloca. Note
+ * that the allocation requests should always be reasonably small, so
+ * that they can fit on the stack. For non-alloca systems, we use a
+ * fix maximum size + an assert.
+ *
+ * TMP_DECL and TMP_ALLOC allocate an array of the given type, and
+ * take the array size (not byte size) as argument.
+ *
+ * TMP_DECL_ALIGN and TMP_ALLOC_ALIGN are intended for context
+ * structs, which need proper alignment. They take the size in bytes,
+ * and produce a void *. On systems without alloca, implemented as an
+ * array of uint64_t, to ensure alignment. Since it is used as void *
+ * argument, no type casts are needed.
+ */
+
+#if HAVE_ALLOCA
+#define TMP_DECL(name, type, max) type *name
+#define TMP_ALLOC(name, size) (name = alloca(sizeof(*name) * (size)))
+#define TMP_DECL_ALIGN(name, max) void *name
+#define TMP_ALLOC_ALIGN(name, size) (name = alloca(size))
+#else /* !HAVE_ALLOCA */
+#define TMP_DECL(name, type, max) type name[max]
+#define TMP_ALLOC(name, size)                                               \
+       do {                                                                \
+               assert((size_t)(size) <= (sizeof(name) / sizeof(name[0]))); \
+       } while (0)
+#define TMP_DECL_ALIGN(name, max) \
+       uint64_t name[((max) + (sizeof(uint64_t) - 1)) / sizeof(uint64_t)]
+#define TMP_ALLOC_ALIGN(name, size)                       \
+       do {                                              \
+               assert((size_t)(size) <= (sizeof(name))); \
+       } while (0)
+#endif
+
+#endif /* GNUTLS_NETTLE_INT_NETTLE_INTERNAL_H_INCLUDED */