diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj b/builds/msvc/vs2010/libsodium/libsodium.vcxproj
index c5848161..ec340a17 100644
--- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj
@@ -259,6 +259,7 @@
+
diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters
index 80701640..079094b9 100644
--- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters
@@ -566,6 +566,9 @@
include\sodium\private
+
+ include\sodium\private
+
include\sodium\private
diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj b/builds/msvc/vs2012/libsodium/libsodium.vcxproj
index 72040cbf..f140d161 100644
--- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj
@@ -259,6 +259,7 @@
+
diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters
index 80701640..079094b9 100644
--- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters
@@ -566,6 +566,9 @@
include\sodium\private
+
+ include\sodium\private
+
include\sodium\private
diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj b/builds/msvc/vs2013/libsodium/libsodium.vcxproj
index b60bc018..cddd4ad6 100644
--- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj
@@ -259,6 +259,7 @@
+
diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters
index 80701640..079094b9 100644
--- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters
@@ -566,6 +566,9 @@
include\sodium\private
+
+ include\sodium\private
+
include\sodium\private
diff --git a/builds/msvc/vs2015/libsodium/libsodium.vcxproj b/builds/msvc/vs2015/libsodium/libsodium.vcxproj
index 00d5bfb3..230086a9 100644
--- a/builds/msvc/vs2015/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2015/libsodium/libsodium.vcxproj
@@ -259,6 +259,7 @@
+
diff --git a/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters
index 80701640..079094b9 100644
--- a/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters
@@ -566,6 +566,9 @@
include\sodium\private
+
+ include\sodium\private
+
include\sodium\private
diff --git a/builds/msvc/vs2017/libsodium/libsodium.vcxproj b/builds/msvc/vs2017/libsodium/libsodium.vcxproj
index ed26b978..8a175e0b 100644
--- a/builds/msvc/vs2017/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2017/libsodium/libsodium.vcxproj
@@ -259,6 +259,7 @@
+
diff --git a/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters
index 80701640..079094b9 100644
--- a/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters
@@ -566,6 +566,9 @@
include\sodium\private
+
+ include\sodium\private
+
include\sodium\private
diff --git a/libsodium.vcxproj b/libsodium.vcxproj
index eec2a525..63d5f956 100644
--- a/libsodium.vcxproj
+++ b/libsodium.vcxproj
@@ -497,6 +497,7 @@
+
diff --git a/libsodium.vcxproj.filters b/libsodium.vcxproj.filters
index 8325e43c..b4a4ea96 100644
--- a/libsodium.vcxproj.filters
+++ b/libsodium.vcxproj.filters
@@ -557,6 +557,9 @@
Header Files
+
+ Header Files
+
Header Files
diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am
index cbac4d19..2c3d210f 100644
--- a/src/libsodium/Makefile.am
+++ b/src/libsodium/Makefile.am
@@ -82,6 +82,7 @@ libsodium_la_SOURCES = \
crypto_stream/salsa20/stream_salsa20.h \
crypto_stream/xsalsa20/stream_xsalsa20.c \
crypto_verify/sodium/verify.c \
+ include/sodium/private/chacha20_ietf_ext.h \
include/sodium/private/common.h \
include/sodium/private/ed25519_ref10.h \
include/sodium/private/implementations.h \
diff --git a/src/libsodium/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c b/src/libsodium/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c
index c79407a1..c3540879 100644
--- a/src/libsodium/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c
+++ b/src/libsodium/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c
@@ -12,6 +12,7 @@
#include "randombytes.h"
#include "utils.h"
+#include "private/chacha20_ietf_ext.h"
#include "private/common.h"
static const unsigned char _pad0[16] = { 0 };
diff --git a/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c b/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c
index 04971a82..7e48c0d7 100644
--- a/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c
+++ b/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c
@@ -5,14 +5,118 @@
#include
#include "core.h"
-#include "crypto_aead_xchacha20poly1305.h"
#include "crypto_aead_chacha20poly1305.h"
+#include "crypto_aead_xchacha20poly1305.h"
#include "crypto_core_hchacha20.h"
+#include "crypto_onetimeauth_poly1305.h"
+#include "crypto_stream_chacha20.h"
+#include "crypto_verify_16.h"
#include "randombytes.h"
#include "utils.h"
+#include "private/chacha20_ietf_ext.h"
#include "private/common.h"
+static const unsigned char _pad0[16] = { 0 };
+
+static int
+_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_chacha20_ietf(block0, sizeof block0, npub, k);
+ crypto_onetimeauth_poly1305_init(&state, block0);
+ sodium_memzero(block0, sizeof block0);
+
+ crypto_onetimeauth_poly1305_update(&state, ad, adlen);
+ crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf);
+
+ crypto_stream_chacha20_ietf_ext_xor_ic(c, m, mlen, npub, 1U, k);
+
+ crypto_onetimeauth_poly1305_update(&state, c, mlen);
+ crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf);
+
+ STORE64_LE(slen, (uint64_t) adlen);
+ crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
+
+ 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_chacha20poly1305_ietf_ABYTES;
+ }
+ return 0;
+}
+
+static int
+_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_chacha20poly1305_ietf_ABYTES];
+ unsigned long long mlen;
+ int ret;
+
+ (void) nsec;
+ crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k);
+ crypto_onetimeauth_poly1305_init(&state, block0);
+ sodium_memzero(block0, sizeof block0);
+
+ crypto_onetimeauth_poly1305_update(&state, ad, adlen);
+ crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf);
+
+ mlen = clen;
+ crypto_onetimeauth_poly1305_update(&state, c, mlen);
+ crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf);
+
+ STORE64_LE(slen, (uint64_t) adlen);
+ crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
+
+ 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);
+
+ COMPILER_ASSERT(sizeof computed_mac == 16U);
+ 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_chacha20_ietf_ext_xor_ic(m, c, mlen, npub, 1U, k);
+
+ return 0;
+}
+
int
crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c,
unsigned char *mac,
@@ -32,8 +136,8 @@ crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c,
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);
+ ret = _encrypt_detached(c, mac, maclen_p, m, mlen, ad, adlen,
+ nsec, npub2, k2);
sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES);
return ret;
@@ -85,12 +189,10 @@ crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m,
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);
+ ret = _decrypt_detached(m, nsec, c, clen, mac, ad, adlen, npub2, k2);
sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES);
return ret;
-
}
int
@@ -105,7 +207,7 @@ crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m,
const unsigned char *k)
{
unsigned long long mlen = 0ULL;
- int ret = -1;
+ int ret = -1;
if (clen >= crypto_aead_xchacha20poly1305_ietf_ABYTES) {
ret = crypto_aead_xchacha20poly1305_ietf_decrypt_detached
diff --git a/src/libsodium/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c b/src/libsodium/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c
index ef000d16..6d677e0e 100644
--- a/src/libsodium/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c
+++ b/src/libsodium/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c
@@ -12,6 +12,7 @@
#include "randombytes.h"
#include "utils.h"
+#include "private/chacha20_ietf_ext.h"
#include "private/common.h"
#define crypto_secretstream_xchacha20poly1305_COUNTERBYTES 4U
@@ -136,13 +137,13 @@ crypto_secretstream_xchacha20poly1305_push
memset(block, 0, sizeof block);
block[0] = tag;
- crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block,
- state->nonce, 1U, state->k);
+ crypto_stream_chacha20_ietf_ext_xor_ic(block, block, sizeof block,
+ state->nonce, 1U, state->k);
crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block);
out[0] = block[0];
c = out + (sizeof tag);
- crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k);
+ crypto_stream_chacha20_ietf_ext_xor_ic(c, m, mlen, state->nonce, 2U, state->k);
crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen);
crypto_onetimeauth_poly1305_update
(&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf);
@@ -212,8 +213,8 @@ crypto_secretstream_xchacha20poly1305_pull
memset(block, 0, sizeof block);
block[0] = in[0];
- crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block,
- state->nonce, 1U, state->k);
+ crypto_stream_chacha20_ietf_ext_xor_ic(block, block, sizeof block,
+ state->nonce, 1U, state->k);
tag = block[0];
block[0] = in[0];
crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block);
@@ -237,7 +238,7 @@ crypto_secretstream_xchacha20poly1305_pull
return -1;
}
- crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k);
+ crypto_stream_chacha20_ietf_ext_xor_ic(m, c, mlen, state->nonce, 2U, state->k);
XOR_BUF(STATE_INONCE(state), mac,
crypto_secretstream_xchacha20poly1305_INONCEBYTES);
sodium_increment(STATE_COUNTER(state),
diff --git a/src/libsodium/crypto_stream/chacha20/stream_chacha20.c b/src/libsodium/crypto_stream/chacha20/stream_chacha20.c
index 3b089511..8294c99b 100644
--- a/src/libsodium/crypto_stream/chacha20/stream_chacha20.c
+++ b/src/libsodium/crypto_stream/chacha20/stream_chacha20.c
@@ -1,4 +1,5 @@
#include "crypto_stream_chacha20.h"
+#include "core.h"
#include "private/common.h"
#include "private/implementations.h"
#include "randombytes.h"
@@ -77,6 +78,19 @@ crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m,
unsigned long long mlen,
const unsigned char *n, uint32_t ic,
const unsigned char *k)
+{
+ if ((unsigned long long) ic >
+ crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX / 64ULL - (mlen + 63ULL) / 64ULL) {
+ sodium_misuse();
+ }
+ return implementation->stream_ietf_xor_ic(c, m, mlen, n, ic, k);
+}
+
+int
+crypto_stream_chacha20_ietf_ext_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n, uint32_t ic,
+ const unsigned char *k)
{
return implementation->stream_ietf_xor_ic(c, m, mlen, n, ic, k);
}
diff --git a/src/libsodium/include/sodium/private/chacha20_ietf_ext.h b/src/libsodium/include/sodium/private/chacha20_ietf_ext.h
new file mode 100644
index 00000000..2f3c048f
--- /dev/null
+++ b/src/libsodium/include/sodium/private/chacha20_ietf_ext.h
@@ -0,0 +1,13 @@
+#ifndef chacha20_ietf_ext_H
+#define chacha20_ietf_ext_H
+
+#include
+
+/* The ietf_ext variant allows the internal counter to overflow into the IV */
+int
+crypto_stream_chacha20_ietf_ext_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n, uint32_t ic,
+ const unsigned char *k);
+#endif
+
diff --git a/test/default/chacha20.c b/test/default/chacha20.c
index 0abe8d34..d92b11e8 100644
--- a/test/default/chacha20.c
+++ b/test/default/chacha20.c
@@ -105,7 +105,7 @@ void tv_ietf(void)
1U },
{ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"000000090000004a00000000",
- 0xffffffff }};
+ 0xfeffffff }};
unsigned char key[crypto_stream_chacha20_KEYBYTES];
unsigned char nonce[crypto_stream_chacha20_IETF_NONCEBYTES];
unsigned char *part;
diff --git a/test/default/chacha20.exp b/test/default/chacha20.exp
index 17e1e5c1..1b2017c7 100644
--- a/test/default/chacha20.exp
+++ b/test/default/chacha20.exp
@@ -35,7 +35,7 @@
[72d54dfbf12ec44b362692df94137f328fea8da73990265ec1bbbea1ae9af0ca13b25aa26cb4a648cb9b9d1be65b2c0924a66c54d545ec1b7374f4872e99f096bf74dbd52cc4fc95ceb6097fe5e65358c9dbc0a5ecbf7894a132a9a54ae3e951f2e9f209aa9c3d9a877ac9dab62433d2961a17d103e455dfb7337c90f6857aad233065955a212b5c7a8eab4dc8a629e5b6b8ba914afd06de7177054b33d21c96]
[c2c64d378cd536374ae204b9ef933fcd1a8b2288b3dfa49672ab765b54ee27c78a970e0e955c14f3a88e741b97c286f75f8fc299e8148362fa198a39531bed6d1a91288c874ec254f322c2a197340c55bb3e9b3998f7de2309486a0bb494abd20c9c5ef99c1370d61e77f408ac5514f49202bcc6828d45409d2d1416f8ae106b06ebd2541256264fa415bd54cb12e1d4449ed85299a1b7a249b75ff6c89b2e3f]
[10f1e7e4d13b5915500fdd1fa32071c4c7d1f4c733c068030422aa9ac3d46c4ed2826446079faa0914c2d705d98b02a2b5129cd1de164eb9cbd083e8a2503c4e0a88837739d7bf4ef8ccacb0ea2bb9d69d56c394aa351dfda5bf459f0a2e9fe8e721f89255f9c486bf21679c683d4f9c5cf2fa27865526005b06ca374c86af3bdcbfbdcb83be65862ed5c20eae5a43241d6a92da6dca9a156be25297f51c2718]
-[ff2941b8d740f6cbb50936bf997ebd5218cb108dc53f41c64841d0218167430ca03b770ca74ccb642a28194d1dedd2ed13151e25ec5d7faeb6d060bfb7e6b146880b67b55162bca26abe045fad14b0f492a3f369dcd52f98bc1513eaf238a3f434c7527121b4b756613e270395358d831d4950b6c7812fb724dc7c9be5e5c62ec8796d6690205061108b113f695582e4cf5d8b51112a51d157ef15e2cb95e4d5]
+[75924bad7831b25662dbac54b46827990b6168ae990e7bd7e1fd2ad282bf23ef052c7d1a0a6c1ef862070943a0d4da24705fbc006dfb85e2af18c0a264d772a44c70fbedac9d6a6867ff6be0a32826507f2c784101583211c9e2453d4cc8b283d5e86682bd4bf511271b91dbd351415f5a009d1f78b64085a9a4341be7d42e2679d57e2747097f0129950e2c9e9ca1356022d45da252af71ac37f351a2e77911]
[61010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101]
[6146f256040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404]
[6146f2564fe1bd070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707]