mirror of
https://github.com/jedisct1/libsodium.git
synced 2026-08-25 08:37:13 +09:00
Interleave stream encryption and Poly1305 on cache-sized chunks
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
|
||||
static const unsigned char _pad0[16] = { 0 };
|
||||
|
||||
#define STREAM_POLY1305_CHUNK 131072
|
||||
|
||||
int
|
||||
crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c,
|
||||
unsigned char *mac,
|
||||
@@ -42,9 +44,22 @@ crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c,
|
||||
STORE64_LE(slen, (uint64_t) adlen);
|
||||
crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
|
||||
|
||||
crypto_stream_chacha20_xor_ic(c, m, mlen, npub, 1U, k);
|
||||
{
|
||||
unsigned long long off = 0U;
|
||||
uint64_t ic = 1U;
|
||||
|
||||
crypto_onetimeauth_poly1305_update(&state, c, mlen);
|
||||
COMPILER_ASSERT(STREAM_POLY1305_CHUNK % 64U == 0U);
|
||||
while (off < mlen) {
|
||||
unsigned long long cl = mlen - off;
|
||||
if (cl > STREAM_POLY1305_CHUNK) {
|
||||
cl = STREAM_POLY1305_CHUNK;
|
||||
}
|
||||
crypto_stream_chacha20_xor_ic(c + off, m + off, cl, npub, ic, k);
|
||||
crypto_onetimeauth_poly1305_update(&state, c + off, cl);
|
||||
off += cl;
|
||||
ic += cl / 64U;
|
||||
}
|
||||
}
|
||||
STORE64_LE(slen, (uint64_t) mlen);
|
||||
crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
|
||||
|
||||
@@ -112,9 +127,22 @@ crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c,
|
||||
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);
|
||||
{
|
||||
unsigned long long off = 0U;
|
||||
uint32_t ic = 1U;
|
||||
|
||||
crypto_onetimeauth_poly1305_update(&state, c, mlen);
|
||||
while (off < mlen) {
|
||||
unsigned long long cl = mlen - off;
|
||||
if (cl > STREAM_POLY1305_CHUNK) {
|
||||
cl = STREAM_POLY1305_CHUNK;
|
||||
}
|
||||
crypto_stream_chacha20_ietf_xor_ic(c + off, m + off, cl,
|
||||
npub, ic, k);
|
||||
crypto_onetimeauth_poly1305_update(&state, c + off, cl);
|
||||
off += cl;
|
||||
ic += (uint32_t) (cl / 64U);
|
||||
}
|
||||
}
|
||||
crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf);
|
||||
|
||||
STORE64_LE(slen, (uint64_t) adlen);
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
static const unsigned char _pad0[16] = { 0 };
|
||||
|
||||
#define STREAM_POLY1305_CHUNK 131072
|
||||
|
||||
static int
|
||||
_encrypt_detached(unsigned char *c,
|
||||
unsigned char *mac,
|
||||
@@ -43,9 +45,31 @@ _encrypt_detached(unsigned char *c,
|
||||
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);
|
||||
{
|
||||
unsigned long long off = 0U;
|
||||
uint32_t ic = 1U;
|
||||
/*
|
||||
* The ietf_ext counter is 32-bit and overflows into the IV past
|
||||
* ~256 GiB, which a chunk restart cannot reproduce, so oversized
|
||||
* messages make a single pass instead.
|
||||
*/
|
||||
unsigned long long chunk = mlen <= 64ULL * (0xffffffffULL - 1ULL)
|
||||
? STREAM_POLY1305_CHUNK
|
||||
: mlen;
|
||||
|
||||
crypto_onetimeauth_poly1305_update(&state, c, mlen);
|
||||
COMPILER_ASSERT(STREAM_POLY1305_CHUNK % 64U == 0U);
|
||||
while (off < mlen) {
|
||||
unsigned long long cl = mlen - off;
|
||||
if (cl > chunk) {
|
||||
cl = chunk;
|
||||
}
|
||||
crypto_stream_chacha20_ietf_ext_xor_ic(c + off, m + off, cl,
|
||||
npub, ic, k);
|
||||
crypto_onetimeauth_poly1305_update(&state, c + off, cl);
|
||||
off += cl;
|
||||
ic += (uint32_t) (cl / 64U);
|
||||
}
|
||||
}
|
||||
crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf);
|
||||
|
||||
STORE64_LE(slen, (uint64_t) adlen);
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "private/common.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define STREAM_POLY1305_CHUNK 131072
|
||||
|
||||
int
|
||||
crypto_secretbox_detached(unsigned char *c, unsigned char *mac,
|
||||
const unsigned char *m,
|
||||
@@ -60,13 +62,27 @@ crypto_secretbox_detached(unsigned char *c, unsigned char *mac,
|
||||
c[i] = block0[crypto_secretbox_ZEROBYTES + i];
|
||||
}
|
||||
sodium_memzero(block0, sizeof block0);
|
||||
if (mlen > mlen0) {
|
||||
crypto_stream_salsa20_xor_ic(c + mlen0, m + mlen0, mlen - mlen0,
|
||||
n + 16, 1U, subkey);
|
||||
|
||||
crypto_onetimeauth_poly1305_update(&state, c, mlen0);
|
||||
{
|
||||
unsigned long long off = mlen0;
|
||||
uint64_t ic = 1U;
|
||||
|
||||
COMPILER_ASSERT(STREAM_POLY1305_CHUNK % 64U == 0U);
|
||||
while (off < mlen) {
|
||||
unsigned long long cl = mlen - off;
|
||||
if (cl > STREAM_POLY1305_CHUNK) {
|
||||
cl = STREAM_POLY1305_CHUNK;
|
||||
}
|
||||
crypto_stream_salsa20_xor_ic(c + off, m + off, cl,
|
||||
n + 16, ic, subkey);
|
||||
crypto_onetimeauth_poly1305_update(&state, c + off, cl);
|
||||
off += cl;
|
||||
ic += cl / 64U;
|
||||
}
|
||||
}
|
||||
sodium_memzero(subkey, sizeof subkey);
|
||||
|
||||
crypto_onetimeauth_poly1305_update(&state, c, mlen);
|
||||
crypto_onetimeauth_poly1305_final(&state, mac);
|
||||
sodium_memzero(&state, sizeof state);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user