Commit bb6be1a9 authored by Niels Möller's avatar Niels Möller

Update chacha-poly1305 for draft-irtf-cfrg-chacha20-poly1305-08.

parent c6319980
2015-01-30 Niels Möller <nisse@lysator.liu.se>
Update chacha-poly1305 for draft-irtf-cfrg-chacha20-poly1305-08.
* chacha-poly1305.h (CHACHA_POLY1305_NONCE_SIZE): Increase to 12
bytes, i.e., CHACHA_NONCE96_SIZE.
* chacha-poly1305.c (chacha_poly1305_set_nonce): Use
chacha_set_nonce96.
(poly1305_pad): New function.
(chacha_poly1305_encrypt): Use poly1305_pad.
(chacha_poly1305_digest): Call poly1305_pad, and format length
fields as a single poly1305 block.
* chacha-set-nonce.c (chacha_set_nonce96): New function.
* chacha.h (CHACHA_NONCE96_SIZE): New constant.
* testsuite/chacha-test.c: Add test for chacha with 96-bit nonce.
......
......@@ -2,7 +2,7 @@
AEAD mechanism based on chacha and poly1305.
Copyright (C) 2014 Niels Möller
Copyright (C) 2014, 2015 Niels Möller
This file is part of GNU Nettle.
......@@ -31,6 +31,20 @@
not, see http://www.gnu.org/licenses/.
*/
/* This implements chacha-poly1305 according to
draft-irtf-cfrg-chacha20-poly1305-08. The inputs to poly1305 are:
associated data
zero padding
ciphertext
zero padding
length of associated data (64-bit, little endian)
length of ciphertext (64-bit, little endian)
where the padding fields are 0-15 zero bytes, filling up to a
16-byte boundary.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
......@@ -62,7 +76,7 @@ chacha_poly1305_set_nonce (struct chacha_poly1305_ctx *ctx,
uint8_t subkey[32];
} u;
chacha_set_nonce (&ctx->chacha, nonce);
chacha_set_nonce96 (&ctx->chacha, nonce);
/* Generate authentication key */
_chacha_core (u.x, ctx->chacha.state, CHACHA_ROUNDS);
poly1305_set_key (&ctx->poly1305, u.subkey);
......@@ -84,6 +98,17 @@ poly1305_update (struct chacha_poly1305_ctx *ctx,
MD_UPDATE (ctx, length, data, COMPRESS, (void) 0);
}
static void
poly1305_pad (struct chacha_poly1305_ctx *ctx)
{
if (ctx->index)
{
memset (ctx->block + ctx->index, 0,
POLY1305_BLOCK_SIZE - ctx->index);
_poly1305_block(&ctx->poly1305, ctx->block, 1);
ctx->index = 0;
}
}
void
chacha_poly1305_update (struct chacha_poly1305_ctx *ctx,
size_t length, const uint8_t *data)
......@@ -102,12 +127,8 @@ chacha_poly1305_encrypt (struct chacha_poly1305_ctx *ctx,
return;
assert (ctx->data_size % CHACHA_POLY1305_BLOCK_SIZE == 0);
if (!ctx->data_size)
{
uint8_t buf[8];
LE_WRITE_UINT64 (buf, ctx->auth_size);
poly1305_update (ctx, sizeof(buf), buf);
}
poly1305_pad (ctx);
chacha_crypt (&ctx->chacha, length, dst, src);
poly1305_update (ctx, length, dst);
ctx->data_size += length;
......@@ -121,12 +142,8 @@ chacha_poly1305_decrypt (struct chacha_poly1305_ctx *ctx,
return;
assert (ctx->data_size % CHACHA_POLY1305_BLOCK_SIZE == 0);
if (!ctx->data_size)
{
uint8_t buf[8];
LE_WRITE_UINT64 (buf, ctx->auth_size);
poly1305_update (ctx, sizeof(buf), buf);
}
poly1305_pad (ctx);
poly1305_update (ctx, length, src);
chacha_crypt (&ctx->chacha, length, dst, src);
ctx->data_size += length;
......@@ -136,27 +153,14 @@ void
chacha_poly1305_digest (struct chacha_poly1305_ctx *ctx,
size_t length, uint8_t *digest)
{
uint8_t buf[8];
if (!ctx->data_size)
{
LE_WRITE_UINT64 (buf, ctx->auth_size);
poly1305_update (ctx, sizeof(buf), buf);
}
LE_WRITE_UINT64 (buf, ctx->data_size);
poly1305_update (ctx, sizeof(buf), buf);
uint8_t buf[16];
/* Final bytes. FIXME: Duplicated in poly1305_aes128.c */
if (ctx->index > 0)
{
assert (ctx->index < POLY1305_BLOCK_SIZE);
poly1305_pad (ctx);
LE_WRITE_UINT64 (buf, ctx->auth_size);
LE_WRITE_UINT64 (buf + 8, ctx->data_size);
ctx->block[ctx->index] = 1;
memset (ctx->block + ctx->index + 1,
0, POLY1305_BLOCK_SIZE - 1 - ctx->index);
_poly1305_block (&ctx->poly1305, buf, 1);
_poly1305_block (&ctx->poly1305, ctx->block, 0);
}
poly1305_digest (&ctx->poly1305, &ctx->s);
memcpy (digest, &ctx->s.b, length);
}
......@@ -53,7 +53,7 @@ extern "C" {
#define CHACHA_POLY1305_BLOCK_SIZE 64
/* FIXME: Any need for 128-bit variant? */
#define CHACHA_POLY1305_KEY_SIZE 32
#define CHACHA_POLY1305_NONCE_SIZE CHACHA_NONCE_SIZE
#define CHACHA_POLY1305_NONCE_SIZE CHACHA_NONCE96_SIZE
#define CHACHA_POLY1305_DIGEST_SIZE 16
struct chacha_poly1305_ctx
......
......@@ -4,13 +4,30 @@
void
test_main(void)
{
/* From draft-agl-tls-chacha20poly1305-04 */
/* From draft-irtf-cfrg-chacha20-poly1305-08 */
test_aead (&nettle_chacha_poly1305, NULL,
SHEX("4290bcb154173531f314af57f3be3b50"
"06da371ece272afa1b5dbdd1100a1007"), /* key */
SHEX("87e229d4500845a079c0"), /* auth data */
SHEX("86d09974840bded2a5ca"), /* plain text */
SHEX("e3e446f7ede9a19b62a4"), /* ciphertext */
SHEX("cd7cf67be39c794a"), /* nonce */
SHEX("677dabf4e3d24b876bb284753896e1d6")); /* tag */
SHEX("8081828384858687 88898a8b8c8d8e8f"
"9091929394959697 98999a9b9c9d9e9f"),
SHEX("50515253c0c1c2c3 c4c5c6c7"),
SHEX("4c61646965732061 6e642047656e746c"
"656d656e206f6620 74686520636c6173"
"73206f6620273939 3a20496620492063"
"6f756c64206f6666 657220796f75206f"
"6e6c79206f6e6520 74697020666f7220"
"7468652066757475 72652c2073756e73"
"637265656e20776f 756c642062652069"
"742e"),
SHEX("d31a8d34648e60db7b86afbc53ef7ec2"
"a4aded51296e08fea9e2b5a736ee62d6"
"3dbea45e8ca9671282fafb69da92728b"
"1a71de0a9e060b2905d6a5b67ecd3b36"
"92ddbd7f2d778b8c9803aee328091b58"
"fab324e4fad675945585808b4831d7bc"
"3ff4def08e4b7a9de576d26586cec64b"
"6116"),
/* The draft splits the nonce into a "common part" and an
iv, and it seams the "common part" is the first 4
bytes. */
SHEX("0700000040414243 44454647"),
SHEX("1ae10b594f09e26a 7e902ecbd0600691"));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment