From 157c4a80c13b117608aeae12178b2d38825f9f8f Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sat, 26 Nov 2016 21:29:26 +0100 Subject: [PATCH] + crypto_aead_xchacha20poly1305 --- src/libsodium/Makefile.am | 1 + .../sodium/aead_xchacha20poly1305.c | 184 ++++++++++++++++++ src/libsodium/include/Makefile.am | 1 + src/libsodium/include/sodium.h | 1 + .../sodium/crypto_aead_xchacha20poly1305.h | 81 ++++++++ 5 files changed, 268 insertions(+) create mode 100644 src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c create mode 100644 src/libsodium/include/sodium/crypto_aead_xchacha20poly1305.h diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index 31b04534..7cec3ab0 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -3,6 +3,7 @@ lib_LTLIBRARIES = \ libsodium_la_SOURCES = \ crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c \ + crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c \ crypto_auth/crypto_auth.c \ crypto_auth/hmacsha256/auth_hmacsha256_api.c \ crypto_auth/hmacsha256/cp/hmac_hmacsha256.c \ diff --git a/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c b/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c new file mode 100644 index 00000000..3a40995c --- /dev/null +++ b/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c @@ -0,0 +1,184 @@ + +#include +#include +#include +#include + +#include "crypto_aead_xchacha20poly1305.h" +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_stream_xchacha20.h" +#include "crypto_verify_16.h" +#include "utils.h" + +#include "private/common.h" + +int +crypto_aead_xchacha20poly1305_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) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + + (void) nsec; + crypto_stream_xchacha20(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_stream_xchacha20_xor_ic(c, m, mlen, npub, 1U, k); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, mac); + sodium_memzero(&state, sizeof state); + + if (maclen_p != NULL) { + *maclen_p = crypto_aead_xchacha20poly1305_ABYTES; + } + return 0; +} + +int +crypto_aead_xchacha20poly1305_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 > UINT64_MAX - crypto_aead_xchacha20poly1305_ABYTES) { + abort(); /* LCOV_EXCL_LINE */ + } + ret = crypto_aead_xchacha20poly1305_encrypt_detached(c, + c + mlen, NULL, + m, mlen, + ad, adlen, + nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + crypto_aead_xchacha20poly1305_ABYTES; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_xchacha20poly1305_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) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + unsigned char computed_mac[crypto_aead_xchacha20poly1305_ABYTES]; + unsigned long long mlen; + int ret; + + (void) nsec; + crypto_stream_xchacha20(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + mlen = clen; + crypto_onetimeauth_poly1305_update(&state, c, mlen); + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, computed_mac); + sodium_memzero(&state, sizeof state); + + (void) sizeof(int[sizeof computed_mac == 16U ? 1 : -1]); + 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; + } + crypto_stream_xchacha20_xor_ic(m, c, mlen, npub, 1U, k); + + return 0; +} + +int +crypto_aead_xchacha20poly1305_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 >= crypto_aead_xchacha20poly1305_ABYTES) { + ret = crypto_aead_xchacha20poly1305_decrypt_detached + (m, nsec, + c, clen - crypto_aead_xchacha20poly1305_ABYTES, + c + clen - crypto_aead_xchacha20poly1305_ABYTES, + ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_xchacha20poly1305_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +size_t +crypto_aead_xchacha20poly1305_keybytes(void) { + return crypto_aead_xchacha20poly1305_KEYBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_npubbytes(void) { + return crypto_aead_xchacha20poly1305_NPUBBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_nsecbytes(void) { + return crypto_aead_xchacha20poly1305_NSECBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_abytes(void) { + return crypto_aead_xchacha20poly1305_ABYTES; +} diff --git a/src/libsodium/include/Makefile.am b/src/libsodium/include/Makefile.am index a333d142..1aba51e0 100644 --- a/src/libsodium/include/Makefile.am +++ b/src/libsodium/include/Makefile.am @@ -4,6 +4,7 @@ SODIUM_EXPORT = \ sodium/core.h \ sodium/crypto_aead_aes256gcm.h \ sodium/crypto_aead_chacha20poly1305.h \ + sodium/crypto_aead_xchacha20poly1305.h \ sodium/crypto_auth.h \ sodium/crypto_auth_hmacsha256.h \ sodium/crypto_auth_hmacsha512.h \ diff --git a/src/libsodium/include/sodium.h b/src/libsodium/include/sodium.h index 2f0db1dc..4d87a803 100644 --- a/src/libsodium/include/sodium.h +++ b/src/libsodium/include/sodium.h @@ -5,6 +5,7 @@ #include "sodium/core.h" #include "sodium/crypto_aead_aes256gcm.h" #include "sodium/crypto_aead_chacha20poly1305.h" +#include "sodium/crypto_aead_xchacha20poly1305.h" #include "sodium/crypto_auth.h" #include "sodium/crypto_auth_hmacsha256.h" #include "sodium/crypto_auth_hmacsha512.h" diff --git a/src/libsodium/include/sodium/crypto_aead_xchacha20poly1305.h b/src/libsodium/include/sodium/crypto_aead_xchacha20poly1305.h new file mode 100644 index 00000000..f1460750 --- /dev/null +++ b/src/libsodium/include/sodium/crypto_aead_xchacha20poly1305.h @@ -0,0 +1,81 @@ +#ifndef crypto_aead_xchacha20poly1305_H +#define crypto_aead_xchacha20poly1305_H + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_aead_xchacha20poly1305_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_keybytes(void); + +#define crypto_aead_xchacha20poly1305_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_nsecbytes(void); + +#define crypto_aead_xchacha20poly1305_NPUBBYTES 24U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_npubbytes(void); + +#define crypto_aead_xchacha20poly1305_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_abytes(void); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_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); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_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)); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_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); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_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)); + +#ifdef __cplusplus +} +#endif + +#endif