Skip to content

Commit

Permalink
Remove devision for aad pos calculation
Browse files Browse the repository at this point in the history
Slighly change buffer size behaviour
  • Loading branch information
jonasschnelli committed Mar 22, 2019
1 parent 2edcbf3 commit 3ed011c
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 37 deletions.
2 changes: 1 addition & 1 deletion bench.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ static void bench_chacha20poly1305_crypt(void *data) {

uint8_t buffer[BUFFER_SIZE + 16];
for (i = 0; i < 30; i++) {
chacha20poly1305_crypt(ctx, seqnr, buffer, buffer, BUFFER_SIZE - 3, 1);
chacha20poly1305_crypt(ctx, seqnr, seqnr, 0, buffer, BUFFER_SIZE+16, buffer, BUFFER_SIZE, 1);
}
}

Expand Down
47 changes: 24 additions & 23 deletions chachapoly_aead.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <stdio.h>
#include <inttypes.h>

#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && \
#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && \
!defined(__WINDOWS__)
#define __WINDOWS__
#endif
Expand Down Expand Up @@ -95,60 +95,63 @@ int chacha20poly1305_init(struct chachapolyaead_ctx *ctx, const uint8_t *k_1,
return 0;
}

int chacha20poly1305_crypt(struct chachapolyaead_ctx *ctx, uint64_t seqnr,
uint8_t *dest, const uint8_t *src, uint32_t len,
int chacha20poly1305_crypt(struct chachapolyaead_ctx *ctx, uint64_t seqnr, uint64_t seqnr_aad,
int pos_aad,
uint8_t *dest, size_t dest_len, const uint8_t *src, size_t src_len,
int is_encrypt) {
uint8_t seqbuf[8];
const uint8_t one[8] = {1, 0, 0, 0, 0, 0, 0, 0}; /* NB little-endian */
uint64_t aad_chacha_nonce_hdr = 0;
uint8_t expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
int r = -1;
int aad_pos = 0;

if (
// if we encrypt, make sure the source contains at least the expected AAD and the destination has at least space for the source + MAC
(is_encrypt && (src_len < CHACHA20_POLY1305_AEAD_AAD_LEN || dest_len < src_len + POLY1305_TAGLEN)) ||
// if we decrypt, make sure the source contains at least the expected AAD+MAC and the destination has at least space for the source - MAc
(!is_encrypt && (src_len < CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN || dest_len < src_len - POLY1305_TAGLEN))) {
return r;
}

uint64_t chacha_iv = htole64(seqnr);
memset(poly_key, 0, sizeof(poly_key));
chacha_ivsetup(&ctx->main_ctx, (uint8_t *)&chacha_iv, NULL);
chacha_encrypt_bytes(&ctx->main_ctx, poly_key, poly_key, sizeof(poly_key));

if (!is_encrypt) {
const uint8_t *tag = src + CHACHA20_POLY1305_AEAD_AAD_LEN + len;
const uint8_t *tag = src + src_len - POLY1305_TAGLEN;

poly1305_auth(expected_tag, src, CHACHA20_POLY1305_AEAD_AAD_LEN + len, poly_key);
poly1305_auth(expected_tag, src, src_len - POLY1305_TAGLEN, poly_key);
if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) {
r = -1;
goto out;
}
/* MAC has been successfully verified, make sure we don't covert it in decryption */
src_len -= POLY1305_TAGLEN;
}

// add AAD (encrypted length)
aad_pos = seqnr % AAD_PACKAGES_PER_ROUND * CHACHA20_POLY1305_AEAD_AAD_LEN; // the current position in the keystream
seqnr = seqnr / AAD_PACKAGES_PER_ROUND; // 21 x 3byte length packages fits in a ChaCha20 round
if (ctx->cached_aad_seqnr != seqnr) {
ctx->cached_aad_seqnr = seqnr;
aad_chacha_nonce_hdr = htole64(seqnr);
/* add AAD (encrypted length) */
if (ctx->cached_aad_seqnr != seqnr_aad) {
ctx->cached_aad_seqnr = seqnr_aad;
aad_chacha_nonce_hdr = htole64(seqnr_aad);
chacha_ivsetup(&ctx->header_ctx, (uint8_t *)&aad_chacha_nonce_hdr, NULL); // block counter 0
chacha_encrypt_bytes(&ctx->header_ctx, NULL, ctx->aad_keystream_buffer, CHACHA20_ROUND_OUTPUT);
}
printf("(CRYPT) keystream at pos %d with seq %" PRIu64 ": %d %d %d\n", aad_pos, seqnr, ctx->aad_keystream_buffer[aad_pos+0], ctx->aad_keystream_buffer[aad_pos+1], ctx->aad_keystream_buffer[aad_pos+2]);
// crypt the AAD (3 byte length)
/* crypt the AAD (3 byte length) */
dest[0] = XOR(src[0], ctx->aad_keystream_buffer[aad_pos+0]);
dest[1] = XOR(src[1], ctx->aad_keystream_buffer[aad_pos+1]);
dest[2] = XOR(src[2], ctx->aad_keystream_buffer[aad_pos+2]);

printf("(CRYPT) m: %d %d %d <-> c: %d %d %d\n", (uint8_t)src[0], (uint8_t)src[1], (uint8_t)src[2], dest[0], dest[1], dest[2]);

/* Set Chacha's block counter to 1 */
/* Set Chacha's block counter to 1 and encipher */
chacha_ivsetup(&ctx->main_ctx, (uint8_t *)&chacha_iv, one);
chacha_encrypt_bytes(&ctx->main_ctx, src + CHACHA20_POLY1305_AEAD_AAD_LEN, dest + CHACHA20_POLY1305_AEAD_AAD_LEN, len);
chacha_encrypt_bytes(&ctx->main_ctx, src + CHACHA20_POLY1305_AEAD_AAD_LEN, dest + CHACHA20_POLY1305_AEAD_AAD_LEN, src_len - CHACHA20_POLY1305_AEAD_AAD_LEN);

/* If encrypting, calculate and append tag */
if (is_encrypt) {
poly1305_auth(dest + CHACHA20_POLY1305_AEAD_AAD_LEN + len, dest, CHACHA20_POLY1305_AEAD_AAD_LEN + len, poly_key);
poly1305_auth(dest + src_len, dest, src_len, poly_key);
}
r = 0;
out:
memory_cleanse(expected_tag, sizeof(expected_tag));
memory_cleanse(seqbuf, sizeof(seqbuf));
memory_cleanse(&chacha_iv, sizeof(chacha_iv));
memory_cleanse(poly_key, sizeof(poly_key));
return r;
Expand All @@ -175,8 +178,6 @@ int chacha20poly1305_get_length(struct chachapolyaead_ctx *ctx,
XOR(ciphertext[1], ctx->aad_keystream_buffer[pos+1]) << 8 |
XOR(ciphertext[2], ctx->aad_keystream_buffer[pos+2]) << 16;

printf("(LENGTH) keystream at pos %d with seq %" PRIu64 ": %d %d %d\n", pos, seqnr, ctx->aad_keystream_buffer[pos+0], ctx->aad_keystream_buffer[pos+1], ctx->aad_keystream_buffer[pos+2]);
printf("(LENGTH) m: %d %d %d <-> c: %d %d %d\n", (uint8_t)len_out[0], (uint8_t)len_out[1], (uint8_t)len_out[2], ciphertext[0], ciphertext[1], ciphertext[2]);
/* convert to host endianness 32bit integer (only 24bit though) */
*len_out = le32toh(*len_out);
return 0;
Expand Down
5 changes: 3 additions & 2 deletions chachapoly_aead.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ struct chachapolyaead_ctx {

int chacha20poly1305_init(struct chachapolyaead_ctx *cpctx, const uint8_t *k_1,
int k_1_len, const uint8_t *k_2, int k_2_len);
int chacha20poly1305_crypt(struct chachapolyaead_ctx *ctx, uint64_t seqnr,
uint8_t *dest, const uint8_t *src, uint32_t len,
int chacha20poly1305_crypt(struct chachapolyaead_ctx *ctx, uint64_t seqnr, uint64_t seqnr_aad,
int pos_aad,
uint8_t *dest, size_t dest_len, const uint8_t *src, size_t srv_len,
int is_encrypt);
int chacha20poly1305_get_length(struct chachapolyaead_ctx *ctx,
uint32_t *len_out, uint64_t seqnr,
Expand Down
22 changes: 11 additions & 11 deletions tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,16 @@ int main(void) {
/* test chacha20poly1305 AEAD */
struct chachapolyaead_ctx aead_ctx;
uint32_t seqnr = 0;
uint32_t seqnr_aad = 0;
int pos_aad = 0;
uint8_t aead_k_1[64] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
uint8_t aead_k_2[64] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00};
uint8_t aead_k_2[64] = {
0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};

uint8_t plaintext_buf[256] = {
0xff, 0x00, 0x00, 0xf1, 0x95, 0xe6, 0x69, 0x82, 0x10, 0x5f, 0xfb,
Expand All @@ -192,17 +194,15 @@ int main(void) {
0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a, 0x6d, 0xeb, 0x3a, 0xb7,
0x8f, 0xab, 0x78, 0xc9};

uint8_t ciphertext_buf[300];
uint8_t plaintext_buf_new[256];
memset(ciphertext_buf, 0, 300);
memset(plaintext_buf_new, 0, 256);
uint8_t ciphertext_buf[255+16] = {0};
uint8_t plaintext_buf_new[255] = {0};
chacha20poly1305_init(&aead_ctx, aead_k_1, 32, aead_k_2, 32);
assert((uint32_t)plaintext_buf[0] == 255);
chacha20poly1305_crypt(&aead_ctx, seqnr, ciphertext_buf, plaintext_buf, 252, 1);
chacha20poly1305_crypt(&aead_ctx, seqnr, seqnr_aad, pos_aad, ciphertext_buf, 300, plaintext_buf, 255, 1);
uint32_t out_len = 0;
chacha20poly1305_get_length(&aead_ctx, &out_len, seqnr, ciphertext_buf);
assert(out_len == 255);
chacha20poly1305_crypt(&aead_ctx, seqnr, plaintext_buf_new, ciphertext_buf,
252, 0);
chacha20poly1305_crypt(&aead_ctx, seqnr, seqnr_aad, pos_aad, plaintext_buf_new, 255, ciphertext_buf,
sizeof(ciphertext_buf), 0);
assert(memcmp(plaintext_buf, plaintext_buf_new, 252) == 0);
}

0 comments on commit 3ed011c

Please sign in to comment.