diff options
author | Daiki Ueno <ueno@gnu.org> | 2020-04-26 19:26:57 +0200 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2020-05-04 14:26:16 +0200 |
commit | a8493e2f024f25c36d519347dec71c2998a479b2 (patch) | |
tree | 022f3b08ebbcf00b8ca64c5fdcc0c477cf7e8c40 /lib | |
parent | de52bcc82e672f188e6d763cf95436738154f481 (diff) | |
download | gnutls-a8493e2f024f25c36d519347dec71c2998a479b2.tar.gz |
nettle: avoid manual backports of CFB8, CMAC, and XTS
Signed-off-by: Daiki Ueno <ueno@gnu.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/nettle/Makefile.am | 23 | ||||
-rw-r--r-- | lib/nettle/backport/cfb8.c | 123 | ||||
-rw-r--r-- | lib/nettle/backport/cfb8.h | 100 | ||||
-rw-r--r-- | lib/nettle/backport/cmac.c | 217 | ||||
-rw-r--r-- | lib/nettle/backport/cmac.h | 139 | ||||
-rw-r--r-- | lib/nettle/backport/xts.c | 273 | ||||
-rw-r--r-- | lib/nettle/backport/xts.h | 122 | ||||
-rw-r--r-- | lib/nettle/cipher.c | 6 | ||||
-rw-r--r-- | lib/nettle/int/block8.h | 61 |
9 files changed, 85 insertions, 979 deletions
diff --git a/lib/nettle/Makefile.am b/lib/nettle/Makefile.am index 188abab845..078e634eb6 100644 --- a/lib/nettle/Makefile.am +++ b/lib/nettle/Makefile.am @@ -40,15 +40,13 @@ 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 \ - backport/cmac.c backport/cmac.h \ - backport/xts.c backport/xts.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 \ int/dsa-compute-k.c int/dsa-compute-k.h \ int/ecdsa-compute-k.c int/ecdsa-compute-k.h \ - int/mpn-base256.c int/mpn-base256.h + int/mpn-base256.c int/mpn-base256.h \ + int/block8.h backport/block-internal.h if WINDOWS libcrypto_la_SOURCES += sysrng-windows.c @@ -166,6 +164,23 @@ libcrypto_la_SOURCES += \ ecc/ed448-shake256-sign.c ecc/ed448-shake256-verify.c endif +if NEED_CFB +libcrypto_la_SOURCES += \ + backport/cfb.c backport/cfb.h +endif + +if NEED_CMAC +libcrypto_la_SOURCES += \ + backport/cmac.c backport/cmac.h \ + backport/cmac-aes128.c backport/cmac-aes256.c +endif + +if NEED_XTS +libcrypto_la_SOURCES += \ + backport/xts.c backport/xts.h \ + backport/xts-aes128.c backport/xts-aes256.c +endif + if NEED_CHACHA libcrypto_la_SOURCES += \ backport/chacha-core-internal.c backport/chacha-crypt.c \ diff --git a/lib/nettle/backport/cfb8.c b/lib/nettle/backport/cfb8.c deleted file mode 100644 index 1762192f44..0000000000 --- a/lib/nettle/backport/cfb8.c +++ /dev/null @@ -1,123 +0,0 @@ -/* 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 https://www.gnu.org/licenses/. -*/ - -/* ############################################# - * THIS IS A BACKPORT FROM NETTLE, DO NOT MODIFY - * ############################################# - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#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; - - if (i == block_size) - { - 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 deleted file mode 100644 index 9aa7559a65..0000000000 --- a/lib/nettle/backport/cfb8.h +++ /dev/null @@ -1,100 +0,0 @@ -/* 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 https://www.gnu.org/licenses/. -*/ - -#ifndef GNUTLS_LIB_NETTLE_BACKPORT_CFB8_H -#define GNUTLS_LIB_NETTLE_BACKPORT_CFB8_H - -#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 - -#undef cfb8_encrypt -#undef cfb8_decrypt - -/* 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 /* GNUTLS_LIB_NETTLE_BACKPORT_CFB8_H */ diff --git a/lib/nettle/backport/cmac.c b/lib/nettle/backport/cmac.c deleted file mode 100644 index a665f0ea6b..0000000000 --- a/lib/nettle/backport/cmac.c +++ /dev/null @@ -1,217 +0,0 @@ -/* backport of cmac*.c for CMAC - - AES-CMAC-128 (rfc 4493) - Copyright (C) Stefan Metzmacher 2012 - Copyright (C) Jeremy Allison 2012 - Copyright (C) Michael Adam 2012 - Copyright (C) 2017, Red Hat Inc. - - 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 https://www.gnu.org/licenses/. -*/ - -/* ############################################# - * THIS IS A BACKPORT FROM NETTLE, DO NOT MODIFY - * ############################################# - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifndef HAVE_NETTLE_CMAC128_UPDATE - -#include <nettle/aes.h> -#include "cmac.h" -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include <nettle/memxor.h> -#include <nettle/macros.h> - -/* shift one and XOR with 0x87. */ -static void -block_mulx(union nettle_block16 *dst, - const union nettle_block16 *src) -{ - uint64_t b1 = READ_UINT64(src->b); - uint64_t b2 = READ_UINT64(src->b+8); - - b1 = (b1 << 1) | (b2 >> 63); - b2 <<= 1; - - if (src->b[0] & 0x80) - b2 ^= 0x87; - - WRITE_UINT64(dst->b, b1); - WRITE_UINT64(dst->b+8, b2); -} - -void -cmac128_set_key(struct cmac128_ctx *ctx, const void *cipher, - nettle_cipher_func *encrypt) -{ - static const uint8_t const_zero[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - union nettle_block16 *L = &ctx->block; - memset(ctx, 0, sizeof(*ctx)); - - /* step 1 - generate subkeys k1 and k2 */ - encrypt(cipher, 16, L->b, const_zero); - - block_mulx(&ctx->K1, L); - block_mulx(&ctx->K2, &ctx->K1); -} - -#define MIN(x,y) ((x)<(y)?(x):(y)) - -void -cmac128_update(struct cmac128_ctx *ctx, const void *cipher, - nettle_cipher_func *encrypt, - size_t msg_len, const uint8_t *msg) -{ - union nettle_block16 Y; - /* - * check if we expand the block - */ - if (ctx->index < 16) - { - size_t len = MIN(16 - ctx->index, msg_len); - memcpy(&ctx->block.b[ctx->index], msg, len); - msg += len; - msg_len -= len; - ctx->index += len; - } - - if (msg_len == 0) { - /* if it is still the last block, we are done */ - return; - } - - /* - * now checksum everything but the last block - */ - memxor3(Y.b, ctx->X.b, ctx->block.b, 16); - encrypt(cipher, 16, ctx->X.b, Y.b); - - while (msg_len > 16) - { - memxor3(Y.b, ctx->X.b, msg, 16); - encrypt(cipher, 16, ctx->X.b, Y.b); - msg += 16; - msg_len -= 16; - } - - /* - * copy the last block, it will be processed in - * cmac128_digest(). - */ - memcpy(ctx->block.b, msg, msg_len); - ctx->index = msg_len; -} - -void -cmac128_digest(struct cmac128_ctx *ctx, const void *cipher, - nettle_cipher_func *encrypt, - unsigned length, - uint8_t *dst) -{ - union nettle_block16 Y; - - memset(ctx->block.b+ctx->index, 0, sizeof(ctx->block.b)-ctx->index); - - /* re-use ctx->block for memxor output */ - if (ctx->index < 16) - { - ctx->block.b[ctx->index] = 0x80; - memxor(ctx->block.b, ctx->K2.b, 16); - } - else - { - memxor(ctx->block.b, ctx->K1.b, 16); - } - - memxor3(Y.b, ctx->block.b, ctx->X.b, 16); - - assert(length <= 16); - if (length == 16) - { - encrypt(cipher, 16, dst, Y.b); - } - else - { - encrypt(cipher, 16, ctx->block.b, Y.b); - memcpy(dst, ctx->block.b, length); - } - - /* reset state for re-use */ - memset(&ctx->X, 0, sizeof(ctx->X)); - ctx->index = 0; -} - -void -cmac_aes128_set_key(struct cmac_aes128_ctx *ctx, const uint8_t *key) -{ - CMAC128_SET_KEY(ctx, aes128_set_encrypt_key, aes128_encrypt, key); -} - -void -cmac_aes128_update (struct cmac_aes128_ctx *ctx, - size_t length, const uint8_t *data) -{ - CMAC128_UPDATE (ctx, aes128_encrypt, length, data); -} - -void -cmac_aes128_digest(struct cmac_aes128_ctx *ctx, - size_t length, uint8_t *digest) -{ - CMAC128_DIGEST(ctx, aes128_encrypt, length, digest); -} - -void -cmac_aes256_set_key(struct cmac_aes256_ctx *ctx, const uint8_t *key) -{ - CMAC128_SET_KEY(ctx, aes256_set_encrypt_key, aes256_encrypt, key); -} - -void -cmac_aes256_update (struct cmac_aes256_ctx *ctx, - size_t length, const uint8_t *data) -{ - CMAC128_UPDATE (ctx, aes256_encrypt, length, data); -} - -void -cmac_aes256_digest(struct cmac_aes256_ctx *ctx, - size_t length, uint8_t *digest) -{ - CMAC128_DIGEST(ctx, aes256_encrypt, length, digest); -} -#endif /* HAVE_NETTLE_CMAC128_UPDATE */ diff --git a/lib/nettle/backport/cmac.h b/lib/nettle/backport/cmac.h deleted file mode 100644 index 41dbfcf31b..0000000000 --- a/lib/nettle/backport/cmac.h +++ /dev/null @@ -1,139 +0,0 @@ -/* backport of cmac.h - - CMAC mode, as specified in RFC4493 - - Copyright (C) 2017 Red Hat, Inc. - - Contributed by Nikos Mavrogiannopoulos - - 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 https://www.gnu.org/licenses/. -*/ - -#ifndef GNUTLS_LIB_NETTLE_BACKPORT_CMAC_H -#define GNUTLS_LIB_NETTLE_BACKPORT_CMAC_H - -#include <nettle/nettle-types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define CMAC128_DIGEST_SIZE 16 - -#define cmac128_set_key _gnutls_backport_nettle_cmac128_set_key -#define cmac128_update _gnutls_backport_nettle_cmac128_update -#define cmac128_digest _gnutls_backport_nettle_cmac128_digest -#define cmac_aes128_set_key _gnutls_backport_nettle_cmac_aes128_set_key -#define cmac_aes128_update _gnutls_backport_nettle_cmac_aes128_update -#define cmac_aes128_digest _gnutls_backport_nettle_cmac_aes128_digest -#define cmac_aes256_set_key _gnutls_backport_nettle_cmac_aes256_set_key -#define cmac_aes256_update _gnutls_backport_nettle_cmac_aes256_update -#define cmac_aes256_digest _gnutls_backport_nettle_cmac_aes256_digest - -struct cmac128_ctx -{ - /* Key */ - union nettle_block16 K1; - union nettle_block16 K2; - - /* MAC state */ - union nettle_block16 X; - - /* Block buffer */ - union nettle_block16 block; - size_t index; -}; - -void -cmac128_set_key(struct cmac128_ctx *ctx, const void *cipher, - nettle_cipher_func *encrypt); -void -cmac128_update(struct cmac128_ctx *ctx, const void *cipher, - nettle_cipher_func *encrypt, - size_t msg_len, const uint8_t *msg); -void -cmac128_digest(struct cmac128_ctx *ctx, const void *cipher, - nettle_cipher_func *encrypt, - unsigned length, - uint8_t *digest); - - -#define CMAC128_CTX(type) \ - { struct cmac128_ctx ctx; type cipher; } - -/* NOTE: Avoid using NULL, as we don't include anything defining it. */ -#define CMAC128_SET_KEY(self, set_key, encrypt, cmac_key) \ - do { \ - (set_key)(&(self)->cipher, (cmac_key)); \ - if (0) (encrypt)(&(self)->cipher, ~(size_t) 0, \ - (uint8_t *) 0, (const uint8_t *) 0); \ - cmac128_set_key(&(self)->ctx, &(self)->cipher, \ - (nettle_cipher_func *) (encrypt)); \ - } while (0) - -#define CMAC128_UPDATE(self, encrypt, length, src) \ - cmac128_update(&(self)->ctx, &(self)->cipher, \ - (nettle_cipher_func *)encrypt, (length), (src)) - -#define CMAC128_DIGEST(self, encrypt, length, digest) \ - (0 ? (encrypt)(&(self)->cipher, ~(size_t) 0, \ - (uint8_t *) 0, (const uint8_t *) 0) \ - : cmac128_digest(&(self)->ctx, &(self)->cipher, \ - (nettle_cipher_func *) (encrypt), \ - (length), (digest))) - -struct cmac_aes128_ctx CMAC128_CTX(struct aes128_ctx); - -void -cmac_aes128_set_key(struct cmac_aes128_ctx *ctx, const uint8_t *key); - -void -cmac_aes128_update(struct cmac_aes128_ctx *ctx, - size_t length, const uint8_t *data); - -void -cmac_aes128_digest(struct cmac_aes128_ctx *ctx, - size_t length, uint8_t *digest); - -struct cmac_aes256_ctx CMAC128_CTX(struct aes256_ctx); - -void -cmac_aes256_set_key(struct cmac_aes256_ctx *ctx, const uint8_t *key); - -void -cmac_aes256_update(struct cmac_aes256_ctx *ctx, - size_t length, const uint8_t *data); - -void -cmac_aes256_digest(struct cmac_aes256_ctx *ctx, - size_t length, uint8_t *digest); - -#ifdef __cplusplus -} -#endif - -#endif /* GNUTLS_LIB_NETTLE_BACKPORT_CMAC_H */ diff --git a/lib/nettle/backport/xts.c b/lib/nettle/backport/xts.c deleted file mode 100644 index d8c258f650..0000000000 --- a/lib/nettle/backport/xts.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2018 Red Hat, Inc. - * - * Author: Simo Sorce - * - * This file is part of GnuTLS. - * - * The GnuTLS 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. - * - * This library 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 IS A BACKPORT FROM NETTLE, DO NOT MODIFY - * ############################################# - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifndef HAVE_NETTLE_XTS_ENCRYPT_MESSAGE -#include "xts.h" - -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include <nettle/macros.h> -#include <nettle/memxor.h> - -/* An aligned 16-byte block. */ -union _backport_nettle_block16 -{ - uint8_t b[16]; - unsigned long w[16 / sizeof(unsigned long)]; - uint64_t u64[2]; -}; - -/* shift left one and XOR with 0x87 if there is carry. */ -/* the algorithm reads this as a 128bit Little Endian number */ -/* src and dest can point to the same buffer for in-place operations */ -#if WORDS_BIGENDIAN -#define BE_SHIFT(x) ((((x) & 0x7f7f7f7f7f7f7f7f) << 1) | \ - (((x) & 0x8080808080808080) >> 15)) -static void -xts_shift(union _backport_nettle_block16 *dst, - const union _backport_nettle_block16 *src) -{ - uint64_t carry = (src->u64[1] & 0x80) >> 7; - dst->u64[1] = BE_SHIFT(src->u64[1]) | ((src->u64[0] & 0x80) << 49); - dst->u64[0] = BE_SHIFT(src->u64[0]); - dst->u64[0] ^= 0x8700000000000000 & -carry; -} -#else /* !WORDS_BIGENDIAN */ -static void -xts_shift(union _backport_nettle_block16 *dst, - const union _backport_nettle_block16 *src) -{ - uint64_t carry = src->u64[1] >> 63; - dst->u64[1] = (src->u64[1] << 1) | (src->u64[0] >> 63); - dst->u64[0] = src->u64[0] << 1; - dst->u64[0] ^= 0x87 & -carry; -} -#endif /* !WORDS_BIGNDIAN */ - -static void -check_length(size_t length, uint8_t *dst) -{ - assert(length >= XTS_BLOCK_SIZE); - /* asserts may be compiled out, try to save the user by zeroing the dst in - * case the buffer contains sensitive data (like the clear text for inplace - * encryption) */ - if (length < XTS_BLOCK_SIZE) - memset(dst, '\0', length); -} - -/* works also for inplace encryption/decryption */ - -void -xts_encrypt_message(const void *enc_ctx, const void *twk_ctx, - nettle_cipher_func *encf, - const uint8_t *tweak, size_t length, - uint8_t *dst, const uint8_t *src) -{ - union _backport_nettle_block16 T; - union _backport_nettle_block16 P; - - check_length(length, dst); - - encf(twk_ctx, XTS_BLOCK_SIZE, T.b, tweak); - - /* the zeroth power of alpha is the initial ciphertext value itself, so we - * skip shifting and do it at the end of each block operation instead */ - for (;length >= 2 * XTS_BLOCK_SIZE || length == XTS_BLOCK_SIZE; - length -= XTS_BLOCK_SIZE, src += XTS_BLOCK_SIZE, dst += XTS_BLOCK_SIZE) - { - memxor3(P.b, src, T.b, XTS_BLOCK_SIZE); /* P -> PP */ - encf(enc_ctx, XTS_BLOCK_SIZE, dst, P.b); /* CC */ - memxor(dst, T.b, XTS_BLOCK_SIZE); /* CC -> C */ - - /* shift T for next block if any */ - if (length > XTS_BLOCK_SIZE) - xts_shift(&T, &T); - } - - /* if the last block is partial, handle via stealing */ - if (length) - { - /* S Holds the real C(n-1) (Whole last block to steal from) */ - union _backport_nettle_block16 S; - - memxor3(P.b, src, T.b, XTS_BLOCK_SIZE); /* P -> PP */ - encf(enc_ctx, XTS_BLOCK_SIZE, S.b, P.b); /* CC */ - memxor(S.b, T.b, XTS_BLOCK_SIZE); /* CC -> S */ - - /* shift T for next block */ - xts_shift(&T, &T); - - length -= XTS_BLOCK_SIZE; - src += XTS_BLOCK_SIZE; - - memxor3(P.b, src, T.b, length); /* P |.. */ - /* steal ciphertext to complete block */ - memxor3(P.b + length, S.b + length, T.b + length, - XTS_BLOCK_SIZE - length); /* ..| S_2 -> PP */ - - encf(enc_ctx, XTS_BLOCK_SIZE, dst, P.b); /* CC */ - memxor(dst, T.b, XTS_BLOCK_SIZE); /* CC -> C(n-1) */ - - /* Do this after we read src so inplace operations do not break */ - dst += XTS_BLOCK_SIZE; - memcpy(dst, S.b, length); /* S_1 -> C(n) */ - } -} - -void -xts_decrypt_message(const void *dec_ctx, const void *twk_ctx, - nettle_cipher_func *decf, nettle_cipher_func *encf, - const uint8_t *tweak, size_t length, - uint8_t *dst, const uint8_t *src) -{ - union _backport_nettle_block16 T; - union _backport_nettle_block16 C; - - check_length(length, dst); - - encf(twk_ctx, XTS_BLOCK_SIZE, T.b, tweak); - - for (;length >= 2 * XTS_BLOCK_SIZE || length == XTS_BLOCK_SIZE; - length -= XTS_BLOCK_SIZE, src += XTS_BLOCK_SIZE, dst += XTS_BLOCK_SIZE) - { - memxor3(C.b, src, T.b, XTS_BLOCK_SIZE); /* c -> CC */ - decf(dec_ctx, XTS_BLOCK_SIZE, dst, C.b); /* PP */ - memxor(dst, T.b, XTS_BLOCK_SIZE); /* PP -> P */ - - /* shift T for next block if any */ - if (length > XTS_BLOCK_SIZE) - xts_shift(&T, &T); - } - - /* if the last block is partial, handle via stealing */ - if (length) - { - union _backport_nettle_block16 T1; - /* S Holds the real P(n) (with part of stolen ciphertext) */ - union _backport_nettle_block16 S; - - /* we need the last T(n) and save the T(n-1) for later */ - xts_shift(&T1, &T); - - memxor3(C.b, src, T1.b, XTS_BLOCK_SIZE); /* C -> CC */ - decf(dec_ctx, XTS_BLOCK_SIZE, S.b, C.b); /* PP */ - memxor(S.b, T1.b, XTS_BLOCK_SIZE); /* PP -> S */ - - /* process next block (Pn-1) */ - length -= XTS_BLOCK_SIZE; - src += XTS_BLOCK_SIZE; - - /* Prepare C, P holds the real P(n) */ - memxor3(C.b, src, T.b, length); /* C_1 |.. */ - memxor3(C.b + length, S.b + length, T.b + length, - XTS_BLOCK_SIZE - length); /* ..| S_2 -> CC */ - decf(dec_ctx, XTS_BLOCK_SIZE, dst, C.b); /* PP */ - memxor(dst, T.b, XTS_BLOCK_SIZE); /* PP -> P(n-1) */ - - /* Do this after we read src so inplace operations do not break */ - dst += XTS_BLOCK_SIZE; - memcpy(dst, S.b, length); /* S_1 -> P(n) */ - } -} - -void -xts_aes128_set_encrypt_key(struct xts_aes128_key *xts_key, const uint8_t *key) -{ - aes128_set_encrypt_key(&xts_key->cipher, key); - aes128_set_encrypt_key(&xts_key->tweak_cipher, &key[AES128_KEY_SIZE]); -} - -void -xts_aes128_set_decrypt_key(struct xts_aes128_key *xts_key, const uint8_t *key) -{ - aes128_set_decrypt_key(&xts_key->cipher, key); - aes128_set_encrypt_key(&xts_key->tweak_cipher, &key[AES128_KEY_SIZE]); -} - -void -xts_aes128_encrypt_message(struct xts_aes128_key *xts_key, - const uint8_t *tweak, size_t length, - uint8_t *dst, const uint8_t *src) -{ - xts_encrypt_message(&xts_key->cipher, &xts_key->tweak_cipher, - (nettle_cipher_func *) aes128_encrypt, - tweak, length, dst, src); -} - -void -xts_aes128_decrypt_message(struct xts_aes128_key *xts_key, - const uint8_t *tweak, size_t length, - uint8_t *dst, const uint8_t *src) -{ - xts_decrypt_message(&xts_key->cipher, &xts_key->tweak_cipher, - (nettle_cipher_func *) aes128_decrypt, - (nettle_cipher_func *) aes128_encrypt, - tweak, length, dst, src); -} - -void -xts_aes256_set_encrypt_key(struct xts_aes256_key *xts_key, const uint8_t *key) -{ - aes256_set_encrypt_key(&xts_key->cipher, key); - aes256_set_encrypt_key(&xts_key->tweak_cipher, &key[AES256_KEY_SIZE]); -} - -void -xts_aes256_set_decrypt_key(struct xts_aes256_key *xts_key, const uint8_t *key) -{ - aes256_set_decrypt_key(&xts_key->cipher, key); - aes256_set_encrypt_key(&xts_key->tweak_cipher, &key[AES256_KEY_SIZE]); -} - -void -xts_aes256_encrypt_message(struct xts_aes256_key *xts_key, - const uint8_t *tweak, size_t length, - uint8_t *dst, const uint8_t *src) -{ - xts_encrypt_message(&xts_key->cipher, &xts_key->tweak_cipher, - (nettle_cipher_func *) aes256_encrypt, - tweak, length, dst, src); -} - -void -xts_aes256_decrypt_message(struct xts_aes256_key *xts_key, - const uint8_t *tweak, size_t length, - uint8_t *dst, const uint8_t *src) -{ - xts_decrypt_message(&xts_key->cipher, &xts_key->tweak_cipher, - (nettle_cipher_func *) aes256_decrypt, - (nettle_cipher_func *) aes256_encrypt, - tweak, length, dst, src); -} - -#endif /* HAVE_NETTLE_XTS_ENCRYPT_MESSAGE */ diff --git a/lib/nettle/backport/xts.h b/lib/nettle/backport/xts.h deleted file mode 100644 index 8c52f9a092..0000000000 --- a/lib/nettle/backport/xts.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2018 Red Hat, Inc. - * - * Author: Simo Sorce - * - * This file is part of GnuTLS. - * - * The GnuTLS 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. - * - * This library 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 GNUTLS_LIB_NETTLE_BACKPORT_XTS_H -#define GNUTLS_LIB_NETTLE_BACKPORT_XTS_H - -#ifdef HAVE_NETTLE_XTS_ENCRYPT_MESSAGE -#include <nettle/xts.h> - -#else /* Nettle version is old, use a vendored version instead */ - -#ifndef NETTLE_XTS_H_INCLUDED -#define NETTLE_XTS_H_INCLUDED - -#include <nettle/nettle-types.h> -#include <nettle/aes.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* Name mangling */ -#define xts_encrypt_message nettle_xts_encrypt_message -#define xts_decrypt_message nettle_xts_decrypt_message -#define xts_aes128_set_encrypt_key nettle_xts_aes128_set_encrypt_key -#define xts_aes128_set_decrypt_key nettle_xts_aes128_set_decrypt_key -#define xts_aes128_encrypt_message nettle_xts_aes128_encrypt_message -#define xts_aes128_decrypt_message nettle_xts_aes128_decrypt_message -#define xts_aes256_set_encrypt_key nettle_xts_aes256_set_encrypt_key -#define xts_aes256_set_decrypt_key nettle_xts_aes256_set_decrypt_key -#define xts_aes256_encrypt_message nettle_xts_aes256_encrypt_message -#define xts_aes256_decrypt_message nettle_xts_aes256_decrypt_message - -#define XTS_BLOCK_SIZE 16 - -void -xts_encrypt_message(const void *enc_ctx, const void *twk_ctx, - nettle_cipher_func *encf, - const uint8_t *tweak, size_t length, - uint8_t *dst, const uint8_t *src); -void -xts_decrypt_message(const void *dec_ctx, const void *twk_ctx, - nettle_cipher_func *decf, nettle_cipher_func *encf, - const uint8_t *tweak, size_t length, - uint8_t *dst, const uint8_t *src); - -/* XTS Mode with AES-128 */ -struct xts_aes128_key { - struct aes128_ctx cipher; - struct aes128_ctx tweak_cipher; -}; - -void -xts_aes128_set_encrypt_key(struct xts_aes128_key *xts_key, - const uint8_t *key); - -void -xts_aes128_set_decrypt_key(struct xts_aes128_key *xts_key, - const uint8_t *key); - -void -xts_aes128_encrypt_message(struct xts_aes128_key *xtskey, - const uint8_t *tweak, size_t length, - uint8_t *dst, const uint8_t *src); - -void -xts_aes128_decrypt_message(struct xts_aes128_key *xts_key, - const uint8_t *tweak, size_t length, - uint8_t *dst, const uint8_t *src); - -/* XTS Mode with AES-256 */ -struct xts_aes256_key { - struct aes256_ctx cipher; - struct aes256_ctx tweak_cipher; -}; - -void -xts_aes256_set_encrypt_key(struct xts_aes256_key *xts_key, - const uint8_t *key); - -void -xts_aes256_set_decrypt_key(struct xts_aes256_key *xts_key, - const uint8_t *key); - -void -xts_aes256_encrypt_message(struct xts_aes256_key *xts_key, - const uint8_t *tweak, size_t length, - uint8_t *dst, const uint8_t *src); - -void -xts_aes256_decrypt_message(struct xts_aes256_key *xts_key, - const uint8_t *tweak, size_t length, - uint8_t *dst, const uint8_t *src); - -#ifdef __cplusplus -} -#endif - -#endif /* NETTLE_XTS_H_INCLUDED */ - -#endif /* HAVE_NETTLE_XTS_ENCRYPT_MESSAGE */ - -#endif /* GNUTLS_LIB_NETTLE_BACKPORT_XTS_H */ diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c index 0a94c49a95..6624e6b84c 100644 --- a/lib/nettle/cipher.c +++ b/lib/nettle/cipher.c @@ -55,9 +55,13 @@ #ifdef HAVE_NETTLE_CFB8_ENCRYPT #include <nettle/cfb.h> #else -#include "cfb8.h" +#include "cfb.h" #endif /* HAVE_NETTLE_CFB8_ENCRYPT */ +#ifdef HAVE_NETTLE_XTS_ENCRYPT_MESSAGE +#include <nettle/xts.h> +#else #include "xts.h" +#endif #include <fips.h> struct nettle_cipher_ctx; diff --git a/lib/nettle/int/block8.h b/lib/nettle/int/block8.h new file mode 100644 index 0000000000..a1f6efec20 --- /dev/null +++ b/lib/nettle/int/block8.h @@ -0,0 +1,61 @@ +/* nettle-types.h + + Copyright (C) 2005, 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_LIB_NETTLE_BLOCK8_H +#define GNUTLS_LIB_NETTLE_BLOCK8_H + +#include "config.h" + +#ifndef HAVE_UNION_NETTLE_BLOCK8 + +/* An aligned 16-byte block. */ +union gnutls_nettle_backport_nettle_block16 +{ + uint8_t b[16]; + unsigned long w[16 / sizeof(unsigned long)]; + uint64_t u64[2]; +}; + +union gnutls_nettle_backport_nettle_block8 +{ + uint8_t b[8]; + uint64_t u64; +}; + +#undef nettle_block16 +#undef nettle_block8 + +#define nettle_block16 gnutls_nettle_backport_nettle_block16 +#define nettle_block8 gnutls_nettle_backport_nettle_block8 + +#endif + +#endif /* GNUTLS_LIB_NETTLE_BLOCK8_H */ |