diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj b/builds/msvc/vs2010/libsodium/libsodium.vcxproj index 117e28d8..e3402320 100644 --- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj @@ -174,6 +174,9 @@ + + + @@ -228,6 +231,7 @@ + diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters index dc96b0a7..17c6ab39 100644 --- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters @@ -315,6 +315,15 @@ crypto_aead\xchacha20poly1305\sodium + + crypto_aead\aegis128l + + + crypto_aead\aegis128l\aesni + + + crypto_aead\aegis128l\armcrypto + crypto_aead\aegis256 @@ -473,6 +482,9 @@ include\sodium + + include\sodium + include\sodium @@ -760,6 +772,15 @@ {a6837e41-3751-38c9-bb90-dd59d5f4af7b} + + {9e2a023d-fef1-3231-90ba-9a0ffc9bc9ab} + + + {77ed2f29-bed2-35a2-acce-0c09b665d57b} + + + {2abca274-f068-3cf1-bd4e-5bfc5ee81de6} + {6897a4cc-0091-3970-b712-c0ac75c16b67} diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj b/builds/msvc/vs2012/libsodium/libsodium.vcxproj index 2cdc40eb..837f1063 100644 --- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj @@ -174,6 +174,9 @@ + + + @@ -228,6 +231,7 @@ + diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters index dc96b0a7..17c6ab39 100644 --- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters @@ -315,6 +315,15 @@ crypto_aead\xchacha20poly1305\sodium + + crypto_aead\aegis128l + + + crypto_aead\aegis128l\aesni + + + crypto_aead\aegis128l\armcrypto + crypto_aead\aegis256 @@ -473,6 +482,9 @@ include\sodium + + include\sodium + include\sodium @@ -760,6 +772,15 @@ {a6837e41-3751-38c9-bb90-dd59d5f4af7b} + + {9e2a023d-fef1-3231-90ba-9a0ffc9bc9ab} + + + {77ed2f29-bed2-35a2-acce-0c09b665d57b} + + + {2abca274-f068-3cf1-bd4e-5bfc5ee81de6} + {6897a4cc-0091-3970-b712-c0ac75c16b67} diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj b/builds/msvc/vs2013/libsodium/libsodium.vcxproj index b5c9f6e0..d29a0c6c 100644 --- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj @@ -174,6 +174,9 @@ + + + @@ -228,6 +231,7 @@ + diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters index dc96b0a7..17c6ab39 100644 --- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters @@ -315,6 +315,15 @@ crypto_aead\xchacha20poly1305\sodium + + crypto_aead\aegis128l + + + crypto_aead\aegis128l\aesni + + + crypto_aead\aegis128l\armcrypto + crypto_aead\aegis256 @@ -473,6 +482,9 @@ include\sodium + + include\sodium + include\sodium @@ -760,6 +772,15 @@ {a6837e41-3751-38c9-bb90-dd59d5f4af7b} + + {9e2a023d-fef1-3231-90ba-9a0ffc9bc9ab} + + + {77ed2f29-bed2-35a2-acce-0c09b665d57b} + + + {2abca274-f068-3cf1-bd4e-5bfc5ee81de6} + {6897a4cc-0091-3970-b712-c0ac75c16b67} diff --git a/builds/msvc/vs2015/libsodium/libsodium.vcxproj b/builds/msvc/vs2015/libsodium/libsodium.vcxproj index c43fa443..e581c78a 100644 --- a/builds/msvc/vs2015/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2015/libsodium/libsodium.vcxproj @@ -174,6 +174,9 @@ + + + @@ -228,6 +231,7 @@ + diff --git a/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters index dc96b0a7..17c6ab39 100644 --- a/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters @@ -315,6 +315,15 @@ crypto_aead\xchacha20poly1305\sodium + + crypto_aead\aegis128l + + + crypto_aead\aegis128l\aesni + + + crypto_aead\aegis128l\armcrypto + crypto_aead\aegis256 @@ -473,6 +482,9 @@ include\sodium + + include\sodium + include\sodium @@ -760,6 +772,15 @@ {a6837e41-3751-38c9-bb90-dd59d5f4af7b} + + {9e2a023d-fef1-3231-90ba-9a0ffc9bc9ab} + + + {77ed2f29-bed2-35a2-acce-0c09b665d57b} + + + {2abca274-f068-3cf1-bd4e-5bfc5ee81de6} + {6897a4cc-0091-3970-b712-c0ac75c16b67} diff --git a/builds/msvc/vs2017/libsodium/libsodium.vcxproj b/builds/msvc/vs2017/libsodium/libsodium.vcxproj index b1887a3c..55168ad8 100644 --- a/builds/msvc/vs2017/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2017/libsodium/libsodium.vcxproj @@ -174,6 +174,9 @@ + + + @@ -228,6 +231,7 @@ + diff --git a/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters index dc96b0a7..17c6ab39 100644 --- a/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters @@ -315,6 +315,15 @@ crypto_aead\xchacha20poly1305\sodium + + crypto_aead\aegis128l + + + crypto_aead\aegis128l\aesni + + + crypto_aead\aegis128l\armcrypto + crypto_aead\aegis256 @@ -473,6 +482,9 @@ include\sodium + + include\sodium + include\sodium @@ -760,6 +772,15 @@ {a6837e41-3751-38c9-bb90-dd59d5f4af7b} + + {9e2a023d-fef1-3231-90ba-9a0ffc9bc9ab} + + + {77ed2f29-bed2-35a2-acce-0c09b665d57b} + + + {2abca274-f068-3cf1-bd4e-5bfc5ee81de6} + {6897a4cc-0091-3970-b712-c0ac75c16b67} diff --git a/builds/msvc/vs2019/libsodium/libsodium.vcxproj b/builds/msvc/vs2019/libsodium/libsodium.vcxproj index 8d43cd5e..c5549a12 100644 --- a/builds/msvc/vs2019/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2019/libsodium/libsodium.vcxproj @@ -174,6 +174,9 @@ + + + @@ -228,6 +231,7 @@ + diff --git a/builds/msvc/vs2019/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2019/libsodium/libsodium.vcxproj.filters index dc96b0a7..17c6ab39 100644 --- a/builds/msvc/vs2019/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2019/libsodium/libsodium.vcxproj.filters @@ -315,6 +315,15 @@ crypto_aead\xchacha20poly1305\sodium + + crypto_aead\aegis128l + + + crypto_aead\aegis128l\aesni + + + crypto_aead\aegis128l\armcrypto + crypto_aead\aegis256 @@ -473,6 +482,9 @@ include\sodium + + include\sodium + include\sodium @@ -760,6 +772,15 @@ {a6837e41-3751-38c9-bb90-dd59d5f4af7b} + + {9e2a023d-fef1-3231-90ba-9a0ffc9bc9ab} + + + {77ed2f29-bed2-35a2-acce-0c09b665d57b} + + + {2abca274-f068-3cf1-bd4e-5bfc5ee81de6} + {6897a4cc-0091-3970-b712-c0ac75c16b67} diff --git a/dist-build/emscripten-symbols.def b/dist-build/emscripten-symbols.def index be849ec4..22ef6319 100644 --- a/dist-build/emscripten-symbols.def +++ b/dist-build/emscripten-symbols.def @@ -1,3 +1,14 @@ +_crypto_aead_aegis128l_abytes 0 0 +_crypto_aead_aegis128l_decrypt 0 0 +_crypto_aead_aegis128l_decrypt_detached 0 0 +_crypto_aead_aegis128l_encrypt 0 0 +_crypto_aead_aegis128l_encrypt_detached 0 0 +_crypto_aead_aegis128l_is_available 0 0 +_crypto_aead_aegis128l_keybytes 0 0 +_crypto_aead_aegis128l_keygen 0 0 +_crypto_aead_aegis128l_messagebytes_max 0 0 +_crypto_aead_aegis128l_npubbytes 0 0 +_crypto_aead_aegis128l_nsecbytes 0 0 _crypto_aead_aegis256_abytes 0 0 _crypto_aead_aegis256_decrypt 0 0 _crypto_aead_aegis256_decrypt_detached 0 0 diff --git a/libsodium.vcxproj b/libsodium.vcxproj index 749ada97..12e90dd1 100644 --- a/libsodium.vcxproj +++ b/libsodium.vcxproj @@ -412,6 +412,9 @@ + + + @@ -466,6 +469,7 @@ + diff --git a/libsodium.vcxproj.filters b/libsodium.vcxproj.filters index 9de5c18a..d5226704 100644 --- a/libsodium.vcxproj.filters +++ b/libsodium.vcxproj.filters @@ -306,6 +306,15 @@ Source Files + + Source Files + + + Source Files + + + Source Files + Source Files @@ -464,6 +473,9 @@ Header Files + + Header Files + Header Files diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index 2fd7ebbd..ebb2ce9a 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -2,6 +2,7 @@ lib_LTLIBRARIES = \ libsodium.la libsodium_la_SOURCES = \ + crypto_aead/aegis128l/aead_aegis128l.c \ crypto_aead/aegis256/aead_aegis256.c \ crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c \ crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c \ @@ -219,6 +220,7 @@ libarmcrypto_la_LDFLAGS = $(libsodium_la_LDFLAGS) libarmcrypto_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \ @CFLAGS_ARMCRYPTO@ libarmcrypto_la_SOURCES = \ + crypto_aead/aegis128l/armcrypto/aead_aegis128l_armcrypto.c \ crypto_aead/aegis256/armcrypto/aead_aegis256_armcrypto.c libaesni_la_LDFLAGS = $(libsodium_la_LDFLAGS) @@ -226,6 +228,7 @@ libaesni_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \ @CFLAGS_SSE2@ @CFLAGS_SSSE3@ @CFLAGS_AESNI@ @CFLAGS_PCLMUL@ libaesni_la_SOURCES = \ crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c \ + crypto_aead/aegis128l/aesni/aead_aegis128l_aesni.c \ crypto_aead/aegis256/aesni/aead_aegis256_aesni.c libsse2_la_LDFLAGS = $(libsodium_la_LDFLAGS) diff --git a/src/libsodium/crypto_aead/aegis128l/aead_aegis128l.c b/src/libsodium/crypto_aead/aegis128l/aead_aegis128l.c new file mode 100644 index 00000000..796b1596 --- /dev/null +++ b/src/libsodium/crypto_aead/aegis128l/aead_aegis128l.c @@ -0,0 +1,99 @@ + +#include +#include + +#include "crypto_aead_aegis128l.h" +#include "private/common.h" +#include "randombytes.h" + +size_t +crypto_aead_aegis128l_keybytes(void) +{ + return crypto_aead_aegis128l_KEYBYTES; +} + +size_t +crypto_aead_aegis128l_nsecbytes(void) +{ + return crypto_aead_aegis128l_NSECBYTES; +} + +size_t +crypto_aead_aegis128l_npubbytes(void) +{ + return crypto_aead_aegis128l_NPUBBYTES; +} + +size_t +crypto_aead_aegis128l_abytes(void) +{ + return crypto_aead_aegis128l_ABYTES; +} + +size_t +crypto_aead_aegis128l_messagebytes_max(void) +{ + return crypto_aead_aegis128l_MESSAGEBYTES_MAX; +} + +void +crypto_aead_aegis128l_keygen(unsigned char k[crypto_aead_aegis128l_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_aegis128l_KEYBYTES); +} + +#if !((defined(HAVE_TMMINTRIN_H) && defined(HAVE_WMMINTRIN_H)) || \ + defined(HAVE_ARMCRYPTO)) + +#ifndef ENOSYS +# define ENOSYS ENXIO +#endif + +int +crypto_aead_aegis128l_encrypt_detached(unsigned char *c, unsigned char *mac, + unsigned long long *maclen_p, const unsigned char *m, + unsigned long long mlen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aegis128l_encrypt(unsigned char *c, unsigned long long *clen_p, const unsigned char *m, + unsigned long long mlen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aegis128l_decrypt_detached(unsigned char *m, unsigned char *nsec, const unsigned char *c, + unsigned long long clen, const unsigned char *mac, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aegis128l_decrypt(unsigned char *m, unsigned long long *mlen_p, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aegis128l_is_available(void) +{ + return 0; +} + +#endif diff --git a/src/libsodium/crypto_aead/aegis128l/aesni/aead_aegis128l_aesni.c b/src/libsodium/crypto_aead/aegis128l/aesni/aead_aegis128l_aesni.c new file mode 100644 index 00000000..ff44ecc4 --- /dev/null +++ b/src/libsodium/crypto_aead/aegis128l/aesni/aead_aegis128l_aesni.c @@ -0,0 +1,298 @@ +/* + * AEGIS-128l based on https://bench.cr.yp.to/supercop/supercop-20200409.tar.xz + */ + +#include +#include +#include + +#include "core.h" +#include "crypto_aead_aegis128l.h" +#include "crypto_verify_16.h" +#include "export.h" +#include "randombytes.h" +#include "runtime.h" +#include "utils.h" + +#include "private/common.h" +#include "private/sse2_64_32.h" + +#if defined(HAVE_TMMINTRIN_H) && defined(HAVE_WMMINTRIN_H) + +#ifdef __GNUC__ +# pragma GCC target("ssse3") +# pragma GCC target("aes") +#endif + +#include +#include + +static inline void +crypto_aead_aegis128l_update(__m128i *const state, const __m128i d1, const __m128i d2) +{ + __m128i tmp, tmp2; + + tmp = state[7]; + state[7] = _mm_aesenc_si128(state[6], state[7]); + state[6] = _mm_aesenc_si128(state[5], state[6]); + state[5] = _mm_aesenc_si128(state[4], state[5]); + state[4] = _mm_aesenc_si128(state[3], state[4]); + state[3] = _mm_aesenc_si128(state[2], state[3]); + state[2] = _mm_aesenc_si128(state[1], state[2]); + state[1] = _mm_aesenc_si128(state[0], state[1]); + state[0] = _mm_aesenc_si128(tmp, state[0]); + + state[0] = _mm_xor_si128(state[0], d1); + state[4] = _mm_xor_si128(state[4], d2); +} + +static void +crypto_aead_aegis128l_init(const unsigned char *key, const unsigned char *iv, __m128i *const state) +{ + const __m128i c1 = _mm_set_epi8(0xdd, 0x28, 0xb5, 0x73, 0x42, 0x31, 0x11, 0x20, 0xf1, 0x2f, 0xc2, 0x6d, + 0x55, 0x18, 0x3d, 0xdb); + const __m128i c2 = _mm_set_epi8(0x62, 0x79, 0xe9, 0x90, 0x59, 0x37, 0x22, 0x15, 0x0d, 0x08, 0x05, 0x03, + 0x02, 0x01, 0x01, 0x00); + __m128i k1, k2; + int i; + + k1 = _mm_loadu_si128((__m128i *) key); + k2 = _mm_xor_si128(k1, _mm_loadu_si128((__m128i *) iv)); + + state[0] = k2; + state[1] = c1; + state[2] = c2; + state[3] = c1; + state[4] = k2; + state[5] = _mm_xor_si128(k1, c2); + state[6] = _mm_xor_si128(k1, c1); + state[7] = _mm_xor_si128(k1, c2); + for (i = 0; i < 10; i++) { + crypto_aead_aegis128l_update(state, k1, k2); + } +} + +static void +crypto_aead_aegis128l_mac(unsigned char *mac, unsigned long long mlen, unsigned long long adlen, + __m128i *const state) +{ + __m128i tmp; + int i; + + tmp = _mm_set_epi64x(mlen << 3, adlen << 3); + tmp = _mm_xor_si128(tmp, state[2]); + + for (i = 0; i < 7; i++) { + crypto_aead_aegis128l_update(state, tmp, tmp); + } + + tmp = _mm_xor_si128(state[6], state[5]); + tmp = _mm_xor_si128(tmp, state[4]); + tmp = _mm_xor_si128(tmp, state[3]); + tmp = _mm_xor_si128(tmp, state[2]); + tmp = _mm_xor_si128(tmp, state[1]); + tmp = _mm_xor_si128(tmp, state[0]); + + _mm_storeu_si128((__m128i *) mac, tmp); +} + +static void +crypto_aead_aegis128l_enc(unsigned char *const dst, const unsigned char *const src, + __m128i *const state) +{ + __m128i msg0, msg1; + __m128i tmp0, tmp1; + + msg0 = _mm_loadu_si128((__m128i *) src); + msg1 = _mm_loadu_si128((__m128i *) (src + 16)); + tmp0 = _mm_xor_si128(msg0, state[6]); + tmp0 = _mm_xor_si128(tmp0, state[1]); + tmp1 = _mm_xor_si128(msg1, state[2]); + tmp1 = _mm_xor_si128(tmp1, state[5]); + tmp0 = _mm_xor_si128(tmp0, _mm_and_si128(state[2], state[3])); + tmp1 = _mm_xor_si128(tmp1, _mm_and_si128(state[6], state[7])); + _mm_storeu_si128((__m128i *) dst, tmp0); + _mm_storeu_si128((__m128i *) (dst + 16), tmp1); + + crypto_aead_aegis128l_update(state, msg0, msg1); +} + +static void +crypto_aead_aegis128l_dec(unsigned char *const dst, const unsigned char *const src, + __m128i *const state) +{ + __m128i msg0, msg1; + + msg0 = _mm_loadu_si128((__m128i *) src); + msg1 = _mm_loadu_si128((__m128i *) (src + 16)); + msg0 = _mm_xor_si128(msg0, state[6]); + msg0 = _mm_xor_si128(msg0, state[1]); + msg1 = _mm_xor_si128(msg1, state[2]); + msg1 = _mm_xor_si128(msg1, state[5]); + msg0 = _mm_xor_si128(msg0, _mm_and_si128(state[2], state[3])); + msg1 = _mm_xor_si128(msg1, _mm_and_si128(state[6], state[7])); + _mm_storeu_si128((__m128i *) dst, msg0); + _mm_storeu_si128((__m128i *) (dst + 16), msg1); + + crypto_aead_aegis128l_update(state, msg0, msg1); +} + +int +crypto_aead_aegis128l_encrypt_detached(unsigned char *c, unsigned char *mac, + unsigned long long *maclen_p, const unsigned char *m, + unsigned long long mlen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + __m128i state[8]; + CRYPTO_ALIGN(16) unsigned char src[32]; + CRYPTO_ALIGN(16) unsigned char dst[32]; + unsigned long long i; + + (void) nsec; + crypto_aead_aegis128l_init(k, npub, state); + + for (i = 0ULL; i + 32ULL <= adlen; i += 32ULL) { + crypto_aead_aegis128l_enc(dst, ad + i, state); + } + if (adlen & 0x1f) { + memset(src, 0, 32); + memcpy(src, ad + i, adlen & 0x1f); + crypto_aead_aegis128l_enc(dst, src, state); + } + for (i = 0ULL; i + 32ULL <= mlen; i += 32ULL) { + crypto_aead_aegis128l_enc(c + i, m + i, state); + } + if (mlen & 0x1f) { + memset(src, 0, 32); + memcpy(src, m + i, mlen & 0x1f); + crypto_aead_aegis128l_enc(dst, src, state); + memcpy(c + i, dst, mlen & 0x1f); + } + + crypto_aead_aegis128l_mac(mac, mlen, adlen, state); + sodium_memzero(state, sizeof state); + sodium_memzero(src, sizeof src); + sodium_memzero(dst, sizeof dst); + + if (maclen_p != NULL) { + *maclen_p = 16ULL; + } + return 0; +} + +int +crypto_aead_aegis128l_encrypt(unsigned char *c, unsigned long long *clen_p, const unsigned char *m, + unsigned long long mlen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + if (mlen > crypto_aead_aegis128l_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + ret = crypto_aead_aegis128l_encrypt_detached(c, c + mlen, NULL, m, mlen, + ad, adlen, nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + 16ULL; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_aegis128l_decrypt_detached(unsigned char *m, unsigned char *nsec, const unsigned char *c, + unsigned long long clen, const unsigned char *mac, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, const unsigned char *k) +{ + __m128i state[8]; + CRYPTO_ALIGN(16) unsigned char src[32]; + CRYPTO_ALIGN(16) unsigned char dst[32]; + CRYPTO_ALIGN(16) unsigned char computed_mac[16]; + unsigned long long i; + unsigned long long mlen; + int ret; + + (void) nsec; + mlen = clen; + crypto_aead_aegis128l_init(k, npub, state); + + for (i = 0ULL; i + 32ULL <= adlen; i += 32ULL) { + crypto_aead_aegis128l_enc(dst, ad + i, state); + } + if (adlen & 0x1f) { + memset(src, 0, 32); + memcpy(src, ad + i, adlen & 0x1f); + crypto_aead_aegis128l_enc(dst, src, state); + } + if (m != NULL) { + for (i = 0ULL; i + 32ULL <= mlen; i += 32ULL) { + crypto_aead_aegis128l_dec(m + i, c + i, state); + } + } else { + for (i = 0ULL; i + 32ULL <= mlen; i += 32ULL) { + crypto_aead_aegis128l_dec(dst, c + i, state); + } + } + if (mlen & 0x1f) { + memset(src, 0, 32); + memcpy(src, c + i, mlen & 0x1f); + crypto_aead_aegis128l_dec(dst, src, state); + if (m != NULL) { + memcpy(m + i, dst, mlen & 0x1f); + } + memset(dst, 0, mlen & 0x1f); + state[0] = _mm_xor_si128(state[0], _mm_loadu_si128((__m128i *) dst)); + state[4] = _mm_xor_si128(state[4], _mm_loadu_si128((__m128i *) (dst + 16))); + } + + crypto_aead_aegis128l_mac(computed_mac, mlen, adlen, state); + sodium_memzero(state, sizeof state); + sodium_memzero(src, sizeof src); + sodium_memzero(dst, sizeof dst); + ret = crypto_verify_16(computed_mac, mac); + sodium_memzero(computed_mac, sizeof computed_mac); + if (m == NULL) { + return ret; + } + if (ret != 0) { + memset(m, 0, mlen); + return -1; + } + return 0; +} + +int +crypto_aead_aegis128l_decrypt(unsigned char *m, unsigned long long *mlen_p, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= 16ULL) { + ret = crypto_aead_aegis128l_decrypt_detached + (m, nsec, c, clen - 16ULL, c + clen - 16ULL, ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - 16ULL; + } + *mlen_p = mlen; + } + return ret; +} + +int +crypto_aead_aegis128l_is_available(void) +{ + return sodium_runtime_has_aesni(); +} + +#endif diff --git a/src/libsodium/crypto_aead/aegis128l/armcrypto/aead_aegis128l_armcrypto.c b/src/libsodium/crypto_aead/aegis128l/armcrypto/aead_aegis128l_armcrypto.c new file mode 100644 index 00000000..8e86ed6e --- /dev/null +++ b/src/libsodium/crypto_aead/aegis128l/armcrypto/aead_aegis128l_armcrypto.c @@ -0,0 +1,301 @@ +#include +#include +#include + +#include "core.h" +#include "crypto_aead_aegis128l.h" +#include "crypto_verify_16.h" +#include "export.h" +#include "randombytes.h" +#include "runtime.h" +#include "utils.h" + +#include "private/common.h" + +#ifdef HAVE_ARMCRYPTO + +# include + +static inline void +crypto_aead_aegis128l_update(uint8x16_t *const state, + const uint8x16_t d1, const uint8x16_t d2) +{ + const uint8x16_t zero = vmovq_n_u8(0); + uint8x16_t tmp, tmp2; + + tmp = state[7]; + state[7] = veorq_u8(vaesmcq_u8(vaeseq_u8(state[6], zero)), state[7]); + state[6] = veorq_u8(vaesmcq_u8(vaeseq_u8(state[5], zero)), state[6]); + state[5] = veorq_u8(vaesmcq_u8(vaeseq_u8(state[4], zero)), state[5]); + state[4] = veorq_u8(vaesmcq_u8(vaeseq_u8(state[3], zero)), state[4]); + state[3] = veorq_u8(vaesmcq_u8(vaeseq_u8(state[2], zero)), state[3]); + state[2] = veorq_u8(vaesmcq_u8(vaeseq_u8(state[1], zero)), state[2]); + state[1] = veorq_u8(vaesmcq_u8(vaeseq_u8(state[0], zero)), state[1]); + state[0] = veorq_u8(vaesmcq_u8(vaeseq_u8(tmp, zero)), state[0]); + + state[0] = veorq_u8(state[0], d1); + state[4] = veorq_u8(state[4], d2); +} + +static void +crypto_aead_aegis128l_init(const unsigned char *key, const unsigned char *iv, + uint8x16_t *const state) +{ + static CRYPTO_ALIGN(16) const unsigned char c1_[] = { + 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, + 0x73, 0xb5, 0x28, 0xdd + }; + static CRYPTO_ALIGN(16) const unsigned char c2_[] = { + 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, + 0x90, 0xe9, 0x79, 0x62 + }; + const uint8x16_t c1 = vld1q_u8(c1_); + const uint8x16_t c2 = vld1q_u8(c2_); + uint8x16_t k1, k2; + int i; + + k1 = vld1q_u8(key); + k2 = veorq_u8(k1, vld1q_u8(iv)); + + state[0] = k2; + state[1] = c1; + state[2] = c2; + state[3] = c1; + state[4] = k2; + state[5] = veorq_u8(k1, c2); + state[6] = veorq_u8(k1, c1); + state[7] = veorq_u8(k1, c2); + for (i = 0; i < 10; i++) { + crypto_aead_aegis128l_update(state, k1, k2); + } +} + +static void +crypto_aead_aegis128l_mac(unsigned char *mac, unsigned long long mlen, + unsigned long long adlen, uint8x16_t *const state) +{ + uint8x16_t tmp; + int i; + + tmp = vreinterpretq_u8_u64(vsetq_lane_u64(mlen << 3, + vmovq_n_u64(adlen << 3), 1)); + tmp = veorq_u8(tmp, state[2]); + + for (i = 0; i < 7; i++) { + crypto_aead_aegis128l_update(state, tmp, tmp); + } + + tmp = veorq_u8(state[6], state[5]); + tmp = veorq_u8(tmp, state[5]); + tmp = veorq_u8(tmp, state[4]); + tmp = veorq_u8(tmp, state[3]); + tmp = veorq_u8(tmp, state[2]); + tmp = veorq_u8(tmp, state[1]); + tmp = veorq_u8(tmp, state[0]); + + vst1q_u8(mac, tmp); +} + +static void +crypto_aead_aegis128l_enc(unsigned char *const dst, + const unsigned char *const src, + uint8x16_t *const state) +{ + uint8x16_t msg0, msg1; + uint8x16_t tmp0, tmp1; + + msg0 = vld1q_u8(src); + msg1 = vld1q_u8(src + 16); + tmp0 = veorq_u8(msg0, state[6]); + tmp0 = veorq_u8(tmp0, state[1]); + tmp1 = veorq_u8(msg1, state[2]); + tmp1 = veorq_u8(tmp1, state[5]); + tmp0 = veorq_u8(tmp0, vandq_u8(state[2], state[3])); + tmp1 = veorq_u8(tmp1, vandq_u8(state[6], state[7])); + vst1q_u8(dst, tmp0); + vst1q_u8(dst + 16, tmp1); + + crypto_aead_aegis128l_update(state, msg0, msg1); +} + + +static void +crypto_aead_aegis128l_dec(unsigned char *const dst, + const unsigned char *const src, + uint8x16_t *const state) +{ + uint8x16_t msg0, msg1; + + msg0 = vld1q_u8(src); + msg1 = vld1q_u8(src + 16); + msg0 = veorq_u8(msg0, state[6]); + msg0 = veorq_u8(msg0, state[1]); + msg1 = veorq_u8(msg1, state[2]); + msg1 = veorq_u8(msg1, state[5]); + msg0 = veorq_u8(msg0, vandq_u8(state[2], state[3])); + msg1 = veorq_u8(msg1, vandq_u8(state[6], state[7])); + vst1q_u8(dst, msg0); + vst1q_u8(dst + 16, msg1); + + crypto_aead_aegis128l_update(state, msg0, msg1); +} + +int +crypto_aead_aegis128l_encrypt_detached(unsigned char *c, unsigned char *mac, + unsigned long long *maclen_p, const unsigned char *m, + unsigned long long mlen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + uint8x16_t state[8]; + CRYPTO_ALIGN(16) unsigned char src[32]; + CRYPTO_ALIGN(16) unsigned char dst[32]; + unsigned long long i; + + (void) nsec; + crypto_aead_aegis128l_init(k, npub, state); + + for (i = 0ULL; i + 32ULL <= adlen; i += 32ULL) { + crypto_aead_aegis128l_enc(dst, ad + i, state); + } + if (adlen & 0x1f) { + memset(src, 0, 32); + memcpy(src, ad + i, adlen & 0x1f); + crypto_aead_aegis128l_enc(dst, src, state); + } + for (i = 0ULL; i + 32ULL <= mlen; i += 32ULL) { + crypto_aead_aegis128l_enc(c + i, m + i, state); + } + if (mlen & 0x1f) { + memset(src, 0, 32); + memcpy(src, m + i, mlen & 0x1f); + crypto_aead_aegis128l_enc(dst, src, state); + memcpy(c + i, dst, mlen & 0x1f); + } + + crypto_aead_aegis128l_mac(mac, mlen, adlen, state); + sodium_memzero(state, sizeof state); + sodium_memzero(src, sizeof src); + sodium_memzero(dst, sizeof dst); + + if (maclen_p != NULL) { + *maclen_p = 16ULL; + } + return 0; +} + +int +crypto_aead_aegis128l_encrypt(unsigned char *c, unsigned long long *clen_p, const unsigned char *m, + unsigned long long mlen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + if (mlen > crypto_aead_aegis128l_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + ret = crypto_aead_aegis128l_encrypt_detached(c, c + mlen, NULL, m, mlen, + ad, adlen, nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + 16ULL; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_aegis128l_decrypt_detached(unsigned char *m, unsigned char *nsec, const unsigned char *c, + unsigned long long clen, const unsigned char *mac, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, const unsigned char *k) +{ + uint8x16_t state[8]; + CRYPTO_ALIGN(16) unsigned char src[32]; + CRYPTO_ALIGN(16) unsigned char dst[32]; + CRYPTO_ALIGN(16) unsigned char computed_mac[16]; + unsigned long long i; + unsigned long long mlen; + int ret; + + (void) nsec; + mlen = clen; + crypto_aead_aegis128l_init(k, npub, state); + + for (i = 0ULL; i + 32ULL <= adlen; i += 32ULL) { + crypto_aead_aegis128l_enc(dst, ad + i, state); + } + if (adlen & 0x1f) { + memset(src, 0, 32); + memcpy(src, ad + i, adlen & 0x1f); + crypto_aead_aegis128l_enc(dst, src, state); + } + if (m != NULL) { + for (i = 0ULL; i + 32ULL <= mlen; i += 32ULL) { + crypto_aead_aegis128l_dec(m + i, c + i, state); + } + } else { + for (i = 0ULL; i + 32ULL <= mlen; i += 32ULL) { + crypto_aead_aegis128l_dec(dst, c + i, state); + } + } + if (mlen & 0x1f) { + memset(src, 0, 32); + memcpy(src, c + i, mlen & 0x1f); + crypto_aead_aegis128l_dec(dst, src, state); + if (m != NULL) { + memcpy(m + i, dst, mlen & 0x1f); + } + memset(dst, 0, mlen & 0x1f); + state[0] = veorq_u8(state[0], vld1q_u8(dst)); + state[4] = veorq_u8(state[4], vld1q_u8(dst + 16)); + } + + crypto_aead_aegis128l_mac(computed_mac, mlen, adlen, state); + sodium_memzero(state, sizeof state); + sodium_memzero(src, sizeof src); + sodium_memzero(dst, sizeof dst); + ret = crypto_verify_16(computed_mac, mac); + sodium_memzero(computed_mac, sizeof computed_mac); + if (m == NULL) { + return ret; + } + if (ret != 0) { + memset(m, 0, mlen); + return -1; + } + return 0; +} + +int +crypto_aead_aegis128l_decrypt(unsigned char *m, unsigned long long *mlen_p, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= 16ULL) { + ret = crypto_aead_aegis128l_decrypt_detached + (m, nsec, c, clen - 16ULL, c + clen - 16ULL, ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - 16ULL; + } + *mlen_p = mlen; + } + return ret; +} + +int +crypto_aead_aegis128l_is_available(void) +{ + return sodium_runtime_has_armcrypto(); +} + +#endif diff --git a/src/libsodium/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c b/src/libsodium/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c index e0fe757a..4c347485 100644 --- a/src/libsodium/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c +++ b/src/libsodium/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c @@ -582,8 +582,8 @@ int crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_, const unsigned char *k) { aes256gcm_state *ctx = (aes256gcm_state *) (void *) ctx_; - unsigned char * H = ctx->H; - const __m128i * rkeys = ctx->rkeys; + unsigned char *H = ctx->H; + __m128i *rkeys = ctx->rkeys; const __m128i zero = _mm_setzero_si128(); COMPILER_ASSERT((sizeof *ctx_) >= (sizeof *ctx)); diff --git a/src/libsodium/include/Makefile.am b/src/libsodium/include/Makefile.am index b9978776..d639c634 100644 --- a/src/libsodium/include/Makefile.am +++ b/src/libsodium/include/Makefile.am @@ -3,6 +3,7 @@ SODIUM_EXPORT = \ sodium.h \ sodium/core.h \ sodium/crypto_aead_aes256gcm.h \ + sodium/crypto_aead_aegis128l.h \ sodium/crypto_aead_aegis256.h \ sodium/crypto_aead_chacha20poly1305.h \ sodium/crypto_aead_xchacha20poly1305.h \ diff --git a/src/libsodium/include/sodium.h b/src/libsodium/include/sodium.h index e0ffedf2..610d6328 100644 --- a/src/libsodium/include/sodium.h +++ b/src/libsodium/include/sodium.h @@ -6,6 +6,7 @@ #include "sodium/core.h" #include "sodium/crypto_aead_aes256gcm.h" +#include "sodium/crypto_aead_aegis128l.h" #include "sodium/crypto_aead_aegis256.h" #include "sodium/crypto_aead_chacha20poly1305.h" #include "sodium/crypto_aead_xchacha20poly1305.h" diff --git a/src/libsodium/include/sodium/crypto_aead_aegis128l.h b/src/libsodium/include/sodium/crypto_aead_aegis128l.h new file mode 100644 index 00000000..ed8d2f2b --- /dev/null +++ b/src/libsodium/include/sodium/crypto_aead_aegis128l.h @@ -0,0 +1,96 @@ +#ifndef crypto_aead_aegis128l_H +#define crypto_aead_aegis128l_H + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +SODIUM_EXPORT +int crypto_aead_aegis128l_is_available(void); + +#define crypto_aead_aegis128l_KEYBYTES 16U +SODIUM_EXPORT +size_t crypto_aead_aegis128l_keybytes(void); + +#define crypto_aead_aegis128l_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_aegis128l_nsecbytes(void); + +#define crypto_aead_aegis128l_NPUBBYTES 16U +SODIUM_EXPORT +size_t crypto_aead_aegis128l_npubbytes(void); + +#define crypto_aead_aegis128l_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_aegis128l_abytes(void); + +#define crypto_aead_aegis128l_MESSAGEBYTES_MAX \ + SODIUM_MIN(SODIUM_SIZE_MAX - crypto_aead_aegis128l_ABYTES, \ + (1ULL << 61) - 1) +SODIUM_EXPORT +size_t crypto_aead_aegis128l_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_aead_aegis128l_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((nonnull(1, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_aegis128l_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(4, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_aegis128l_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((nonnull(1, 2, 9, 10))); + +SODIUM_EXPORT +int crypto_aead_aegis128l_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 5, 8, 9))); + +SODIUM_EXPORT +void crypto_aead_aegis128l_keygen(unsigned char k[crypto_aead_aegis128l_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/test/symbols/all-symbols.txt b/test/symbols/all-symbols.txt index 673b070b..18f4253f 100644 --- a/test/symbols/all-symbols.txt +++ b/test/symbols/all-symbols.txt @@ -32,6 +32,17 @@ blake2b_long blake2b_pick_best_implementation blake2b_salt_personal blake2b_update +crypto_aead_aegis128l_abytes +crypto_aead_aegis128l_decrypt +crypto_aead_aegis128l_decrypt_detached +crypto_aead_aegis128l_encrypt +crypto_aead_aegis128l_encrypt_detached +crypto_aead_aegis128l_is_available +crypto_aead_aegis128l_keybytes +crypto_aead_aegis128l_keygen +crypto_aead_aegis128l_messagebytes_max +crypto_aead_aegis128l_npubbytes +crypto_aead_aegis128l_nsecbytes crypto_aead_aegis256_abytes crypto_aead_aegis256_decrypt crypto_aead_aegis256_decrypt_detached