O kernel GKI inclui um módulo de kernel Linux chamado fips140.ko
que está em conformidade com os requisitos FIPS 140-3 para módulos de software criptográfico. Este módulo pode ser enviado para certificação FIPS se o produto que executa o kernel GKI exigir isso.
Os seguintes requisitos FIPS 140-3 em particular devem ser atendidos antes que as rotinas criptográficas 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 respostas conhecidas 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 certificado um módulo baseado em software ou hardware, ele nunca será alterado. Se alterado, deverá ser recertificado. Isso não corresponde prontamente aos processos de desenvolvimento de software em uso atualmente e, como resultado desse requisito, os módulos de software FIPS são geralmente projetados para serem tão focados quanto possível nos componentes criptográficos, para garantir que alterações não relacionadas à criptografia não sejam afetadas. não requer uma reavaliação da criptografia.
O kernel GKI deve ser atualizado regularmente durante toda a vida útil do suporte. Isso torna inviável que todo o kernel esteja dentro dos limites do módulo FIPS, já que tal módulo precisaria ser recertificado a cada atualização do kernel. Definir o "módulo FIPS" como um subconjunto da imagem do kernel atenuaria esse problema, mas não o resolveria, pois o conteúdo binário do "módulo FIPS" ainda mudaria 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) habilitado, já que LTO era um pré-requisito para Control Flow Integrity , que é um importante recurso de segurança.
Portanto, todo o código coberto pelos requisitos 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 criado. Isso garante que o módulo possa ser usado com diferentes versões do GKI da mesma geração e que ele deverá ser atualizado e reenviado para certificação somente se algum problema tiver sido corrigido no código transportado pelo próprio módulo.
Quando usar o módulo
O próprio kernel GKI carrega código que depende das rotinas criptográficas que também são empacotadas no módulo do kernel FIPS 140-3. Portanto, as rotinas criptográficas integradas 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 criptográficas integradas são canceladas do registro da CryptoAPI do Linux 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 oferece 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 à versã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 adicionado amodules.load
no destino.modules.load
contém a lista de módulos que são carregados peloinit
quando o dispositivo é inicializado.
A autoverificação de integridade
O módulo do 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 de módulo do Linux já fez as modificações usuais, como processamento de realocação ELF e correção alternativa de 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 no sentido inverso à entrada do HMAC.
- Todas as outras correções de código estão desabilitadas para o módulo, incluindo chaves estáticas e, portanto, pontos de rastreamento, bem como ganchos de fornecedor.
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 a Orientação de implementação 10.3.A do FIPS 140-3 , 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 que usa instruções criptográficas especiais e um substituto para CPUs que não implementam essas instruções) do mesmo algoritmo podem coexistir. Portanto, há 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, em vez disso, seja selecionado um algoritmo de prioridade mais baixa.
Algoritmos incluídos no módulo
Todos os algoritmos incluídos no módulo FIPS 140-3 estão listados a seguir. Isso se aplica às ramificações do kernel android12-5.10
, android13-5.10
, android13-5.15
, android14-5.15
e android14-6.1
, embora as diferenças entre as versões do kernel sejam observadas quando apropriado.
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 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 suportados. 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 suportados. 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 cifrado: A convenção usada é CS3 ; os dois blocos finais de texto cifrado são trocados incondicionalmente. Todos os tamanhos de chave AES são suportados. 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: Todos os tamanhos de chave AES 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; isto é, as chaves XTS cuja primeira e segunda metades são iguais são rejeitadas. |
gcm(aes) | gcm (modelo), gcm-aes-ce | Não 1 | AES-GCM: Todos os tamanhos de chave AES são suportados. Somente IVs de 96 bits são suportados. Tal como acontece com 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 hash criptográfica 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 | biblioteca sha256-generic , sha256-arm64 , sha256-ce , SHA-256 | Sim | Função de hash criptográfico SHA-256: Uma interface de biblioteca é fornecida ao SHA-256 além da interface CryptoAPI tradicional. Esta 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 SHA-512. |
sha512 | sha512-generic , sha512-arm64 , sha512-ce | Sim | Função hash criptográfica SHA-512 |
hmac | hmac (modelo) | Sim | HMAC (código de autenticação de mensagem Keyed-Hash): O modelo hmac pode ser composto com qualquer algoritmo SHA ou implementação 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 à predição habilitada: verificações de integridade estão incluídas. Os usuários desta 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 resistência à predição desabilitada. O código é compartilhado com a variante resistente à previsão. Na versão 5.10 do kernel, o DRBG de maior prioridade é drbg_nopr_hmac_sha256 . Na versão 5.15 do kernel e posterior, é drbg_pr_hmac_sha512 . |
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 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 posterior. |
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 |
Construa o módulo a partir da fonte
Para Android 14 ou posterior (incluindo android-mainline
), crie o módulo fips140.ko
a partir do código-fonte usando os comandos a seguir.
Construir com Bazel:
tools/bazel run //common:fips140_dist
Construa com
build.sh
(legado):BUILD_CONFIG=common/build.config.gki.aarch64.fips140 build/build.sh
Esses comandos executam uma construção completa incluindo o kernel e o módulo fips140.ko
com o conteúdo do resumo HMAC-SHA256 incorporado nele.
Orientação ao usuário final
Orientação do Crypto Officer
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 está incluído como parte do firmware do dispositivo e é carregado automaticamente na inicialização. Ele opera apenas 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 o FIPS é limitado aos algoritmos aprovados. Para satisfazer o 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
No caso de uma falha no autoteste, o módulo do kernel faz com que o kernel entre em pânico e o dispositivo não continue a inicialização. Se uma reinicialização do dispositivo não resolver o problema, o dispositivo deverá inicializar no modo de recuperação para corrigir o problema atualizando novamente o dispositivo.
Espera-se que as implementações AES-GCM do módulo possam ser "aprovadas pelo algoritmo", mas não "aprovadas pelo 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. ↩