Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15
gnutls.14806
0001-Vendor-in-XTS-functionality-from-Nettle.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Vendor-in-XTS-functionality-from-Nettle.patch of Package gnutls.14806
From ea46e149b69cf1c4b963e6d156a6b3e38d710894 Mon Sep 17 00:00:00 2001 From: Simo Sorce <simo@redhat.com> Date: Fri, 19 Oct 2018 15:53:27 -0400 Subject: [PATCH] Vendor in XTS functionality from Nettle If nettle's XTS 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> --- configure.ac | 7 + lib/algorithms/ciphers.c | 15 ++ lib/crypto-selftests.c | 51 ++++++ lib/fips.c | 6 + lib/fips.h | 2 + lib/includes/gnutls/gnutls.h.in | 8 + lib/nettle/Makefile.am | 1 + lib/nettle/backport/xts.c | 273 ++++++++++++++++++++++++++++++++ lib/nettle/backport/xts.h | 122 ++++++++++++++ lib/nettle/cipher.c | 51 ++++++ 10 files changed, 536 insertions(+) create mode 100644 lib/nettle/backport/xts.c create mode 100644 lib/nettle/backport/xts.h diff --git a/configure.ac b/configure.ac index b686726d1b..f9d40b4ea2 100644 --- a/configure.ac +++ b/configure.ac @@ -563,6 +563,13 @@ LIBS="$LIBS $NETTLE_LIBS" AC_CHECK_FUNCS(nettle_cmac128_update) LIBS=$save_LIBS +# Check if nettle has XTS support +save_LIBS=$LIBS +LIBS="$LIBS $NETTLE_LIBS" +AC_CHECK_FUNCS(xts_encrypt_message) +LIBS=$save_LIBS + + AC_MSG_CHECKING([whether to build libdane]) AC_ARG_ENABLE(libdane, AS_HELP_STRING([--disable-libdane], diff --git a/lib/algorithms/ciphers.c b/lib/algorithms/ciphers.c index 9fa6f0d805..6f503fd0b2 100644 --- a/lib/algorithms/ciphers.c +++ b/lib/algorithms/ciphers.c @@ -219,6 +219,7 @@ static const cipher_entry_st algorithms[] = { .type = CIPHER_STREAM, .implicit_iv = 8, .cipher_iv = 8}, + { .name = "AES-128-CFB8", .id = GNUTLS_CIPHER_AES_128_CFB8, .blocksize = 16, @@ -240,6 +241,20 @@ static const cipher_entry_st algorithms[] = { .type = CIPHER_BLOCK, .explicit_iv = 16, .cipher_iv = 16}, + { .name = "AES-128-XTS", + .id = GNUTLS_CIPHER_AES_128_XTS, + .blocksize = 16, + .keysize = 32, + .type = CIPHER_BLOCK, + .explicit_iv = 16, + .cipher_iv = 16}, + { .name = "AES-256-XTS", + .id = GNUTLS_CIPHER_AES_256_XTS, + .blocksize = 16, + .keysize = 64, + .type = CIPHER_BLOCK, + .explicit_iv = 16, + .cipher_iv = 16}, { .name = "3DES-CBC", .id = GNUTLS_CIPHER_3DES_CBC, .blocksize = 8, diff --git a/lib/crypto-selftests.c b/lib/crypto-selftests.c index d5475d2ffd..5d040fb603 100644 --- a/lib/crypto-selftests.c +++ b/lib/crypto-selftests.c @@ -499,6 +499,51 @@ const struct cipher_vectors_st gost28147_tc26z_cfb_vectors[] = { }, }; +const struct cipher_vectors_st aes128_xts_vectors[] = { + { + STR(key, key_size, + "\xa1\xb9\x0c\xba\x3f\x06\xac\x35\x3b\x2c\x34\x38\x76\x08\x17\x62" + "\x09\x09\x23\x02\x6e\x91\x77\x18\x15\xf2\x9d\xab\x01\x93\x2f\x2f"), + STR(plaintext, plaintext_size, + "\xeb\xab\xce\x95\xb1\x4d\x3c\x8d\x6f\xb3\x50\x39\x07\x90\x31\x1c"), + .ciphertext = (uint8_t *) + "\x77\x8a\xe8\xb4\x3c\xb9\x8d\x5a\x82\x50\x81\xd5\xbe\x47\x1c\x63", + STR(iv, iv_size, + "\x4f\xae\xf7\x11\x7c\xda\x59\xc6\x6e\x4b\x92\x01\x3e\x76\x8a\xd5"), + }, + { + STR(key, key_size, + "\x75\x03\x72\xc3\xd8\x2f\x63\x38\x28\x67\xbe\x66\x62\xac\xfa\x4a" + "\x25\x9b\xe3\xfa\x9b\xc6\x62\xa1\x15\x4f\xfa\xae\xd8\xb4\x48\xa5"), + STR(plaintext, plaintext_size, + "\xd8\xe3\xa5\x65\x59\xa4\x36\xce\x0d\x8b\x21\x2c\x80\xa8\x8b\x23" + "\xaf\x62\xb0\xe5\x98\xf2\x08\xe0\x3c\x1f\x2e\x9f\xa5\x63\xa5\x4b"), + .ciphertext = (uint8_t *) + "\x49\x5f\x78\x55\x53\x5e\xfd\x13\x34\x64\xdc\x9a\x9a\xbf\x8a\x0f" + "\x28\xfa\xcb\xce\x21\xbd\x3c\x22\x17\x8e\xc4\x89\xb7\x99\xe4\x91", + STR(iv, iv_size, + "\x93\xa2\x92\x54\xc4\x7e\x42\x60\x66\x96\x21\x30\x7d\x4f\x5c\xd3"), + }, +}; + +const struct cipher_vectors_st aes256_xts_vectors[] = { + { + STR(key, key_size, + "\x1e\xa6\x61\xc5\x8d\x94\x3a\x0e\x48\x01\xe4\x2f\x4b\x09\x47\x14" + "\x9e\x7f\x9f\x8e\x3e\x68\xd0\xc7\x50\x52\x10\xbd\x31\x1a\x0e\x7c" + "\xd6\xe1\x3f\xfd\xf2\x41\x8d\x8d\x19\x11\xc0\x04\xcd\xa5\x8d\xa3" + "\xd6\x19\xb7\xe2\xb9\x14\x1e\x58\x31\x8e\xea\x39\x2c\xf4\x1b\x08"), + STR(plaintext, plaintext_size, + "\x2e\xed\xea\x52\xcd\x82\x15\xe1\xac\xc6\x47\xe8\x10\xbb\xc3\x64" + "\x2e\x87\x28\x7f\x8d\x2e\x57\xe3\x6c\x0a\x24\xfb\xc1\x2a\x20\x2e"), + .ciphertext = (uint8_t *) + "\xcb\xaa\xd0\xe2\xf6\xce\xa3\xf5\x0b\x37\xf9\x34\xd4\x6a\x9b\x13" + "\x0b\x9d\x54\xf0\x7e\x34\xf3\x6a\xf7\x93\xe8\x6f\x73\xc6\xd7\xdb", + STR(iv, iv_size, + "\xad\xf8\xd9\x26\x27\x46\x4a\xd2\xf0\x42\x8e\x84\xa9\xf8\x75\x64"), + }, +}; + static int test_cipher(gnutls_cipher_algorithm_t cipher, const struct cipher_vectors_st *vectors, size_t vectors_size, unsigned flags) @@ -1582,6 +1627,12 @@ int gnutls_cipher_self_test(unsigned flags, gnutls_cipher_algorithm_t cipher) FALLTHROUGH; CASE(GNUTLS_CIPHER_AES_256_CFB8, test_cipher, aes256_cfb8_vectors); + FALLTHROUGH; + CASE(GNUTLS_CIPHER_AES_128_XTS, test_cipher, + aes128_xts_vectors); + FALLTHROUGH; + CASE(GNUTLS_CIPHER_AES_256_XTS, test_cipher, + aes256_xts_vectors); #if ENABLE_GOST FALLTHROUGH; NON_FIPS_CASE(GNUTLS_CIPHER_GOST28147_CPA_CFB, test_cipher, diff --git a/lib/fips.c b/lib/fips.c index 32436ad1f8..ef1f7cbc35 100644 --- a/lib/fips.c +++ b/lib/fips.c @@ -323,6 +323,12 @@ int _gnutls_fips_perform_self_checks2(void) goto error; } + ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_XTS); + if (ret < 0) { + gnutls_assert(); + goto error; + } + /* Digest tests */ ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHA3_224); if (ret < 0) { diff --git a/lib/fips.h b/lib/fips.h index beb540f76b..97f1c26219 100644 --- a/lib/fips.h +++ b/lib/fips.h @@ -144,6 +144,8 @@ static unsigned is_cipher_algo_forbidden(gnutls_cipher_algorithm_t algo) case GNUTLS_CIPHER_AES_128_CFB8: case GNUTLS_CIPHER_AES_192_CFB8: case GNUTLS_CIPHER_AES_256_CFB8: + case GNUTLS_CIPHER_AES_128_XTS: + case GNUTLS_CIPHER_AES_256_XTS: return 0; default: if (mode == GNUTLS_FIPS140_LAX) diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 20e9784754..5b5d9bab8a 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -119,6 +119,12 @@ extern "C" { * @GNUTLS_CIPHER_GOST28147_CPB_CFB: GOST 28147-89 (Magma) cipher in CFB mode with CryptoPro B S-box. * @GNUTLS_CIPHER_GOST28147_CPC_CFB: GOST 28147-89 (Magma) cipher in CFB mode with CryptoPro C S-box. * @GNUTLS_CIPHER_GOST28147_CPD_CFB: GOST 28147-89 (Magma) cipher in CFB mode with CryptoPro D S-box. + * @GNUTLS_CIPHER_AES_128_XTS: AES in XTS mode with 128-bit key + 128bit tweak key. + * @GNUTLS_CIPHER_AES_256_XTS: AES in XTS mode with 256-bit key + 256bit tweak key. + * Note that the XTS ciphers are message oriented. + * The whole message needs to be provided with a single call, because + * cipher-stealing requires to know where the message actually terminates + * in order to be able to compute where the stealing occurs. * @GNUTLS_CIPHER_IDEA_PGP_CFB: IDEA in CFB mode (placeholder - unsupported). * @GNUTLS_CIPHER_3DES_PGP_CFB: 3DES in CFB mode (placeholder - unsupported). * @GNUTLS_CIPHER_CAST5_PGP_CFB: CAST5 in CFB mode (placeholder - unsupported). @@ -164,6 +170,8 @@ typedef enum gnutls_cipher_algorithm { GNUTLS_CIPHER_AES_128_CFB8 = 29, GNUTLS_CIPHER_AES_192_CFB8 = 30, GNUTLS_CIPHER_AES_256_CFB8 = 31, + GNUTLS_CIPHER_AES_128_XTS = 32, + GNUTLS_CIPHER_AES_256_XTS = 33, /* used only for PGP internals. Ignored in TLS/SSL */ diff --git a/lib/nettle/Makefile.am b/lib/nettle/Makefile.am index 4dbce087f6..1c60d3244b 100644 --- a/lib/nettle/Makefile.am +++ b/lib/nettle/Makefile.am @@ -42,6 +42,7 @@ 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 diff --git a/lib/nettle/backport/xts.c b/lib/nettle/backport/xts.c new file mode 100644 index 0000000000..a7ef120aa0 --- /dev/null +++ b/lib/nettle/backport/xts.c @@ -0,0 +1,273 @@ +/* + * 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_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_XTS_ENCRYPT_MESSAGE */ diff --git a/lib/nettle/backport/xts.h b/lib/nettle/backport/xts.h new file mode 100644 index 0000000000..5111af0f38 --- /dev/null +++ b/lib/nettle/backport/xts.h @@ -0,0 +1,122 @@ +/* + * 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 _BACKPORT_NETTLE_XTS_H_INCLUDED +#define _BACKPORT_NETTLE_XTS_H_INCLUDED + +#ifdef HAVE_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_XTS_ENCRYPT_MESSAGE */ + +#endif /* _BACKPORT_NETTLE_XTS_H_INCLUDED */ diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c index da33099974..9194fb750c 100644 --- a/lib/nettle/cipher.c +++ b/lib/nettle/cipher.c @@ -47,6 +47,7 @@ #else #include "cfb8.h" #endif /* HAVE_NETTLE_CFB8_ENCRYPT */ +#include "xts.h" #include <fips.h> struct nettle_cipher_ctx; @@ -280,6 +281,34 @@ _cfb8_decrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst, length, dst, src); } +static void +_xts_aes128_encrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst, + const uint8_t * src) +{ + xts_aes128_encrypt_message(ctx->ctx_ptr, ctx->iv, length, dst, src); +} + +static void +_xts_aes128_decrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst, + const uint8_t * src) +{ + xts_aes128_decrypt_message(ctx->ctx_ptr, ctx->iv, length, dst, src); +} + +static void +_xts_aes256_encrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst, + const uint8_t * src) +{ + xts_aes256_encrypt_message(ctx->ctx_ptr, ctx->iv, length, dst, src); +} + +static void +_xts_aes256_decrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst, + const uint8_t * src) +{ + xts_aes256_decrypt_message(ctx->ctx_ptr, ctx->iv, length, dst, src); +} + static const struct nettle_cipher_st builtin_ciphers[] = { { .algo = GNUTLS_CIPHER_AES_128_GCM, .block_size = AES_BLOCK_SIZE, @@ -677,6 +706,28 @@ static const struct nettle_cipher_st builtin_ciphers[] = { .set_decrypt_key = (nettle_set_key_func*)aes256_set_encrypt_key, .max_iv_size = AES_BLOCK_SIZE, }, + { .algo = GNUTLS_CIPHER_AES_128_XTS, + .block_size = AES_BLOCK_SIZE, + .key_size = AES128_KEY_SIZE * 2, + + .ctx_size = sizeof(struct xts_aes128_key), + .encrypt = _xts_aes128_encrypt, + .decrypt = _xts_aes128_decrypt, + .set_encrypt_key = (nettle_set_key_func*)xts_aes128_set_encrypt_key, + .set_decrypt_key = (nettle_set_key_func*)xts_aes128_set_decrypt_key, + .max_iv_size = AES_BLOCK_SIZE, + }, + { .algo = GNUTLS_CIPHER_AES_256_XTS, + .block_size = AES_BLOCK_SIZE, + .key_size = AES256_KEY_SIZE * 2, + + .ctx_size = sizeof(struct xts_aes256_key), + .encrypt = _xts_aes256_encrypt, + .decrypt = _xts_aes256_decrypt, + .set_encrypt_key = (nettle_set_key_func*)xts_aes256_set_encrypt_key, + .set_decrypt_key = (nettle_set_key_func*)xts_aes256_set_decrypt_key, + .max_iv_size = AES_BLOCK_SIZE, + }, }; static int wrap_nettle_cipher_exists(gnutls_cipher_algorithm_t algo) -- 2.25.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor