mirror of
https://github.com/jedisct1/libsodium.git
synced 2026-08-25 08:37:13 +09:00
Add IETF-compatible version of chacha20poly1305
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
#include "crypto_verify_16.h"
|
||||
#include "utils.h"
|
||||
|
||||
static unsigned char _pad0[16];
|
||||
|
||||
static inline void
|
||||
_u64_le_from_ull(unsigned char out[8U], unsigned long long x)
|
||||
{
|
||||
@@ -23,7 +25,7 @@ _u64_le_from_ull(unsigned char out[8U], unsigned long long x)
|
||||
|
||||
int
|
||||
crypto_aead_chacha20poly1305_encrypt(unsigned char *c,
|
||||
unsigned long long *clen,
|
||||
unsigned long long *clen_p,
|
||||
const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
const unsigned char *ad,
|
||||
@@ -40,8 +42,8 @@ crypto_aead_chacha20poly1305_encrypt(unsigned char *c,
|
||||
/* LCOV_EXCL_START */
|
||||
#ifdef ULONG_LONG_MAX
|
||||
if (mlen > ULONG_LONG_MAX - crypto_aead_chacha20poly1305_ABYTES) {
|
||||
if (clen != NULL) {
|
||||
*clen = 0ULL;
|
||||
if (clen_p != NULL) {
|
||||
*clen_p = 0ULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -65,15 +67,69 @@ crypto_aead_chacha20poly1305_encrypt(unsigned char *c,
|
||||
crypto_onetimeauth_poly1305_final(&state, c + mlen);
|
||||
sodium_memzero(&state, sizeof state);
|
||||
|
||||
if (clen != NULL) {
|
||||
*clen = mlen + crypto_aead_chacha20poly1305_ABYTES;
|
||||
if (clen_p != NULL) {
|
||||
*clen_p = mlen + crypto_aead_chacha20poly1305_ABYTES;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
crypto_aead_chacha20poly1305_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)
|
||||
{
|
||||
crypto_onetimeauth_poly1305_state state;
|
||||
unsigned char block0[64U];
|
||||
unsigned char slen[8U];
|
||||
|
||||
(void) nsec;
|
||||
/* LCOV_EXCL_START */
|
||||
#ifdef ULONG_LONG_MAX
|
||||
if (mlen > ULONG_LONG_MAX - crypto_aead_chacha20poly1305_ABYTES) {
|
||||
if (clen_p != NULL) {
|
||||
*clen_p = 0ULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
/* LCOV_EXCL_STOP */
|
||||
|
||||
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_xor_ic(c, m, mlen, npub, 1U, k);
|
||||
|
||||
crypto_onetimeauth_poly1305_update(&state, c, mlen);
|
||||
crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf);
|
||||
|
||||
_u64_le_from_ull(slen, adlen);
|
||||
crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
|
||||
|
||||
_u64_le_from_ull(slen, mlen);
|
||||
crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
|
||||
|
||||
crypto_onetimeauth_poly1305_final(&state, c + mlen);
|
||||
sodium_memzero(&state, sizeof state);
|
||||
|
||||
if (clen_p != NULL) {
|
||||
*clen_p = mlen + crypto_aead_chacha20poly1305_ABYTES;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
crypto_aead_chacha20poly1305_decrypt(unsigned char *m,
|
||||
unsigned long long *mlen,
|
||||
unsigned long long *mlen_p,
|
||||
unsigned char *nsec,
|
||||
const unsigned char *c,
|
||||
unsigned long long clen,
|
||||
@@ -86,11 +142,12 @@ crypto_aead_chacha20poly1305_decrypt(unsigned char *m,
|
||||
unsigned char block0[64U];
|
||||
unsigned char slen[8U];
|
||||
unsigned char mac[crypto_aead_chacha20poly1305_ABYTES];
|
||||
unsigned long long mlen;
|
||||
int ret;
|
||||
|
||||
(void) nsec;
|
||||
if (mlen != NULL) {
|
||||
*mlen = 0ULL;
|
||||
if (mlen_p != NULL) {
|
||||
*mlen_p = 0ULL;
|
||||
}
|
||||
if (clen < crypto_aead_chacha20poly1305_ABYTES) {
|
||||
return -1;
|
||||
@@ -103,26 +160,84 @@ crypto_aead_chacha20poly1305_decrypt(unsigned char *m,
|
||||
_u64_le_from_ull(slen, adlen);
|
||||
crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
|
||||
|
||||
crypto_onetimeauth_poly1305_update
|
||||
(&state, c, clen - crypto_aead_chacha20poly1305_ABYTES);
|
||||
_u64_le_from_ull(slen, clen - crypto_aead_chacha20poly1305_ABYTES);
|
||||
mlen = clen - crypto_aead_chacha20poly1305_ABYTES;
|
||||
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, mac);
|
||||
sodium_memzero(&state, sizeof state);
|
||||
|
||||
(void) sizeof(int[sizeof mac == 16U ? 1 : -1]);
|
||||
ret = crypto_verify_16(mac,
|
||||
c + clen - crypto_aead_chacha20poly1305_ABYTES);
|
||||
ret = crypto_verify_16(mac, c + mlen);
|
||||
sodium_memzero(mac, sizeof mac);
|
||||
if (ret != 0) {
|
||||
memset(m, 0, clen - crypto_aead_chacha20poly1305_ABYTES);
|
||||
memset(m, 0, mlen);
|
||||
return -1;
|
||||
}
|
||||
crypto_stream_chacha20_xor_ic
|
||||
(m, c, clen - crypto_aead_chacha20poly1305_ABYTES, npub, 1U, k);
|
||||
if (mlen != NULL) {
|
||||
*mlen = clen - crypto_aead_chacha20poly1305_ABYTES;
|
||||
(m, c, mlen, npub, 1U, k);
|
||||
if (mlen_p != NULL) {
|
||||
*mlen_p = mlen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
crypto_aead_chacha20poly1305_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)
|
||||
{
|
||||
crypto_onetimeauth_poly1305_state state;
|
||||
unsigned char block0[64U];
|
||||
unsigned char slen[8U];
|
||||
unsigned char mac[crypto_aead_chacha20poly1305_ABYTES];
|
||||
unsigned long long mlen;
|
||||
int ret;
|
||||
|
||||
(void) nsec;
|
||||
if (mlen_p != NULL) {
|
||||
*mlen_p = 0ULL;
|
||||
}
|
||||
if (clen < crypto_aead_chacha20poly1305_ABYTES) {
|
||||
return -1;
|
||||
}
|
||||
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_aead_chacha20poly1305_ABYTES;
|
||||
crypto_onetimeauth_poly1305_update(&state, c, mlen);
|
||||
crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf);
|
||||
|
||||
_u64_le_from_ull(slen, adlen);
|
||||
crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
|
||||
|
||||
_u64_le_from_ull(slen, mlen);
|
||||
crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
|
||||
|
||||
crypto_onetimeauth_poly1305_final(&state, mac);
|
||||
sodium_memzero(&state, sizeof state);
|
||||
|
||||
(void) sizeof(int[sizeof mac == 16U ? 1 : -1]);
|
||||
ret = crypto_verify_16(mac, c + mlen);
|
||||
sodium_memzero(mac, sizeof mac);
|
||||
if (ret != 0) {
|
||||
memset(m, 0, mlen);
|
||||
return -1;
|
||||
}
|
||||
crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, npub, 1U, k);
|
||||
if (mlen_p != NULL) {
|
||||
*mlen_p = mlen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -137,6 +252,11 @@ crypto_aead_chacha20poly1305_npubbytes(void) {
|
||||
return crypto_aead_chacha20poly1305_NPUBBYTES;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_aead_chacha20poly1305_ietf_npubbytes(void) {
|
||||
return crypto_aead_chacha20poly1305_IETF_NPUBBYTES;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_aead_chacha20poly1305_nsecbytes(void) {
|
||||
return crypto_aead_chacha20poly1305_NSECBYTES;
|
||||
|
||||
@@ -10,3 +10,13 @@ crypto_stream_chacha20_ref_xor_ic(unsigned char *c, const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
const unsigned char *n, uint64_t ic,
|
||||
const unsigned char *k);
|
||||
|
||||
int
|
||||
crypto_stream_chacha20_ietf_ref(unsigned char *c, unsigned long long clen,
|
||||
const unsigned char *n, const unsigned char *k);
|
||||
|
||||
int
|
||||
crypto_stream_chacha20_ietf_ref_xor_ic(unsigned char *c, const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
const unsigned char *n, uint32_t ic,
|
||||
const unsigned char *k);
|
||||
|
||||
@@ -91,6 +91,15 @@ chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
|
||||
x->input[15] = U8TO32_LITTLE(iv + 4);
|
||||
}
|
||||
|
||||
static void
|
||||
chacha_ietf_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
|
||||
{
|
||||
x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter);
|
||||
x->input[13] = U8TO32_LITTLE(iv + 0);
|
||||
x->input[14] = U8TO32_LITTLE(iv + 4);
|
||||
x->input[15] = U8TO32_LITTLE(iv + 8);
|
||||
}
|
||||
|
||||
static void
|
||||
chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, unsigned long long bytes)
|
||||
{
|
||||
@@ -248,6 +257,25 @@ crypto_stream_chacha20_ref(unsigned char *c, unsigned long long clen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
crypto_stream_chacha20_ietf_ref(unsigned char *c, unsigned long long clen,
|
||||
const unsigned char *n, const unsigned char *k)
|
||||
{
|
||||
struct chacha_ctx ctx;
|
||||
|
||||
if (!clen) {
|
||||
return 0;
|
||||
}
|
||||
(void) sizeof(int[crypto_stream_chacha20_KEYBYTES == 256 / 8 ? 1 : -1]);
|
||||
chacha_keysetup(&ctx, k);
|
||||
chacha_ietf_ivsetup(&ctx, n, NULL);
|
||||
memset(c, 0, clen);
|
||||
chacha_encrypt_bytes(&ctx, c, c, clen);
|
||||
sodium_memzero(&ctx, sizeof ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
crypto_stream_chacha20_ref_xor_ic(unsigned char *c, const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
@@ -269,6 +297,29 @@ crypto_stream_chacha20_ref_xor_ic(unsigned char *c, const unsigned char *m,
|
||||
chacha_keysetup(&ctx, k);
|
||||
chacha_ivsetup(&ctx, n, ic_bytes);
|
||||
chacha_encrypt_bytes(&ctx, m, c, mlen);
|
||||
|
||||
sodium_memzero(&ctx, sizeof ctx);
|
||||
sodium_memzero(ic_bytes, sizeof ic_bytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
crypto_stream_chacha20_ietf_ref_xor_ic(unsigned char *c, const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
const unsigned char *n, uint32_t ic,
|
||||
const unsigned char *k)
|
||||
{
|
||||
struct chacha_ctx ctx;
|
||||
uint8_t ic_bytes[4];
|
||||
|
||||
if (!mlen) {
|
||||
return 0;
|
||||
}
|
||||
U32TO8_LITTLE(ic_bytes, ic);
|
||||
chacha_keysetup(&ctx, k);
|
||||
chacha_ietf_ivsetup(&ctx, n, ic_bytes);
|
||||
chacha_encrypt_bytes(&ctx, m, c, mlen);
|
||||
sodium_memzero(&ctx, sizeof ctx);
|
||||
sodium_memzero(ic_bytes, sizeof ic_bytes);
|
||||
|
||||
|
||||
@@ -11,6 +11,11 @@ crypto_stream_chacha20_noncebytes(void) {
|
||||
return crypto_stream_chacha20_NONCEBYTES;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_stream_chacha20_ietf_noncebytes(void) {
|
||||
return crypto_stream_chacha20_IETF_NONCEBYTES;
|
||||
}
|
||||
|
||||
int
|
||||
crypto_stream_chacha20(unsigned char *c, unsigned long long clen,
|
||||
const unsigned char *n, const unsigned char *k)
|
||||
@@ -18,6 +23,13 @@ crypto_stream_chacha20(unsigned char *c, unsigned long long clen,
|
||||
return crypto_stream_chacha20_ref(c, clen, n, k);
|
||||
}
|
||||
|
||||
int
|
||||
crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen,
|
||||
const unsigned char *n, const unsigned char *k)
|
||||
{
|
||||
return crypto_stream_chacha20_ietf_ref(c, clen, n, k);
|
||||
}
|
||||
|
||||
int
|
||||
crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
@@ -27,6 +39,15 @@ crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m,
|
||||
return crypto_stream_chacha20_ref_xor_ic(c, m, mlen, n, ic, k);
|
||||
}
|
||||
|
||||
int
|
||||
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)
|
||||
{
|
||||
return crypto_stream_chacha20_ietf_ref_xor_ic(c, m, mlen, n, ic, k);
|
||||
}
|
||||
|
||||
int
|
||||
crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m,
|
||||
unsigned long long mlen, const unsigned char *n,
|
||||
@@ -34,3 +55,11 @@ crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m,
|
||||
{
|
||||
return crypto_stream_chacha20_ref_xor_ic(c, m, mlen, n, 0U, k);
|
||||
}
|
||||
|
||||
int
|
||||
crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m,
|
||||
unsigned long long mlen, const unsigned char *n,
|
||||
const unsigned char *k)
|
||||
{
|
||||
return crypto_stream_chacha20_ietf_ref_xor_ic(c, m, mlen, n, 0U, k);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ size_t crypto_aead_chacha20poly1305_abytes(void);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_aead_chacha20poly1305_encrypt(unsigned char *c,
|
||||
unsigned long long *clen,
|
||||
unsigned long long *clen_p,
|
||||
const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
const unsigned char *ad,
|
||||
@@ -40,7 +40,7 @@ int crypto_aead_chacha20poly1305_encrypt(unsigned char *c,
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_aead_chacha20poly1305_decrypt(unsigned char *m,
|
||||
unsigned long long *mlen,
|
||||
unsigned long long *mlen_p,
|
||||
unsigned char *nsec,
|
||||
const unsigned char *c,
|
||||
unsigned long long clen,
|
||||
@@ -48,6 +48,32 @@ int crypto_aead_chacha20poly1305_decrypt(unsigned char *m,
|
||||
unsigned long long adlen,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k);
|
||||
|
||||
#define crypto_aead_chacha20poly1305_IETF_NPUBBYTES 12U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_aead_chacha20poly1305_ietf_npubbytes(void);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_aead_chacha20poly1305_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_chacha20poly1305_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);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -28,6 +28,8 @@ size_t crypto_stream_chacha20_keybytes(void);
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_stream_chacha20_noncebytes(void);
|
||||
|
||||
/* ChaCha20 with a 64-bit nonce and a 64-bit counter, as originally designed */
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_stream_chacha20(unsigned char *c, unsigned long long clen,
|
||||
const unsigned char *n, const unsigned char *k);
|
||||
@@ -42,6 +44,27 @@ int crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
const unsigned char *n, uint64_t ic,
|
||||
const unsigned char *k);
|
||||
|
||||
/* ChaCha20 with a 96-bit nonce and a 32-bit counter (IETF) */
|
||||
|
||||
#define crypto_stream_chacha20_IETF_NONCEBYTES 12U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_stream_chacha20_ietf_noncebytes(void);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen,
|
||||
const unsigned char *n, const unsigned char *k);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m,
|
||||
unsigned long long mlen, const unsigned char *n,
|
||||
const unsigned char *k);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int 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);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2,24 +2,21 @@
|
||||
#define TEST_NAME "aead_chacha20poly1305"
|
||||
#include "cmptest.h"
|
||||
|
||||
static unsigned char firstkey[crypto_aead_chacha20poly1305_KEYBYTES]
|
||||
= { 0x42, 0x90, 0xbc, 0xb1, 0x54, 0x17, 0x35, 0x31, 0xf3, 0x14, 0xaf,
|
||||
0x57, 0xf3, 0xbe, 0x3b, 0x50, 0x06, 0xda, 0x37, 0x1e, 0xce, 0x27,
|
||||
0x2a, 0xfa, 0x1b, 0x5d, 0xbd, 0xd1, 0x10, 0x0a, 0x10, 0x07 };
|
||||
|
||||
static unsigned char m[10U]
|
||||
= { 0x86, 0xd0, 0x99, 0x74, 0x84, 0x0b, 0xde, 0xd2, 0xa5, 0xca };
|
||||
|
||||
static unsigned char nonce[crypto_aead_chacha20poly1305_NPUBBYTES]
|
||||
= { 0xcd, 0x7c, 0xf6, 0x7b, 0xe3, 0x9c, 0x79, 0x4a };
|
||||
|
||||
static unsigned char ad[10U]
|
||||
= { 0x87, 0xe2, 0x29, 0xd4, 0x50, 0x08, 0x45, 0xa0, 0x79, 0xc0 };
|
||||
|
||||
static unsigned char c[10U + crypto_aead_chacha20poly1305_ABYTES];
|
||||
|
||||
int main(void)
|
||||
static int
|
||||
tv(void)
|
||||
{
|
||||
static unsigned char firstkey[crypto_aead_chacha20poly1305_KEYBYTES]
|
||||
= { 0x42, 0x90, 0xbc, 0xb1, 0x54, 0x17, 0x35, 0x31, 0xf3, 0x14, 0xaf,
|
||||
0x57, 0xf3, 0xbe, 0x3b, 0x50, 0x06, 0xda, 0x37, 0x1e, 0xce, 0x27,
|
||||
0x2a, 0xfa, 0x1b, 0x5d, 0xbd, 0xd1, 0x10, 0x0a, 0x10, 0x07 };
|
||||
static unsigned char m[10U]
|
||||
= { 0x86, 0xd0, 0x99, 0x74, 0x84, 0x0b, 0xde, 0xd2, 0xa5, 0xca };
|
||||
static unsigned char nonce[crypto_aead_chacha20poly1305_NPUBBYTES]
|
||||
= { 0xcd, 0x7c, 0xf6, 0x7b, 0xe3, 0x9c, 0x79, 0x4a };
|
||||
static unsigned char ad[10U]
|
||||
= { 0x87, 0xe2, 0x29, 0xd4, 0x50, 0x08, 0x45, 0xa0, 0x79, 0xc0 };
|
||||
static unsigned char c[10U + crypto_aead_chacha20poly1305_ABYTES];
|
||||
|
||||
unsigned char m2[10U];
|
||||
unsigned long long clen;
|
||||
unsigned long long m2len;
|
||||
@@ -126,3 +123,139 @@ int main(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tv_ietf(void)
|
||||
{
|
||||
static unsigned char firstkey[crypto_aead_chacha20poly1305_KEYBYTES]
|
||||
= {
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
|
||||
};
|
||||
#define MESSAGE "Ladies and Gentlemen of the class of '99: If I could offer you " \
|
||||
"only one tip for the future, sunscreen would be it."
|
||||
static unsigned char m[114U];
|
||||
static unsigned char nonce[crypto_aead_chacha20poly1305_IETF_NPUBBYTES]
|
||||
= { 0x07, 0x00, 0x00, 0x00,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 };
|
||||
static unsigned char ad[12U]
|
||||
= { 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 };
|
||||
static unsigned char c[114U + crypto_aead_chacha20poly1305_ABYTES];
|
||||
|
||||
unsigned char m2[114U];
|
||||
unsigned long long clen;
|
||||
unsigned long long m2len;
|
||||
size_t i;
|
||||
|
||||
assert(sizeof MESSAGE - 1U == sizeof m);
|
||||
memcpy(m, MESSAGE, sizeof m);
|
||||
crypto_aead_chacha20poly1305_ietf_encrypt(c, &clen, m, sizeof m, ad, sizeof ad,
|
||||
NULL, nonce, firstkey);
|
||||
if (clen != sizeof m + crypto_aead_chacha20poly1305_abytes()) {
|
||||
printf("clen is not properly set\n");
|
||||
}
|
||||
for (i = 0U; i < sizeof c; ++i) {
|
||||
printf(",0x%02x", (unsigned int)c[i]);
|
||||
if (i % 8 == 7) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if (crypto_aead_chacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, sizeof c, ad,
|
||||
sizeof ad, nonce, firstkey) != 0) {
|
||||
printf("crypto_aead_chacha20poly1305_ietf_decrypt() failed\n");
|
||||
}
|
||||
if (m2len != sizeof c - crypto_aead_chacha20poly1305_abytes()) {
|
||||
printf("m2len is not properly set\n");
|
||||
}
|
||||
if (memcmp(m, m2, sizeof m) != 0) {
|
||||
printf("m != m2\n");
|
||||
}
|
||||
|
||||
for (i = 0U; i < sizeof c; i++) {
|
||||
c[i] ^= (i + 1U);
|
||||
if (crypto_aead_chacha20poly1305_ietf_decrypt(m2, NULL, NULL, c, sizeof c,
|
||||
ad, sizeof ad, nonce, firstkey)
|
||||
== 0 || memcmp(m, m2, sizeof m) == 0) {
|
||||
printf("message can be forged\n");
|
||||
}
|
||||
c[i] ^= (i + 1U);
|
||||
}
|
||||
crypto_aead_chacha20poly1305_ietf_encrypt(c, &clen, m, sizeof m, NULL, 0U, NULL,
|
||||
nonce, firstkey);
|
||||
if (clen != sizeof m + crypto_aead_chacha20poly1305_abytes()) {
|
||||
printf("clen is not properly set (adlen=0)\n");
|
||||
}
|
||||
for (i = 0U; i < sizeof c; ++i) {
|
||||
printf(",0x%02x", (unsigned int)c[i]);
|
||||
if (i % 8 == 7) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
if (crypto_aead_chacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, sizeof c,
|
||||
NULL, 0U, nonce, firstkey) != 0) {
|
||||
printf("crypto_aead_chacha20poly1305_ietf_decrypt() failed (adlen=0)\n");
|
||||
}
|
||||
if (m2len != sizeof c - crypto_aead_chacha20poly1305_abytes()) {
|
||||
printf("m2len is not properly set (adlen=0)\n");
|
||||
}
|
||||
if (memcmp(m, m2, sizeof m) != 0) {
|
||||
printf("m != m2 (adlen=0)\n");
|
||||
}
|
||||
|
||||
if (crypto_aead_chacha20poly1305_ietf_decrypt(
|
||||
m2, &m2len, NULL, c, crypto_aead_chacha20poly1305_ABYTES / 2, NULL,
|
||||
0U, nonce, firstkey) != -1) {
|
||||
printf("crypto_aead_chacha20poly1305_ietf_decrypt() worked with a short "
|
||||
"ciphertext\n");
|
||||
}
|
||||
if (crypto_aead_chacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, 0U, NULL, 0U,
|
||||
nonce, firstkey) != -1) {
|
||||
printf("crypto_aead_chacha20poly1305_ietf_decrypt() worked with an empty "
|
||||
"ciphertext\n");
|
||||
}
|
||||
|
||||
memcpy(c, m, sizeof m);
|
||||
crypto_aead_chacha20poly1305_ietf_encrypt(c, &clen, c, sizeof m, NULL, 0U, NULL,
|
||||
nonce, firstkey);
|
||||
if (clen != sizeof m + crypto_aead_chacha20poly1305_abytes()) {
|
||||
printf("clen is not properly set (adlen=0)\n");
|
||||
}
|
||||
for (i = 0U; i < sizeof c; ++i) {
|
||||
printf(",0x%02x", (unsigned int)c[i]);
|
||||
if (i % 8 == 7) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if (crypto_aead_chacha20poly1305_ietf_decrypt(c, &m2len, NULL, c, sizeof c,
|
||||
NULL, 0U, nonce, firstkey) != 0) {
|
||||
printf("crypto_aead_chacha20poly1305_ietf_decrypt() failed (adlen=0)\n");
|
||||
}
|
||||
if (m2len != sizeof c - crypto_aead_chacha20poly1305_abytes()) {
|
||||
printf("m2len is not properly set (adlen=0)\n");
|
||||
}
|
||||
if (memcmp(m, c, sizeof m) != 0) {
|
||||
printf("m != c (adlen=0)\n");
|
||||
}
|
||||
|
||||
assert(crypto_aead_chacha20poly1305_keybytes() > 0U);
|
||||
assert(crypto_aead_chacha20poly1305_ietf_npubbytes() > 0U);
|
||||
assert(crypto_aead_chacha20poly1305_nsecbytes() == 0U);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
tv();
|
||||
tv_ietf();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10,3 +10,54 @@
|
||||
,0x62,0xa4,0x69,0xe7,0x78,0x9b,0xcd,0x95
|
||||
,0x4e,0x65,0x8e,0xd3,0x84,0x23,0xe2,0x31
|
||||
,0x61,0xdc
|
||||
,0xd3,0x1a,0x8d,0x34,0x64,0x8e,0x60,0xdb
|
||||
,0x7b,0x86,0xaf,0xbc,0x53,0xef,0x7e,0xc2
|
||||
,0xa4,0xad,0xed,0x51,0x29,0x6e,0x08,0xfe
|
||||
,0xa9,0xe2,0xb5,0xa7,0x36,0xee,0x62,0xd6
|
||||
,0x3d,0xbe,0xa4,0x5e,0x8c,0xa9,0x67,0x12
|
||||
,0x82,0xfa,0xfb,0x69,0xda,0x92,0x72,0x8b
|
||||
,0x1a,0x71,0xde,0x0a,0x9e,0x06,0x0b,0x29
|
||||
,0x05,0xd6,0xa5,0xb6,0x7e,0xcd,0x3b,0x36
|
||||
,0x92,0xdd,0xbd,0x7f,0x2d,0x77,0x8b,0x8c
|
||||
,0x98,0x03,0xae,0xe3,0x28,0x09,0x1b,0x58
|
||||
,0xfa,0xb3,0x24,0xe4,0xfa,0xd6,0x75,0x94
|
||||
,0x55,0x85,0x80,0x8b,0x48,0x31,0xd7,0xbc
|
||||
,0x3f,0xf4,0xde,0xf0,0x8e,0x4b,0x7a,0x9d
|
||||
,0xe5,0x76,0xd2,0x65,0x86,0xce,0xc6,0x4b
|
||||
,0x61,0x16,0x1a,0xe1,0x0b,0x59,0x4f,0x09
|
||||
,0xe2,0x6a,0x7e,0x90,0x2e,0xcb,0xd0,0x60
|
||||
,0x06,0x91
|
||||
,0xd3,0x1a,0x8d,0x34,0x64,0x8e,0x60,0xdb
|
||||
,0x7b,0x86,0xaf,0xbc,0x53,0xef,0x7e,0xc2
|
||||
,0xa4,0xad,0xed,0x51,0x29,0x6e,0x08,0xfe
|
||||
,0xa9,0xe2,0xb5,0xa7,0x36,0xee,0x62,0xd6
|
||||
,0x3d,0xbe,0xa4,0x5e,0x8c,0xa9,0x67,0x12
|
||||
,0x82,0xfa,0xfb,0x69,0xda,0x92,0x72,0x8b
|
||||
,0x1a,0x71,0xde,0x0a,0x9e,0x06,0x0b,0x29
|
||||
,0x05,0xd6,0xa5,0xb6,0x7e,0xcd,0x3b,0x36
|
||||
,0x92,0xdd,0xbd,0x7f,0x2d,0x77,0x8b,0x8c
|
||||
,0x98,0x03,0xae,0xe3,0x28,0x09,0x1b,0x58
|
||||
,0xfa,0xb3,0x24,0xe4,0xfa,0xd6,0x75,0x94
|
||||
,0x55,0x85,0x80,0x8b,0x48,0x31,0xd7,0xbc
|
||||
,0x3f,0xf4,0xde,0xf0,0x8e,0x4b,0x7a,0x9d
|
||||
,0xe5,0x76,0xd2,0x65,0x86,0xce,0xc6,0x4b
|
||||
,0x61,0x16,0x6a,0x23,0xa4,0x68,0x1f,0xd5
|
||||
,0x94,0x56,0xae,0xa1,0xd2,0x9f,0x82,0x47
|
||||
,0x72,0x16
|
||||
,0xd3,0x1a,0x8d,0x34,0x64,0x8e,0x60,0xdb
|
||||
,0x7b,0x86,0xaf,0xbc,0x53,0xef,0x7e,0xc2
|
||||
,0xa4,0xad,0xed,0x51,0x29,0x6e,0x08,0xfe
|
||||
,0xa9,0xe2,0xb5,0xa7,0x36,0xee,0x62,0xd6
|
||||
,0x3d,0xbe,0xa4,0x5e,0x8c,0xa9,0x67,0x12
|
||||
,0x82,0xfa,0xfb,0x69,0xda,0x92,0x72,0x8b
|
||||
,0x1a,0x71,0xde,0x0a,0x9e,0x06,0x0b,0x29
|
||||
,0x05,0xd6,0xa5,0xb6,0x7e,0xcd,0x3b,0x36
|
||||
,0x92,0xdd,0xbd,0x7f,0x2d,0x77,0x8b,0x8c
|
||||
,0x98,0x03,0xae,0xe3,0x28,0x09,0x1b,0x58
|
||||
,0xfa,0xb3,0x24,0xe4,0xfa,0xd6,0x75,0x94
|
||||
,0x55,0x85,0x80,0x8b,0x48,0x31,0xd7,0xbc
|
||||
,0x3f,0xf4,0xde,0xf0,0x8e,0x4b,0x7a,0x9d
|
||||
,0xe5,0x76,0xd2,0x65,0x86,0xce,0xc6,0x4b
|
||||
,0x61,0x16,0x6a,0x23,0xa4,0x68,0x1f,0xd5
|
||||
,0x94,0x56,0xae,0xa1,0xd2,0x9f,0x82,0x47
|
||||
,0x72,0x16
|
||||
|
||||
+71
-4
@@ -2,7 +2,8 @@
|
||||
#define TEST_NAME "chacha20"
|
||||
#include "cmptest.h"
|
||||
|
||||
static void tv(void)
|
||||
static
|
||||
void tv(void)
|
||||
{
|
||||
static struct {
|
||||
const char *key_hex;
|
||||
@@ -21,8 +22,8 @@ static void tv(void)
|
||||
unsigned char key[crypto_stream_chacha20_KEYBYTES];
|
||||
unsigned char nonce[crypto_stream_chacha20_NONCEBYTES];
|
||||
unsigned char out[160];
|
||||
char out_hex[160 * 2 + 1];
|
||||
size_t i = 0U;
|
||||
char out_hex[160 * 2 + 1];
|
||||
size_t i = 0U;
|
||||
|
||||
do {
|
||||
sodium_hex2bin((unsigned char *)key, sizeof key, tests[i].key_hex,
|
||||
@@ -54,12 +55,78 @@ static void tv(void)
|
||||
printf("[%s]\n", out_hex);
|
||||
};
|
||||
|
||||
int main(void)
|
||||
static
|
||||
void tv_ietf(void)
|
||||
{
|
||||
static struct {
|
||||
const char *key_hex;
|
||||
const char *nonce_hex;
|
||||
uint32_t ic;
|
||||
} tests[]
|
||||
= { { "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"000000000000000000000000",
|
||||
0U },
|
||||
{ "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"000000000000000000000000",
|
||||
1U },
|
||||
{ "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"000000000000000000000000",
|
||||
1U },
|
||||
{ "00ff000000000000000000000000000000000000000000000000000000000000",
|
||||
"000000000000000000000000",
|
||||
2U },
|
||||
{ "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"000000000000000000000002",
|
||||
0U },
|
||||
{ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
|
||||
"000000090000004a00000000",
|
||||
1U }};
|
||||
unsigned char key[crypto_stream_chacha20_KEYBYTES];
|
||||
unsigned char nonce[crypto_stream_chacha20_IETF_NONCEBYTES];
|
||||
unsigned char out[160];
|
||||
char out_hex[160 * 2 + 1];
|
||||
size_t i = 0U;
|
||||
|
||||
do {
|
||||
sodium_hex2bin((unsigned char *)key, sizeof key, tests[i].key_hex,
|
||||
strlen(tests[i].key_hex), ": ", NULL, NULL);
|
||||
sodium_hex2bin(nonce, sizeof nonce, tests[i].nonce_hex,
|
||||
strlen(tests[i].nonce_hex), ": ", NULL, NULL);
|
||||
memset(out, 0, sizeof out);
|
||||
crypto_stream_chacha20_ietf_xor_ic(out, out, sizeof out, nonce, tests[i].ic, key);
|
||||
sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
|
||||
printf("[%s]\n", out_hex);
|
||||
} while (++i < (sizeof tests) / (sizeof tests[0]));
|
||||
|
||||
memset(out, 0x42, sizeof out);
|
||||
|
||||
assert(crypto_stream_chacha20_ietf(out, 0U, nonce, key) == 0);
|
||||
assert(crypto_stream_chacha20_ietf_xor(out, out, 0U, nonce, key) == 0);
|
||||
assert(crypto_stream_chacha20_ietf_xor(out, out, 0U, nonce, key) == 0);
|
||||
assert(crypto_stream_chacha20_ietf_xor_ic(out, out, 0U, nonce, 1U, key) == 0);
|
||||
|
||||
crypto_stream_chacha20_ietf_xor(out, out, sizeof out, nonce, key);
|
||||
sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
|
||||
printf("[%s]\n", out_hex);
|
||||
|
||||
crypto_stream_chacha20_ietf_xor_ic(out, out, sizeof out, nonce, 0U, key);
|
||||
sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
|
||||
printf("[%s]\n", out_hex);
|
||||
|
||||
crypto_stream_chacha20_ietf_xor_ic(out, out, sizeof out, nonce, 1U, key);
|
||||
sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out);
|
||||
printf("[%s]\n", out_hex);
|
||||
};
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
tv();
|
||||
tv_ietf();
|
||||
|
||||
assert(crypto_stream_chacha20_keybytes() > 0U);
|
||||
assert(crypto_stream_chacha20_noncebytes() > 0U);
|
||||
assert(crypto_stream_chacha20_ietf_noncebytes() > 0U);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6,3 +6,12 @@
|
||||
[b5dae3cbb3d7a42bc0521db92649f5373d15dfe15440bed1ae43ee14ba18818376e616393179040372008b06420b552b4791fc1ba85e11b31b54571e69aa66587a42c9d864fe77d65c6606553ec89c24cb9cd7640bc49b1acbb922aa046b8bffd818895e835afc147cfbf1e6e630ba6c4be5a53a0b69146cb5514cca9da27385dffb96b585eadb5759d8051270f47d81c7661da216a19f18d5e7b734bc440267]
|
||||
[42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242]
|
||||
[7a42c9d864fe77d65c6606553ec89c24cb9cd7640bc49b1acbb922aa046b8bffd818895e835afc147cfbf1e6e630ba6c4be5a53a0b69146cb5514cca9da27385dffb96b585eadb5759d8051270f47d81c7661da216a19f18d5e7b734bc440267918c466e1428f08745f37a99c77c7f2b1b244bd4162e8b86e4a8bf85358202954ced04b52fef7b3ba787744e715554285ecb0ed6e133c528d69d346abc0ce8b0]
|
||||
[76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee65869f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed29b721769ce64e43d57133b074d839d531ed1f28510afb45ace10a1f4b794d6f2d09a0e663266ce1ae7ed1081968a0758e718e997bd362c6b0c34634a9a0b35d]
|
||||
[9f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed29b721769ce64e43d57133b074d839d531ed1f28510afb45ace10a1f4b794d6f2d09a0e663266ce1ae7ed1081968a0758e718e997bd362c6b0c34634a9a0b35d012737681f7b5d0f281e3afde458bc1e73d2d313c9cf94c05ff3716240a248f21320a058d7b3566bd520daaa3ed2bf0ac5b8b120fb852773c3639734b45c91a4]
|
||||
[3aeb5224ecf849929b9d828db1ced4dd832025e8018b8160b82284f3c949aa5a8eca00bbb4a73bdad192b5c42f73f2fd4e273644c8b36125a64addeb006c13a096d68b9ff7b57e7090f880392effd5b297a83bbaf2fbe8cf5d4618965e3dc776cd430d9b4e7eda8a767fb0e860319aadb5fd96a855de1fbfc92cb0489190cfdd87da6dbf1f736a2d499941ca097e5170bd685578611323120cebf296181ed4f5]
|
||||
[72d54dfbf12ec44b362692df94137f328fea8da73990265ec1bbbea1ae9af0ca13b25aa26cb4a648cb9b9d1be65b2c0924a66c54d545ec1b7374f4872e99f096bf74dbd52cc4fc95ceb6097fe5e65358c9dbc0a5ecbf7894a132a9a54ae3e951f2e9f209aa9c3d9a877ac9dab62433d2961a17d103e455dfb7337c90f6857aad233065955a212b5c7a8eab4dc8a629e5b6b8ba914afd06de7177054b33d21c96]
|
||||
[c2c64d378cd536374ae204b9ef933fcd1a8b2288b3dfa49672ab765b54ee27c78a970e0e955c14f3a88e741b97c286f75f8fc299e8148362fa198a39531bed6d1a91288c874ec254f322c2a197340c55bb3e9b3998f7de2309486a0bb494abd20c9c5ef99c1370d61e77f408ac5514f49202bcc6828d45409d2d1416f8ae106b06ebd2541256264fa415bd54cb12e1d4449ed85299a1b7a249b75ff6c89b2e3f]
|
||||
[10f1e7e4d13b5915500fdd1fa32071c4c7d1f4c733c068030422aa9ac3d46c4ed2826446079faa0914c2d705d98b02a2b5129cd1de164eb9cbd083e8a2503c4e0a88837739d7bf4ef8ccacb0ea2bb9d69d56c394aa351dfda5bf459f0a2e9fe8e721f89255f9c486bf21679c683d4f9c5cf2fa27865526005b06ca374c86af3bdcbfbdcb83be65862ed5c20eae5a43241d6a92da6dca9a156be25297f51c2718]
|
||||
[c89ed3bfddb6b2b7594def12bd579475a64cbfe0448e1085c1e50042127e57c08fda71743f4816973f7edcdbcd0b4ca4dee10e5dbbab7be517c6876f2b48779652b3a5a693791b57124d9f5de16233868593b68571822a414660e8d881962e0c90c0260445dde84b568095479bc940e0f750de939c540cfb8992c1aae0127e0c48cac1357b95fd0cba8eeef2a869fb94df1481d6e8775fbfe7fd07dd486cddaa]
|
||||
[42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242]
|
||||
[52b3a5a693791b57124d9f5de16233868593b68571822a414660e8d881962e0c90c0260445dde84b568095479bc940e0f750de939c540cfb8992c1aae0127e0c48cac1357b95fd0cba8eeef2a869fb94df1481d6e8775fbfe7fd07dd486cddaaa563bad017bb86c4fd6325de2a7f0dde1eb0b865c4176442194488750ec4ed799efdff89c1fc27c46c97804cec1801665f28d0982f88d85729a010d5b75e655a]
|
||||
|
||||
Reference in New Issue
Block a user