mirror of
https://github.com/jedisct1/libsodium.git
synced 2026-08-25 08:37:13 +09:00
Move the tag to the end for crypto_aead_chacha20poly1305
This commit is contained in:
+21
-23
@@ -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.
|
||||
The length of the additional data can be `0`.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user