Looking at http://www.lysator.liu.se/~nisse/nettle/plan.html, the most important things are done. I think documentation is the only item left which is both important and requires several hours of work.
* Versioned symbols. I think this is complete, I just have forgotten to merge that branch.
* Base64 with other alphabets. A patch was posted to the list some month ago, I had some comments, and then it seems to have stalled. If it's desirable to break the ABI to implement it, 3.1 may be the last chance for some years time.
* OCB mode. Is it a good idea to try to get this into the release? I don't think patents are a problem, but I've mailed sflc, and it would be nice to get their opinion too. Needs not just the code, but also test cases and documentation.
* Also OFB mode has been requested, used by openpgp, iirc.
Anything else I've missed? And which of the above items are important?
There are a lot of things that could be better optimized, including the curve25519 code and the aesni code, but I don't think the release should be delayed for that.
Regards, /Niels
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
Aloha!
Niels Möller wrote:
- OCB mode. Is it a good idea to try to get this into the release? I
don't think patents are a problem, but I've mailed sflc, and it would be nice to get their opinion too. Needs not just the code, but also test cases and documentation.
IANAL, but License 1 for OCB should be very much in line with nettle: http://web.cs.ucdavis.edu/~rogaway/ocb/license.htm
The problem I have with it is that it specifies Open-Source _Software_ implementations. Since I work on open source HW implementations I would like to do OCB and that limitation is a bit of a problem.
OCB seems to be a very nice alternative/completent to GCM and CCM.
- -- Med vänlig hälsning, Yours
Joachim Strömbergson - Alltid i harmonisk svängning. ======================================================================== Joachim Strömbergson Secworks AB joachim@secworks.se ========================================================================
Joachim Strömbergson joachim@secworks.se writes:
IANAL, but License 1 for OCB should be very much in line with nettle: http://web.cs.ucdavis.edu/~rogaway/ocb/license.htm
The problem I have with it is that it specifies Open-Source _Software_ implementations. Since I work on open source HW implementations I would like to do OCB and that limitation is a bit of a problem.
I also noticed that, but it's an unlikely problem for nettle. In theory I guess one could tart from a C implementation in nettle and translate it to verilog/vhdl code for a hardware design, but I suspect that's not a good way to do it.
I see another potential problem. We allow proprietary programs to link with Nettle (under LGPLv3 terms). As far as I understand, such a program can't be sold or distributed without negotiating a separate patent license. Which seems a bit contrary to the spirit og the LGPL.
But I don't fully understand the implications of the patent language in the GPLv3, section 11. Is the extra patent license requirement a problem for LGPL distribution of Nettle? Or does it mean that it's only a problem for the party distributing the proprietary (or free but non-public) stuff, who must arrange that his/her patent license is properly extended to comply with the GPLv3 text?
OCB seems to be a very nice alternative/completent to GCM and CCM.
How does it compare to EAX, which is also very nice and simple. Is OCB faster than EAX? (I haven't yet digested the definition of OCB).
Regards, /Niels
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
Aloha!
Niels Möller wrote:
I also noticed that, but it's an unlikely problem for nettle. In theory I guess one could tart from a C implementation in nettle and translate it to verilog/vhdl code for a hardware design, but I suspect that's not a good way to do it.
Sorry, my bad. I didn't imply that the constraint had anything to do with Nettle, just my personal problem with it. I am involved in open source hardware projects where these issues appears.
- -- Med vänlig hälsning, Yours
Joachim Strömbergson - Alltid i harmonisk svängning. ======================================================================== Joachim Strömbergson Secworks AB joachim@secworks.se ========================================================================
On 29/01/2015 9:35 a.m., Niels Möller wrote:
Looking at http://www.lysator.liu.se/~nisse/nettle/plan.html, the most important things are done. I think documentation is the only item left which is both important and requires several hours of work.
- Base64 with other alphabets. A patch was posted to the list some month ago, I had some comments, and then it seems to have stalled. If it's desirable to break the ABI to implement it, 3.1 may be the last chance for some years time.
Sorry for the stall, I will prioritize re-working it as todays task.
Amos
On Wed, 2015-01-28 at 21:35 +0100, Niels Möller wrote:
Looking at http://www.lysator.liu.se/~nisse/nettle/plan.html, the most important things are done. I think documentation is the only item left which is both important and requires several hours of work.
- Versioned symbols. I think this is complete, I just have forgotten to merge that branch.
- Base64 with other alphabets. A patch was posted to the list some month ago, I had some comments, and then it seems to have stalled. If it's desirable to break the ABI to implement it, 3.1 may be the last chance for some years time.
- OCB mode. Is it a good idea to try to get this into the release? I don't think patents are a problem, but I've mailed sflc, and it would be nice to get their opinion too. Needs not just the code, but also test cases and documentation.
- Also OFB mode has been requested, used by openpgp, iirc.
Anything else I've missed? And which of the above items are important?
For me OCB is low priority. The draft has been defined now and it could take years before it translates to something I could include in gnutls. Chacha with poly (not in the list above) however is more important to me to implement the final draft (on the current state the algorithm is fixed, only typos and other non-essential parts can be changed) https://tools.ietf.org/html/draft-irtf-cfrg-chacha20-poly1305-08
There are a lot of things that could be better optimized, including the curve25519 code and the aesni code, but I don't think the release should be delayed for that.
I also believe so. If I can rely on that ABI, I'll release gnutls 3.4.0 based on 3.1.
regards, Nikos
Nikos Mavrogiannopoulos nmav@gnutls.org writes:
For me OCB is low priority.
Ok, let's leave ocb for now (I will still consider it if someone else writes a complete patch, including testcases and docs, in time for the release).
Chacha with poly (not in the list above) however is more important to me to implement the final draft (on the current state the algorithm is fixed, only typos and other non-essential parts can be changed) https://tools.ietf.org/html/draft-irtf-cfrg-chacha20-poly1305-08
Thanks for the reminder. I agree that makes a lot of sense for 3.1. You have done some work to update of Nettle's implementation, but I don't remember the status?
It would be nice if the interface makes it possible to implement the other variants, like what's used in openssh, and nacl (or maybe nacl is using salsa20 rather than chacha?)?
Regards, /Niels
On Thu, Jan 29, 2015 at 9:18 AM, Niels Möller nisse@lysator.liu.se wrote:
Chacha with poly (not in the list above) however is more important to me to implement the final draft (on the current state the algorithm is fixed, only typos and other non-essential parts can be changed) https://tools.ietf.org/html/draft-irtf-cfrg-chacha20-poly1305-08
Thanks for the reminder. I agree that makes a lot of sense for 3.1. You have done some work to update of Nettle's implementation, but I don't remember the status?
I don't think I have anything. I remember I had an initial patch for the issues in https://www.mail-archive.com/nettle-bugs@lists.lysator.liu.se/msg01109.html but didn't pass the test vectors. I can't find it patch though.
It would be nice if the interface makes it possible to implement the other variants, like what's used in openssh, and nacl (or maybe nacl is using salsa20 rather than chacha?)?
Is it final then that openssh will not use the updated draft?
regards, Nikos
Nikos Mavrogiannopoulos nmav@gnutls.org writes:
I don't think I have anything. I remember I had an initial patch for the issues in https://www.mail-archive.com/nettle-bugs@lists.lysator.liu.se/msg01109.html but didn't pass the test vectors. I can't find it patch though.
I'm adding it to plan.html, so I don't forget it.
Is it final then that openssh will not use the updated draft?
No idea. There have been no recent discussions on the ietf ssh list, and I don't follow openssh development.
But the ssh protocol is a bit special, since it encrypts the packet length field. With cacha-poly1305, I think it's natural to use the left over bits of block 0 and xor them to the packet length, but iirc openssh used a separately keyed chacha instance instead.
Regards, /Niels
nisse@lysator.liu.se (Niels Möller) writes:
Nikos Mavrogiannopoulos nmav@gnutls.org writes:
For me OCB is low priority.
Ok, let's leave ocb for now (I will still consider it if someone else writes a complete patch, including testcases and docs, in time for the release).
Chacha with poly (not in the list above) however is more important to me to implement the final draft (on the current state the algorithm is fixed, only typos and other non-essential parts can be changed) https://tools.ietf.org/html/draft-irtf-cfrg-chacha20-poly1305-08
Thanks for the reminder. I agree that makes a lot of sense for 3.1. You have done some work to update of Nettle's implementation, but I don't remember the status?
Patch below (and also in the "chacha96"-branch in the public repo). Any comments before I merge it? In particular, is chacha_set_nonce96 a good name and function?
Regards, /Niels
diff --git a/ChangeLog b/ChangeLog index 00007fe..9fd2d8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +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. + 2015-01-27 Niels Möller nisse@lysator.liu.se
* ecc.h: Deleted declarations of unused itch functions. Moved diff --git a/chacha-poly1305.c b/chacha-poly1305.c index 35c4bfe..c5109b8 100644 --- a/chacha-poly1305.c +++ b/chacha-poly1305.c @@ -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); } diff --git a/chacha-poly1305.h b/chacha-poly1305.h index 9c2688b..ce40b77 100644 --- a/chacha-poly1305.h +++ b/chacha-poly1305.h @@ -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 diff --git a/chacha-set-nonce.c b/chacha-set-nonce.c index e73babc..607f176 100644 --- a/chacha-set-nonce.c +++ b/chacha-set-nonce.c @@ -59,3 +59,12 @@ chacha_set_nonce(struct chacha_ctx *ctx, const uint8_t *nonce) ctx->state[14] = LE_READ_UINT32(nonce + 0); ctx->state[15] = LE_READ_UINT32(nonce + 4); } + +void +chacha_set_nonce96(struct chacha_ctx *ctx, const uint8_t *nonce) +{ + ctx->state[12] = 0; + ctx->state[13] = LE_READ_UINT32(nonce + 0); + ctx->state[14] = LE_READ_UINT32(nonce + 4); + ctx->state[15] = LE_READ_UINT32(nonce + 8); +} diff --git a/chacha.h b/chacha.h index 41df707..3f08283 100644 --- a/chacha.h +++ b/chacha.h @@ -45,6 +45,7 @@ extern "C" { /* Name mangling */ #define chacha_set_key nettle_chacha_set_key #define chacha_set_nonce nettle_chacha_set_nonce +#define chacha_set_nonce96 nettle_chacha_set_nonce96 #define chacha_crypt nettle_chacha_crypt #define _chacha_core _nettle_chacha_core
@@ -52,6 +53,7 @@ extern "C" { #define CHACHA_KEY_SIZE 32 #define CHACHA_BLOCK_SIZE 64 #define CHACHA_NONCE_SIZE 8 +#define CHACHA_NONCE96_SIZE 12
#define _CHACHA_STATE_LENGTH 16
@@ -78,6 +80,9 @@ void chacha_set_nonce(struct chacha_ctx *ctx, const uint8_t *nonce);
void +chacha_set_nonce96(struct chacha_ctx *ctx, const uint8_t *nonce); + +void chacha_crypt(struct chacha_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src);
diff --git a/testsuite/chacha-poly1305-test.c b/testsuite/chacha-poly1305-test.c index 2f320f3..313e822 100644 --- a/testsuite/chacha-poly1305-test.c +++ b/testsuite/chacha-poly1305-test.c @@ -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")); } diff --git a/testsuite/chacha-test.c b/testsuite/chacha-test.c index 8c5630d..9edb941 100644 --- a/testsuite/chacha-test.c +++ b/testsuite/chacha-test.c @@ -44,20 +44,30 @@ test_chacha(const struct tstring *key, const struct tstring *nonce,
ASSERT (key->length == CHACHA_KEY_SIZE); chacha_set_key (&ctx, key->data); - ASSERT (nonce->length == CHACHA_NONCE_SIZE);
if (rounds == 20) { uint8_t *data = xalloc (expected->length + 2); - data++; size_t length; + data++;
for (length = 1; length <= expected->length; length++) { data[-1] = 17; memset (data, 0, length); data[length] = 17; - chacha_set_nonce(&ctx, nonce->data); + if (nonce->length == CHACHA_NONCE_SIZE) + chacha_set_nonce(&ctx, nonce->data); + else if (nonce->length == CHACHA_NONCE96_SIZE) + { + chacha_set_nonce96(&ctx, nonce->data); + /* Use initial counter 1, for + draft-irtf-cfrg-chacha20-poly1305-08 test cases. */ + ctx.state[12]++; + } + else + die ("Bad nonce size %u.\n", (unsigned) nonce->length); + chacha_crypt (&ctx, length, data, data);
ASSERT (data[-1] == 17); @@ -84,6 +94,7 @@ test_chacha(const struct tstring *key, const struct tstring *nonce, numbers of rounds. */ uint32_t out[_CHACHA_STATE_LENGTH]; ASSERT (expected->length == CHACHA_BLOCK_SIZE); + ASSERT (nonce->length == CHACHA_NONCE_SIZE);
chacha_set_nonce(&ctx, nonce->data); _chacha_core (out, ctx.state, rounds); @@ -622,4 +633,14 @@ test_main(void) "ae2c4c90225ba9ea 14d518f55929dea0" "98ca7a6ccfe61227 053c84e49a4a3332"), 20); + + /* From draft-irtf-cfrg-chacha20-poly1305-08, with 96-bit nonce */ + test_chacha(SHEX("0001020304050607 08090a0b0c0d0e0f" + "1011121314151617 18191a1b1c1d1e1f"), + SHEX("000000090000004a 00000000"), + SHEX("10f1e7e4d13b5915 500fdd1fa32071c4" + "c7d1f4c733c06803 0422aa9ac3d46c4e" + "d2826446079faa09 14c2d705d98b02a2" + "b5129cd1de164eb9 cbd083e8a2503c4e"), + 20); }
nisse@lysator.liu.se (Niels Möller) writes:
Patch below (and also in the "chacha96"-branch in the public repo). Any comments before I merge it? In particular, is chacha_set_nonce96 a good name and function?
Merged now. I've also merged the versioned-symbols branch.
Regards, /Niels
nettle-bugs@lists.lysator.liu.se