What M-23-02 actually requires, decoded to wire reality
M-23-02 gets cited as "the federal post-quantum mandate," usually by someone reading it as "deploy PQC now." It isn't that. Read literally, its binding near-term requirement is narrower and far more tractable: know where your quantum-vulnerable cryptography is. That is an inventory problem — and an inventory, decoded to the wire, is a much smaller thing than a migration.
What the memo actually says
OMB Memorandum M-23-02, Migrating to Post-Quantum Cryptography (November 2022), operationalizes National Security Memorandum 10. Its core obligation is a prioritized inventory of cryptographic systems — weighted toward high-value assets and anything that will still hold sensitive data past the threat horizon — plus a designated migration lead and a cost estimate, reported up through OMB and ONCD.
What it does not require yet is flipping production to ML-KEM. The actual replacement schedule — which algorithms, and the 2035 deadline for national security systems — lives in CNSA 2.0 and the finalized NIST standards (ML-KEM is FIPS 203), not in M-23-02. So the first federal deliverable is a list, not a cutover. Most teams overshoot the memo and stall on the migration; the memo only asks you to see clearly first.
"Inventory your cryptography," decoded
An inventory entry, at the wire, is three fields per TLS connection: protocol version, cipher suite, and key-exchange group. The quantum-vulnerable part is the key exchange — the asymmetric key establishment (ECDH, RSA), which Shor's algorithm breaks outright. The symmetric AEAD (AES-GCM, ChaCha20) is only weakened by Grover and is not what the inventory is hunting. So the question "is this connection quantum-vulnerable?" collapses to one smaller question: what is in supported_groups and key_share?
# Quantum-vulnerable: classical ECDH only
supported_groups
0x001d x25519
0x0017 secp256r1
# Quantum-resistant: hybrid ECDH + ML-KEM-768
supported_groups
0x11ec X25519MLKEM768 # draft-ietf-tls-ecdhe-mlkem; ML-KEM = FIPS 203
0x001d x25519 # kept for fallback
An inventory is, mechanically, classifying every observed key exchange into one of those two buckets. That is the whole technical core of the requirement.
Why this is an observability problem first
You cannot produce this inventory from configuration files. What gets negotiated on the wire is not what is in your config: client and server each pick from the other's offers, libraries default differently across versions, middleboxes rewrite handshakes, and third-party callouts and shadow IT appear in no config you own. The negotiated group is decided per handshake, at runtime.
Which means an inventory built from an asset spreadsheet is wrong on day one — it records intent, not the bytes that actually crossed the wire. The only authoritative source for "what cryptography is this system really using" is the handshake itself.
# the only inventory that is true is the one taken from the wire
ClientHello -> offered: 0x11ec, 0x001d
ServerHello -> selected: 0x001d # vulnerable: server has no ML-KEM
What "done" looks like
A real inventory answers, continuously: for each service, what fraction of handshakes negotiated a quantum-vulnerable group versus a hybrid one. When that number reads 100% x25519, you know exactly what to migrate. When it shows 0x11ec, that path is already hybrid-protected and drops off the list. The same per-handshake record that finds the vulnerable crypto is also your evidence that you fixed it — which is the audit trail the memo is ultimately after.
Decoding what M-23-02 asks for is the easy part. Producing the wire-truth inventory it actually wants — across services you don't control, without touching the endpoints — is the work, and it is where we start. See how we approach it. Inventory is the first step of the broader post-quantum TLS migration path; for the wire-level background, see what X25519MLKEM768 looks like on the wire and the bug that hid PQC.
← All posts