29 Commits

Author SHA1 Message Date
Amaury Denoyelle
5eadc27623 MINOR: quic: remove return val of quic_aead_iv_build()
quic_aead_iv_build() should never fail unless we call it with buffers of
different size. This never happens in the code as every input buffers
are of size QUIC_TLS_IV_LEN.

Remove the return value and add a BUG_ON() to prevent future misusage.
This is especially useful to remove one error handling on the sending
patch via quic_packet_encrypt().

This should be backported up to 2.7.
2023-05-22 11:17:18 +02:00
Frédéric Lécaille
51a7caf921 MINOR: quic: Add traces about QUIC TLS key update
Dump the secret used to derive the next one during a key update initiated by the
client and dump the resulted new secret and the new key and iv to be used to
decryption Application level packets.

Also add a trace when the key update is supposed to be initiated on haproxy side.

This has already helped in diagnosing an issue evealed by the key update interop
test with xquic as client.

Must be backported to 2.7.
2023-03-03 19:12:26 +01:00
Frdric Lcaille
21c4c9b854 MINOR: quic: Replace v2 draft definitions by those of the final 2 version
This should finalize the support for the QUIC version 2.

Must be backported to 2.7.
2023-01-17 16:35:20 +01:00
Amaury Denoyelle
92fa63f735 CLEANUP: quic: create a dedicated quic_conn module
xprt_quic module was too large and did not reflect the true architecture
by contrast to the other protocols in haproxy.

Extract code related to XPRT layer and keep it under xprt_quic module.
This code should only contains a simple API to communicate between QUIC
lower layer and connection/MUX.

The vast majority of the code has been moved into a new module named
quic_conn. This module is responsible to the implementation of QUIC
lower layer. Conceptually, it overlaps with TCP kernel implementation
when comparing QUIC and HTTP1/2 stacks of haproxy.

This should be backported up to 2.6.
2022-10-03 16:25:17 +02:00
Amaury Denoyelle
ac9bf016bf CLEANUP: quic: remove unused function prototype
Removed hexdump unusued prototype from quic_tls.c.

This should be backported up to 2.6.
2022-10-03 16:25:17 +02:00
Amaury Denoyelle
5c25dc5bfd CLEANUP: quic: fix headers
Clean up quic sources by adjusting headers list included depending
on the actual dependency of each source file.

On some occasion, xprt_quic.h was removed from included list. This is
useful to help reducing the dependency on this single file and cleaning
up QUIC haproxy architecture.

This should be backported up to 2.6.
2022-10-03 16:25:17 +02:00
Amaury Denoyelle
f3c40f83fb BUG/MINOR: quic: adjust quic_tls prototypes
Two prototypes in quic_tls module were not identical to the actual
function definition.

* quic_tls_decrypt2() : the second argument const attribute is not
  present, to be able to use it with EVP_CIPHER_CTX_ctlr(). As a
  consequence of this change, token field of quic_rx_packet is now
  declared as non-const.

* quic_tls_generate_retry_integrity_tag() : the second argument type
  differ between the two. Adjust this by fixing it to as unsigned char
  to match EVP_EncryptUpdate() SSL function.

This situation did not seem to have any visible effect. However, this is
clearly an undefined behavior and should be treated as a bug.

This should be backported up to 2.6.
2022-10-03 16:25:17 +02:00
Amaury Denoyelle
a19bb6f0b2 CLEANUP: quic: remove global var definition in quic_tls header
Some variables related to QUIC TLS were defined in a header file : their
definitions are now moved properly in the implementation file, with only
declarations in the header.

This should be backported up to 2.6.
2022-10-03 16:25:17 +02:00
cui fliter
a94bedc0de CLEANUP: quic,ssl: fix tiny typos in C comments
This fixes 4 tiny and harmless typos in mux_quic.c, quic_tls.c and
ssl_sock.c. Originally sent via GitHub PR #1843.

Signed-off-by: cui fliter <imcusg@gmail.com>
[Tim: Rephrased the commit message]
[wt: further complete the commit message]
2022-09-17 10:59:59 +02:00
Frédéric Lécaille
86a53c5669 MINOR: quic: Add reusable cipher contexts for header protection
Implement quic_tls_rx_hp_ctx_init() and quic_tls_tx_hp_ctx_init() to initiliaze
such header protection cipher contexts for each RX and TX parts and for each
packet number spaces, only one time by connection.
Make qc_new_isecs() call these two functions to initialize the cipher contexts
of the Initial secrets. Same thing for ha_quic_set_encryption_secrets() to
initialize the cipher contexts of the subsequent derived secrets (ORTT, 1RTT,
Handshake).
Modify qc_do_rm_hp() and quic_apply_header_protection() to reuse these
cipher contexts.
Note that there is no need to modify the key update for the header protection.
The header protection secrets are never updated.
2022-08-19 18:31:59 +02:00
Frédéric Lécaille
e06f7459fa CLEANUP: quic: Remove any reference to boringssl
I do not think we will support boringssl for QUIC soon ;)
2022-06-16 15:58:48 +02:00
Frédéric Lécaille
86845c5171 MEDIUM: quic: Add QUIC v2 draft support
This is becoming difficult to handle the QUIC TLS related definitions
which arrive with a QUIC version (draft or not). So, here we add
quic_version C struct which does not define only the QUIC version number,
but also the QUIC TLS definitions which depend on a QUIC version.
Modify consequently all the QUIC TLS API to reuse these definitions
through new quic_version C struct.
Implement quic_pkt_type() function which return a packet type (0 up to 3)
depending on the QUIC version number.
Stop harding the Retry packet first byte in send_retry(): this is not more
possible because the packet type field depends on the QUIC version.
Also modify quic_build_packet_long_header() for the same reason: the packet
type depends on the QUIC version.
Add a quic_version C struct member to quic_conn C struct.
Modify qc_lstnr_pkt_rcv() to set this member asap.
Remove the version member from quic_rx_packet C struct: a packet is attached
asap to a connection (or dropped) which is the unique object which should
store the QUIC version.
Modify qc_pkt_is_supported_version() to return a supported quic_version C
struct from a version number.
Add Initial salt for QUIC v2 draft (initial_salt_v2_draft).
2022-06-16 14:56:24 +02:00
Frédéric Lécaille
3f96a0a4c1 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.
2022-06-16 14:56:24 +02:00
Frédéric Lécaille
55367c8679 MINOR: quic_tls: Add quic_tls_decrypt2() implementation
This function does exactly the same thing as quic_tls_decrypt(), except that
it does reuse its input buffer as output buffer. This is needed
to decrypt the Retry token without modifying the packet buffer which
contains this token. Indeed, this would prevent us from decryption
the packet itself as the token belong to the AEAD AAD for the packet.
2022-05-20 16:57:12 +02:00
Frédéric Lécaille
a9c5d8da58 MINOR: quic_tls: Add quic_tls_derive_retry_token_secret()
This function must be used to derive strong secrets from a non pseudo-random
secret (cluster-secret setting in our case) and an IV. First it call
quic_hkdf_extract_and_expand() to do that for a temporary strong secret (tmpkey)
then two calls to quic_hkdf_expand() reusing this strong temporary secret
to derive the final strong secret and IV.
2022-05-20 16:57:12 +02:00
Frédéric Lécaille
4ba3b4ef67 CLEANUP: quic: Useless use of pointer for quic_hkdf_extract()
There is no need to use a pointer to the output buffer length.
2022-05-12 17:48:35 +02:00
Frédéric Lécaille
7b92c81e43 MINOR: quic-tls: Add quic_hkdf_extract_and_expand() for HKDF
This is a wrapper function around OpenSSL HKDF API functions to
use the "extract-then-expand" HKDF mode as defined by rfc5869.
This function will be used to derived stateless reset tokens
from secrets ("cluster-secret" conf. keyword) and CIDs (as salts).
2022-05-12 17:48:35 +02:00
Frédéric Lécaille
f2f4a4eee5 MINOR: quic_tls: Stop hardcoding cipher IV lengths
For QUIC AEAD usage, the number of bytes for the IVs is always 12.
2022-04-08 15:38:29 +02:00
Frédéric Lécaille
f4605748f4 MINOR: quic_tls: Add reusable cipher contexts to QUIC TLS contexts
Add ->ctx new member field to quic_tls_secrets struct to store the cipher context
for each QUIC TLS context TX/RX parts.
Add quic_tls_rx_ctx_init() and quic_tls_tx_ctx_init() functions to initialize
these cipher context for RX and TX parts respectively.
Make qc_new_isecs() call these two functions to initialize the cipher contexts
of the Initial secrets. Same thing for ha_quic_set_encryption_secrets() to
initialize the cipher contexts of the subsequent derived secrets (ORTT, Handshake,
1RTT).
Modify quic_tls_decrypt() and quic_tls_encrypt() to always use the same cipher
context without allocating it each time they are called.
2022-04-08 15:38:29 +02:00
Amaury Denoyelle
6efec292ef MINOR: quic: implement Retry TLS AEAD tag generation
Implement a new QUIC TLS related function
quic_tls_generate_retry_integrity_tag(). This function can be used to
calculate the AEAD tag of a Retry packet.
2022-01-12 11:08:48 +01:00
Amaury Denoyelle
4fd53d772f MINOR: quic: add const qualifier for traces function
Add const qualifier on arguments of several dump functions used in the
trace callback. This is required to be able to replace the first trace
argument by a quic_conn instance. The first argument is a const pointer
and so the members accessed through it must also be const.
2021-12-21 15:53:19 +01:00
Frédéric Lécaille
6e351d6c19 MINOR: quic: Optional header protection key for quic_tls_derive_keys()
quic_tls_derive_keys() is responsible to derive the AEAD keys, IVs and$
header protection key from a secret provided by the TLS stack. We want
to make the derivation of the header protection key be optional. This
is required for the Key Update process where there is no update for
the header protection key.
2021-11-30 11:51:12 +01:00
Frédéric Lécaille
39484de813 MINOR: quic: Add a function to derive the key update secrets
This is the function used to derive an n+1th secret from the nth one as
described in RFC9001 par. 6.1.
2021-11-30 11:51:12 +01:00
Frédéric Lécaille
fc768ecc88 MINOR: quic: Dynamically allocate the secrete keys
This is done for any encryption level. This is to prepare the Key Update feature.
2021-11-30 11:51:12 +01:00
Frédéric Lécaille
2fc76cffaf MINOR: quic: Make QUIC-TLS support at least two initial salts
These salts are used to derive initial secrets to decrypt the first Initial packet.
We support draft-29 and v1 QUIC version initial salts.
Add parameters to our QUIC-TLS API functions used to derive these secret for
these salts.
Make our xprt_quic use the correct initial salt upon QUIC version field found in
the first paquet. Useful to support connections with curl which use draft-29
QUIC version.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
98ad56a049 MINOR: quic_tls: Make use of the QUIC V1 salt.
This salt is used to derive the Initial secrets.
2021-09-23 15:27:25 +02:00
Frédéric Lécaille
82d1daa268 MINOR: quic: Add the QUIC v1 initial salt.
See initial_salt value for QUIC-TLS RFC 9001 at
https://www.rfc-editor.org/rfc/rfc9001.html#name-initial-secrets
2021-09-23 15:27:25 +02:00
Frdric Lcaille
b4e17386cb MINOR: quic: Update the initial salt to that of draft-29.
This salt is ued at leat up to draft-32. At this date ngtcp2 always
uses this salt even if it started the draft-33 development.

Note that when the salt is not correct, we cannot remove the header
protection. In this case the packet number length is wrong.
2020-12-23 11:57:26 +01:00
Frdric Lcaille
a7e7ce957d MINOR: quic: Import C source code files for QUIC protocol.
This patch imports all the C files for QUIC protocol implementation with few
modifications from 20200720-quic branch of quic-dev repository found at
https://github.com/haproxytech/quic-dev.

Traces were implemented to help with the development.
2020-12-23 11:57:26 +01:00