Repository navigation
colibri 0.6.0: AES-256-GCM first on the AES instructions, and a client's own suite order
colibri 0.6.0 runs AES-256-GCM first where the CPU has the AES instructions, as a TLS client and as a server, and lets a client choose the suites it offers. It pins chapulin at 10a5bc8, whose default order this is, and stdx at c134f2c. qlog writes each record's tokens many at a call, and the client and the server send a failed record's alert before they close.
Breaking
qlog:TextWriteris now qlog's batch writer, which gathers a record's tokens and hands them to stdx's JSON writer many at a call (81707f2). It keepsjson.TextWriter's calls, butwritten()returns an error union, because it writes what is still gathered. The records are the same octets.
To move from 0.5.0, handle the error qlog.TextWriter.written() may return.
Changed
tls: on a target with the AES instructions, both roles prefer TLS_AES_256_GCM_SHA384, then TLS_AES_128_GCM_SHA256, then TLS_CHACHA20_POLY1305_SHA256, where 0.5.0 put ChaCha20 first (b3880da, chapulin's decision 80). AES-256-GCM comes first for CNSA 2.0. Against Go's server a client still runs AES-128-GCM, because Go chooses among the AES suites by its own order once the client lists one first. A target without the AES instructions holds ChaCha20 alone, as before. A program that wants another order setstls.values.Server.cipher_suites, or the new client field below.
Added
tls:values.Client.cipher_suites, the suites a client offers, most preferred first, as RFC 9846 Appendix B.4 codepoints. The ClientHello offers exactly this list, and an empty one keeps chapulin's order. An object without AES-GCM refuses a list withSuitesUnavailable, and chapulin refuses a suite named twice when the session starts (b3880da).tls.quic:version, the QUIC version every session and Retry protects packets for: version 1 (RFC 9000 §15).
Dependencies
- chapulin is pinned at
10a5bc8, where 0.5.0 pinned0adcf33. It brings the default order above, a client's own order, and a version argument on each QUIC packet call, which colibri fills in. - stdx is pinned at
c134f2c, where 0.5.0 pinned8c2a3b8(a5bfb50). Its DEFLATE encoder, which the server's content codings run, writes smaller output, and runs level 1 at 0.91 and 0.93 of its old speed (stdx's decision 36). Its brotli command loop runs without Zig's runtime checks, and colibri never runs brotli.
Fixed
clientandserver: after a record failed,should_closesaid to close beforesendwrote thebad_record_macalert the connection owes (RFC 9846 §5.2), so a caller that asked before its nextsendclosed without it. Each now waits for the alert (4ed2108). The interop scripts check it with a record no key sealed (628449b, #74).
Checked against
CI ran tools/ci.sh on 830af4c, on Ubuntu 24.04 with an AMD EPYC 7763, and every section passed:
- TLS against Go 1.27.1: colibri's server selected TLS_AES_256_GCM_SHA384 (
suite=0x1302), and its client ran TLS_AES_128_GCM_SHA256 (suite=0x1301), the suite Go's server chose. On 0.5.0 both ran ChaCha20 (0x1303). - h2spec 2.6.0: 144 passed in cleartext and over TLS, and 2 skipped by name, which test an RFC 7540 rule RFC 9113 dropped. h3spec 0.1.13: 49 examples, 0 failures.
- The client and the server over h11 and h2 against Go 1.27.1, nghttpd 1.52.0, h2o 2.2.5, curl 7.88.1 and nghttp, in cleartext and over TLS, with gzip content codings in both directions and the scripts' forged-record checks.
- The client's
Channelfetched over h3 from aioquic 1.3.0 and quic-go9d085cc, and over h2 from Go's server with no UDP. - aioquic in both directions over hq-interop and h3, QPACK against ls-qpack, the TLA+ models with the h2, h3 and client traces, the Lean proofs, and 2,337 tests in Debug and in ReleaseSafe. The tests also passed on Linux and macOS arm64.
The HTTP Garden and the QUIC Interop Runner ran on b5a7c79, which adds documentation alone to 830af4c. The Garden fed its 72 streams to colibri's server and to 35 other origins, and compared every one. In the runner, colibri passed every case against quic-go, ngtcp2, neqo, quinn and itself, as the server and as the client, but two:
chacha20, wherever colibri was the client. The case requires the client to offer ChaCha20 alone, and the test endpoint still offered its object's order, now AES-256-GCM first.0af377eon main gives the endpoint achacha20option.handshakelosswith quinn's client, which also failed at9796e95and passed atbb9263e.
The runner ran again at 0af377e, main with that fix and the QUIC version 2 work that follows this release, and colibri passed every case, chacha20 and quinn's handshakeloss included.
quic-go runs no ecn case. Every qlog file colibri wrote, in 168 test cases, passed tools/qlog_check.py.
docs/design.md §8 records each check: what ran, on what machine, and what it printed.
Install
zig fetch --save git+https://github.com/c4milo/colibri#v0.6.0