Skip to content

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

Edited by John Thacker
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information