diff options
author | Simo Sorce <simo@redhat.com> | 2018-10-24 13:04:22 -0400 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2018-10-24 17:56:56 -0400 |
commit | 2e30163b1fda16ae1e7373458f1cbbce96fe4a6b (patch) | |
tree | e1afd5393cccab0f9d583a7e24904b4faa83a89e | |
parent | 940143cccea91fdc41f9a052ee2b64ecbd3a5dac (diff) | |
download | gnutls-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.ac | 6 | ||||
-rw-r--r-- | lib/nettle/Makefile.am | 2 | ||||
-rw-r--r-- | lib/nettle/backport/cfb8.c | 117 | ||||
-rw-r--r-- | lib/nettle/backport/cfb8.h | 96 | ||||
-rw-r--r-- | lib/nettle/cipher.c | 5 |
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; |