up:: In the Protocols MOC
BoringSSL
BoringSSL is Google’s open-source fork of OpenSSL, maintained for Google’s own products, chiefly TLS in Chrome and Chromium, Android, and Google’s services, and its own documentation states it is not intended for general use as a drop-in library. Its importance to the post-quantum transition is deployment scale: BoringSSL was one of the first production TLS stacks to ship hybrid post-quantum key exchange, first with X25519Kyber768 and then the standardized ML-KEM group X25519MLKEM768, and because it is the cryptographic library inside Chrome, that change put post-quantum key exchange in front of a large fraction of live web traffic, one of the largest real-world PQC rollouts to date.
Source: BoringSSL, project README; A. Langley, “BoringSSL,” ImperialViolet (2014).
The short version:
- BoringSSL is a fork of OpenSSL that Google maintains for its own software, and Google says third parties should not depend on it because it offers no API or ABI stability.
- It is the TLS and cryptography library inside Chrome and Chromium, Android, and other Google products, so a change made in BoringSSL reaches an enormous installed base at once.
- BoringSSL shipped the hybrid key exchange X25519Kyber768 (TLS codepoint
0x6399) to Chrome starting in Chrome 116 (August 2023), and Google enabled it by default for 100% of Chrome desktop by Chrome 124 (May 2024). - Chrome 131 (November 2024) replaced Kyber with the standardized ML-KEM as X25519MLKEM768 (codepoint
0x11EC), which is not interoperable with the earlier Kyber draft, so BoringSSL dropped0x6399rather than carry both. - BoringSSL’s source tree carries post-quantum modules for ML-KEM, ML-DSA, and SLH-DSA, and the sibling library AWS-LC is itself based partly on BoringSSL code.
Think of BoringSSL as an automaker’s in-house engine that it builds only for its own cars. The automaker tunes it exactly for its fleet, rebuilds it constantly, and tells outside mechanics not to bolt it into other vehicles because the mounting points change without notice. That sounds narrow, until you remember how many cars this particular automaker sells. When Google decided its fleet should run on post-quantum fuel, it re-tuned this one engine to burn ML-KEM, and overnight a huge share of the cars on the road were running the new fuel, whether their drivers noticed or not.
What is BoringSSL?
BoringSSL is a production cryptography and TLS library written in C, forked from OpenSSL and maintained by Google to meet Google’s own requirements. The project README describes it plainly as “a fork of OpenSSL that is designed to meet Google’s needs,” and Adam Langley’s original 2014 announcement explains the motivation: Google had accumulated a large set of patches over OpenSSL across its products and consolidated them into a fork it could steer directly.
Source: BoringSSL, project README; A. Langley, “BoringSSL,” ImperialViolet (2014).
The library sits at two tiers at once. It supplies low-level cryptographic primitives (the libcrypto layer: key exchange, signatures, hashing, symmetric ciphers) and it implements the TLS protocol itself (the libssl layer that negotiates a handshake). That is a different shape from the AWS-LC plus s2n-tls split, where the primitives and the TLS state machine live in two separate libraries. In BoringSSL the same project ships both, which is part of why a single BoringSSL update can move Chrome’s entire handshake behavior.
BoringSSL is where a large amount of shared cryptographic engineering originates. AWS-LC, Amazon’s library, states in its own README that it is based on code from the BoringSSL project and the OpenSSL project, so BoringSSL is upstream of AWS-LC as well as downstream of OpenSSL. The lineage runs OpenSSL to BoringSSL to AWS-LC.
Source: aws/aws-lc, README.
Why isn’t BoringSSL meant to be a general-purpose OpenSSL replacement?
Because Google maintains it on a rolling model with no stable API, no stable ABI, and no versioned releases, and it says so directly. The README states, “Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is,” and warns, “We don’t recommend that third parties depend upon it. Doing so is likely to be frustrating because there are no guarantees of API or ABI stability.”
Source: BoringSSL, project README.
The porting guide is even more concrete about the boundary. It states that BoringSSL “does not have a stable API or ABI. It must be updated with its consumers. It is not suitable for, say, a system library in a traditional Linux distribution,” and it notes that Android’s system copy must not be used by third-party applications. The intended pattern is that each consumer, Chromium being the worked example, statically links its own pinned copy and updates it in lockstep with the rest of the code.
Source: BoringSSL, PORTING.md.
That design choice is the whole reason BoringSSL can move fast on something like post-quantum key exchange. A library that promised API and ABI stability to thousands of outside programs would have to move at the speed of its slowest consumer. By serving mainly Google’s own tightly-coupled software, BoringSSL can add a hybrid group, roll it to Chrome, measure real handshake latency, and then swap Kyber for standardized ML-KEM, all on Google’s timeline. The tradeoff is that the same properties make it a poor pick as a general shared library for an unrelated project.
How did BoringSSL put post-quantum TLS in front of the web?
Through Chrome. BoringSSL is the cryptographic library inside Chrome and Chromium, so when BoringSSL gained hybrid post-quantum key exchange and Chrome turned it on, every updated Chrome desktop client began offering a post-quantum TLS handshake to every server it connected to. The rollout came in stages.
- Chrome 116, August 2023. Chrome began supporting X25519Kyber768 for establishing the session secret in TLS, available behind a flag in Chrome 115 and shipping in Chrome 116. The mechanism paired classical X25519 with Kyber-768, the pre-standard version of ML-KEM.
- Chrome 124, May 2024. Google enabled the hybrid key exchange by default for TLS 1.3 and QUIC across all Chrome desktop platforms, reaching 100% of Chrome desktop clients. Google reported roughly a 4% median latency increase to TLS handshakes from the larger key share, and held back a default mobile launch because of latency sensitivity on mobile networks.
- Chrome 131, November 2024. Chrome replaced the Kyber draft with standardized ML-KEM, advertised as X25519MLKEM768.
Sources: Chromium Blog, “Protecting Chrome Traffic with Hybrid Kyber KEM” (2023-08-10); Google, “Advancing Our Amazing Bet on Asymmetric Cryptography” (2024-05-23).
The scale is the point. Chrome carries a large share of global web traffic, so enabling a hybrid group in one BoringSSL build did more to normalize post-quantum key exchange on the public internet than any standards document could. It also flushed out the real-world deployment problem this hub keeps returning to: the oversized post-quantum ClientHello broke a long tail of middleboxes that assumed the classical handshake size, which is exactly the crypto-agility and endpoint-coverage failure mode that makes applied PQC a rollout rather than a switch.
Why did Chrome switch from Kyber to ML-KEM, and what changed?
Because the algorithm finished standardization with small technical changes that made the final ML-KEM incompatible with the Kyber draft Chrome had deployed, so the two could not share a codepoint. Google’s “A new path for Kyber on the web” states that “the changes to the final version of ML-KEM make it incompatible with the previously deployed version of Kyber,” and that “Chrome will not support Kyber and ML-KEM at the same time.”
Source: Google Security Blog / Chromium, “A new path for Kyber on the web” (2024-09-13).
The visible change is the negotiated group and its TLS codepoint. The draft used X25519Kyber768 at experimental codepoint 0x6399, and the standardized version uses X25519MLKEM768 at the official codepoint 0x11EC. Google’s stated reasoning for a clean cut rather than running both is that Kyber was always experimental, that keeping it risked ossifying non-standard code, and that a post-quantum key share is large enough that offering two of them in every handshake is a real cost worth avoiding.
Source: Google Security Blog / Chromium, “A new path for Kyber on the web” (2024-09-13).
| Chrome milestone | Date | Hybrid group | TLS codepoint | Status |
|---|---|---|---|---|
| Chrome 115 | 2023 | X25519Kyber768 | 0x6399 | Behind a flag |
| Chrome 116 | Aug 2023 | X25519Kyber768 | 0x6399 | Shipped, opt-in rollout |
| Chrome 124 | May 2024 | X25519Kyber768 | 0x6399 | Default on for 100% of Chrome desktop |
| Chrome 131 | Nov 2024 | X25519MLKEM768 | 0x11EC | Standardized ML-KEM, replaced Kyber |
Sources: Chromium Blog, “Protecting Chrome Traffic with Hybrid Kyber KEM”; Google, “Advancing Our Amazing Bet on Asymmetric Cryptography” (2024-05-23); Google, “A new path for Kyber on the web” (2024-09-13).
The lesson underneath the codepoint swap is a crypto-agility one. Because a draft algorithm and its final standard are genuinely different objects on the wire, anything that hard-coded the Kyber draft group had to change, and the clean way to do that is to negotiate algorithms rather than pin one. An endpoint that pinned 0x6399 and never updated simply stopped getting post-quantum key exchange once Chrome moved on.
Which post-quantum algorithms does BoringSSL implement?
BoringSSL carries ML-KEM for key exchange, ML-DSA for signatures, and SLH-DSA as the hash-based signature, present as distinct modules in its source tree (crypto/fipsmodule/mlkem, mldsa, and slhdsa, confirmed 2026-07-09). The algorithm most people encounter is ML-KEM, because that is the one wired into Chrome’s default TLS handshake through the X25519MLKEM768 group.
Source: BoringSSL, fipsmodule source tree (confirmed 2026-07-09).
| Algorithm | Role | Where it shows up |
|---|---|---|
| ML-KEM | Key encapsulation | Chrome’s default TLS via X25519MLKEM768 (0x11EC) |
| ML-DSA | General-purpose signature | Present as a module; signature migration is the slower Non-HNDL track |
| SLH-DSA | Hash-based signature | Present as a module for the conservative signature case |
| Classical RSA, ECDSA, ECDH / X25519 | Key exchange and signatures | Long-standing; the classical half of the hybrid group |
Source: BoringSSL, fipsmodule source tree.
A caution on validation, because it is where BoringSSL differs from AWS-LC in a way that matters to regulated buyers. AWS-LC’s headline is a completed FIPS 140-3 validation carrying ML-KEM, and it is packaged for outside consumers. BoringSSL’s value is deployment reach through Chrome, and Google explicitly steers third parties away from depending on it. So for a regulated estate that needs a validated module it can build against, BoringSSL is usually the wrong shelf even though it is where much of the code originated; AWS-LC or OpenSSL is the one to reach for.
When should a developer use BoringSSL?
For most teams, the honest answer is that you already use BoringSSL without choosing it, and you should not adopt it as a standalone dependency for a new project. It reaches you indirectly whenever your users run Chrome or an Android app, and Google’s own guidance is that outside programs should not link it directly because of the missing stability guarantees.
Source: BoringSSL, project README and PORTING.md.
The practical decisions look like this:
- You want post-quantum TLS in your own service, in C or C++. Reach for OpenSSL 3.5’s native ML-KEM or AWS-LC with s2n-tls, both of which are packaged for outside use, rather than embedding BoringSSL.
- You need a FIPS-validated module carrying ML-KEM. AWS-LC is one of the earliest validated routes; BoringSSL is not offered to third parties as a general validated library.
- You are inside the Chromium or Android ecosystem. Then BoringSSL is already your cryptography, and the question becomes keeping your embedded copy current so you inherit its post-quantum groups.
- You are testing whether your servers and middleboxes accept post-quantum clients. Chrome, powered by BoringSSL, is effectively the largest post-quantum client population in the world, so confirming that your endpoints negotiate X25519MLKEM768 with a current Chrome is a real-world coverage check.
Common misconceptions
- “BoringSSL is a drop-in OpenSSL replacement for my app.” Google states the opposite. It carries no stable API or ABI, ships no versioned releases, and its porting guide says it is unsuitable as a general system library. The intended consumers are Google’s own tightly-coupled products, each pinning its own copy.
- “BoringSSL and OpenSSL are the same library.” BoringSSL is a fork that has diverged substantially, removing and reshaping large parts of the OpenSSL API for Google’s needs. Code written for OpenSSL often needs porting to build against BoringSSL.
- “Using Chrome means my traffic is already post-quantum.” Chrome offers X25519MLKEM768, and the handshake only uses it when the server (and every middlebox in the path) also supports it. Against a classical-only server, Chrome falls back to classical key exchange, which keeps the HNDL window open.
- “BoringSSL is a FIPS-validated module I can certify against.” BoringSSL has an internal FIPS-oriented build (BoringCrypto), and Google does not package it for third parties to depend on as a validated library. For a compliance gate, AWS-LC or a validated OpenSSL build is the module to point at.
- “Chrome still supports the old Kyber group.” As of Chrome 131, Chrome moved to standardized ML-KEM (
0x11EC) and dropped the incompatible Kyber draft (0x6399), and Google stated Chrome will not carry both at once. - “BoringSSL only does key exchange for post-quantum.” Its source tree also carries ML-DSA and SLH-DSA signature modules; ML-KEM is simply the one deployed in Chrome’s default handshake today.
Questions people ask
Is BoringSSL the same as OpenSSL? No. BoringSSL is a fork of OpenSSL that Google created in 2014 and maintains for its own products. It shares heritage and some code, and it has removed and reshaped much of the OpenSSL API, so it is not API-compatible and porting is usually required.
Does Chrome use BoringSSL? Yes. BoringSSL is the TLS and cryptography library inside Chrome and Chromium, which is why a post-quantum change in BoringSSL reaches Chrome’s very large user base directly. It is also the SSL library in Android, though not as part of the NDK.
What post-quantum group does Chrome negotiate? As of Chrome 131 (November 2024), Chrome advertises X25519MLKEM768, TLS codepoint 0x11EC, pairing classical X25519 with standardized ML-KEM-768. Earlier versions used the pre-standard X25519Kyber768 at codepoint 0x6399.
Why did Chrome drop Kyber for ML-KEM? Standardization changed the algorithm enough that final ML-KEM is not interoperable with the deployed Kyber draft. Google chose a clean switch rather than supporting both, citing the risk of ossifying experimental code and the size cost of offering two post-quantum key shares in every handshake.
Can I use BoringSSL in my own product? Google recommends against depending on it directly, because there is no API or ABI stability and no versioned releases. For post-quantum TLS in your own service, OpenSSL 3.5 or AWS-LC plus s2n-tls are packaged for outside use and are the better fit.
Is BoringSSL FIPS-validated for ML-KEM? BoringSSL is not offered to third parties as a general FIPS-validated library, and its value for the transition is deployment reach through Chrome. When a regulated deployment needs a validated module carrying ML-KEM, AWS-LC is one of the earliest completed routes.
How is BoringSSL related to AWS-LC? AWS-LC is based partly on BoringSSL code (and partly on OpenSSL), so BoringSSL is upstream of AWS-LC. The practical difference is packaging and validation: AWS-LC is built for outside consumers and carries a FIPS validation with ML-KEM, while BoringSSL is steered toward Google’s own software.
Did the post-quantum handshake break anything in practice? Yes, at the edges. The larger post-quantum ClientHello exceeded size assumptions in some older middleboxes, which dropped or mishandled the connection. That is the endpoint-coverage and crypto-agility problem the whole applied PQC hub turns on, surfaced at internet scale by Chrome’s rollout.
Everything here is the map, given freely. When your team needs to know which of its servers, load balancers, and vendor surfaces actually negotiate a post-quantum group with a modern Chrome, and where the handshake silently falls back, that’s the work I do, and there’s an alignment briefing for it.
Last verified 2026-07-09 · Maintained by Addie LaMarr, LaMarr Labs.