diff options
author | Dmitry Baryshkov <dbaryshkov@gmail.com> | 2020-05-04 14:40:07 +0000 |
---|---|---|
committer | Dmitry Baryshkov <dbaryshkov@gmail.com> | 2020-05-04 14:40:07 +0000 |
commit | d51399272886d909fbc40f2c5e26db3e87a45a0a (patch) | |
tree | 5afe042bbd3dc91d4c11e49c06bf0998cdb1e1a5 | |
parent | cb5171409a8e8e9b6127e0acaa0136411b46fcd0 (diff) | |
parent | d28e3b5a886f7f5a6ee0170be15143a716e641f5 (diff) | |
download | gnutls-d51399272886d909fbc40f2c5e26db3e87a45a0a.tar.gz |
Merge branch 'tmp-siv' into 'master'
nettle: expose SIV-CMAC through the AEAD interface
Closes #974 and #463
See merge request gnutls/gnutls!1238
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | bootstrap.conf | 2 | ||||
-rw-r--r-- | configure.ac | 20 | ||||
-rwxr-xr-x | devel/import-from-nettle.sh (renamed from devel/import-chacha-from-nettle.sh) | 62 | ||||
-rw-r--r-- | devel/libdane-latest-x86_64.abi | 4 | ||||
-rw-r--r-- | devel/libgnutls-latest-x86_64.abi | 2 | ||||
-rw-r--r-- | lib/algorithms/ciphers.c | 18 | ||||
-rw-r--r-- | lib/crypto-selftests.c | 109 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 8 | ||||
-rw-r--r-- | lib/nettle/Makefile.am | 41 | ||||
-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 | 93 | ||||
-rw-r--r-- | lib/nettle/int/block8.h | 61 |
19 files changed, 396 insertions, 1006 deletions
diff --git a/.gitignore b/.gitignore index 766595b5e2..e19ca802cb 100644 --- a/.gitignore +++ b/.gitignore @@ -233,7 +233,7 @@ lib/minitasn1/libminitasn1.la lib/minitasn1/Makefile lib/minitasn1/Makefile.in lib/nettle/libcrypto.la -lib/nettle/chacha +lib/nettle/backport lib/nettle/ecc lib/opencdk/libminiopencdk.la lib/opencdk/Makefile @@ -5,6 +5,12 @@ Copyright (C) 2000-2016 Free Software Foundation, Inc. Copyright (C) 2013-2019 Nikos Mavrogiannopoulos See the end for copying conditions. +* Version 3.6.14 (unreleased) + +** API and ABI modifications: +GNUTLS_CIPHER_AES_128_SIV: Added +GNUTLS_CIPHER_AES_256_SIV: Added + * Version 3.6.13 (released 2020-03-31) ** libgnutls: Fix a DTLS-protocol regression (caused by TLS1.3 support), since 3.6.3. diff --git a/bootstrap.conf b/bootstrap.conf index 04e670ddeb..3693846aaf 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -103,5 +103,5 @@ bootstrap_post_import_hook () touch ChangeLog || return 1 devel/import-ecc-from-nettle.sh - devel/import-chacha-from-nettle.sh + devel/import-from-nettle.sh } diff --git a/configure.ac b/configure.ac index de4c54d508..2aca4b9fca 100644 --- a/configure.ac +++ b/configure.ac @@ -602,9 +602,8 @@ LIBS=$save_LIBS # Check if nettle has CFB8 support if test -z "$ac_cv_func_nettle_cfb8_encrypt"; then - # nettle_cfb8_decrypt in nettle 3.5 is known to be broken - ver=`$PKG_CONFIG --modversion nettle` - if expr "$ver" : '^3\.5\b' >/dev/null; then + # nettle_cfb8_decrypt in nettle upto 3.6 is known to be broken + if ! $PKG_CONFIG --atleast-version=3.6 nettle; then ac_cv_func_nettle_cfb8_encrypt=no fi fi @@ -613,18 +612,26 @@ save_LIBS=$LIBS LIBS="$LIBS $NETTLE_LIBS" AC_CHECK_FUNCS(nettle_cfb8_encrypt) LIBS=$save_LIBS +AM_CONDITIONAL(NEED_CFB, [test "$ac_cv_func_nettle_cfb8_encrypt" != "yes"]) # Check if nettle has CMAC support +save_CFLAGS=$CFLAGS +CFLAGS="$CFLAGS $NETTLE_CFLAGS" +AC_CHECK_TYPES([union nettle_block8], , , [[#include <nettle/nettle-types.h>]]) +CFLAGS=$save_CFLAGS + save_LIBS=$LIBS LIBS="$LIBS $NETTLE_LIBS" AC_CHECK_FUNCS(nettle_cmac128_update) LIBS=$save_LIBS +AM_CONDITIONAL(NEED_CMAC, [test "$ac_cv_func_nettle_cmac128_update" != "yes"]) # Check if nettle has XTS support save_LIBS=$LIBS LIBS="$LIBS $NETTLE_LIBS" AC_CHECK_FUNCS(nettle_xts_encrypt_message) LIBS=$save_LIBS +AM_CONDITIONAL(NEED_XTS, [test "$ac_cv_func_nettle_xts_encrypt_message" != "yes"]) # Check for Gosthash94 with CryptoPro S-box support save_LIBS=$LIBS @@ -663,6 +670,13 @@ AC_CHECK_FUNCS([nettle_chacha_set_counter], LIBS=$save_LIBS AM_CONDITIONAL(NEED_CHACHA, [test "$have_chacha_set_counter" != "yes"]) +# Check for SIV-CMAC +save_LIBS=$LIBS +LIBS="$LIBS $NETTLE_LIBS" +AC_CHECK_FUNCS(nettle_siv_cmac_aes128_set_key) +LIBS=$save_LIBS +AM_CONDITIONAL(NEED_SIV, [test "$ac_cv_func_nettle_siv_cmac_aes128_set_key" != "yes"]) + # Check sonames of the linked libraries needed for FIPS selftests. save_LIBS=$LIBS LIBS="$LIBS $GMP_LIBS" diff --git a/devel/import-chacha-from-nettle.sh b/devel/import-from-nettle.sh index 4b686df765..3867f9e2a7 100755 --- a/devel/import-chacha-from-nettle.sh +++ b/devel/import-from-nettle.sh @@ -1,15 +1,22 @@ #!/bin/sh -# This script copies the ChaCha20 implementation from the -# nettle upstream, with necessary adjustments for bundling in GnuTLS. +# This script copies files from the nettle upstream, with necessary +# adjustments for bundling in GnuTLS. set +e : ${srcdir=.} SRC=$srcdir/devel/nettle -DST=$srcdir/lib/nettle/chacha +DST=$srcdir/lib/nettle/backport IMPORTS=" +block-internal.h +cfb.c +cfb.h +cmac.c +cmac.h +cmac-aes128.c +cmac-aes256.c chacha-core-internal.c chacha-crypt.c chacha-internal.h @@ -21,14 +28,25 @@ chacha.h poly1305-internal.c poly1305-internal.h poly1305.h +xts.c +xts.h +xts-aes128.c +xts-aes256.c +siv-cmac.c +siv-cmac.h +siv-cmac-aes128.c +siv-cmac-aes256.c " PUBLIC=" aes.h bignum.h +ctr.h +des.h ecc-curve.h ecc.h macros.h +memops.h memxor.h nettle-meta.h nettle-types.h @@ -66,7 +84,7 @@ for f in $IMPORTS; do # Rename header guard so as not to conflict with the public ones. if grep '^#ifndef NETTLE_.*_H\(_INCLUDED\)*' $dst 2>&1 >/dev/null; then g=$(sed -n 's/^#ifndef NETTLE_\(.*_H\(_INCLUDED\)*\)/\1/p' $dst) - sed 's/\(NETTLE_'$g'\)/GNUTLS_LIB_NETTLE_CHACHA_\1/' $dst > $dst-t && \ + sed 's/\(NETTLE_'$g'\)/GNUTLS_LIB_NETTLE_BACKPORT_\1/' $dst > $dst-t && \ mv $dst-t $dst fi ;; @@ -74,13 +92,43 @@ for f in $IMPORTS; do case $dst in *.h) # Add prefix to function symbols avoid clashing with the public ones. - sed -e 's/^#define \(.*\) nettle_\1/#define \1 gnutls_nettle_chacha_\1/' \ - -e 's/^#define _\(.*\) _nettle_\1/#define _\1 _gnutls_nettle_chacha_\1/' \ - -e 's/^#define \(.*\) _nettle_\1/#define \1 _gnutls_nettle_chacha_\1/' \ + sed -e 's/^#define \(.*\) nettle_\1/#define \1 gnutls_nettle_backport_\1/' \ + -e 's/^#define _\(.*\) _nettle_\1/#define _\1 _gnutls_nettle_backport_\1/' \ + -e 's/^#define \(.*\) _nettle_\1/#define \1 _gnutls_nettle_backport_\1/' \ $dst > $dst-t && \ mv $dst-t $dst ;; esac + case $dst in + */cfb.c | */cmac.c | */xts.c | */siv-cmac.c) + sed \ + -e 's/"nettle-internal\.h"/"nettle-alloca.h"/' \ + $dst > $dst-t && mv $dst-t $dst + ;; + esac + case $dst in + */*.[ch]) + sed \ + -e '/^#include <nettle\/nettle-types\.h>/a\ +#include "block8.h" +' \ + $dst > $dst-t && mv $dst-t $dst + ;; + esac + case $dst in + */siv-cmac*.[ch]) + sed \ + -e '/^#include "cmac\.h"/ { i\ +#ifdef HAVE_NETTLE_CMAC128_UPDATE\ +#include <nettle/cmac.h>\ +#else\ +#include "cmac.h"\ +#endif +; d +}' \ + $dst > $dst-t && mv $dst-t $dst + ;; + esac else echo "Error: $src not found" 1>&2 exit 1 diff --git a/devel/libdane-latest-x86_64.abi b/devel/libdane-latest-x86_64.abi index 6974f143a9..cf25f40e1e 100644 --- a/devel/libdane-latest-x86_64.abi +++ b/devel/libdane-latest-x86_64.abi @@ -252,6 +252,10 @@ <enumerator name='GNUTLS_CIPHER_AES_128_XTS' value='32'/> <enumerator name='GNUTLS_CIPHER_AES_256_XTS' value='33'/> <enumerator name='GNUTLS_CIPHER_GOST28147_TC26Z_CNT' value='34'/> + <enumerator name='GNUTLS_CIPHER_CHACHA20_64' value='35'/> + <enumerator name='GNUTLS_CIPHER_CHACHA20_32' value='36'/> + <enumerator name='GNUTLS_CIPHER_AES_128_SIV' value='37'/> + <enumerator name='GNUTLS_CIPHER_AES_256_SIV' value='38'/> <enumerator name='GNUTLS_CIPHER_IDEA_PGP_CFB' value='200'/> <enumerator name='GNUTLS_CIPHER_3DES_PGP_CFB' value='201'/> <enumerator name='GNUTLS_CIPHER_CAST5_PGP_CFB' value='202'/> diff --git a/devel/libgnutls-latest-x86_64.abi b/devel/libgnutls-latest-x86_64.abi index 8aa81a55dd..cc44d1898e 100644 --- a/devel/libgnutls-latest-x86_64.abi +++ b/devel/libgnutls-latest-x86_64.abi @@ -1515,6 +1515,8 @@ <enumerator name='GNUTLS_CIPHER_GOST28147_TC26Z_CNT' value='34'/> <enumerator name='GNUTLS_CIPHER_CHACHA20_64' value='35'/> <enumerator name='GNUTLS_CIPHER_CHACHA20_32' value='36'/> + <enumerator name='GNUTLS_CIPHER_AES_128_SIV' value='37'/> + <enumerator name='GNUTLS_CIPHER_AES_256_SIV' value='38'/> <enumerator name='GNUTLS_CIPHER_IDEA_PGP_CFB' value='200'/> <enumerator name='GNUTLS_CIPHER_3DES_PGP_CFB' value='201'/> <enumerator name='GNUTLS_CIPHER_CAST5_PGP_CFB' value='202'/> diff --git a/lib/algorithms/ciphers.c b/lib/algorithms/ciphers.c index 1318c88caf..59dc7ea7fb 100644 --- a/lib/algorithms/ciphers.c +++ b/lib/algorithms/ciphers.c @@ -270,6 +270,24 @@ static const cipher_entry_st algorithms[] = { .type = CIPHER_BLOCK, .explicit_iv = 16, .cipher_iv = 16}, + { .name = "AES-128-SIV", + .id = GNUTLS_CIPHER_AES_128_SIV, + .blocksize = 16, + .keysize = 32, + .type = CIPHER_AEAD, + .explicit_iv = 16, + .cipher_iv = 16, + .flags = GNUTLS_CIPHER_FLAG_ONLY_AEAD, + .tagsize = 16}, + { .name = "AES-256-SIV", + .id = GNUTLS_CIPHER_AES_256_SIV, + .blocksize = 16, + .keysize = 64, + .type = CIPHER_AEAD, + .explicit_iv = 16, + .cipher_iv = 16, + .flags = GNUTLS_CIPHER_FLAG_ONLY_AEAD, + .tagsize = 16}, { .name = "GOST28147-TC26Z-CNT", .id = GNUTLS_CIPHER_GOST28147_TC26Z_CNT, .blocksize = 8, diff --git a/lib/crypto-selftests.c b/lib/crypto-selftests.c index a1a308f410..f904b029b2 100644 --- a/lib/crypto-selftests.c +++ b/lib/crypto-selftests.c @@ -73,6 +73,7 @@ struct cipher_aead_vectors_st { const uint8_t *iv; const uint8_t *tag; unsigned tag_size; + unsigned tag_prepended; }; const struct cipher_aead_vectors_st chacha_poly1305_vectors[] = { @@ -570,6 +571,60 @@ const struct cipher_vectors_st aes256_xts_vectors[] = { }, }; +const struct cipher_aead_vectors_st aes128_siv_vectors[] = { + { + STR(key, key_size, + "\x7f\x7e\x7d\x7c\x7b\x7a\x79\x78\x77\x76\x75\x74\x73\x72\x71\x70" + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"), + STR(auth, auth_size, + "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff" + "\xde\xad\xda\xda\xde\xad\xda\xda\xff\xee\xdd\xcc\xbb\xaa\x99\x88" + "\x77\x66\x55\x44\x33\x22\x11\x00"), + STR(plaintext, plaintext_size, + "\x74\x68\x69\x73\x20\x69\x73\x20\x73\x6f\x6d\x65\x20\x70\x6c\x61" + "\x69\x6e\x74\x65\x78\x74\x20\x74\x6f\x20\x65\x6e\x63\x72\x79\x70" + "\x74\x20\x75\x73\x69\x6e\x67\x20\x53\x49\x56\x2d\x41\x45\x53"), + .ciphertext = (uint8_t *) + "\xa4\xff\xb8\x7f\xdb\xa9\x7c\x89\x44\xa6\x23\x25\xf1\x33\xb4\xe0" + "\x1c\xa5\x52\x76\xe2\x26\x1c\x1a\x1d\x1d\x42\x48\xd1\xda\x30\xba" + "\x52\xb9\xc8\xd7\x95\x5d\x65\xc8\xd2\xce\x6e\xb7\xe3\x67\xd0", + STR(iv, iv_size, + "\x02\x03\x04"), + .tag_size = 16, + .tag = (void *) + "\xf1\xdb\xa3\x3d\xe5\xb3\x36\x9e\x88\x3f\x67\xb6\xfc\x82\x3c\xee", + .tag_prepended = 1, + } +}; + +const struct cipher_aead_vectors_st aes256_siv_vectors[] = { + { + STR(key, key_size, + "\xc2\x7d\xf2\xfd\xae\xc3\x5d\x4a\x2a\x41\x2a\x50\xc3\xe8\xc4\x7d" + "\x2d\x56\x8e\x91\xa3\x8e\x54\x14\x8a\xbd\xc0\xb6\xe8\x6c\xaf\x87" + "\x69\x5c\x0a\x8a\xdf\x4c\x5f\x8e\xb2\xc6\xc8\xb1\x36\x52\x98\x64" + "\xf3\xb8\x4b\x3a\xe8\xe3\x67\x6c\xe7\x60\xc4\x61\xf3\xa1\x3e\x83"), + STR(auth, auth_size, + "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff" + "\xde\xad\xda\xda\xde\xad\xda\xda\xff\xee\xdd\xcc\xbb\xaa\x99\x88" + "\x77\x66\x55\x44\x33\x22\x11\x00"), + STR(plaintext, plaintext_size, + "\x74\x68\x69\x73\x20\x69\x73\x20\x73\x6f\x6d\x65\x20\x70\x6c\x61" + "\x69\x6e\x74\x65\x78\x74\x20\x74\x6f\x20\x65\x6e\x63\x72\x79\x70" + "\x74\x20\x75\x73\x69\x6e\x67\x20\x53\x49\x56\x2d\x41\x45\x53"), + .ciphertext = (uint8_t *) + "\x50\x93\x3d\xa8\x04\x7b\xc3\x06\xfa\xba\xf0\xc3\xd9\xfa\x84\x71" + "\xc7\x0a\x7d\xef\x39\xa2\xf9\x1d\x68\xa2\x02\x1c\x99\xac\x7e\x2a\x24" + "\x53\x5a\x13\x4b\xa2\x3e\xc1\x57\x87\xce\xbe\x5c\x53\xcc", + STR(iv, iv_size, + "\x09\xf9\x11\x02\x9d\x74\xe3\x5b\xd8\x41\x56\xc5\x63\x56\x88\xc0"), + .tag_size = 16, + .tag = (void *) + "\x5a\x97\x9b\x0d\xa5\x8f\xde\x80\x51\x62\x1a\xe6\xbf\x96\xfe\xda", + .tag_prepended = 1, + } +}; + const struct cipher_vectors_st chacha20_32_vectors[] = { /* RFC8439 */ { STR(key, key_size, @@ -1002,6 +1057,8 @@ static int test_cipher_aead_scatter(gnutls_cipher_algorithm_t cipher, int auth_iov_len; int iov_len; giovec_t iov[IOV_PARTS]; + const uint8_t *tag; + uint8_t *ciphertext; _gnutls_debug_log("running scatter (iovec) tests for: %s\n", gnutls_cipher_get_name(cipher)); @@ -1055,16 +1112,26 @@ static int test_cipher_aead_scatter(gnutls_cipher_algorithm_t cipher, (GNUTLS_E_SELF_TEST_ERROR); } - if (memcmp(tmp+vectors[i].plaintext_size, vectors[i].tag, tag_size) != 0) { + if (vectors[i].tag_prepended) + tag = tmp; + else + tag = tmp+vectors[i].plaintext_size; + + if (memcmp(tag, vectors[i].tag, tag_size) != 0) { _gnutls_debug_log ("%s test vector %d failed (tag)!\n", gnutls_cipher_get_name(cipher), i); return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } + if (vectors[i].tag_prepended) + ciphertext = tmp+vectors[i].tag_size; + else + ciphertext = tmp; + if (vectors[i].plaintext_size > 0) { if (memcmp - (tmp, vectors[i].ciphertext, + (ciphertext, vectors[i].ciphertext, vectors[i].plaintext_size) != 0) { _gnutls_debug_log ("%s test vector %d failed!\n", @@ -1134,16 +1201,26 @@ static int test_cipher_aead_scatter(gnutls_cipher_algorithm_t cipher, (GNUTLS_E_SELF_TEST_ERROR); } - if (memcmp(tmp+vectors[i].plaintext_size, vectors[i].tag, tag_size) != 0) { + if (vectors[i].tag_prepended) + tag = tmp; + else + tag = tmp+vectors[i].plaintext_size; + + if (memcmp(tag, vectors[i].tag, tag_size) != 0) { _gnutls_debug_log ("%s test vector %d failed (tag)!\n", gnutls_cipher_get_name(cipher), i); return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } + if (vectors[i].tag_prepended) + ciphertext = tmp+vectors[i].tag_size; + else + ciphertext = tmp; + if (vectors[i].plaintext_size > 0) { if (memcmp - (tmp, vectors[i].ciphertext, + (ciphertext, vectors[i].ciphertext, vectors[i].plaintext_size) != 0) { _gnutls_debug_log ("%s test vector %d failed!\n", @@ -1182,7 +1259,9 @@ static int test_cipher_aead(gnutls_cipher_algorithm_t cipher, uint8_t tmp2[384]; gnutls_datum_t key, iv; size_t s, s2; + const uint8_t *tag; unsigned tag_size; + uint8_t *ciphertext; _gnutls_debug_log("running tests for: %s\n", gnutls_cipher_get_name(cipher)); @@ -1231,16 +1310,26 @@ static int test_cipher_aead(gnutls_cipher_algorithm_t cipher, (GNUTLS_E_SELF_TEST_ERROR); } - if (memcmp(tmp+vectors[i].plaintext_size, vectors[i].tag, tag_size) != 0) { + if (vectors[i].tag_prepended) + tag = tmp; + else + tag = tmp+vectors[i].plaintext_size; + + if (memcmp(tag, vectors[i].tag, tag_size) != 0) { _gnutls_debug_log ("%s test vector %d failed (tag)!\n", gnutls_cipher_get_name(cipher), i); return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } + if (vectors[i].tag_prepended) + ciphertext = tmp+vectors[i].tag_size; + else + ciphertext = tmp; + if (vectors[i].plaintext_size > 0) { if (memcmp - (tmp, vectors[i].ciphertext, + (ciphertext, vectors[i].ciphertext, vectors[i].plaintext_size) != 0) { _gnutls_debug_log ("%s test vector %d failed!\n", @@ -1275,7 +1364,7 @@ static int test_cipher_aead(gnutls_cipher_algorithm_t cipher, /* test tag verification */ if (s > 0) { - tmp[0]++; + (*ciphertext)++; s2 = sizeof(tmp2); ret = @@ -1926,6 +2015,12 @@ int gnutls_cipher_self_test(unsigned flags, gnutls_cipher_algorithm_t cipher) CASE(GNUTLS_CIPHER_AES_256_XTS, test_cipher, aes256_xts_vectors); FALLTHROUGH; + NON_FIPS_CASE(GNUTLS_CIPHER_AES_128_SIV, test_cipher_aead, + aes128_siv_vectors); + FALLTHROUGH; + NON_FIPS_CASE(GNUTLS_CIPHER_AES_256_SIV, test_cipher_aead, + aes256_siv_vectors); + FALLTHROUGH; NON_FIPS_CASE(GNUTLS_CIPHER_CHACHA20_32, test_cipher, chacha20_32_vectors); FALLTHROUGH; diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index fdcf914f42..7d9870996a 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -137,6 +137,12 @@ extern "C" { * @GNUTLS_CIPHER_AES192_PGP_CFB: AES in CFB mode with 192-bit keys (placeholder - unsupported). * @GNUTLS_CIPHER_AES256_PGP_CFB: AES in CFB mode with 256-bit keys (placeholder - unsupported). * @GNUTLS_CIPHER_TWOFISH_PGP_CFB: Twofish in CFB mode (placeholder - unsupported). + * @GNUTLS_CIPHER_AES_128_SIV: AES in SIV mode with 128-bit key. + * @GNUTLS_CIPHER_AES_256_SIV: AES in SIV mode with 256-bit key. + * Note that the SIV ciphers can only be used with + * the AEAD interface, and the IV plays a role as + * the authentication tag while it is prepended to + * the cipher text. * * Enumeration of different symmetric encryption algorithms. */ @@ -178,6 +184,8 @@ typedef enum gnutls_cipher_algorithm { GNUTLS_CIPHER_GOST28147_TC26Z_CNT = 34, GNUTLS_CIPHER_CHACHA20_64 = 35, GNUTLS_CIPHER_CHACHA20_32 = 36, + GNUTLS_CIPHER_AES_128_SIV = 37, + GNUTLS_CIPHER_AES_256_SIV = 38, /* used only for PGP internals. Ignored in TLS/SSL */ diff --git a/lib/nettle/Makefile.am b/lib/nettle/Makefile.am index 9595aef532..936f20c6ad 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,12 +164,35 @@ 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 += \ - chacha/chacha-core-internal.c chacha/chacha-crypt.c \ - chacha/chacha-internal.h chacha/chacha-poly1305.c \ - chacha/chacha-poly1305.h chacha/chacha-set-key.c \ - chacha/chacha-set-nonce.c chacha/chacha.h \ - chacha/poly1305.h chacha/poly1305-internal.c \ - chacha/poly1305-internal.h + backport/chacha-core-internal.c backport/chacha-crypt.c \ + backport/chacha-internal.h backport/chacha-poly1305.c \ + backport/chacha-poly1305.h backport/chacha-set-key.c \ + backport/chacha-set-nonce.c backport/chacha.h \ + backport/poly1305.h backport/poly1305-internal.c \ + backport/poly1305-internal.h +endif + +if NEED_SIV +libcrypto_la_SOURCES += \ + backport/siv-cmac-aes128.c backport/siv-cmac-aes256.c \ + backport/siv-cmac.c backport/siv-cmac.h endif 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 35719357f4..70a6509f2b 100644 --- a/lib/nettle/cipher.c +++ b/lib/nettle/cipher.c @@ -49,15 +49,24 @@ #include <nettle/chacha.h> #include <nettle/chacha-poly1305.h> #else -#include "chacha/chacha.h" -#include "chacha/chacha-poly1305.h" +#include "chacha.h" +#include "chacha-poly1305.h" #endif #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 +#ifdef HAVE_NETTLE_SIV_CMAC_AES128_SET_KEY +#include <nettle/siv-cmac.h> +#else +#include "siv-cmac.h" +#endif #include <fips.h> struct nettle_cipher_ctx; @@ -253,6 +262,62 @@ _ccm_decrypt(struct nettle_cipher_ctx *ctx, } static void +_siv_cmac_aes128_encrypt_message(struct nettle_cipher_ctx *ctx, + size_t nonce_size, const void *nonce, + size_t auth_size, const void *auth, + size_t tag_size, + size_t length, uint8_t * dst, + const uint8_t * src) +{ + siv_cmac_aes128_encrypt_message((void*)ctx->ctx_ptr, + nonce_size, nonce, + auth_size, auth, + length, dst, src); +} + +static int +_siv_cmac_aes128_decrypt_message(struct nettle_cipher_ctx *ctx, + size_t nonce_size, const void *nonce, + size_t auth_size, const void *auth, + size_t tag_size, + size_t length, uint8_t * dst, + const uint8_t * src) +{ + return siv_cmac_aes128_decrypt_message((void*)ctx->ctx_ptr, + nonce_size, nonce, + auth_size, auth, + length, dst, src); +} + +static void +_siv_cmac_aes256_encrypt_message(struct nettle_cipher_ctx *ctx, + size_t nonce_size, const void *nonce, + size_t auth_size, const void *auth, + size_t tag_size, + size_t length, uint8_t * dst, + const uint8_t * src) +{ + siv_cmac_aes256_encrypt_message((void*)ctx->ctx_ptr, + nonce_size, nonce, + auth_size, auth, + length, dst, src); +} + +static int +_siv_cmac_aes256_decrypt_message(struct nettle_cipher_ctx *ctx, + size_t nonce_size, const void *nonce, + size_t auth_size, const void *auth, + size_t tag_size, + size_t length, uint8_t * dst, + const uint8_t * src) +{ + return siv_cmac_aes256_decrypt_message((void*)ctx->ctx_ptr, + nonce_size, nonce, + auth_size, auth, + length, dst, src); +} + +static void _chacha_set_nonce(struct chacha_ctx *ctx, size_t length, const uint8_t *nonce) { @@ -861,6 +926,28 @@ static const struct nettle_cipher_st builtin_ciphers[] = { .set_decrypt_key = (nettle_set_key_func*)_xts_aes256_set_decrypt_key, .max_iv_size = AES_BLOCK_SIZE, }, + { .algo = GNUTLS_CIPHER_AES_128_SIV, + .block_size = SIV_BLOCK_SIZE, + .key_size = SIV_CMAC_AES128_KEY_SIZE, + + .ctx_size = sizeof(struct siv_cmac_aes128_ctx), + .aead_encrypt = (aead_encrypt_func)_siv_cmac_aes128_encrypt_message, + .aead_decrypt = (aead_decrypt_func)_siv_cmac_aes128_decrypt_message, + .set_encrypt_key = (nettle_set_key_func*)siv_cmac_aes128_set_key, + .set_decrypt_key = (nettle_set_key_func*)siv_cmac_aes128_set_key, + .max_iv_size = SIV_DIGEST_SIZE, + }, + { .algo = GNUTLS_CIPHER_AES_256_SIV, + .block_size = SIV_BLOCK_SIZE, + .key_size = SIV_CMAC_AES256_KEY_SIZE, + + .ctx_size = sizeof(struct siv_cmac_aes256_ctx), + .aead_encrypt = (aead_encrypt_func)_siv_cmac_aes256_encrypt_message, + .aead_decrypt = (aead_decrypt_func)_siv_cmac_aes256_decrypt_message, + .set_encrypt_key = (nettle_set_key_func*)siv_cmac_aes256_set_key, + .set_decrypt_key = (nettle_set_key_func*)siv_cmac_aes256_set_key, + .max_iv_size = SIV_DIGEST_SIZE, + }, }; static int wrap_nettle_cipher_exists(gnutls_cipher_algorithm_t algo) 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 */ |