TLS: Firefox (NSS) does not write Handshake keys to SSLKEYLOGFILE when using ML-KEM/mlkem768 post-quantum key exchange
Description
Firefox 132 added support for mlkem768 "post-quantum key exchange". After this change, Wireshark is no longer able to look inside TLS streams to inspect the underlying HTTP data using firefox's SSLKEYLOGFILE
mechanism.
How Wireshark displays the TLS key_share in the Client Hello packet:
Old Firefox 131:
Transport Layer Security
TLSv1.3 Record Layer: Handshake Protocol: Client Hello
Handshake Protocol: Client Hello
Extension: key_share (len=107) x25519, secp256r1
Key Share extension
Key Share Entry: Group: x25519, Key Exchange length: 32
Key Share Entry: Group: secp256r1, Key Exchange length: 65
New Firefox 132:
Transport Layer Security
TLSv1.3 Record Layer: Handshake Protocol: Client Hello
Handshake Protocol: Client Hello
Extension: key_share (len=1327) Unknown (4588), x25519, secp256r1
Key Share extension
Key Share Entry: Group: Unknown (4588), Key Exchange length: 1216
Key Share Entry: Group: x25519, Key Exchange length: 32
Key Share Entry: Group: secp256r1, Key Exchange length: 65
And then, everything that used to be decoded HTTP packets now just shows as opaque TLS Encrypted Application Data
.
(Note that Firefox 132 also added support for TLS certificate compression. I don't know if Wireshark will need updating to support this. But, there are about:config
flags for certificate compression, so it can be turned off while working on mlkem768 support. The flags for that are:
security.tls.enable_certificate_compression_brotli false
security.tls.enable_certificate_compression_zlib false
security.tls.enable_certificate_compression_zstd false
)
Wireshark version info (Click to expand)
Version 4.4.2 (Git commit 9947b17309f4).
Compiled (64-bit) using GCC 13.2.0, with GLib 2.80.2, with Qt 6.7.2, with
libpcap, with POSIX capabilities (Linux), with libnl 3, with zlib 1.3.1, without
zlib-ng, with PCRE2, without Lua, with GnuTLS 3.8.5 and PKCS #11 support, with
Gcrypt 1.10.3, with Kerberos (MIT), with MaxMind, with nghttp2 1.61.0, with
nghttp3 1.2.0, with brotli, with LZ4, with Zstandard, with Snappy, with libxml2
2.12.7, with libsmi 0.5.0, with Minizip 1.3.1, with QtMultimedia, with QtDBus,
without automatic updates, with binary plugins.
Running on Linux 6.10.14, with Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz (with
SSE4.2), with 15904 MB of physical memory, with GLib 2.80.2, with Qt 6.7.2, with
libpcap 1.10.4 (with TPACKET_V3), with zlib 1.3.1, with PCRE2 10.43 2024-02-16,
with c-ares 1.27.0, with GnuTLS 3.8.5, with Gcrypt 1.10.3, with nghttp2 1.61.0,
with nghttp3 1.2.0, with brotli 1.1.0, with LZ4 1.9.4, with Zstandard 1.5.6,
with libsmi 0.5.0, with dark display mode, without HiDPI, with Xorg, with QPA
plugin "xcb", with LC_TYPE=en_US.UTF-8, binary plugins supported.
Sample capture file
Attached are two packet captures, from Firefoxes 131.0.2 and 132.0.1, with the corresponding SSLKEYLOGFILE
logs. They capture Firefox navigating to google.com. To keep things simple, these captures were generated with javascript, http2, and http3 turned off with these Firefox about:config
flags:
javascript.enabled false
network.http.http2.enabled false
network.http.http3.enable false
Links / references / protocol specifications
- Protocol specification: ML-KEM Post-Quantum Key Agreement for TLS 1.3
- Firefox 132 release notes
- NSS: mlkem768 support tracking bug