Post-quantum support on Linux depends on the OpenSSL and OpenSSH versions supplied by your distribution, along with any distro-specific crypto policies. This guide begins with capability checks that work across Linux distributions, then demonstrates ML-KEM, ML-DSA, TLS, and SSH on Rocky Linux 10.2. Sections that use RHEL-family system-wide crypto policies are labeled separately.
The capability checks and OpenSSL/OpenSSH labs can work on any Linux distribution that provides the required versions and algorithms. The commands involving update-crypto-policies, DEFAULT, FUTURE, NO-PQ, and TEST-PQ are specific to the RHEL family and related distributions.
I will show you how to check what your host already supports, then walk through small labs you can run on your own machines without leaning on a public website.
Tested on: Rocky Linux 10.2 (Red Quartz); OpenSSL 3.5.5; OpenSSH 9.9p1.
| Reader's goal | Jump to |
|---|---|
| See the two-VM lab layout | Lab environment |
| Check whether PQC is enabled | Inspect PQC support on the current system |
| Test hybrid TLS key exchange | Test hybrid ML-KEM key exchange with TLS 1.3 |
| Generate and verify a PQ signature | Generate and verify ML-DSA signatures |
| Check an SSH connection | Verify post-quantum key exchange in SSH |
| Understand RHEL-family crypto policies | RHEL-family crypto policies and PQC interoperability |
| Compare distro release history | How PQC support differs across Linux distributions |
Lab environment
Most labs need only one host. For the RHEL-family crypto-policy lab I used two disposable VMs on the same lab network. You can mirror that layout if you want to see client and server behaviour side by side.
| Role | Example address | Used for |
|---|---|---|
| Client | 192.168.56.108 |
OpenSSL TLS and ML-DSA labs; RHEL-family update-crypto-policies changes |
| Server | 192.168.56.109 |
SSH peer, hybrid TLS server, classical-only sshd on port 2222 |
Both hosts began with the DEFAULT crypto policy for the policy lab. One section later switches only the client to FUTURE so you can see what that change does. I configured root SSH public-key trust between them. If firewalld is active on your server, open test ports temporarily. I used firewall-cmd --add-port=2222/tcp for the classical SSH demo and firewall-cmd --add-port=14433/tcp for cross-host TLS.
Swap in your own lab IPs. The hostnames here are disposable labels, not production DNS names.
What post-quantum cryptography changes
Today's public-key algorithms (RSA and elliptic-curve cryptography) could become vulnerable to a sufficiently capable quantum computer. No cryptographically relevant quantum computer is known today, but traffic can still be recorded now and attacked later. That harvest-now-decrypt-later risk is why vendors are adding NIST-standardized post-quantum algorithms next to the classical ones.
Symmetric ciphers such as AES are a separate story. Post-quantum work on Linux concentrates on key exchange and digital signatures, because that is where RSA and ECC carry the long-term risk.
| Purpose | Algorithm | Protects |
|---|---|---|
| Establish a shared secret | ML-KEM | Key exchange and confidentiality |
| Sign and authenticate data | ML-DSA or SLH-DSA | Integrity and authenticity |
Current TLS and SSH implementations commonly combine classical and post-quantum key exchange:
Classical ECDH/X25519 + ML-KEMCombining both components provides a security hedge: the session remains protected unless both components are broken. Both peers must support the same hybrid method. TLS uses names such as X25519MLKEM768, while OpenSSH uses mlkem768x25519-sha256. Compatibility with classical-only peers comes from negotiating a separate classical method, not from the classical component inside the hybrid method.
How PQC support differs across Linux distributions
No two distributions ship post-quantum cryptography on the same schedule. Fedora, Debian, Ubuntu, SUSE, Arch, and the RHEL family each package OpenSSL and OpenSSH on their own timelines. Some backport PQC support into older upstream version numbers. Others wait for a newer upstream release. The portable checks in the next section tell you what your installed build actually supports, regardless of distribution name.
OpenSSL 3.5 provides native ML-KEM and ML-DSA support. Upstream OpenSSH added mlkem768x25519-sha256 in 9.9 and made it the default key-exchange method in OpenSSH 10.0. Your distribution may ship those capabilities earlier or later than the upstream version string suggests.
RHEL-family release timeline
The following timeline explains the RHEL-family implementation used for the tested labs. Other distributions may package upstream OpenSSL and OpenSSH support on a different schedule.
Many online instructions still describe the initial RHEL-family Technology Preview behaviour. If you are on a current release, you can skip the old workarounds. Glance at this table once when you plan an upgrade or when an older blog post mentions TEST-PQ or oqsprovider.
| Release | PQC status and important changes |
|---|---|
| 10.0 | Technology Preview; required crypto-policies-pq-preview, DEFAULT:TEST-PQ, and oqsprovider for OpenSSL |
| 10.1 | Standardized PQC fully supported; OpenSSL 3.5 provides ML-KEM, ML-DSA, and SLH-DSA; supported PQ algorithms enabled by predefined policies |
| 10.2 | Expanded OpenSSH and libssh hybrid ML-KEM support; NIST-curve SSH hybrids in FIPS mode; FUTURE permits only hybrid ML-KEM key exchange |
Keep these migration points in mind when you read older blog posts:
- RHEL 10.0 used oqsprovider for its Technology Preview implementation. Current RHEL-family releases with OpenSSL 3.5 provide native standardized algorithms and do not require it for these labs.
- The 10.0 release used pre-standard private-key formats; existing ML-KEM and ML-DSA keys from that era may need conversion after an upgrade.
TEST-PQis no longer required to enable normal hybrid PQC on current releases.TEST-PQtoday is mainly relevant when testing pure ML-KEM in OpenSSL.
If you still have keys from the Technology Preview era, Red Hat documents conversion to the standardized PKCS #8 form:
openssl pkcs8 -in old-private-key.pem -nocrypt -topk8 -out standard-private-key.pemTreat that command as an upgrade note, not a full migration procedure.
Supported algorithms and applications
Core algorithms
| Algorithm | Function | Standard | Available parameter sets |
|---|---|---|---|
| ML-KEM | Key encapsulation | NIST FIPS 203 | 512, 768, 1024 |
| ML-DSA | Digital signatures | NIST FIPS 204 | 44, 65, 87 |
| SLH-DSA | Hash-based digital signatures | NIST FIPS 205 | SHA2 and SHAKE variants |
The suffix identifies a parameter set, not a key size. Names cannot be compared directly across algorithm families, although ML-KEM-768 and ML-DSA-65 both target NIST security category 3 for different cryptographic functions.
Major components
| Component | Relevant PQC support |
|---|---|
| OpenSSL 3.5 | ML-KEM, ML-DSA, SLH-DSA, and hybrid TLS 1.3 groups |
| GnuTLS | Hybrid ML-KEM key exchange and ML-DSA signatures |
| NSS | Hybrid ML-KEM TLS support and ML-DSA keys/signatures |
| OpenSSH | Hybrid post-quantum key exchange |
| libssh | Hybrid ML-KEM key exchange (expanded in recent releases) |
| Crypto policies (RHEL family) | System-wide enablement and algorithm ordering on RHEL, Rocky Linux, AlmaLinux, Fedora, and related distributions |
Library support is not the same as application support. OpenSSL may know about ML-KEM even when a service linked to an older library build never offers it.
Inspect PQC support on the current system
Before you change anything, confirm what your host already has. These commands work on any Linux distribution and answer the core question: does this build actually know about post-quantum algorithms?
Start with the OpenSSL version:
openssl versionSample output:
OpenSSL 3.5.5 27 Jan 2026 (Library: OpenSSL 3.5.5 27 Jan 2026)OpenSSL 3.5 is the release that brought native ML-KEM and ML-DSA into the default provider. Older builds may need a newer package or a distribution backport before these checks show PQ entries.
List ML-KEM key-encapsulation algorithms:
openssl list -kem-algorithms | grep -i ml-kemSample output:
{ 2.16.840.1.101.3.4.4.1, id-alg-ml-kem-512, ML-KEM-512, MLKEM512 } @ default
{ 2.16.840.1.101.3.4.4.2, id-alg-ml-kem-768, ML-KEM-768, MLKEM768 } @ default
{ 2.16.840.1.101.3.4.4.3, id-alg-ml-kem-1024, ML-KEM-1024, MLKEM1024 } @ defaultList TLS 1.3 hybrid groups:
openssl list -tls1_3 -tls-groups | grep -i mlkemSample output:
MLKEM512
MLKEM768
MLKEM1024
SecP256r1MLKEM768
X25519MLKEM768
SecP384r1MLKEM1024Check the OpenSSH build:
ssh -VSample output:
OpenSSH_9.9p1, OpenSSL 3.5.5 27 Jan 2026List post-quantum SSH key-exchange methods the client knows about:
ssh -Q kex | grep -iE 'mlkem|sntrup'Sample output:
sntrup761x25519-sha512
[email protected]
mlkem768x25519-sha256
mlkem768nistp256-sha256
mlkem1024nistp384-sha384If those commands show ML-KEM entries, your installed OpenSSL and OpenSSH builds include post-quantum support. That still does not prove a live connection negotiated a PQ algorithm.
Identify the distribution with the portable OS metadata file:
cat /etc/os-releaseAbridged sample output on Rocky Linux:
NAME="Rocky Linux"
VERSION="10.2 (Red Quartz)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="10.2"On RHEL-compatible systems you can also read /etc/redhat-release as a shortcut.
Check installed package versions with the command that matches your distribution family:
| Distribution family | Check the core packages |
|---|---|
| RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora | rpm -q openssl openssh |
| Debian and Ubuntu | dpkg-query -W openssl openssh-client openssh-server |
| SUSE and openSUSE | rpm -q openssl openssh |
| Arch Linux | pacman -Q openssl openssh |
Sample output on Rocky Linux:
rpm -q openssl opensshopenssl-3.5.5-4.el10_2.x86_64
openssh-9.9p1-23.el10_2.rocky.0.1.x86_64Package names and backports differ between distributions, so version numbers alone are not conclusive. Use the OpenSSL and OpenSSH capability commands above to see what the installed build actually supports.
List loaded OpenSSL providers:
openssl list -providersSample output:
Providers:
default
name: OpenSSL Default Provider
version: 3.5.5
status: active
pkcs11
name: PKCS#11 Provider
version: 3.2.2
status: activeThe tested Rocky Linux system also loads pkcs11; other distributions may show only default.
With native OpenSSL 3.5, standardized ML-KEM and ML-DSA implementations appear under the default provider. Systems using an older OpenSSL release may expose PQ algorithms through a separately installed oqsprovider. The provider list is build-dependent, and seeing only the default provider is sufficient for these OpenSSL 3.5 labs.
List signature algorithms:
openssl list -signature-algorithms | grep -iE 'ml-dsa|slh-dsa'Sample output:
{ 2.16.840.1.101.3.4.3.17, id-ml-dsa-44, ML-DSA-44, MLDSA44 } @ default
{ 2.16.840.1.101.3.4.3.18, id-ml-dsa-65, ML-DSA-65, MLDSA65 } @ default
{ 2.16.840.1.101.3.4.3.19, id-ml-dsa-87, ML-DSA-87, MLDSA87 } @ default
{ 2.16.840.1.101.3.4.3.20, id-slh-dsa-sha2-128s, SLH-DSA-SHA2-128s } @ default
{ 2.16.840.1.101.3.4.3.21, id-slh-dsa-sha2-128f, SLH-DSA-SHA2-128f } @ defaultAdditional SLH-DSA SHA2 and SHAKE parameter sets appear in the full listing.
Four separate layers trip people up. Work out which one you are actually looking at before you draw a conclusion:
| Layer | Question it answers |
|---|---|
| Implemented by the library | Does OpenSSL or OpenSSH know the algorithm? |
| Allowed by crypto policy | On RHEL-family systems, may this host use it at all? |
| Offered by an application | Does this particular server or client propose it? |
| Negotiated with the peer | Did both sides agree on it for this session? |
You need proof at the negotiated layer before you tell anyone the connection is post-quantum protected.
Test hybrid ML-KEM key exchange with TLS 1.3
I like using a local OpenSSL server and client for this test because you are not guessing whether a public website happens to support ML-KEM today. You also do not need a post-quantum certificate. A normal RSA or ECDSA server certificate is enough to prove the key exchange.
Create a short-lived classical test certificate:
openssl req -x509 -newkey rsa:2048 -keyout tls-lab.key -out tls-lab.crt -days 1 -nodes -subj "/CN=pqc-lab.local"The command creates tls-lab.key and tls-lab.crt. Key-generation progress may appear before the prompt returns.
Start a TLS 1.3 server that offers only the hybrid group X25519MLKEM768:
openssl s_server -accept 14433 -cert tls-lab.crt -key tls-lab.key -tls1_3 -groups X25519MLKEM768 -www -naccept 1In a second shell, connect with a matching client:
echo | openssl s_client -connect 127.0.0.1:14433 -tls1_3 -groups X25519MLKEM768Look for the negotiated group near the end of the client output:
Negotiated TLS1.3 group: X25519MLKEM768
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Protocol: TLSv1.3
Verify return code: 18 (self-signed certificate)That line tells you TLS 1.3 picked a hybrid X25519 plus ML-KEM-768 key exchange. The session secret gets protection from both worlds. It does not tell you whether the server certificate used a post-quantum signature, whether every app on the host will make the same choice, or whether a remote peer even offers X25519MLKEM768.
Repeat the exercise with classical X25519 only. Start the server:
openssl s_server -accept 14434 -cert tls-lab.crt -key tls-lab.key -tls1_3 -groups X25519 -www -naccept 1Connect the client:
echo | openssl s_client -connect 127.0.0.1:14434 -tls1_3 -groups X25519Sample output:
Peer Temp Key: X25519, 253 bits
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Protocol: TLSv1.3
Verify return code: 18 (self-signed certificate)OpenSSL prints Negotiated TLS1.3 group for hybrid groups and Peer Temp Key for classical-only exchanges. Comparing the two runs makes the difference visible in your own terminal.
You can run the same hybrid test across two lab hosts. Start openssl s_server on the server VM and connect with openssl s_client from the client VM using the server address instead of 127.0.0.1. On my two-VM lab I saw Negotiated TLS1.3 group: X25519MLKEM768 between 192.168.56.108 and 192.168.56.109.
For broader OpenSSL TLS work (renewals, chains, and CSR choices), keep certificate management separate from key-exchange testing.
Generate and verify ML-DSA signatures
ML-DSA does a different job from ML-KEM. ML-KEM helps two parties agree on a shared secret. ML-DSA signs and verifies files. The commands below use the OpenSSL 3.5 names you will see on a current release, not the lowercase oqsprovider spellings from older tutorials.
Generate an ML-DSA-65 private key:
openssl genpkey -algorithm ML-DSA-65 -out mldsa65-lab.keyOpenSSL creates the key file with no terminal output on success.
Extract the public key:
openssl pkey -in mldsa65-lab.key -pubout -out mldsa65-lab.pubCreate a sample file and sign it:
echo 'Post-quantum signature lab file.' > sample.txt
openssl pkeyutl -sign -inkey mldsa65-lab.key -in sample.txt -out sample.sigPublic-key extraction and signing normally produce no terminal output on success. They create mldsa65-lab.pub and sample.sig.
Verify the signature:
openssl pkeyutl -verify -pubin -inkey mldsa65-lab.pub -in sample.txt -sigfile sample.sigSample output:
Signature Verified SuccessfullyChange the file and confirm verification fails:
echo 'tampered content' > sample-bad.txt
openssl pkeyutl -verify -pubin -inkey mldsa65-lab.pub -in sample-bad.txt -sigfile sample.sigSample output:
Signature Verification Failure| Algorithm | NIST security category | General trade-off |
|---|---|---|
| ML-DSA-44 | 2 | Smaller and faster |
| ML-DSA-65 | 3 | Middle parameter set |
| ML-DSA-87 | 5 | Larger keys and signatures |
ML-DSA-65 is a sensible choice for this lab. Pick a different parameter set if your security team has already settled on one.
Optional: create an ML-DSA test certificate
You can mint a short-lived self-signed certificate from the same key for inspection:
openssl req -x509 -new -key mldsa65-lab.key -out mldsa65-lab.crt -days 1 -subj "/CN=pqc-mldsa-lab.local"Inspect the certificate:
openssl x509 -in mldsa65-lab.crt -text -nooutSample output:
Signature Algorithm: ML-DSA-65
Issuer: CN=pqc-mldsa-lab.local
Subject: CN=pqc-mldsa-lab.local
Subject Public Key Info:
Public Key Algorithm: ML-DSA-65
Signature Algorithm: ML-DSA-65Public CAs may not issue ML-DSA certificates yet, and many older TLS clients will not understand them. During a long transition you might run traditional and ML-DSA certificates side by side. You can adopt hybrid TLS key exchange long before post-quantum certificates are common.
Verify post-quantum key exchange in SSH
SSH handles key exchange, host authentication, user authentication, and session encryption as separate steps. Post-quantum support shows up mainly in key exchange. Your session can negotiate hybrid ML-KEM there while the server still uses an Ed25519, ECDSA, or RSA host key.
List available SSH key-exchange algorithms:
ssh -Q kex | grep -iE 'mlkem|sntrup'Sample output:
sntrup761x25519-sha512
[email protected]
mlkem768x25519-sha256
mlkem768nistp256-sha256
mlkem1024nistp384-sha384Upstream OpenSSH added mlkem768x25519-sha256 in version 9.9. OpenSSH 10.0 made it the default key-exchange method. Any recent Linux distribution that ships a current OpenSSH build can offer this algorithm.
The sample output above came from Rocky Linux 10.2. You may also see mlkem768nistp256-sha256 and mlkem1024nistp384-sha384 on RHEL-family builds.
Those NIST-curve hybrids were added for documented FIPS-mode SSH support on that platform and are not guaranteed on every Linux OpenSSH package. sntrup761x25519-sha512 is another hybrid post-quantum exchange, but its PQ component is not ML-KEM.
Connect from the client VM to the server VM with verbose logging:
ssh -vv [email protected] exitSample output:
debug1: kex: algorithm: mlkem768x25519-sha256
Authenticated to 192.168.56.109 ([192.168.56.109]:22) using "publickey".That kex line is the proof you want in your notes. Seeing ML-KEM in ssh -Q kex only tells you the client knows the name.
Force the hybrid algorithm when you need an explicit test:
ssh -o KexAlgorithms=mlkem768x25519-sha256 -vv [email protected] exitWhen both machines support the hybrid method, you should still see mlkem768x25519-sha256 even if you force it explicitly.
You rarely need to force algorithms in daily use. If you want client-wide defaults, see SSH client configuration and the SSH command reference.
Ansible and other tools may use libssh instead of the OpenSSH client, so the algorithm list can differ even between machines on the same distribution.
RHEL-family crypto policies and PQC interoperability
This section applies to distributions that use the RHEL/Fedora system-wide crypto-policies framework, including RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, and Fedora. Debian, Ubuntu, Arch, and other distributions do not necessarily provide an equivalent DEFAULT, FUTURE, NO-PQ, or TEST-PQ policy interface.
There is no safe universal replacement for update-crypto-policies --show. On other distributions, configuration may be controlled separately by OpenSSL, OpenSSH, GnuTLS, or the application itself.
Crypto policies set the ceiling for what your applications are allowed to use on RHEL-family systems. Here I am only talking about the post-quantum side of that picture. Broader update-crypto-policies administration belongs in your normal hardening notes.
| Policy | What it means for post-quantum cryptography |
|---|---|
| DEFAULT | Hybrid PQC is on and preferred, but classical algorithms remain available for older peers |
| LEGACY | Hybrid PQC stays available, with more older algorithms still permitted |
| FIPS | PQ availability is component-specific; only hybrid ML-KEM combinations supported by the release's FIPS configuration work, while ML-DSA availability depends on the library and provider |
| FUTURE | On RHEL 10.2 and aligned builds, hybrid ML-KEM only; many connections to non-PQ services stop working |
| DEFAULT:NO-PQ | Turns off PQ algorithms that the system policy would otherwise allow |
| TEST-PQ | Helps you test pure ML-KEM in OpenSSL; not needed for everyday hybrid PQC |
See which policy is active on your host:
update-crypto-policies --showSample output:
DEFAULTDEFAULT is the policy you will see on most fresh RHEL-family installs. It turns on supported hybrid post-quantum algorithms and still leaves room for classical fallbacks when the other side needs them.
Check which PQ algorithms the active policy allows:
grep -E 'MLKEM|MLDSA|KEM-ECDH' /etc/crypto-policies/state/CURRENT.polAbridged sample output:
group = MLKEM768-X25519 P256-MLKEM768 P384-MLKEM1024 MLKEM1024-X448 X25519 SECP256R1 ...
key_exchange = KEM-ECDH ECDHE DHE ...
sign = MLDSA44 MLDSA65 MLDSA87 ECDSA-SHA3-256 ...For the labs here and for most day-to-day RHEL-family systems, stay on DEFAULT. I would only move a machine to FUTURE on RHEL 10.2 or an aligned build when you have a deliberate test plan. That policy is strict: it can block public TLS sites without PQ key exchange, older SSH servers, some Java TLS clients, and package mirrors that still speak only classical algorithms.
DEFAULT:NO-PQ is useful when you need to compare behaviour or chase a compatibility problem. I would not leave it in place as routine hardening.
Keep these interoperability points in mind:
- Both ends need a hybrid group they agree on.
- Allowed in policy is not the same as negotiated on the wire.
- Hybrid TLS groups need TLS 1.3.
- PQ handshakes are larger than classical-only ones.
- Post-quantum certificates are still rare compared with hybrid key exchange.
- Keys from the Technology Preview era may not match today's on-disk formats.
What breaks when you enable the FUTURE policy
The table above tells you what FUTURE is supposed to do on RHEL 10.2 and aligned builds. Policy contents can differ across Fedora and RHEL-family releases even when update-crypto-policies exists. The lab below shows you what that feels like on a real SSH client.
I used the two VMs from the lab environment. The client at 192.168.56.108 is where you change crypto policy. The server at 192.168.56.109 runs a second sshd that speaks only classical key exchange.
Take a snapshot or keep console access before you change policy. Red Hat recommends a reboot after policy changes so long-running services pick up the new rules. On my lab, opening a fresh ssh client was enough to reproduce the failure.
On the server VM, create the lab directory:
mkdir -p /tmp/pqc-lab/sshd-classicalSave this minimal configuration as /tmp/pqc-lab/sshd-classical/sshd_config:
Port 2222
ListenAddress 192.168.56.109
PidFile /tmp/pqc-lab/sshd-classical/sshd.pid
HostKey /etc/ssh/ssh_host_ed25519_key
AuthorizedKeysFile .ssh/authorized_keys
PermitRootLogin yes
KexAlgorithms curve25519-sha256,ecdh-sha2-nistp256Start that classical server:
/usr/sbin/sshd -f /tmp/pqc-lab/sshd-classical/sshd_configConfirm it is listening on port 2222 so a later failure can be traced to key exchange rather than a server-start problem:
ss -ltn | grep ':2222'Sample output:
LISTEN 0 128 192.168.56.109:2222 0.0.0.0:*If sshd cannot bind to port 2222 on an SELinux-enforcing system, assign the port to the SSH label:
semanage port -a -t ssh_port_t -p tcp 2222If the port is already defined, use semanage port -m -t ssh_port_t -p tcp 2222 instead.
If semanage is unavailable, install the package that supplies it—for example, policycoreutils-python-utils on current RHEL-family systems.
If firewalld is running on the server, allow the test port:
firewall-cmd --add-port=2222/tcpOn the client VM, check which policy is active:
update-crypto-policies --showWhile the client is still on DEFAULT, confirm that the classical server on port 2222 answers:
ssh -p 2222 -o StrictHostKeyChecking=no [email protected] exitA quiet exit means the classical handshake worked.
Now change only the client to the FUTURE policy:
update-crypto-policies --set FUTURETry the same classical connection again:
ssh -p 2222 -vv [email protected] exitSample output:
debug1: kex: algorithm: (no match)
Unable to negotiate with 192.168.56.109 port 2222: no matching key exchange method found. Their offer: curve25519-sha256,ecdh-sha2-nistp256,ext-info-s,[email protected]The client now offers only hybrid ML-KEM methods. The lab server on port 2222 offers only classical methods. With no shared choice, ssh stops and prints the error above.
That does not mean SSH is broken everywhere on the client. Connect to the normal sshd on port 22 on the same server:
ssh -vv [email protected] exitSample output:
debug1: kex: algorithm: mlkem768x25519-sha256Port 22 still negotiates hybrid ML-KEM because both sides support it. FUTURE blocks peers that never learned post-quantum key exchange, not every SSH session.
Do not run this on a production server, a host without console access, a system that must reach non-PQ repositories, or a workstation you rely on for normal internet access.
Switch back to DEFAULT when you finish
On the client VM, return to DEFAULT:
update-crypto-policies --set DEFAULTConfirm the change:
update-crypto-policies --showSample output:
DEFAULTTry the classical lab server on port 2222 again:
ssh -p 2222 -o StrictHostKeyChecking=no [email protected] exitThe connection should work again. Going back to DEFAULT does not strip out post-quantum support. It simply lets the client talk to classical peers again when the remote side has not caught up yet.
On the server VM, stop the lab sshd, remove the temporary firewall rule if you added one, and delete /tmp/pqc-lab when you are done.
Decide what administrators should do now
If you are planning a rollout, this checklist is a practical place to start. It is not a promise that every connection is already quantum-resistant.
- Inventory OpenSSL and OpenSSH versions on every tier, using the capability commands above rather than distribution labels alone.
- Stay on supported package versions so OpenSSL, OpenSSH, and (on RHEL-family systems) crypto-policy fixes arrive together.
- On RHEL-family systems, keep DEFAULT unless your environment documentation calls for something else.
- Verify which PQ algorithms are implemented and allowed, then capture negotiated TLS and SSH output.
- Test interoperability with older clients, proxies, load balancers, HSMs, and monitoring tools.
- Identify data that needs long-term confidentiality and prioritize those paths for hybrid protection.
- Exercise ML-DSA keys and certificates in isolated labs before production issuance.
- Avoid generating new long-lived keys in the old RHEL 10.0 oqsprovider formats.
- On RHEL-family systems, convert important Technology Preview-era PQ keys before depending on them after an upgrade.
- Track vendor, OpenSSL, OpenSSH, IETF, and NIST updates.
- Obtain compliance guidance from your vendor or assessor instead of inferring it from algorithm availability.
The immediate value of post-quantum cryptography on Linux is operational experience, interoperability testing, harvest-now-decrypt-later protection for selected TLS and SSH sessions, and preparation for a gradual migration across certificates, signing workflows, and application stacks.
References
- RHEL 10 Security Hardening: Post-quantum cryptography and crypto policies
- RHEL 10.0: PQC Technology Preview
- RHEL 10.1: PQC enabled in predefined crypto policies
- RHEL 10.2: OpenSSH, libssh, and crypto-policy PQC changes
- RHEL 10.2: FUTURE policy removes non-PQ key exchange
- Red Hat: Interoperability of RHEL 10 post-quantum cryptography
- RHEL 10: Creating post-quantum TLS keys and certificates
- Rocky Linux 10.2 release announcement
- OpenSSH release notes
- OpenSSL 3.5: Listing KEM, signature, and TLS algorithms
- OpenSSL 3.5: ML-KEM support
- OpenSSL 3.5: ML-DSA support
- NIST FIPS 203: Module-Lattice-Based Key-Encapsulation Mechanism
- NIST FIPS 204: Module-Lattice-Based Digital Signature Standard
- NIST FIPS 205: Stateless Hash-Based Digital Signature Standard

