From: Frédéric Lécaille Date: Wed, 8 Jun 2022 06:26:03 +0000 (+0200) Subject: MINOR: quic: Add several nonce and key definitions for Retry tag X-Git-Tag: v2.7-dev1~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3f96a0a4c100664985336dafeaae124c86e124f2;p=thirdparty%2Fhaproxy.git MINOR: quic: Add several nonce and key definitions for Retry tag The nonce and keys used to cipher the Retry tag depend on the QUIC version. Add these definitions for 0xff00001d (draft-29) and v2 QUIC version. At least draft-29 is useful for QUIC tracker tests with "quic-force-retry" enabled on haproxy side. Validated with -v 0xff00001d ngtcp2 option. Could not validate the v2 nonce and key at this time because not supported. --- diff --git a/include/haproxy/quic_tls.h b/include/haproxy/quic_tls.h index 9435e9228a..05b88999a9 100644 --- a/include/haproxy/quic_tls.h +++ b/include/haproxy/quic_tls.h @@ -76,7 +76,7 @@ int quic_tls_decrypt(unsigned char *buf, size_t len, const unsigned char *key, const unsigned char *iv); int quic_tls_generate_retry_integrity_tag(unsigned char *odcid, size_t odcid_len, - unsigned char *buf, size_t len); + unsigned char *buf, size_t len, uint32_t version); int quic_tls_derive_keys(const EVP_CIPHER *aead, const EVP_CIPHER *hp, const EVP_MD *md, diff --git a/include/haproxy/xprt_quic-t.h b/include/haproxy/xprt_quic-t.h index b8bdef74a8..016703b3a0 100644 --- a/include/haproxy/xprt_quic-t.h +++ b/include/haproxy/xprt_quic-t.h @@ -48,6 +48,7 @@ typedef unsigned long long ull; #define QUIC_PROTOCOL_VERSION_DRAFT_28 0xff00001c /* draft-28 */ #define QUIC_PROTOCOL_VERSION_DRAFT_29 0xff00001d /* draft-29 */ #define QUIC_PROTOCOL_VERSION_1 0x00000001 /* V1 */ +#define QUIC_PROTOCOL_VERSION_2_DRAFT 0x709a50c4 /* V2 draft */ #define QUIC_INITIAL_IPV4_MTU 1252 /* (bytes) */ #define QUIC_INITIAL_IPV6_MTU 1232 diff --git a/src/quic_tls.c b/src/quic_tls.c index 623f759be2..bb25ff0d28 100644 --- a/src/quic_tls.c +++ b/src/quic_tls.c @@ -19,6 +19,37 @@ DECLARE_POOL(pool_head_quic_tls_secret, "quic_tls_secret", QUIC_TLS_SECRET_LEN); DECLARE_POOL(pool_head_quic_tls_iv, "quic_tls_iv", QUIC_TLS_IV_LEN); DECLARE_POOL(pool_head_quic_tls_key, "quic_tls_key", QUIC_TLS_KEY_LEN); +/* key/nonce from rfc9001 5.8. Retry Packet Integrity */ +const unsigned char key_v1[] = { + 0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a, + 0x1d, 0x76, 0x6b, 0x54, 0xe3, 0x68, 0xc8, 0x4e, +}; + +const unsigned char nonce_v1[] = { + 0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, + 0x23, 0x98, 0x25, 0xbb, +}; + +const unsigned char key_v2[] = { + 0xba, 0x85, 0x8d, 0xc7, 0xb4, 0x3d, 0xe5, 0xdb, + 0xf8, 0x76, 0x17, 0xff, 0x4a, 0xb2, 0x53, 0xdb, +}; + +const unsigned char nonce_v2[] = { + 0x14, 0x1b, 0x99, 0xc2, 0x39, 0xb0, 0x3e, 0x78, + 0x5d, 0x6a, 0x2e, 0x9f, +}; + +const unsigned char key_draft[] = { + 0xcc, 0xce, 0x18, 0x7e, 0xd0, 0x9a, 0x09, 0xd0, + 0x57, 0x28, 0x15, 0x5a, 0x6c, 0xb9, 0x6b, 0xe1, +}; + +const unsigned char nonce_draft[] = { + 0xe5, 0x49, 0x30, 0xf9, 0x7f, 0x21, 0x36, 0xf0, + 0x53, 0x0a, 0x8c, 0x1c, +}; + __attribute__((format (printf, 3, 4))) void hexdump(const void *buf, size_t buflen, const char *title_fmt, ...); @@ -560,21 +591,13 @@ int quic_tls_derive_retry_token_secret(const EVP_MD *md, * * Returns non-zero on success else zero. */ -int quic_tls_generate_retry_integrity_tag(unsigned char *odcid, - unsigned char odcid_len, - unsigned char *pkt, size_t pkt_len) +int quic_tls_generate_retry_integrity_tag(unsigned char *odcid, unsigned char odcid_len, + unsigned char *pkt, size_t pkt_len, + uint32_t version) { const EVP_CIPHER *evp = EVP_aes_128_gcm(); EVP_CIPHER_CTX *ctx; - - /* key/nonce from rfc9001 5.8. Retry Packet Integrity */ - const unsigned char key[] = { - 0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a, - 0x1d, 0x76, 0x6b, 0x54, 0xe3, 0x68, 0xc8, 0x4e, - }; - const unsigned char nonce[] = { - 0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb, - }; + const unsigned char *key, *nonce; /* encryption buffer - not used as only AEAD tag generation is proceed */ unsigned char *out = NULL; @@ -586,6 +609,20 @@ int quic_tls_generate_retry_integrity_tag(unsigned char *odcid, if (!ctx) return 0; + switch (version) { + case QUIC_PROTOCOL_VERSION_1: + key = key_v1; + nonce = nonce_v1; + break; + case QUIC_PROTOCOL_VERSION_2_DRAFT: + key = key_v2; + nonce = nonce_v2; + break; + default: + key = key_draft; + nonce = nonce_draft; + } + /* rfc9001 5.8. Retry Packet Integrity * * AEAD is proceed over a pseudo-Retry packet used as AAD. It contains diff --git a/src/xprt_quic.c b/src/xprt_quic.c index 50d8e03960..145cf00a86 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -59,6 +59,7 @@ /* list of supported QUIC versions by this implementation */ static int quic_supported_version[] = { 0x00000001, + 0x709a50c4, /* V2 draft */ 0xff00001d, /* draft-29 */ /* placeholder, do not add entry after this */ @@ -5001,7 +5002,7 @@ static int send_retry(int fd, struct sockaddr_storage *addr, /* token integrity tag */ if ((&buf[i] - buf < QUIC_TLS_TAG_LEN) || !quic_tls_generate_retry_integrity_tag(pkt->dcid.data, - pkt->dcid.len, buf, i)) { + pkt->dcid.len, buf, i, pkt->version)) { return 1; }