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

O kernel GKI inclui uma Módulo do kernel do Linux chamado fips140.ko, que está em conformidade com Requisitos do FIPS 140-3 para módulos de software criptográfico. Este módulo pode ser enviado para FIPS certificação se o produto que executa o kernel de GKI precisar dela.

Os seguintes requisitos do FIPS 140-3 precisam ser atendidos antes que as rotinas criptográficas possam ser usadas:

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

Por que um módulo de kernel separado

A validação do FIPS 140-3 é baseada na ideia de que, depois que um módulo baseado em software ou hardware é certificado, ele nunca é alterado. Se for alterado, ele precisará ser recertificado. Isso não corresponde aos processos de desenvolvimento de software em uso atualmente. Como resultado desse requisito, os módulos de software FIPS são geralmente projetados para se concentrarem o máximo possível nos componentes criptográficos, para garantir que as mudanças que não estão relacionadas à criptografia não exijam uma reavaliação dela.

O kernel de GKI precisa ser atualizado regularmente durante todo o suporte vida útil. Isso torna inviável que todo o kernel esteja dentro dos FIPS limite de módulo, portanto, um módulo precisaria ser certificado novamente em cada kernel atualizar. Definir o "módulo FIPS" como um subconjunto da imagem do kernel mitigava o problema, mas não o resolvia, já que o conteúdo binário do "módulo FIPS" ainda mudava com muito mais frequência do que o necessário.

Antes da versão 6.1 do kernel, outra consideração era que o GKI era compilado com LTO (Link Time Optimization) ativado, já que o LTO era um pré-requisito para a integridade de fluxo de controle, que é um recurso de segurança importante.

Portanto, todo o código coberto pelos requisitos do FIPS 140-3 é empacotado em um módulo de kernel fips140.ko separado, que depende apenas de interfaces estáveis exibidas pela fonte do kernel da GKI em que foi criado. Isso significa que o módulo pode ser usado com diferentes versões GKI do mesmo e que precisa ser atualizado e reenviado somente para certificação se algum problema foi corrigido no código carregado pelo próprio módulo.

Quando usar o módulo

O kernel do GKI carrega um código que depende das rotinas de criptografia que também são empacotadas no módulo do kernel FIPS 140-3. Portanto, a criptomoeda integrada não são retiradas do kernel de GKI, mas são copiadas para o no módulo. Quando o módulo é carregado, as rotinas criptográficas integradas são desregistradas da Linux CryptoAPI e substituídas pelas que são transmitidas pelo módulo.

Isso significa que o módulo fips140.ko é totalmente opcional e só torna sentido implantá-lo se a certificação FIPS 140-3 for um requisito. Além disso, o módulo não fornece recursos adicionais, e carregá-lo desnecessariamente pode provavelmente afetaria o tempo de inicialização, sem oferecer nenhum benefício.

Como implantar o módulo

O módulo pode ser incorporado ao build do Android seguindo estas etapas:

  • Adicione o nome do módulo a BOARD_VENDOR_RAMDISK_KERNEL_MODULES. Isso faz com que o 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 adicionado a modules.load no destino. modules.load contém a lista de módulos que são carregados por init quando o inicializações de dispositivos.

A autoverificação de integridade

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

  • As realocações de ELF são preservadas dentro do módulo para que possam ser aplicadas voltar à entrada do HMAC.
  • O módulo reverte quaisquer patches de código feitos pelo kernel para Dynamic Pilha de chamadas sombra. Especificamente, o módulo substitui todas as instruções que empurram ou retiram da pilha de chamadas de sombra com as instruções de código de autenticação de ponteiro (PAC, na sigla em inglês) que estavam presentes originalmente.
  • Todos os outros ajustes de código são desativados para o módulo, incluindo chaves estáticas e tracepoints, além de hooks de fornecedores.

Os autotestes com respostas conhecidas

Todos os algoritmos implementados que estiverem cobertos pelos requisitos do FIPS 140-3 devem realizar um autoteste de resposta conhecida antes de ser usado. De acordo com o FIPS 140-3 Orientações para implementação 10.3.A, um único vetor de teste por algoritmo usando qualquer um dos comprimentos de chave suportados é suficientes para criptografias, contanto que a criptografia e a descriptografia sejam testadas.

A CryptoAPI do Linux tem uma noção de prioridades de algoritmo, em que vários (como uma que usa instruções de criptografia especiais e uma para CPUs que não implementam essas instruções) do mesmo algoritmo pode coexistir. Portanto, é necessário testar todas as implementações do mesmo algoritmo. Isso é necessário porque a CryptoAPI do Linux permite que a seleção baseada na prioridade seja ignorada 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 são listados da seguinte maneira. Isso se aplica aos seguintes formatos: android12-5.10, android13-5.10, android13-5.15 As ramificações de kernel android14-5.15, android14-6.1 e android15-6.6 as diferenças entre as versões do kernel são observadas quando apropriado.

Algoritmo Implementações Aprovável Definição
aes aes-generic, aes-arm64, aes-ce, biblioteca do AES Sim Cifrografia de bloco AES simples, sem modo de operação: todos os tamanhos de chave (128, 192 e 256 bits) são aceitos. Todas as implementações, exceto a da biblioteca, podem ser compostas com um modo de operação usando um modelo.
cmac(aes) cmac (modelo), cmac-aes-neon, cmac-aes-ce Sim AES-CMAC: todos os tamanhos de chave AES são aceitos. O modelo 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 compatíveis. O modelo 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 aceitos. O modelo 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 criptografado: a convenção usada é CS3. os dois últimos blocos de texto criptografado são trocados incondicionalmente. Todos os tamanhos de chave AES são aceitos. O modelo cts pode ser composto com qualquer implementação de 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 modelo 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: no kernel versão 6.1 e anteriores, todos os tamanhos de chave AES são compatíveis; No kernel versão 6.6 e superior, apenas AES-128 e AES-256 são suportados. O modelo 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 com a primeira e a segunda metade iguais são rejeitadas.
gcm(aes) gcm (modelo), gcm-aes-ce Não1 AES-GCM: todos os tamanhos de chave AES são aceitos. Somente IVs de 96 bits são compatíveis. Como em todos os outros modos AES neste módulo, o autor da chamada é 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 hash criptográfica SHA-1
sha224 sha224-generic, sha224-arm64, sha224-ce Sim Função de hash criptográfica SHA-224: o código é compartilhado com o SHA-256.
sha256 sha256-generic, sha256-arm64, sha256-ce, biblioteca SHA-256 Sim Função hash criptográfica SHA-256: uma interface de biblioteca é fornecida para SHA-256, além da interface padrão da CryptoAPI. Essa interface de biblioteca usa uma implementação diferente.
sha384 sha384-generic, sha384-arm64, sha384-ce Sim Função hash criptográfica SHA-384: o código é compartilhado com o SHA-512.
sha512 sha512-generic, sha512-arm64, sha512-ce Sim Função de hash criptográfico SHA-512
sha3-224 sha3-224-generic Sim Função hash criptográfica SHA3-224. Presente apenas na versão 6.6 e mais recentes do kernel.
sha3-256 sha3-256-generic Sim Igual ao anterior, mas com comprimento de resumo de 256 bits (SHA3-256). Todos os comprimentos de resumo usam a mesma implementação do Keccak.
sha3-384 sha3-384-generic Sim Igual ao anterior, mas com comprimento de resumo de 384 bits (SHA3-384). Todos os tamanhos de resumo usam a mesma implementação do Keccak.
sha3-512 sha3-512-generic Sim Igual ao anterior, mas com comprimento de resumo de 512 bits (SHA3-512). Todos os comprimentos de resumo usam a mesma implementação do Keccak.
hmac hmac (modelo) Sim Código de autenticação de mensagens de hash com chave (HMAC): 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 hash nomeada e com resistência à previsão ativada: as verificações de integridade são incluídas. Os usuários dessa interface recebem as próprias instâncias de 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 à previsão desativada. O código é compartilhado com a variante resistente a previsões. Na versão 5.10 do kernel, o DRBG de maior prioridade é drbg_nopr_hmac_sha256. Na versão 5.15 e mais recentes do kernel, é drbg_pr_hmac_sha512.
jitterentropy_rng jitterentropy_rng Não O Jitter RNG, versão 2.2.0 (kernel versão 6.1 e anteriores) ou 3.4.0 (kernel versão 6.6 e mais recentes). Os usuários dessa interface recebem as próprias instâncias de RNG de instabilidade. Eles não reutilizam as instâncias usadas pelos DRBGs.
xcbc(aes) xcbc-aes-neon, xcbc-aes-ce Não
xctr(aes) xctr-aes-neon, xctr-aes-ce Não Presente apenas no kernel versão 5.15 e mais recentes.
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

Criar o módulo a partir da origem

Para o Android 14 e versões mais recentes (incluindo android-mainline), crie o módulo fips140.ko da origem usando os seguintes comandos.

  • Crie com o Bazel:

    tools/bazel run //common:fips140_dist
  • Criar com build.sh (legado):

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

Esses comandos executam um build completo, incluindo o kernel e o módulo fips140.ko com o conteúdo do resumo HMAC-SHA256 incorporado.

Orientação ao usuário final

Orientações para o oficial de criptografia

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

O módulo do kernel não pode ser instalado separadamente. ela é incluída como parte firmware do dispositivo e carregados automaticamente na inicialização. Ele só opera em uma e aprovado.

O oficial de criptografia pode reiniciar o dispositivo a qualquer momento para que os autotestes sejam executados.

Orientações para o 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 o uso de algoritmos e não armazena parâmetros além do tempo para executar uma operação criptográfica.

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

Erros de autoteste

Em caso de falha no autoteste, o módulo do kernel faz com que ele entrar em pânico e o dispositivo não continua a inicializar. Se uma reinicialização do dispositivo não resolver o problema, ele precisará ser inicializado no modo de recuperação para corrigir o problema com uma nova atualização.


  1. Espera-se que as implementações do AES-GCM do módulo possam ser "algoritmos aprovado" mas não "módulo aprovado". 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 o GCM são incompatíveis com implementações do GCM que não geram os próprios IVs.