summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2018-10-24 13:04:22 -0400
committerSimo Sorce <simo@redhat.com>2018-10-24 17:56:56 -0400
commit2e30163b1fda16ae1e7373458f1cbbce96fe4a6b (patch)
treee1afd5393cccab0f9d583a7e24904b4faa83a89e
parent940143cccea91fdc41f9a052ee2b64ecbd3a5dac (diff)
downloadgnutls-2e30163b1fda16ae1e7373458f1cbbce96fe4a6b.tar.gz
Vendor in CFB8 functionality from Nettle
If nettle's CFB8 is not available, use a vendored in version from master. This is necessary as long as we need to link against 3.4 for ABI compatibility reasons. Signed-off-by: Simo Sorce <simo@redhat.com>
-rw-r--r--configure.ac6
-rw-r--r--lib/nettle/Makefile.am2
-rw-r--r--lib/nettle/backport/cfb8.c117
-rw-r--r--lib/nettle/backport/cfb8.h96
-rw-r--r--lib/nettle/cipher.c5
5 files changed, 225 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index 95c756e8bd..7b50f548d2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -559,6 +559,12 @@ if test "$enable_non_suiteb" = "yes";then
fi
AM_CONDITIONAL(ENABLE_NON_SUITEB_CURVES, test "$enable_non_suiteb" = "yes")
+# Check if nettle has CFB8 support
+save_LIBS=$LIBS
+LIBS="$LIBS $NETTLE_LIBS"
+AC_CHECK_FUNCS(nettle_cfb8_encrypt)
+LIBS=$save_LIBS
+
AC_MSG_CHECKING([whether to build libdane])
AC_ARG_ENABLE(libdane,
AS_HELP_STRING([--disable-libdane],
diff --git a/lib/nettle/Makefile.am b/lib/nettle/Makefile.am
index bd5ec45901..7bb88b8c8f 100644
--- a/lib/nettle/Makefile.am
+++ b/lib/nettle/Makefile.am
@@ -24,6 +24,7 @@ AM_CFLAGS += $(HOGWEED_CFLAGS) $(GMP_CFLAGS)
AM_CPPFLAGS = \
-I$(srcdir)/int \
+ -I$(srcdir)/backport \
-I$(srcdir)/../../gl \
-I$(builddir)/../../gl \
-I$(srcdir)/../includes \
@@ -39,6 +40,7 @@ noinst_LTLIBRARIES = libcrypto.la
libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c \
gnettle.h rnd-common.h prf.c \
+ backport/cfb8.c backport/cfb8.h \
rnd.c int/rsa-fips.h int/rsa-keygen-fips186.c int/provable-prime.c \
int/dsa-fips.h int/dsa-keygen-fips186.c int/dsa-validate.c \
int/tls1-prf.c int/tls1-prf.h
diff --git a/lib/nettle/backport/cfb8.c b/lib/nettle/backport/cfb8.c
new file mode 100644
index 0000000000..30e48322fd
--- /dev/null
+++ b/lib/nettle/backport/cfb8.c
@@ -0,0 +1,117 @@
+/* backport of cfb.c for CFB8
+
+ Cipher feedback mode.
+
+ Copyright (C) 2015, 2017 Dmitry Eremin-Solenikov
+ Copyright (C) 2001, 2011 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/.
+*/
+
+/* #############################################
+ * THIS IS A BACKPORT FROM NETTLE, DO NOT MODIFY
+ * #############################################
+ */
+
+#ifndef HAVE_NETTLE_CFB8_ENCRYPT
+
+#include "cfb8.h"
+#include <string.h>
+#include <nettle/memxor.h>
+
+/* CFB-8 uses slight optimization: it encrypts or decrypts up to block_size
+ * bytes and does memcpy/memxor afterwards */
+void
+cfb8_encrypt(const void *ctx, nettle_cipher_func *f,
+ size_t block_size, uint8_t *iv,
+ size_t length, uint8_t *dst,
+ const uint8_t *src)
+{
+ TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
+ TMP_DECL(outbuf, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
+ TMP_ALLOC(buffer, block_size * 2);
+ TMP_ALLOC(outbuf, block_size);
+ uint8_t pos;
+
+ memcpy(buffer, iv, block_size);
+ pos = 0;
+ while (length)
+ {
+ uint8_t t;
+
+ if (pos == block_size)
+ {
+ memcpy(buffer, buffer + block_size, block_size);
+ pos = 0;
+ }
+
+ f(ctx, block_size, outbuf, buffer + pos);
+ t = *(dst++) = *(src++) ^ outbuf[0];
+ buffer[pos + block_size] = t;
+ length--;
+ pos ++;
+ }
+ memcpy(iv, buffer + pos, block_size);
+}
+
+void
+cfb8_decrypt(const void *ctx, nettle_cipher_func *f,
+ size_t block_size, uint8_t *iv,
+ size_t length, uint8_t *dst,
+ const uint8_t *src)
+{
+ TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
+ TMP_DECL(outbuf, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
+ TMP_ALLOC(buffer, block_size * 2);
+ TMP_ALLOC(outbuf, block_size * 2);
+ uint8_t i = 0;
+
+ memcpy(buffer, iv, block_size);
+ memcpy(buffer + block_size, src,
+ length < block_size ? length : block_size);
+
+ while (length)
+ {
+
+ for (i = 0; i < length && i < block_size; i++)
+ f(ctx, block_size, outbuf + i, buffer + i);
+
+ memxor3(dst, src, outbuf, i);
+
+ length -= i;
+ src += i;
+ dst += i;
+
+ memcpy(buffer, buffer + block_size, block_size);
+ memcpy(buffer + block_size, src,
+ length < block_size ? length : block_size);
+
+ }
+
+ memcpy(iv, buffer + i, block_size);
+}
+#endif /* HAVE_NETTLE_CFB8_ENCRYPT */
diff --git a/lib/nettle/backport/cfb8.h b/lib/nettle/backport/cfb8.h
new file mode 100644
index 0000000000..595c367edc
--- /dev/null
+++ b/lib/nettle/backport/cfb8.h
@@ -0,0 +1,96 @@
+/* backport of cfb.h for CFB8
+
+ Cipher feedback mode.
+
+ Copyright (C) 2015, 2017 Dmitry Eremin-Solenikov
+ Copyright (C) 2001 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 NETTLE_CFB8_H_INCLUDED
+#define NETTLE_CFB8_H_INCLUDED
+
+#include <nettle/cfb.h>
+
+#ifndef NETTLE_INTERNAL_H_INCLUDED
+#define NETTLE_INTERNAL_H_INCLUDED
+#if HAVE_ALLOCA
+# define TMP_DECL(name, type, max) type *name
+# define TMP_ALLOC(name, size) (name = alloca(sizeof (*name) * (size)))
+#else /* !HAVE_ALLOCA */
+# define TMP_DECL(name, type, max) type name[max]
+# define TMP_ALLOC(name, size) \
+ do { if ((size) > (sizeof(name) / sizeof(name[0]))) abort(); } while (0)
+#endif
+
+#define NETTLE_MAX_CIPHER_BLOCK_SIZE 32
+#endif /* NETTLE_INTERNAL_H_INCLUDED */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define cfb8_encrypt _gnutls_backport_nettle_cfb8_encrypt
+#define cfb8_decrypt _gnutls_backport_nettle_cfb8_decrypt
+
+void
+cfb8_encrypt(const void *ctx, nettle_cipher_func *f,
+ size_t block_size, uint8_t *iv,
+ size_t length, uint8_t *dst,
+ const uint8_t *src);
+
+void
+cfb8_decrypt(const void *ctx, nettle_cipher_func *f,
+ size_t block_size, uint8_t *iv,
+ size_t length, uint8_t *dst,
+ const uint8_t *src);
+
+#define CFB8_CTX CFB_CTX
+#define CFB8_SET_IV CFB_SET_IV
+
+#define CFB8_ENCRYPT(self, f, length, dst, src) \
+ (0 ? ((f)(&(self)->ctx, ~(size_t) 0, \
+ (uint8_t *) 0, (const uint8_t *) 0)) \
+ : cfb8_encrypt((void *) &(self)->ctx, \
+ (nettle_cipher_func *) (f), \
+ sizeof((self)->iv), (self)->iv, \
+ (length), (dst), (src)))
+
+#define CFB8_DECRYPT(self, f, length, dst, src) \
+ (0 ? ((f)(&(self)->ctx, ~(size_t) 0, \
+ (uint8_t *) 0, (const uint8_t *) 0)) \
+ : cfb8_decrypt((void *) &(self)->ctx, \
+ (nettle_cipher_func *) (f), \
+ sizeof((self)->iv), (self)->iv, \
+ (length), (dst), (src)))
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* NETTLE_CFB8_H_INCLUDED */
diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c
index 0f6c737d6f..eab1a03588 100644
--- a/lib/nettle/cipher.c
+++ b/lib/nettle/cipher.c
@@ -36,14 +36,17 @@
#include <nettle/version.h>
#if ENABLE_GOST
#include "gost/gost28147.h"
-#include <nettle/cfb.h>
#endif
#include <nettle/nettle-meta.h>
#include <nettle/cbc.h>
#include <nettle/gcm.h>
#include <nettle/ccm.h>
#include <nettle/chacha-poly1305.h>
+#ifdef HAVE_NETTLE_CFB8_ENCRYPT
#include <nettle/cfb.h>
+#else
+#include "cfb8.h"
+#endif /* HAVE_NETTLE_CFB8_ENCRYPT */
#include <fips.h>
struct nettle_cipher_ctx;