← Voltar para o blog

Go Simplifica a Conformidade com FIPS 140-3: Segurança e Facilidade para Ambientes Regulamentados

Resumo em português do artigo oficial do Go Blog: Go Simplifica a Conformidade com FIPS 140-3: Segurança e Facilidade para Ambientes Regulamentados

O artigo do blog oficial do Go anuncia a disponibilidade do Módulo Criptográfico Go FIPS 140-3, integrado nativamente à biblioteca padrão e à ferramenta go. Essa novidade visa simplificar a conformidade com o padrão FIPS 140, um requisito comum em ambientes regulamentados que adotam cada vez mais a linguagem Go. Anteriormente, a conformidade com FIPS 140 era um obstáculo significativo para os usuários de Go, exigindo soluções não suportadas com problemas de segurança, experiência do desenvolvedor, funcionalidade, velocidade de lançamento e conformidade.

A solução nativa do Go, incorporada a partir da versão 1.24, promete ser a maneira mais fácil e segura de atender aos requisitos FIPS 140. O Módulo Criptográfico Go v1.0.0 já obteve o certificado A6650 do Cryptographic Algorithm Validation Program (CAVP) e está na lista de Módulos Em Processo (MIP) do Cryptographic Module Validation Program (CMVP), o que significa que já pode ser usado em alguns ambientes regulamentados enquanto aguarda a revisão final do NIST.

A implementação foi liderada pela Geomys em colaboração com a equipe de segurança do Go, com o objetivo de obter uma validação FIPS 140-3 amplamente aplicável para a comunidade Go.

Uma Experiência Nativa para Desenvolvedores

A grande vantagem da solução nativa do Go é a sua integração transparente às aplicações. Todo programa Go compilado com a versão 1.24 já utiliza o módulo para os algoritmos aprovados pelo FIPS 140-3. O módulo nada mais é do que os pacotes crypto/internal/fips140/... da biblioteca padrão, que implementam as operações expostas por pacotes como crypto/ecdsa e crypto/rand.

Esses pacotes não utilizam cgo, o que significa que são compilados de forma cruzada como qualquer outro programa Go, não sofrem sobrecarga de desempenho de FFI (Foreign Function Interface) e evitam problemas de segurança relacionados ao gerenciamento de memória que afligiam a alternativa anterior, Go+BoringCrypto.

O módulo pode ser ativado no modo FIPS 140-3 ao iniciar um binário Go através da opção fips140=on do GODEBUG, que pode ser definida como uma variável de ambiente ou no arquivo go.mod. Quando o modo FIPS 140-3 está habilitado, o módulo usa o NIST DRBG para geração de números aleatórios, o pacote crypto/tls automaticamente negocia apenas versões e algoritmos TLS aprovados pelo FIPS 140-3, e realiza os auto-testes obrigatórios na inicialização e durante a geração de chaves. Não há outras diferenças de comportamento.

Existe também um modo experimental mais restrito, fips140=only, que faz com que todos os algoritmos não aprovados retornem erros ou entrem em pânico. A equipe do Go está buscando feedback sobre como um framework de aplicação de políticas poderia ser implementado.

A variável de ambiente GOFIPS140 permite construir contra versões validadas mais antigas dos pacotes crypto/internal/fips140/.... Se definida como GOFIPS140=v1.0.0, o programa será construído com o snapshot v1.0.0 dos pacotes, tal como foram submetidos para validação ao CMVP. Esse snapshot é distribuído com o restante da biblioteca padrão do Go, como lib/fips140/v1.0.0.zip.

Ao usar GOFIPS140, o GODEBUG fips140 assume o valor padrão on. Portanto, para construir com o módulo FIPS 140-3 e executar no modo FIPS 140-3, basta executar GOFIPS140=v1.0.0 go build.

Se uma toolchain for construída com GOFIPS140 definido, todas as compilações que ela produzir assumirão esse valor por padrão.

A versão de GOFIPS140 utilizada para construir um binário pode ser verificada com go version -m.

Versões futuras do Go continuarão a ser distribuídas e a funcionar com a versão v1.0.0 do Módulo Criptográfico Go até que a próxima versão seja totalmente certificada pela Geomys, mas alguns recursos novos de criptografia podem não estar disponíveis ao construir com módulos antigos. A partir do Go 1.24.3, pode-se usar GOFIPS140=inprocess para selecionar dinamicamente o módulo mais recente para o qual uma validação da Geomys tenha alcançado o estágio “In Process”. A Geomys planeja validar novas versões do módulo pelo menos anualmente, para evitar deixar as compilações FIPS 140 muito desatualizadas, e sempre que uma vulnerabilidade no módulo não puder ser mitigada no código da biblioteca padrão.

Segurança Inabalável

A prioridade no desenvolvimento do módulo foi igualar ou exceder a segurança dos pacotes de criptografia existentes na biblioteca padrão do Go. Para demonstrar a conformidade com os requisitos de segurança do FIPS 140, a equipe do Go optou por não comprometer a segurança.

Por exemplo, o pacote crypto/ecdsa sempre produziu assinaturas “hedged”. As assinaturas “hedged” geram nonces combinando a chave privada, a mensagem e bytes aleatórios. Como o ECDSA determinístico, elas protegem contra falhas do gerador de números aleatórios, que de outra forma vazariam a chave privada. Ao contrário do ECDSA determinístico, elas também são resistentes a problemas de API e ataques de falha, e não vazam a igualdade da mensagem. O FIPS 186-5 introduziu suporte para ECDSA determinístico RFC 6979, mas não para ECDSA “hedged”.

Em vez de fazer um downgrade para assinaturas ECDSA aleatórias ou determinísticas regulares no modo FIPS 140-3 (ou pior, em todos os modos), a equipe trocou o algoritmo de “hedging” e conectou pontos em vários documentos para provar que o novo é uma composição compatível de um DRBG e ECDSA tradicional. Além disso, adicionaram suporte opcional para assinaturas determinísticas.

Outro exemplo é a geração de números aleatórios. O FIPS 140-3 tem regras estritas sobre como a aleatoriedade criptográfica é gerada, o que essencialmente impõe o uso de um CSPRNG (Cryptographically Secure Pseudorandom Number Generator) no espaço do usuário. Por outro lado, a equipe do Go acredita que o kernel é mais adequado para produzir bytes aleatórios seguros, porque está em melhor posição para coletar entropia do sistema e para detectar quando processos ou mesmo máquinas virtuais são clonados (o que poderia levar à reutilização de bytes supostamente aleatórios). Portanto, o pacote crypto/rand encaminha cada operação de leitura para o kernel.

Para resolver essa questão, no modo FIPS 140-3, o Go mantém um NIST DRBG compatível no espaço do usuário baseado em AES-256-CTR e, em seguida, injeta nele 128 bits provenientes do kernel a cada operação de leitura. Essa entropia extra é considerada dados adicionais “não creditados” para fins de FIPS 140-3, mas na prática a torna tão forte quanto a leitura diretamente do kernel, mesmo que mais lenta.

O Módulo Criptográfico Go v1.0.0 foi incluído no recente security audit conduzido pela Trail of Bits, e não foi afetado pela única descoberta não informativa.

Combinado com as garantias de segurança de memória fornecidas pelo compilador e runtime do Go, a equipe acredita que isso cumpre o objetivo de tornar o Go uma das soluções mais fáceis e seguras para conformidade com o FIPS 140.


Artigo Original

Este e um resumo em português do artigo original publicado no blog oficial do Go.

Titulo original: The FIPS 140-3 Go Cryptographic Module

Leia o artigo completo em ingles no Go Blog

Autor original: Filippo Valsorda (Geomys), Daniel McCarney (Geomys), and Roland Shoemaker (Google)