diff --git a/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c b/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c index 3a40995c..716b9064 100644 --- a/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c +++ b/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c @@ -5,9 +5,8 @@ #include #include "crypto_aead_xchacha20poly1305.h" -#include "crypto_onetimeauth_poly1305.h" -#include "crypto_stream_xchacha20.h" -#include "crypto_verify_16.h" +#include "crypto_aead_chacha20poly1305.h" +#include "crypto_core_hchacha20.h" #include "utils.h" #include "private/common.h" @@ -24,32 +23,15 @@ crypto_aead_xchacha20poly1305_encrypt_detached(unsigned char *c, const unsigned char *npub, const unsigned char *k) { - crypto_onetimeauth_poly1305_state state; - unsigned char block0[64U]; - unsigned char slen[8U]; + int ret; + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; - (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; + crypto_core_hchacha20(k2, npub, k, NULL); + ret = crypto_aead_chacha20poly1305_encrypt_detached(c, + mac, maclen_p, m, mlen, ad, adlen, nsec, + npub + crypto_core_hchacha20_INPUTBYTES, k2); + sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES); + return ret; } int @@ -94,43 +76,16 @@ crypto_aead_xchacha20poly1305_decrypt_detached(unsigned char *m, 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; + int ret; + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; - (void) nsec; - crypto_stream_xchacha20(block0, sizeof block0, npub, k); - crypto_onetimeauth_poly1305_init(&state, block0); - sodium_memzero(block0, sizeof block0); + crypto_core_hchacha20(k2, npub, k, NULL); + ret = crypto_aead_chacha20poly1305_decrypt_detached(m, + nsec, c, clen, mac, ad, adlen, + npub + crypto_core_hchacha20_INPUTBYTES, k2); + sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES); + return ret; - 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 @@ -163,6 +118,117 @@ crypto_aead_xchacha20poly1305_decrypt(unsigned char *m, return ret; } +int +crypto_aead_xchacha20poly1305_ietf_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) +{ + int ret; + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; + unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 }; + + crypto_core_hchacha20(k2, npub, k, NULL); + memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES, crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4); + ret = crypto_aead_chacha20poly1305_ietf_encrypt_detached(c, + mac, maclen_p, m, mlen, ad, adlen, nsec, + npub2, k2); + sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES); + return ret; +} + +int +crypto_aead_xchacha20poly1305_ietf_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_ietf_ABYTES) { + abort(); /* LCOV_EXCL_LINE */ + } + ret = crypto_aead_xchacha20poly1305_ietf_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_ietf_ABYTES; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_xchacha20poly1305_ietf_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) +{ + int ret; + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; + unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 }; + + crypto_core_hchacha20(k2, npub, k, NULL); + memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES, crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4); + ret = crypto_aead_chacha20poly1305_ietf_decrypt_detached(m, + nsec, c, clen, mac, ad, adlen, + npub2, k2); + sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES); + return ret; + +} + +int +crypto_aead_xchacha20poly1305_ietf_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_ietf_ABYTES) { + ret = crypto_aead_xchacha20poly1305_ietf_decrypt_detached + (m, nsec, + c, clen - crypto_aead_xchacha20poly1305_ietf_ABYTES, + c + clen - crypto_aead_xchacha20poly1305_ietf_ABYTES, + ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_xchacha20poly1305_ietf_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + size_t crypto_aead_xchacha20poly1305_keybytes(void) { return crypto_aead_xchacha20poly1305_KEYBYTES; @@ -182,3 +248,23 @@ size_t crypto_aead_xchacha20poly1305_abytes(void) { return crypto_aead_xchacha20poly1305_ABYTES; } + +size_t +crypto_aead_xchacha20poly1305_ietf_keybytes(void) { + return crypto_aead_xchacha20poly1305_ietf_KEYBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_npubbytes(void) { + return crypto_aead_xchacha20poly1305_ietf_NPUBBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_nsecbytes(void) { + return crypto_aead_xchacha20poly1305_ietf_NSECBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_abytes(void) { + return crypto_aead_xchacha20poly1305_ietf_ABYTES; +} diff --git a/src/libsodium/include/sodium/crypto_aead_xchacha20poly1305.h b/src/libsodium/include/sodium/crypto_aead_xchacha20poly1305.h index f1460750..a12f4bf9 100644 --- a/src/libsodium/include/sodium/crypto_aead_xchacha20poly1305.h +++ b/src/libsodium/include/sodium/crypto_aead_xchacha20poly1305.h @@ -27,6 +27,22 @@ size_t crypto_aead_xchacha20poly1305_npubbytes(void); SODIUM_EXPORT size_t crypto_aead_xchacha20poly1305_abytes(void); +#define crypto_aead_xchacha20poly1305_ietf_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_keybytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_nsecbytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_NPUBBYTES 24U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_npubbytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_abytes(void); + SODIUM_EXPORT int crypto_aead_xchacha20poly1305_encrypt(unsigned char *c, unsigned long long *clen_p, @@ -74,6 +90,60 @@ int crypto_aead_xchacha20poly1305_decrypt_detached(unsigned char *m, const unsigned char *k) __attribute__ ((warn_unused_result)); +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_ietf_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_ietf_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_ietf_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_ietf_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)); + +/* Aliases */ + +#define crypto_aead_xchacha20poly1305_IETF_KEYBYTES crypto_aead_xchacha20poly1305_ietf_KEYBYTES +#define crypto_aead_xchacha20poly1305_IETF_NSECBYTES crypto_aead_xchacha20poly1305_ietf_NSECBYTES +#define crypto_aead_xchacha20poly1305_IETF_NPUBBYTES crypto_aead_xchacha20poly1305_ietf_NPUBBYTES +#define crypto_aead_xchacha20poly1305_IETF_ABYTES crypto_aead_xchacha20poly1305_ietf_ABYTES + #ifdef __cplusplus } #endif