Tutta la ricerca

FIPS 140-3 disabilita il TLS post-quantistico? Effettua un downgrade silenzioso

Tabella di verità TLS FIPS-140-3: Go rimuove il post-quantistico, OpenSSL mantiene l'ibrido non approvato.

La risposta breve a "FIPS disabilita il TLS post-quantistico" è: non fornisce un TLS post-quantistico conforme, e può disattivarlo silenziosamente. Nel nostro laboratorio, analizzando il traffico di rete, due tra i principali stack hanno mostrato comportamenti opposti una volta impostati in modalità FIPS, e nessuno dei due ha offerto di default il gruppo post-quantistico approvato da FIPS. Go 1.24, sotto GODEBUG=fips140=on e =only, ha rimosso ogni gruppo post-quantistico dal suo ClientHello e ha negoziato silenziosamente il P-256 classico, pertanto una connessione con esito "positivo" non includeva alcuno scambiatore di chiavi resistente ai quanti. Il provider FIPS di OpenSSL 3.5.2 ha fatto l'opposto: ha comunque offerto e negoziato X25519MLKEM768, l'ibrido la cui metà X25519 non è approvata da FIPS. Il suo provider FIPS gestisce tale metà tramite un indicatore di approvazione anziché bloccarla. Quindi il TLS post-quantistico sotto FIPS 140-3 ricade in una di due modalità di errore: attivando FIPS, la protezione post-quantistica viene disattivata (Go) oppure un gruppo non conforme rimane attivo (OpenSSL). La protezione contro gli attacchi "harvest-now-decrypt-later" risulta impostata in modo errato all'insaputa dell'utente proprio per quelle organizzazioni regolamentate obbligate ad adottare FIPS.

In sintesi "FIPS attivo" non significa "post-quantistico attivo." Go 1.24 in modalità FIPS rimuove completamente l'ibrido post-quantistico e ripiega sul classico P-256 senza restituire errori. OpenSSL 3.5 in modalità FIPS mantiene X25519MLKEM768, la cui metà classica non figura nell'elenco delle opzioni approvate da FIPS. Nessuno dei due offre SecP256r1MLKEM768, l'ibrido effettivamente conforme a FIPS, a meno che non lo si configuri manualmente.

Cosa abbiamo scoperto attivando la modalità FIPS

Abbiamo realizzato due client e due server, una coppia su Go 1.24 e una su OpenSSL 3.5.2, e abbiamo analizzato i loro handshake TLS 1.3 a livello di rete con la modalità FIPS prima disattivata e poi attivata. TLS 1.3 invia le estensioni supported_groups e key_share in chiaro, quindi il ClientHello rappresenta il dato oggettivo: è possibile leggere esattamente quali gruppi di scambio chiavi il client sia disposto a utilizzare e per quale di essi abbia preparato una quota. Nessuna supposizione basata sulla documentazione della libreria, solo i byte trasmessi sulla socket.

Con Go 1.24 in modalità FIPS, il ClientHello si è ridotto alle sole curve NIST. L'elenco supported_groups era secp256r1, secp384r1, secp521r1 e niente altro: niente x25519 standalone, niente X25519MLKEM768 e, soprattutto, nemmeno SecP256r1MLKEM768, che è approvato da FIPS. Il key_share era secp256r1 e il gruppo negoziato era secp256r1, ovvero Diffie-Hellman classico su curve ellittiche senza alcuna componente post-quantistica. Il comportamento è stato identico per fips140=on e per il più rigido fips140=only. Un server Go in modalità FIPS, a cui è stato offerto un gruppo post-quantistico da un peer non FIPS, ha risposto con un HelloRetryRequest e ha forzato l'handshake a degradare verso secp256r1. In ciascun caso l'handshake si è concluso con successo. È questo l'aspetto pericoloso: nessun errore, nessun avviso, la connessione ha semplicemente perso in modo silenzioso la sua resistenza quantistica.

Con OpenSSL 3.5.2 il provider FIPS si è comportato in modo opposto. Il suo ClientHello in modalità FIPS presentava in cima X25519MLKEM768 e includeva un key_share per quest'ultimo, seguito da P-256, P-384, P-521 e dai gruppi a campi finiti. Rispetto al valore di riferimento non FIPS, gli unici gruppi rimossi dalla modalità FIPS sono state le curve standalone x25519 e x448; l'ibrido ibrido X25519MLKEM768 è rimasto in cima all'elenco con un key_share attivo, e ha negoziato quel gruppo con un peer che lo supportava. Anche il server OpenSSL ha accettato X25519MLKEM768. Pertanto, OpenSSL in modalità FIPS continua a offrire un gruppo la cui metà classica non verrebbe consentita da sola.

La tabella di verità, a livello di rete

Ecco tutti i casi analizzati, con i gruppi offerti da ciascuno stack, il gruppo negoziato e le relative implicazioni. Le righe relative a Go e OpenSSL descrivono l'intera vicenda: medesima intenzione, ossia "rendere il TLS conforme a FIPS", ma risultato opposto.

Comportamento TLS FIPS-140-3 misurato sul traffico di rete, test di laboratorio del 2026-08-04
StackRuoloModalità FIPSGruppi offertiGruppo negoziatoRisultato
Go 1.24Clientfips140=on / =onlysecp256r1, secp384r1, secp521r1secp256r1Solo classico, niente post-quantistico
Go 1.24Serverfips onCurve NIST; invia HelloRetryRequestsecp256r1Forza il peer al downgrade classico
OpenSSL 3.5.2Clientfips onX25519MLKEM768, secp256r1/384/521, ffdhe2048/3072X25519MLKEM768Post-quantistico, ma ibrido non approvato
OpenSSL 3.5.2Serverfips onAccetta X25519MLKEM768X25519MLKEM768Post-quantistico, ma ibrido non approvato
OpenSSL 3.5.2Entrambi, forzatofips onX25519MLKEM768 (forzato)X25519MLKEM768Handshake completato sotto FIPS
OpenSSL 3.5.2Entrambi, forzatofips onSecP256r1MLKEM768 (forzato)SecP256r1MLKEM768L'ibrido approvato funziona, ma non è mai predefinito

Confrontate le ultime due righe con tutto ciò che le precede. Entrambi gli ibridi post-quantistici eseguono l'handshake senza problemi con entrambi i peer in modalità FIPS, incluso il gruppo SecP256r1MLKEM768 interamente approvato. Gli stack sono perfettamente in grado di comportarsi in modo corretto. Semplicemente non lo selezionano in automatico: Go li rimuove tutti, mentre OpenSSL seleziona di default quello non approvato.

Come abbiamo effettuato le misurazioni, a garanzia dell'affidabilità dei dati

Il dataset è stato generato internamente sui nostri sistemi, ed è unicamente aggregato. Abbiamo eseguito ogni test all'interno di container Docker creati da noi, su una VM cloud effimera, comunicando tramite interfaccia di loopback. Nessun server di terze parti è stato coinvolto, nessun endpoint esterno è stato contattato e non è stato raccolto alcun dato personale. Si tratta di un laboratorio, non di una scansione dell'infrastruttura altrui.

Abbiamo utilizzato tre verifiche indipendenti per evitare di doversi fidare cieca di un singolo strumento:

Perché FIPS si comporta così: X25519 non è approvato, ML-KEM sì

La causa risiede in un disallineamento tra ciò che gli standard approvano e le opzioni predefinite dall'ecosistema. Secondo le regole del NIST per l'accordo sulle chiavi espresse in SP 800-56A, X25519 non è uno schema approvato da FIPS, motivo per cui un modulo rigido lo rifiuta se utilizzato da solo. ML-KEM, standardizzato come FIPS 203, è approvato. L'unico ibrido ampiamente specificato che risulta conforme a FIPS per entrambe le componenti è SecP256r1MLKEM768: NIST P-256, una curva approvata, accoppiata a ML-KEM-768. L'ibrido concorrente X25519MLKEM768 affianca il componente approvato ML-KEM-768 al non approvato X25519, rendendo metà della combinazione fuori norma.

Il problema è che browser, Go e OpenSSL utilizzano tutti come impostazione predefinita X25519MLKEM768, anziché l'approvato SecP256r1MLKEM768, poiché X25519 è veloce ed estremamente diffuso al di fuori dell'ambito FIPS. Entrambi gli ibridi sono specificati nella medesima bozza IETF per lo scambio chiavi ECDHE-MLKEM. Di conseguenza, l'attivazione della modalità FIPS che rimuove X25519 elimina anche l'ibrido post-quantistico basato su di esso, a meno che lo stack non gestisca l'ibrido come eccezione. Questa è esattamente la divergenza che abbiamo riscontrato. Go applica restrizioni eccessive: rimuove qualsiasi gruppo post-quantistico e ripiega sul metodo classico, il che garantisce la conformità ma elimina la resistenza quantistica. OpenSSL applica restrizioni insufficienti: mantiene attivo l'ibrido non approvato, gestendolo tramite un indicatore di approvazione FIPS anziché bloccarlo, una scelta architetturale tracciata in openssl/openssl #27061. Nessuno dei due comportamenti costituisce un bug nel senso tradizionale; si tratta di scelte di libreria difendibili che producono un risultato non evidente finché non si analizza effettivamente il traffico di rete. Il comportamento di Go è discusso in golang/go #78178 e #78298, mentre il supporto post-quantistico di OpenSSL 3.5 è stato introdotto nella sua release di aprile 2025.

Cosa fare se si utilizza FIPS e si intende prevenire gli attacchi harvest-now-decrypt-later

L'obiettivo fondamentale di un ibrido post-quantistico è sventare gli attacchi "harvest now, decrypt later", nei quali un attaccante registra il traffico TLS oggi per decifrarlo in futuro con un computer quantistico. L'attivazione di FIPS che rimuove silenziosamente tale protezione vanifica l'obiettivo proprio per le organizzazioni più esposte a questo rischio. Se si impiega FIPS, non bisogna dare per scontato che l'opzione abbia risolto il problema.

Cosa non dimostra questa analisi

Un risultato privo dei suoi limiti equivale a semplice marketing; pertanto, ecco i perimetri di questo studio.

Domande frequenti

L'abilitazione della modalità FIPS disabilita il TLS post-quantistico?

Può farlo, e nel nostro laboratorio è accaduto. Con Go 1.24 sotto GODEBUG=fips140=on o fips140=only, il ClientHello ha rimosso qualsiasi gruppo post-quantistico e la connessione ha negoziato il P-256 classico, pertanto un handshake completato con successo non presentava alcuno scambio chiavi resistente ai quanti. OpenSSL 3.5.2 ha fatto l'opposto: il suo provider FIPS continuava a offrire e negoziare X25519MLKEM768, la cui metà X25519 non è approvata da FIPS. Nessuno dei due stack ha offerto di default il gruppo post-quantistico approvato da FIPS.

X25519 è approvato da FIPS?

No. X25519 non è uno schema di accordo sulle chiavi approvato secondo NIST SP 800-56A, quindi un modulo FIPS rigoroso lo considera non approvato. Lo abbiamo confermato direttamente: sotto il provider FIPS di OpenSSL 3.5.2, la generazione di chiavi X25519 standalone è fallita poiché non supportata restituendo un codice di uscita diverso da zero, mentre la stessa operazione è riuscita sotto il provider default.

X25519MLKEM768 è approvato da FIPS?

Non pienamente. Si tratta di un ibrido: la metà ML-KEM-768 è approvata da FIPS 203, ma la metà X25519 non è approvata per l'accordo sulle chiavi. Il provider FIPS di OpenSSL non blocca l'ibrido; lo gestisce tramite un indicatore di approvazione FIPS e continua a offrirlo e negozialo di default. Il gruppo funziona sotto FIPS, ma la sua metà classica non figura nell'elenco di quelli approvati.

Qual è il gruppo TLS post-quantistico approvato da FIPS?

L'ibrido ampiamente specificato e conforme a FIPS è SecP256r1MLKEM768: NIST P-256, una curva approvata da SP 800-56A, abbinata a ML-KEM-768 di FIPS 203. Entrambe le metà sono approvate. Nel nostro laboratorio, forzando SecP256r1MLKEM768 con entrambi i peer in modalità FIPS si è ottenuto un handshake con esito positivo, ma né Go 1.24 né OpenSSL 3.5.2 lo hanno offerto per impostazione predefinita.

Perché l'handshake TLS di Go cambia sotto GODEBUG=fips140?

Perché la modalità FIPS di Go 1.24 limita le curve offerte al set NIST. Sotto fips140=on o fips140=only, il ClientHello trasmesso dal client e catturato nei test annunciava unicamente secp256r1, secp384r1 e secp521r1, senza x25519 e senza ibrido post-quantistico, negoziando il P-256 classico. Un server Go in modalità FIPS ha inviato un HelloRetryRequest per forzare il peer al downgrade verso secp256r1. L'handshake si conclude comunque con successo, rendendo il downgrade silenzioso a meno di non ispezionare il gruppo negoziato.

FIPS compromette la protezione contro gli attacchi harvest-now-decrypt-later?

Nelle configurazioni predefinite testate, sì, negli aspetti fondamentali. Go in modalità FIPS ha rimosso qualsiasi scambio chiavi post-quantistico ed è ripiegato sulla crittografia classica, ovvero proprio il tipo di traffico che un attaccante "harvest-now-decrypt-later" intende registrare per decifrarlo in seguito. OpenSSL ha mantenuto lo scambio chiavi post-quantistico ma mediante un ibrido la cui metà classica non è approvata da FIPS, il che costituisce un problema di conformità anziché crittografico. In entrambi i casi, l'attivazione di FIPS non ha garantito di default una protezione post-quantistica conforme.

Letture correlate

Esegui FIPS dando per scontato che gestisca il post-quantistico?

Il nostro controllo da $100 analizza la reale postura crittografica così come verrebbe registrata da un attaccante, su un perimetro verificato di tua proprietà e autorizzato per iscritto, affiancando un operatore senior nella lettura dei risultati. Ciò che i servizi negoziano effettivamente sul traffico di rete fa parte di tale superficie.

Prenota un controllo da $100