Módulo de criptografia GKI certificável FIPS 140-3

O kernel GKI inclui um módulo de kernel Linux chamado fips140.ko que atende aos requisitos FIPS 140-3 para módulos de software criptográfico. Este módulo pode ser submetido à certificação FIPS se o produto que executa o kernel GKI assim o exigir.

Os seguintes requisitos FIPS 140-3 em particular devem ser atendidos antes que as rotinas de criptografia possam ser usadas:

  • O módulo deve verificar sua própria integridade antes de disponibilizar algoritmos criptográficos.
  • O módulo deve exercitar e verificar seus algoritmos criptográficos aprovados usando autotestes de resposta conhecida antes de disponibilizá-los.

Por que um módulo de kernel separado

A validação FIPS 140-3 é baseada na ideia de que uma vez que um módulo baseado em software ou hardware tenha sido certificado, ele nunca será alterado. Se alterado, deve ser recertificado. Isso não corresponde prontamente aos processos de desenvolvimento de software em uso hoje e, como resultado desse requisito, os módulos de software FIPS geralmente são projetados para se concentrar o máximo possível nos componentes criptográficos, para garantir que as alterações não relacionadas à criptografia não requer uma reavaliação da criptografia.

O kernel GKI deve ser atualizado regularmente durante toda a sua vida útil suportada. Isso torna inviável que todo o kernel esteja dentro do limite do módulo FIPS, pois esse módulo precisa ser recertificado a cada atualização do kernel. Além disso, o GKI é compilado com o LTO (Link Time Optimization) ativado, pois o LTO é um pré-requisito para o CFI , que é um importante recurso de segurança. Isso torna inviável traçar o limite do módulo FIPS em torno apenas do código de criptografia do kernel, pois esse código não está em um local claramente definido no binário resultante. As atualizações do kernel também podem alterar o código de criptografia.

Portanto, todo o código coberto pelos requisitos do FIPS 140-3 é empacotado em um módulo de kernel separado fips140.ko que depende apenas de interfaces estáveis ​​expostas pela fonte do kernel GKI a partir da qual foi compilado. Isso garante que o módulo possa ser usado com diferentes versões do GKI da mesma geração, e que ele deve ser atualizado e reenviado para certificação somente se algum problema for corrigido no código que é carregado pelo próprio módulo.

Quando usar o módulo

O próprio kernel GKI carrega código que depende das rotinas de criptografia que também são empacotadas no módulo do kernel FIPS 140-3. Portanto, as rotinas de criptografia embutidas não são realmente movidas para fora do kernel GKI, mas sim copiadas para o módulo. Quando o módulo é carregado, as rotinas de criptografia embutidas são canceladas do Linux CryptoAPI e substituídas pelas transportadas pelo módulo.

Isso significa que o módulo fips140.ko é totalmente opcional e só faz sentido implantá-lo se a certificação FIPS 140-3 for um requisito. Além disso, o módulo não fornece nenhuma funcionalidade adicional, e carregá-lo desnecessariamente provavelmente afetará o tempo de inicialização, sem fornecer nenhum benefício.

Como implantar o módulo

O módulo pode ser incorporado à compilação do Android usando as seguintes etapas:

  • Adicione o nome do módulo a BOARD_VENDOR_RAMDISK_KERNEL_MODULES . Isso faz com que o módulo seja copiado para o ramdisk do fornecedor.
  • Adicione o nome do módulo a BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD . Isso faz com que o nome do módulo seja incluído em modules.load no destino. modules.load contém a lista de módulos que são carregados pelo init quando o dispositivo é inicializado.

A autoverificação de integridade

O módulo de kernel FIPS 140-3 pega o resumo HMAC-SHA256 de suas próprias seções .code e .rodata no tempo de carregamento do módulo e o compara com o resumo registrado no módulo. Isso ocorre depois que o carregador do módulo Linux já fez as modificações usuais, como processamento de realocação ELF e correções alternativas para erratas de CPU para essas seções. As seguintes etapas adicionais são executadas para garantir que o resumo possa ser reproduzido corretamente:

  • As realocações ELF são preservadas dentro do módulo para que possam ser aplicadas em sentido inverso à entrada do HMAC.
  • Todos os outros patches de código são desabilitados para o módulo, incluindo chaves estáticas e, portanto, pontos de rastreamento, bem como ganchos de fornecedores.

Os autotestes de resposta conhecida

Quaisquer algoritmos implementados que sejam cobertos pelos requisitos FIPS 140-3 devem realizar um autoteste de resposta conhecida antes de serem usados. De acordo com o Guia de Implementação FIPS 140-3 10.3.A , um único vetor de teste por algoritmo usando qualquer um dos comprimentos de chave suportados é suficiente para cifras, desde que a criptografia e a descriptografia sejam testadas.

O Linux CryptoAPI tem uma noção de prioridades de algoritmo, onde várias implementações (como uma usando instruções especiais de criptografia e um fallback para CPUs que não implementam essas instruções) do mesmo algoritmo podem coexistir. Portanto, há a necessidade de testar todas as implementações do mesmo algoritmo. Isso é necessário porque o Linux CryptoAPI permite que a seleção baseada em prioridade seja evitada e que um algoritmo de prioridade mais baixa seja selecionado.

Algoritmos incluídos no módulo

Todos os algoritmos incluídos no módulo FIPS 140-3 quando criados a partir das fontes android13-5.10 estão listados a seguir.

Algoritmo Implementações Aprovável Definição
aes aes-generic , aes-arm64 , aes-ce , biblioteca AES Sim Cifra de bloco AES simples, sem modo de operação: Todos os tamanhos de chave (128 bits, 192 bits e 256 bits) são suportados. Todas as implementações, exceto a implementação da biblioteca, podem ser compostas com um modo de operação por meio de um modelo.
cmac(aes) cmac (modelo), cmac-aes-neon , cmac-aes-ce Sim AES-CMAC: Todos os tamanhos de chave AES são suportados. O template cmac pode ser composto com qualquer implementação de aes usando cmac(<aes-impl>) . As outras implementações são independentes.
ecb(aes) ecb (modelo), ecb-aes-neon , ecb-aes-neonbs , ecb-aes-ce Sim AES-ECB: Todos os tamanhos de chave AES são suportados. O template ecb pode ser composto com qualquer implementação de aes usando ecb(<aes-impl>) . As outras implementações são independentes.
cbc(aes) cbc (modelo), cbc-aes-neon , cbc-aes-neonbs , cbc-aes-ce Sim AES-CBC: Todos os tamanhos de chave AES são suportados. O template cbc pode ser composto com qualquer implementação de aes usando ctr(<aes-impl>) . As outras implementações são independentes.
cts(cbc(aes)) cts (modelo), cts-cbc-aes-neon , cts-cbc-aes-ce Sim AES-CBC-CTS ou AES-CBC com roubo de texto cifrado: A convenção utilizada é CS3 ; os dois últimos blocos de texto cifrado são trocados incondicionalmente. Todos os tamanhos de chave AES são suportados. O template cts pode ser composto com qualquer implementação do cbc usando cts(<cbc(aes)-impl>) . As outras implementações são independentes.
ctr(aes) ctr (modelo), ctr-aes-neon , ctr-aes-neonbs , ctr-aes-ce Sim AES-CTR: Todos os tamanhos de chave AES são suportados. O template ctr pode ser composto com qualquer implementação de aes usando ctr(<aes-impl>) . As outras implementações são independentes.
xts(aes) xts (modelo), xts-aes-neon , xts-aes-neonbs , xts-aes-ce Sim AES-XTS: Todos os tamanhos de chave AES são suportados. O template xts pode ser composto com qualquer implementação de ecb(aes) usando xts(<ecb(aes)-impl>) . As outras implementações são independentes. Todas as implementações implementam a verificação de chave fraca exigida pelo FIPS; ou seja, as chaves XTS cujas primeira e segunda metades são iguais são rejeitadas.
gcm(aes) gcm (modelo), gcm-aes-ce1 AES-GCM: Todos os tamanhos de chave AES são suportados. Apenas IVs de 96 bits são suportados. Como em todos os outros modos AES neste módulo, o chamador é responsável por fornecer os IVs. O modelo gcm pode ser composto com qualquer implementação de ctr(aes) e ghash usando gcm_base(<ctr(aes)-impl>,<ghash-impl>) . As outras implementações são independentes.
sha1 sha1-generic , sha1-ce Sim Função de hash criptográfico SHA-1
sha224 sha224-generic , sha224-arm64 , sha224-ce Sim Função hash criptográfica SHA-224: O código é compartilhado com SHA-256.
sha256 sha256-generic , sha256-arm64 , sha256-ce , biblioteca SHA-256 Sim Função de hash criptográfico SHA-256: Uma interface de biblioteca é fornecida para SHA-256 além da interface CryptoAPI tradicional. Essa interface de biblioteca usa uma implementação diferente.
sha384 sha384-generic , sha384-arm64 , sha384-ce Sim Função de hash criptográfico SHA-384: O código é compartilhado com SHA-512.
sha512 sha512-generic , sha512-arm64 , sha512-ce Sim Função de hash criptográfico SHA-512
hmac hmac (modelo) Sim HMAC (Keyed-Hash Message Authentication Code): O modelo hmac pode ser composto com qualquer algoritmo ou implementação SHA usando hmac(<sha-alg>) ou hmac(<sha-impl>) .
stdrng drbg_pr_hmac_sha1 , drbg_pr_hmac_sha256 , drbg_pr_hmac_sha384 , drbg_pr_hmac_sha512 Sim HMAC_DRBG instanciado com a função de hash nomeada e com a resistência de previsão habilitada: as verificações de integridade estão incluídas. Os usuários dessa interface obtêm suas próprias instâncias DRBG.
stdrng drbg_nopr_hmac_sha1 , drbg_nopr_hmac_sha256 , drbg_nopr_hmac_sha384 , drbg_nopr_hmac_sha512 Sim Igual aos algoritmos drbg_pr_* , mas com a resistência de previsão desabilitada. O código é compartilhado com a variante resistente à previsão. O DRBG de maior prioridade é drbg_nopr_hmac_sha256 .
jitterentropy_rng jitterentropy_rng Não Versão 2.2.0 do Jitter RNG : Os usuários desta interface obtêm suas próprias instâncias do Jitter RNG. Eles não reutilizam as instâncias que os DRBGs usam.
xcbc(aes) xcbc-aes-neon , xcbc-aes-ce Não
cbcmac(aes) cbcmac-aes-neon , cbcmac-aes-ce Não
essiv(cbc(aes),sha256) essiv-cbc-aes-sha256-neon , essiv-cbc-aes-sha256-ce Não

Construindo o módulo a partir da fonte

O módulo fips140.ko pode ser compilado a partir das fontes do kernel GKI usando o seguinte comando:

BUILD_CONFIG=common/build.config.gki.aarch64.fips140 build/build.sh

Isso executa a compilação completa com o kernel e o módulo fips140.ko , com o resumo HMAC-SHA256 correto de seu conteúdo incorporado.

Orientação do usuário final

Orientação do oficial de criptografia

Para operar o módulo do kernel, o sistema operacional deve estar restrito a um único modo de operação de operador. Isso é tratado automaticamente pelo Android usando hardware de gerenciamento de memória no processador.

O módulo do kernel não pode ser instalado separadamente; ele é incluído como parte do firmware do dispositivo e carregado automaticamente na inicialização. Ele só opera em um modo de operação aprovado.

O Crypto Officer pode fazer com que os autotestes sejam executados a qualquer momento reiniciando o dispositivo.

Orientação do usuário

O usuário do módulo do kernel são outros componentes do kernel que precisam usar algoritmos criptográficos. O módulo do kernel não fornece lógica adicional no uso dos algoritmos e não armazena nenhum parâmetro além do tempo necessário para realizar uma operação criptográfica.

O uso dos algoritmos para fins de conformidade com FIPS é limitado a algoritmos aprovados. Para satisfazer o requisito de "indicador de serviço" FIPS 140-3, o módulo fornece uma função fips140_is_approved_service que indica se um algoritmo foi aprovado.

Erros de autoteste

No caso de uma falha de autoteste, o módulo do kernel faz com que o kernel entre em pânico e o dispositivo não continue inicializando. Se uma reinicialização do dispositivo não resolver o problema, o dispositivo deverá inicializar no modo de recuperação para corrigir o problema, reativando o dispositivo.


  1. Espera-se que as implementações AES-GCM do módulo possam ser "aprovadas por algoritmo", mas não "aprovadas por módulo". Eles podem ser validados, mas o AES-GCM não pode ser considerado um algoritmo aprovado do ponto de vista do módulo FIPS. Isso ocorre porque os requisitos do módulo FIPS para GCM são incompatíveis com implementações de GCM que não geram seus próprios IVs.