From: Daiki Ueno dueno@redhat.com
The ChaCha20 based header protection algorithm in QUIC requires a way to set the initial value of counter: https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-chacha20-based-...
This will add a new function chacha_set_nonce128, which takes the counter value embedded in the nonce.
Signed-off-by: Daiki Ueno dueno@redhat.com --- chacha-set-nonce.c | 9 +++++++++ chacha.h | 5 +++++ testsuite/chacha-test.c | 15 +++++++++++++++ 3 files changed, 29 insertions(+)
diff --git a/chacha-set-nonce.c b/chacha-set-nonce.c index 607f176b..7098de58 100644 --- a/chacha-set-nonce.c +++ b/chacha-set-nonce.c @@ -68,3 +68,12 @@ chacha_set_nonce96(struct chacha_ctx *ctx, const uint8_t *nonce) ctx->state[14] = LE_READ_UINT32(nonce + 4); ctx->state[15] = LE_READ_UINT32(nonce + 8); } + +void +chacha_set_nonce128(struct chacha_ctx *ctx, const uint8_t *nonce) +{ + ctx->state[12] = LE_READ_UINT32(nonce + 0); + ctx->state[13] = LE_READ_UINT32(nonce + 4); + ctx->state[14] = LE_READ_UINT32(nonce + 8); + ctx->state[15] = LE_READ_UINT32(nonce + 12); +} diff --git a/chacha.h b/chacha.h index 429a55b6..ff33f03d 100644 --- a/chacha.h +++ b/chacha.h @@ -46,6 +46,7 @@ extern "C" { #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_set_nonce128 nettle_chacha_set_nonce128 #define chacha_crypt nettle_chacha_crypt
/* Currently, only 256-bit keys are supported. */ @@ -53,6 +54,7 @@ extern "C" { #define CHACHA_BLOCK_SIZE 64 #define CHACHA_NONCE_SIZE 8 #define CHACHA_NONCE96_SIZE 12 +#define CHACHA_NONCE128_SIZE 16
#define _CHACHA_STATE_LENGTH 16
@@ -81,6 +83,9 @@ 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_set_nonce128(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-test.c b/testsuite/chacha-test.c index d6489e9c..4731598b 100644 --- a/testsuite/chacha-test.c +++ b/testsuite/chacha-test.c @@ -66,6 +66,10 @@ test_chacha(const struct tstring *key, const struct tstring *nonce, draft-irtf-cfrg-chacha20-poly1305-08 test cases. */ ctx.state[12]++; } + else if (nonce->length == CHACHA_NONCE128_SIZE) + { + chacha_set_nonce128(&ctx, nonce->data); + } else die ("Bad nonce size %u.\n", (unsigned) nonce->length);
@@ -644,4 +648,15 @@ test_main(void) "d2826446079faa09 14c2d705d98b02a2" "b5129cd1de164eb9 cbd083e8a2503c4e"), 20); + + /* This is identical to the 96-bit nonce test, but it manually sets + the counter value */ + test_chacha(SHEX("0001020304050607 08090a0b0c0d0e0f" + "1011121314151617 18191a1b1c1d1e1f"), + SHEX("0100000000000009 0000004a00000000"), + SHEX("10f1e7e4d13b5915 500fdd1fa32071c4" + "c7d1f4c733c06803 0422aa9ac3d46c4e" + "d2826446079faa09 14c2d705d98b02a2" + "b5129cd1de164eb9 cbd083e8a2503c4e"), + 20); }
Daiki Ueno ueno@gnu.org writes:
The ChaCha20 based header protection algorithm in QUIC requires a way to set the initial value of counter: https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-chacha20-based-...
Out of curiosity, are you aware on any quic implementation using Nettle?
This will add a new function chacha_set_nonce128, which takes the counter value embedded in the nonce.
I see two issues with this change as is.
First is purely an interface design issue. It may be more useful to have a separate function to set the 32-bit counter. E.g., that would be convenient for random access to a chacha-encrypted file.
The other is more subtle and with interop implications. The way the counter is currently updated in chacha_crypt still assumes a 64-bit counter (as in the original chacha papers with 64 bits each for nonce and counter). This is compatible with RFC 8439, as long as the counter is initialized to a small value such as 0 or 1. But if counter is initialized to a random 32-bit value, and is expected to wrap around mod 2^32, then Nettle will not work as expected but propagate carry into the first 32-bits of the nonce.
Not sure how to best deal with this.
It looks like chacha was added in Nettle-3.0, and chacha_set_nonce96 added in Nettle-3.1 (undocumented and used in the implementation of ChaCha-Poly1305). The Nettle-3.1 release also updated chacha-poly1305 to follow draft-irtf-cfrg-chacha20-poly1305-08 (which later evolved into RFC 8439, if I understood the document history correstly). It seems this change is not documented in the manual or in NEWS; the manual still says that chacha-poly1305 use 64-bit nonce and is experimental.
Regards, /Niels
Hello,
nisse@lysator.liu.se (Niels Möller) writes:
Daiki Ueno ueno@gnu.org writes:
The ChaCha20 based header protection algorithm in QUIC requires a way to set the initial value of counter: https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-chacha20-based-...
Out of curiosity, are you aware on any quic implementation using Nettle?
There is an ongoing effort to add an ngtcp2 backend based on GnuTLS, which surely uses Nettle under the hood: https://gitlab.com/gnutls/gnutls/-/merge_requests/1197
This will add a new function chacha_set_nonce128, which takes the counter value embedded in the nonce.
I see two issues with this change as is.
First is purely an interface design issue. It may be more useful to have a separate function to set the 32-bit counter. E.g., that would be convenient for random access to a chacha-encrypted file.
The other is more subtle and with interop implications. The way the counter is currently updated in chacha_crypt still assumes a 64-bit counter (as in the original chacha papers with 64 bits each for nonce and counter). This is compatible with RFC 8439, as long as the counter is initialized to a small value such as 0 or 1. But if counter is initialized to a random 32-bit value, and is expected to wrap around mod 2^32, then Nettle will not work as expected but propagate carry into the first 32-bits of the nonce.
Not sure how to best deal with this.
It looks like chacha was added in Nettle-3.0, and chacha_set_nonce96 added in Nettle-3.1 (undocumented and used in the implementation of ChaCha-Poly1305). The Nettle-3.1 release also updated chacha-poly1305 to follow draft-irtf-cfrg-chacha20-poly1305-08 (which later evolved into RFC 8439, if I understood the document history correstly). It seems this change is not documented in the manual or in NEWS; the manual still says that chacha-poly1305 use 64-bit nonce and is experimental.
For the QUIC use, I guess it would be acceptable that the 32-bit counter value is only accessible from the chacha_poly1305_* interface (i.e., chacha_poly1305_set_counter), as we would just need to trim the Poly1305 tag at the end of the ciphertext.
Regards,
nettle-bugs@lists.lysator.liu.se