diff --git a/README.markdown b/README.markdown index 7791a34d..b9e43467 100644 --- a/README.markdown +++ b/README.markdown @@ -363,52 +363,50 @@ Additional Data (AEAD) construction, as documented in the [nir-cfrg-chacha20-poly1305-04](http://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04) draft. - int crypto_secretbox_chacha20poly1305_ad(unsigned char *c, + int crypto_aead_chacha20poly1305_encrypt(unsigned char *c, + unsigned long long *clen, const unsigned char *m, unsigned long long mlen, const unsigned char *ad, unsigned long long adlen, - const unsigned char *n, + const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k); This function encrypts the message `m` of length `mlen` with the key -`k` (whose size is `crypto_secretbox_chacha20poly1305_KEYBYTES` bytes) -and nonce `n` (whose size is `crypto_secretbox_chacha20poly1305_NONCEBYTES`). +`k` (whose size is `crypto_aead_chacha20poly1305_KEYBYTES` bytes) +and nonce `n` (whose size is `crypto_aead_chacha20poly1305_NPUBBYTES`). -`c` must be at least `mlen + crypto_secretbox_chacha20poly1305_ZEROBYTES` long. +`c` must be at least `mlen + crypto_aead_chacha20poly1305_ABYTES` long. + +`nsec` should be NULL. The function fills the first bytes of `c` with a tag authenticating both the encrypted message and additional data `ad` whose length is `adlen` bytes. The output of the previous function can be verified and decrypted using: - int crypto_secretbox_chacha20poly1305_ad_open(unsigned char *m, - const unsigned char *c, - unsigned long long clen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *n, - const unsigned char *k); + int crypto_aead_chacha20poly1305_decrypt(unsigned char *m, + unsigned long long *mlen, + 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); `clen` is the length of the ciphertext, as generated by the previous function: it is equal to the length of the plaintext message + -`crypto_secretbox_chacha20poly1305_ZEROBYTES`. +`crypto_aead_chacha20poly1305_ABYTES`. If the MAC can be verified, the plaintext is copied to `m` and the function returns `0`. If the verification fails, the function returns `-1`. -The length of the additional data can be `0`. Alternatively, the -`crypto_secretbox_chacha20poly1305()` and -`crypto_secretbox_chacha20poly1305_open()` variants can be used. - -In order to be consistent with the `secretbox` API, the MAC is stored -*before* the encrypted message. This differs from the -draft on ChaCha20 and Poly1305 for IETF protocols, which stores the -MAC *after* the encrypted message. +The length of the additional data can be `0`. -However, the MAC is computed using the same algorithm, and can be -moved after message if interoperability with other implementations is required. +`nsec` should be NULL. ## Constants available as functions diff --git a/src/libsodium/crypto_aead/chacha20poly1305/aead_chacha20poly1305.c b/src/libsodium/crypto_aead/chacha20poly1305/aead_chacha20poly1305.c index b6fd57c7..8ad30b5a 100644 --- a/src/libsodium/crypto_aead/chacha20poly1305/aead_chacha20poly1305.c +++ b/src/libsodium/crypto_aead/chacha20poly1305/aead_chacha20poly1305.c @@ -35,17 +35,16 @@ crypto_aead_chacha20poly1305_encrypt(unsigned char *c, crypto_onetimeauth_poly1305_state state; unsigned char block0[64U]; unsigned char slen[8U]; - + #ifdef ULONG_LONG_MAX - if (mlen > ULONG_LONG_MAX - crypto_aead_chacha20poly1305_ZEROBYTES) { + if (mlen > ULONG_LONG_MAX - crypto_aead_chacha20poly1305_ABYTES) { if (clen != NULL) { *clen = 0ULL; } return -1; } -#endif - crypto_stream_chacha20_xor_ic - (c + crypto_aead_chacha20poly1305_ZEROBYTES, m, mlen, npub, 1U, k); +#endif + crypto_stream_chacha20_xor_ic(c, m, mlen, npub, 1U, k); crypto_stream_chacha20(block0, sizeof block0, npub, k); crypto_onetimeauth_poly1305_init(&state, block0); @@ -55,16 +54,15 @@ crypto_aead_chacha20poly1305_encrypt(unsigned char *c, _u64_le_from_ull(slen, adlen); crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - crypto_onetimeauth_poly1305_update - (&state, c + crypto_aead_chacha20poly1305_ZEROBYTES, mlen); + crypto_onetimeauth_poly1305_update(&state, c, mlen); _u64_le_from_ull(slen, mlen); crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - crypto_onetimeauth_poly1305_final(&state, c); + crypto_onetimeauth_poly1305_final(&state, c + mlen); sodium_memzero(&state, sizeof state); if (clen != NULL) { - *clen = mlen + crypto_aead_chacha20poly1305_ZEROBYTES; + *clen = mlen + crypto_aead_chacha20poly1305_ABYTES; } return 0; } @@ -83,13 +81,13 @@ crypto_aead_chacha20poly1305_decrypt(unsigned char *m, crypto_onetimeauth_poly1305_state state; unsigned char block0[64U]; unsigned char slen[8U]; - unsigned char mac[crypto_aead_chacha20poly1305_MACBYTES]; + unsigned char mac[crypto_aead_chacha20poly1305_ABYTES]; int ret; if (mlen != NULL) { *mlen = 0ULL; } - if (clen < crypto_aead_chacha20poly1305_ZEROBYTES) { + if (clen < crypto_aead_chacha20poly1305_ABYTES) { return -1; } crypto_stream_chacha20(block0, sizeof block0, npub, k); @@ -101,25 +99,24 @@ crypto_aead_chacha20poly1305_decrypt(unsigned char *m, crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); crypto_onetimeauth_poly1305_update - (&state, c + crypto_aead_chacha20poly1305_ZEROBYTES, - clen - crypto_aead_chacha20poly1305_ZEROBYTES); - _u64_le_from_ull(slen, clen - crypto_aead_chacha20poly1305_ZEROBYTES); + (&state, c, clen - crypto_aead_chacha20poly1305_ABYTES); + _u64_le_from_ull(slen, clen - crypto_aead_chacha20poly1305_ABYTES); crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); crypto_onetimeauth_poly1305_final(&state, mac); sodium_memzero(&state, sizeof state); - ret = crypto_verify_16(mac, c); + ret = crypto_verify_16(mac, + c + clen - crypto_aead_chacha20poly1305_ABYTES); sodium_memzero(mac, sizeof mac); if (ret != 0) { - memset(m, 0, clen - crypto_aead_chacha20poly1305_ZEROBYTES); + memset(m, 0, clen - crypto_aead_chacha20poly1305_ABYTES); return -1; } crypto_stream_chacha20_xor_ic - (m, c + crypto_aead_chacha20poly1305_ZEROBYTES, - clen - crypto_aead_chacha20poly1305_ZEROBYTES, npub, 1U, k); + (m, c, clen - crypto_aead_chacha20poly1305_ABYTES, npub, 1U, k); if (mlen != NULL) { - *mlen = clen - crypto_aead_chacha20poly1305_ZEROBYTES; + *mlen = clen - crypto_aead_chacha20poly1305_ABYTES; } return 0; } @@ -143,8 +140,3 @@ size_t crypto_aead_chacha20poly1305_abytes(void) { return crypto_aead_chacha20poly1305_ABYTES; } - -size_t -crypto_aead_chacha20poly1305_macbytes(void) { - return crypto_aead_chacha20poly1305_MACBYTES; -} diff --git a/src/libsodium/include/sodium/crypto_aead_chacha20poly1305.h b/src/libsodium/include/sodium/crypto_aead_chacha20poly1305.h index 139f1f6f..b36807c6 100644 --- a/src/libsodium/include/sodium/crypto_aead_chacha20poly1305.h +++ b/src/libsodium/include/sodium/crypto_aead_chacha20poly1305.h @@ -23,21 +23,7 @@ size_t crypto_aead_chacha20poly1305_nsecbytes(void); SODIUM_EXPORT size_t crypto_aead_chacha20poly1305_npubbytes(void); -#define crypto_aead_chacha20poly1305_ZEROBYTES 16U -SODIUM_EXPORT -size_t crypto_aead_chacha20poly1305_zerobytes(void); - -#define crypto_aead_chacha20poly1305_BOXZEROBYTES 0U -SODIUM_EXPORT -size_t crypto_aead_chacha20poly1305_boxzerobytes(void); - -#define crypto_aead_chacha20poly1305_MACBYTES \ - (crypto_aead_chacha20poly1305_ZEROBYTES - \ - crypto_aead_chacha20poly1305_BOXZEROBYTES) -SODIUM_EXPORT -size_t crypto_aead_chacha20poly1305_macbytes(void); - -#define crypto_aead_chacha20poly1305_ABYTES 0U +#define crypto_aead_chacha20poly1305_ABYTES 16U SODIUM_EXPORT size_t crypto_aead_chacha20poly1305_abytes(void); diff --git a/test/default/aead_chacha20poly1305.c b/test/default/aead_chacha20poly1305.c index 4fa6c967..31d17863 100644 --- a/test/default/aead_chacha20poly1305.c +++ b/test/default/aead_chacha20poly1305.c @@ -23,7 +23,7 @@ static unsigned char ad[10U] = { 0x87, 0xe2, 0x29, 0xd4, 0x50, 0x08, 0x45, 0xa0, 0x79, 0xc0 }; -static unsigned char c[10U + crypto_aead_chacha20poly1305_MACBYTES]; +static unsigned char c[10U + crypto_aead_chacha20poly1305_ABYTES]; int main(void) { @@ -34,7 +34,7 @@ int main(void) crypto_aead_chacha20poly1305_encrypt(c, &clen, m, sizeof m, ad, sizeof ad, NULL, nonce, firstkey); - if (clen != sizeof m + crypto_aead_chacha20poly1305_macbytes()) { + if (clen != sizeof m + crypto_aead_chacha20poly1305_abytes()) { printf("clen is not properly set\n"); } for (i = 0U; i < sizeof c; ++i) { @@ -50,7 +50,7 @@ int main(void) nonce, firstkey) != 0) { printf("crypto_aead_chacha20poly1305_decrypt() failed\n"); } - if (m2len != sizeof c - crypto_aead_chacha20poly1305_macbytes()) { + if (m2len != sizeof c - crypto_aead_chacha20poly1305_abytes()) { printf("m2len is not properly set\n"); } if (memcmp(m, m2, sizeof m) != 0) { diff --git a/test/default/aead_chacha20poly1305.exp b/test/default/aead_chacha20poly1305.exp index 49a2f554..a846fe0e 100644 --- a/test/default/aead_chacha20poly1305.exp +++ b/test/default/aead_chacha20poly1305.exp @@ -1,4 +1,4 @@ -,0x67,0x7d,0xab,0xf4,0xe3,0xd2,0x4b,0x87 -,0x6b,0xb2,0x84,0x75,0x38,0x96,0xe1,0xd6 ,0xe3,0xe4,0x46,0xf7,0xed,0xe9,0xa1,0x9b -,0x62,0xa4 +,0x62,0xa4,0x67,0x7d,0xab,0xf4,0xe3,0xd2 +,0x4b,0x87,0x6b,0xb2,0x84,0x75,0x38,0x96 +,0xe1,0xd6