summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Baryshkov <dbaryshkov@gmail.com>2020-05-04 14:40:07 +0000
committerDmitry Baryshkov <dbaryshkov@gmail.com>2020-05-04 14:40:07 +0000
commitd51399272886d909fbc40f2c5e26db3e87a45a0a (patch)
tree5afe042bbd3dc91d4c11e49c06bf0998cdb1e1a5
parentcb5171409a8e8e9b6127e0acaa0136411b46fcd0 (diff)
parentd28e3b5a886f7f5a6ee0170be15143a716e641f5 (diff)
downloadgnutls-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--.gitignore2
-rw-r--r--NEWS6
-rw-r--r--bootstrap.conf2
-rw-r--r--configure.ac20
-rwxr-xr-xdevel/import-from-nettle.sh (renamed from devel/import-chacha-from-nettle.sh)62
-rw-r--r--devel/libdane-latest-x86_64.abi4
-rw-r--r--devel/libgnutls-latest-x86_64.abi2
-rw-r--r--lib/algorithms/ciphers.c18
-rw-r--r--lib/crypto-selftests.c109
-rw-r--r--lib/includes/gnutls/gnutls.h.in8
-rw-r--r--lib/nettle/Makefile.am41
-rw-r--r--lib/nettle/backport/cfb8.c123
-rw-r--r--lib/nettle/backport/cfb8.h100
-rw-r--r--lib/nettle/backport/cmac.c217
-rw-r--r--lib/nettle/backport/cmac.h139
-rw-r--r--lib/nettle/backport/xts.c273
-rw-r--r--lib/nettle/backport/xts.h122
-rw-r--r--lib/nettle/cipher.c93
-rw-r--r--lib/nettle/int/block8.h61
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
diff --git a/NEWS b/NEWS
index 50cb2253a5..fe1c6035af 100644
--- a/NEWS
+++ b/NEWS
@@ -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 */