Toda a pesquisa

O FIPS 140-3 desativa o TLS pós-quântico? Ele faz downgrade silenciosamente

Tabela de verdade do TLS no FIPS-140-3: o Go remove o pós-quântico, o OpenSSL mantém o híbrido não aprovado.

A resposta curta para "o FIPS desativa o TLS pós-quântico" é: ele não fornece TLS pós-quântico em conformidade e pode desativá-lo silenciosamente. Em nosso próprio laboratório, diretamente na rede, duas das principais stacks fizeram o oposto quando colocadas em modo FIPS, e nenhuma ofereceu o grupo pós-quântico aprovado pelo FIPS por padrão. O Go 1.24, sob GODEBUG=fips140=on e =only, removeu todos os grupos pós-quânticos de seu ClientHello e negociou silenciosamente P-256 clássico, de modo que uma conexão que "teve sucesso" não realizou nenhuma troca de chaves resistente a computadores quânticos. O provedor FIPS do OpenSSL 3.5.2 fez o oposto: ele ainda ofereceu e negociou X25519MLKEM768, o híbrido cuja metade X25519 não é aprovada pelo FIPS. Seu provedor FIPS gerencia essa metade por meio de um indicador de aprovação em vez de bloqueá-la. Assim, o TLS pós-quântico no FIPS 140-3 cai em um de dois modos de falha: ao ativar o FIPS, a proteção pós-quântica é desligada (Go) ou um grupo fora de conformidade permanece ativo (OpenSSL). A proteção contra "coletar agora, descriptografar depois" fica configurada incorretamente de forma silenciosa justamente para as organizações reguladas obrigadas a executar FIPS.

A versão direta "FIPS ativo" não é "pós-quântico ativo." O Go 1.24 em modo FIPS remove o híbrido pós-quântico inteiramente e faz fallback para o P-256 clássico sem nenhum erro. O OpenSSL 3.5 em modo FIPS mantém o X25519MLKEM768, cuja metade clássica não está na lista de aprovados do FIPS. Nenhum dos dois oferece SecP256r1MLKEM768, o híbrido que é de fato legal perante o FIPS, a menos que você o configure manualmente.

O que encontramos ao ativar a chave do FIPS

Criamos dois clientes e dois servidores, um par em Go 1.24, um par em OpenSSL 3.5.2, e observamos seus handshakes TLS 1.3 diretamente na rede com o modo FIPS desativado e depois ativado. O TLS 1.3 envia as extensões supported_groups e key_share em texto claro, portanto o ClientHello é a fonte de verdade absoluta: você pode ler exatamente quais grupos de troca de chaves o cliente está disposto a usar e para qual deles ele preparou um share. Sem adivinhações baseadas na documentação da biblioteca, apenas os bytes colocados no socket.

Com Go 1.24 em modo FIPS, o ClientHello reduziu-se apenas às curvas do NIST. A lista supported_groups era secp256r1, secp384r1, secp521r1 e nada mais: sem x25519 puro, sem X25519MLKEM768 e, notavelmente, nem mesmo o SecP256r1MLKEM768 aprovado pelo FIPS. O key_share foi secp256r1 e o grupo negociado foi secp256r1, Diffie-Hellman clássico em curva elíptica sem nenhum componente pós-quântico. O comportamento foi idêntico para fips140=on e para o mais rigoroso fips140=only. Um servidor Go em modo FIPS, ao receber uma oferta de grupo pós-quântico de um peer não FIPS, respondeu com um HelloRetryRequest e forçou o handshake para secp256r1. Em todos os casos, o handshake foi concluído com sucesso. Essa é a parte perigosa: nada falhou, nenhum aviso foi emitido, a conexão apenas perdeu silenciosamente sua resistência quântica.

Com o OpenSSL 3.5.2 o provedor FIPS tomou o caminho oposto. Seu ClientHello em modo FIPS começou com X25519MLKEM768 e incluiu um key_share para ele, seguido por P-256, P-384, P-521 e os grupos de campo finito. Em comparação com sua linha de base sem FIPS, os únicos grupos que o modo FIPS removeu foram as curvas autônomas x25519 e x448; o híbrido X25519MLKEM768 permaneceu no topo da lista com um key_share ativo, e negociou esse grupo contra um peer que o suportava. O servidor OpenSSL também aceitou o X25519MLKEM768. Portanto, o OpenSSL em modo FIPS continua oferecendo um grupo cuja metade clássica ele não permite usar isoladamente.

A tabela de verdade, diretamente na rede

Aqui está cada caso que medimos, com os grupos oferecidos por cada stack, o grupo negociado e o que isso significa para você. As linhas do Go e as linhas do OpenSSL mostram o cenário: mesma intenção, "tornar o TLS compatível com FIPS", resultado oposto.

Comportamento do TLS no FIPS-140-3 medido na rede, execução em laboratório 2026-08-04
StackFunçãoModo FIPSGrupos oferecidosGrupo negociadoResultado
Go 1.24Clientefips140=on / =onlysecp256r1, secp384r1, secp521r1secp256r1Apenas clássico, sem pós-quântico
Go 1.24Servidorfips onCurvas NIST; envia HelloRetryRequestsecp256r1Força o peer para o modo clássico
OpenSSL 3.5.2Clientefips onX25519MLKEM768, secp256r1/384/521, ffdhe2048/3072X25519MLKEM768Pós-quântico, mas híbrido não aprovado
OpenSSL 3.5.2Servidorfips onAceita X25519MLKEM768X25519MLKEM768Pós-quântico, mas híbrido não aprovado
OpenSSL 3.5.2Ambos, forçadofips onX25519MLKEM768 (forçado)X25519MLKEM768Handshake é bem-sucedido sob FIPS
OpenSSL 3.5.2Ambos, forçadofips onSecP256r1MLKEM768 (forçado)SecP256r1MLKEM768Híbrido aprovado funciona, mas nunca por padrão

Leia as duas últimas linhas em comparação com tudo acima delas. Ambos os híbridos pós-quânticos realizam o handshake sem problemas com ambos os peers no modo FIPS, incluindo o totalmente aprovado SecP256r1MLKEM768. As stacks são capazes de fazer a coisa certa. Elas apenas não escolhem isso por você: o Go remove todos eles, enquanto o OpenSSL usa o não aprovado por padrão.

Como medimos, para que um cético possa confiar nos números

O conjunto de dados é nosso, construído em nossos próprios sistemas, apenas de forma agregada. Executamos tudo em contêineres Docker próprios, em uma VM temporária em nuvem, comunicando-se via loopback. Nenhum servidor de terceiros foi tocado, nenhum endpoint externo foi contatado e nenhuma informação sobre qualquer indivíduo foi coletada. Isso é um laboratório, não uma varredura da infraestrutura de terceiros.

Usamos três verificações independentes para que nenhuma ferramenta precise ser aceita por fé:

Por que o FIPS faz isso: X25519 não é aprovado, ML-KEM é

O mecanismo é uma incompatibilidade entre o que os padrões aprovam e o que o ecossistema usa por padrão. Sob as regras de acordo de chaves do NIST na SP 800-56A, X25519 não é um esquema aprovado pelo FIPS, razão pela qual um módulo rigoroso o recusa isoladamente. O ML-KEM, padronizado como FIPS 203, é aprovado. O único híbrido amplamente especificado que é legal perante o FIPS em ambas as metades é SecP256r1MLKEM768: NIST P-256, uma curva aprovada, combinada ao ML-KEM-768. O híbrido concorrente X25519MLKEM768 combina o ML-KEM-768 aprovado com o X25519 não aprovado, portanto metade dele está fora da lista.

O problema é que navegadores, Go e OpenSSL usam por padrão o X25519MLKEM768, e não o aprovado SecP256r1MLKEM768, porque o X25519 é rápido e onipresente fora do mundo FIPS. Ambos os híbridos estão especificados no mesmo draft da IETF para troca de chaves ECDHE-MLKEM. Portanto, uma chave de FIPS que remove o X25519 também remove o híbrido pós-quântico construído sobre ele, a menos que a stack trate o híbrido como um caso especial. Essa é exatamente a divergência que medimos. O Go restringe em excesso: ele descarta todos os grupos pós-quânticos e retorna ao modo clássico, o que é seguro para conformidade, mas descarta a resistência quântica. O OpenSSL restringe de menos: ele mantém o híbrido não aprovado ativo, filtrando-o por meio de um indicador de aprovação FIPS em vez de bloqueá-lo, uma abordagem rastreada em openssl/openssl #27061. Nenhum dos dois comportamentos é um bug no sentido usual; ambos são escolhas defensáveis de biblioteca que produzem um resultado não óbvio quando você analisa a rede. O comportamento do Go é discutido em golang/go #78178 e #78298, e o suporte pós-quântico do OpenSSL 3.5 chegou em seu lançamento de abril de 2025.

O que fazer se você executa FIPS e se preocupa com a ameaça de coletar agora e descriptografar depois

O objetivo principal de um híbrido pós-quântico é derrotar um adversário de "coletar agora, descriptografar depois", alguém que grava seu tráfego TLS hoje para descriptografá-lo quando um computador quântico existir. Uma opção de FIPS que remove silenciosamente essa proteção anula o objetivo para as organizações com maior probabilidade de serem alvo. Se você executa FIPS, não presuma que a chave resolveu o problema.

O que isso não prova

Um resultado sem seus limites é marketing, portanto aqui estão as fronteiras deste estudo.

Perguntas frequentes

A ativação do modo FIPS desativa o TLS pós-quântico?

Pode desativar, e em nosso laboratório desativou. Com o Go 1.24 sob GODEBUG=fips140=on ou fips140=only, o ClientHello descartou todos os grupos pós-quânticos e a conexão negociou P-256 clássico, de modo que um handshake bem-sucedido não teve nenhuma troca de chaves resistente a computadores quânticos. O OpenSSL 3.5.2 fez o oposto: seu provedor FIPS ainda ofereceu e negociou o X25519MLKEM768, cuja metade X25519 não é aprovada pelo FIPS. Nenhuma das stacks ofereceu o grupo pós-quântico aprovado pelo FIPS por padrão.

O X25519 é aprovado pelo FIPS?

Não. O X25519 não é um esquema de acordo de chaves aprovado na NIST SP 800-56A, portanto um módulo FIPS estrito o trata como não aprovado. Confirmamos isso diretamente: sob o provedor FIPS do OpenSSL 3.5.2, a geração de chave X25519 isolada falhou como não suportada com um código de saída diferente de zero, enquanto a mesma operação foi bem-sucedida sob o provedor default.

O X25519MLKEM768 é aprovado pelo FIPS?

Não de forma direta. É um híbrido: a metade ML-KEM-768 é aprovada pelo FIPS 203, mas a metade X25519 não é aprovada para acordo de chaves. O provedor FIPS do OpenSSL não bloqueia o híbrido; ele o gerencia por meio de um indicador de aprovação FIPS e ainda o oferece e negocia por padrão. O grupo funciona sob o FIPS, mas sua metade clássica está fora da lista de aprovados.

Qual é o grupo TLS pós-quântico aprovado pelo FIPS?

O híbrido legal perante o FIPS amplamente especificado é o SecP256r1MLKEM768: NIST P-256, uma curva aprovada na SP 800-56A, combinada com o ML-KEM-768 do FIPS 203. Ambas as metades são aprovadas. Em nosso laboratório, forçar o SecP256r1MLKEM768 com ambos os peers no modo FIPS produziu um handshake bem-sucedido, mas nem o Go 1.24 nem o OpenSSL 3.5.2 o ofereceram por padrão.

Por que meu handshake TLS no Go muda sob GODEBUG=fips140?

Porque o modo FIPS do Go 1.24 restringe as curvas oferecidas ao conjunto do NIST. Sob fips140=on ou fips140=only, o ClientHello do cliente que capturamos anunciou apenas secp256r1, secp384r1 e secp521r1, sem x25519 e sem híbrido pós-quântico, e negociou P-256 clássico. Um servidor Go em modo FIPS enviou um HelloRetryRequest para forçar o peer a usar secp256r1. O handshake ainda é bem-sucedido, então o downgrade é silencioso a menos que você inspecione o grupo negociado.

O FIPS quebra a proteção contra coletar agora e descriptografar depois?

Nas configurações padrão que testamos, sim, no sentido que realmente importa. O Go em modo FIPS removeu toda a troca de chaves pós-quântica e retornou à criptografia clássica, exatamente o tráfego que um adversário no modelo "coletar agora, descriptografar depois" quer gravar e quebrar no futuro. O OpenSSL manteve a troca de chaves pós-quântica, mas por meio de um híbrido cuja metade clássica não é aprovada pelo FIPS, o que é um problema de conformidade e não criptográfico. De qualquer forma, ativar o FIPS não ofereceu proteção pós-quântica em conformidade por padrão.

Leitura relacionada

Está executando FIPS e presumindo que ele tratou do pós-quântico?

Nossa verificação de $100 analisa sua postura criptográfica real da mesma forma que um atacante a registra, em escopo que você confirmou possuir e autorizou por escrito, com um operador sênior na análise dos resultados. O que seus serviços realmente negociam na rede faz parte dessa superfície.

Agende uma verificação por $100