]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: Add several nonce and key definitions for Retry tag
authorFrédéric Lécaille <flecaille@haproxy.com>
Wed, 8 Jun 2022 06:26:03 +0000 (08:26 +0200)
committerFrédéric Lécaille <flecaille@haproxy.com>
Thu, 16 Jun 2022 12:56:24 +0000 (14:56 +0200)
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.

include/haproxy/quic_tls.h
include/haproxy/xprt_quic-t.h
src/quic_tls.c
src/xprt_quic.c

index 9435e9228a827870f0066db209b55007c4be50f8..05b88999a9463ab791217d1b87d9783bd485e488 100644 (file)
@@ -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,
index b8bdef74a8f0267cc9388b12b273357068931b4b..016703b3a0be27d0fb265150a555765739135691 100644 (file)
@@ -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
index 623f759be231958ff8475c00d109c488677b993a..bb25ff0d285b3584b12fb8d214dd3d4b55132a9c 100644 (file)
@@ -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
index 50d8e03960681b5f490f04e1e95294ced4fb6026..145cf00a8638cd0ad28bb507fa10bd2ad7dd31b8 100644 (file)
@@ -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;
        }