Modulo di crittografia GKI certificato FIPS 140-3

Il kernel GKI include un modulo kernel Linux chiamato fips140.ko conforme ai requisiti FIPS 140-3 per i moduli software crittografici. Questo modulo può essere inviato per la certificazione FIPS se richiesto dal prodotto che esegue il kernel GKI.

In particolare, i seguenti requisiti FIPS 140-3 devono essere soddisfatti prima di poter utilizzare le routine crittografiche:

  • Il modulo deve verificare la propria integrità prima di rendere disponibili gli algoritmi crittografici.
  • Il modulo deve esercitarsi e verificare gli algoritmi crittografici approvati utilizzando autotest con risposte note prima di renderli disponibili.

Perché un modulo kernel separato

La convalida FIPS 140-3 si basa sull'idea che una volta certificato un modulo basato su software o hardware, non può essere modificato. Se modificata, deve essere ricertificata. Ciò non corrisponde immediatamente ai processi di sviluppo software in uso odierno e, come risultato di questo requisito, i moduli software FIPS sono generalmente progettati per essere strettamente incentrati sui componenti crittografici possibile, in modo da garantire che le modifiche non correlate alla crittografia non richiedano una nuova valutazione della crittografia.

Il kernel GKI è pensato per essere aggiornato regolarmente durante l'intero ciclo di vita supportato. Ciò rende impossibile che l'intero kernel rientri nei limiti del modulo FIPS, poiché un modulo di questo tipo deve essere ricertificato a ogni aggiornamento del kernel. La definizione del "modulo FIPS" come sottoinsieme dell'immagine kernel mitigherebbe il problema, ma non lo risolverebbe, poiché i contenuti binari del "modulo FIPS" cambierebbero comunque molto più spesso del necessario.

Prima della versione 6.1 del kernel, occorreva considerare anche che GKI veniva compilato con LTO (Link Time Optimization) abilitato, dato che LTO era un prerequisito per l'Integrità del flusso di controllo, un'importante funzionalità di sicurezza.

Di conseguenza, tutto il codice coperto dai requisiti FIPS 140-3 viene pacchettizzato in un modulo kernel separato fips140.ko che si basa solo su interfacce stabili esposte dal codice sorgente GKI da cui è stato creato. Ciò garantisce che il modulo può essere utilizzato con release GKI diverse della stessa generazione e che deve essere aggiornato e inviato nuovamente per la certificazione solo se sono stati risolti eventuali problemi nel codice applicato dal modulo stesso.

Quando utilizzare il modulo

Lo stesso kernel GKI trasporta codice che dipende dalle routine crittografiche presenti anche nel modulo kernel FIPS 140-3. Pertanto, le routine di crittografia integrate non vengono effettivamente spostate dal kernel GKI, ma vengono copiate nel modulo. Una volta caricato il modulo, le routine di crittografia integrate vengono deregistrate da Linux CryptoAPI e sostituite da quelle portate dal modulo.

Ciò significa che il modulo fips140.ko è del tutto facoltativo e ha senso eseguire il deployment solo se la certificazione FIPS 140-3 è un requisito. Inoltre, il modulo non fornisce funzionalità aggiuntive e il suo caricamento inutilmente potrebbe influire solo sul tempo di avvio, senza fornire alcun vantaggio.

Come eseguire il deployment del modulo

Il modulo può essere incorporato nella build Android seguendo questa procedura:

  • Aggiungi il nome del modulo a BOARD_VENDOR_RAMDISK_KERNEL_MODULES. Questo fa sì che il modulo venga copiato nel ramdisk del fornitore.
  • Aggiungi il nome del modulo a BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD. In questo modo, il nome del modulo viene aggiunto a modules.load nella destinazione. modules.load contiene l'elenco dei moduli caricati da init all'avvio del dispositivo.

Controllo autonomo dell'integrità

Il modulo kernel FIPS 140-3 prende il digest HMAC-SHA256 delle sezioni .code e .rodata al momento del caricamento del modulo e lo confronta con il digest registrato nel modulo. Ciò avviene dopo che il caricatore dei moduli Linux ha già apportato le consuete modifiche, come l'elaborazione del trasferimento ELF e l'applicazione di patch alternative per gli errori della CPU in queste sezioni. Per garantire che il digest possa essere riprodotto correttamente, vengono eseguiti i seguenti passaggi aggiuntivi:

  • Le riposizioni in ELF vengono conservate all'interno del modulo in modo che possano essere applicate invertendo all'input dell'HMAC.
  • Il modulo inverte eventuali patch di codice create dal kernel per lo stack di chiamate di Dynamic Shadow. In particolare, il modulo sostituisce qualsiasi istruzione di push o pop dallo stack di chiamate shadow con le istruzioni PAC (Pointer Authentication Code) presenti in origine.
  • Tutte le altre patch del codice sono disabilitate per il modulo, incluse le chiavi statiche, quindi i tracepoint e gli hook del fornitore.

I test automatici a risposta nota

Tutti gli algoritmi implementati che sono coperti dai requisiti FIPS 140-3 devono eseguire un autotest a risposta nota prima di essere utilizzati. In base allo standard FIPS 140-3 Implementation Guidance 10.3.A, un singolo vettore di test per algoritmo che utilizza una qualsiasi delle lunghezze di chiave supportate è sufficiente per le crittografie, a condizione che la crittografia e la decrittografia siano testate.

La CryptoAPI di Linux ha una nozione di priorità dell'algoritmo, in cui diverse implementazioni dello stesso algoritmo possono coesistere (ad esempio una che utilizza istruzioni crittografiche speciali e un'implementazione di riserva per le CPU che non le implementano). È quindi necessario testare tutte le implementazioni dello stesso algoritmo. Ciò è necessario perché Linux CryptoAPI consente di aggirare la selezione basata sulla priorità e di selezionare invece un algoritmo con priorità inferiore.

Algoritmi inclusi nel modulo

Di seguito sono elencati tutti gli algoritmi inclusi nel modulo FIPS 140-3. Questo vale per i rami del kernel android12-5.10, android13-5.10, android13-5.15, android14-5.15, android14-6.1 e android15-6.6, anche se le differenze tra le versioni del kernel sono indicate ove appropriato.

Algoritmo Implementazioni Approvabile Definizione
aes aes-generic, aes-arm64, aes-ce, libreria AES Crittografia a blocchi AES semplice, senza modalità operativa: sono supportate tutte le dimensioni di chiave (128, 192 e 256 bit). Tutte le implementazioni, diverse dall'implementazione della libreria, possono essere create con una modalità operativa mediante un modello.
cmac(aes) cmac (modello), cmac-aes-neon, cmac-aes-ce AES-CMAC: sono supportate tutte le dimensioni delle chiavi AES. Il modello cmac può essere composto con qualsiasi implementazione di aes utilizzando cmac(<aes-impl>). Le altre implementazioni sono autonome.
ecb(aes) ecb (modello), ecb-aes-neon, ecb-aes-neonbs, ecb-aes-ce AES-ECB: sono supportate tutte le dimensioni delle chiavi AES. Il modello ecb può essere composto con qualsiasi implementazione di aes utilizzando ecb(<aes-impl>). Le altre implementazioni sono autonome.
cbc(aes) cbc (modello), cbc-aes-neon, cbc-aes-neonbs, cbc-aes-ce AES-CBC: sono supportate tutte le dimensioni delle chiavi AES. Il modello cbc può essere composto con qualsiasi implementazione di aes utilizzando ctr(<aes-impl>). Le altre implementazioni sono autonome.
cts(cbc(aes)) cts (modello), cts-cbc-aes-neon, cts-cbc-aes-ce AES-CBC-CTS o AES-CBC con furto del testo crittografato: la convenzione utilizzata è CS3; gli ultimi due blocchi di testo crittografato vengono scambiati incondizionatamente.Sono supportate tutte le dimensioni delle chiavi AES.Il modello cts può essere composto con qualsiasi implementazione di cbc utilizzando cts(<cbc(aes)-impl>).Le altre implementazioni sono autonome.
ctr(aes) ctr (modello), ctr-aes-neon, ctr-aes-neonbs, ctr-aes-ce AES-CTR: sono supportate tutte le dimensioni delle chiavi AES. Il modello ctr può essere composto con qualsiasi implementazione di aes utilizzando ctr(<aes-impl>). Le altre implementazioni sono autonome.
xts(aes) xts (modello), xts-aes-neon, xts-aes-neonbs, xts-aes-ce AES-XTS: nella versione del kernel 6.1 e precedenti, sono supportate tutte le dimensioni delle chiavi AES; nella versione 6.6 e successive, sono supportati solo AES-128 e AES-256. Il modello xts può essere composto con qualsiasi implementazione di ecb(aes) utilizzando xts(<ecb(aes)-impl>). Le altre implementazioni sono autonome. Tutte le implementazioni implementano il controllo della chiave debole richiesto da FIPS, ovvero le chiavi XTS la cui prima e seconda metà sono uguali vengono rifiutate.
gcm(aes) gcm (modello), gcm-aes-ce N.1 AES-GCM: sono supportate tutte le dimensioni delle chiavi AES. Sono supportati solo gli IV a 96 bit. Come per tutte le altre modalità AES in questo modulo, il chiamante è responsabile della fornitura degli IV. Il modello gcm può essere composto con qualsiasi implementazione di ctr(aes) e ghash utilizzando gcm_base(<ctr(aes)-impl>,<ghash-impl>). Le altre implementazioni sono autonome.
sha1 sha1-generic, sha1-ce Funzione hash crittografica SHA-1
sha224 sha224-generic, sha224-arm64 e sha224-ce Funzione hash crittografica SHA-224: il codice viene condiviso con SHA-256.
sha256 sha256-generic, sha256-arm64, sha256-ce, libreria SHA-256 Funzione hash crittografica SHA-256: a SHA-256 viene fornita un'interfaccia della libreria oltre alla tradizionale interfaccia CryptoAPI. L'interfaccia di questa libreria utilizza un'implementazione diversa.
sha384 sha384-generic, sha384-arm64 e sha384-ce Funzione hash crittografica SHA-384: il codice viene condiviso con l'algoritmo SHA-512.
sha512 sha512-generic, sha512-arm64 e sha512-ce Funzione hash crittografica SHA-512
sha3-224 sha3-224-generic Funzione hash crittografica SHA3-224. Presente solo nella versione kernel 6.6 e successive.
sha3-256 sha3-256-generic Come la versione precedente, ma con lunghezza digest a 256 bit (SHA3-256). Tutte le lunghezze del digest utilizzano la stessa implementazione Keccak.
sha3-384 sha3-384-generic Come la versione precedente, ma con lunghezza digest a 384 bit (SHA3-384). Tutte le lunghezze del digest utilizzano la stessa implementazione Keccak.
sha3-512 sha3-512-generic Come la versione precedente, ma con lunghezza digest a 512 bit (SHA3-512). Tutte le lunghezze del digest utilizzano la stessa implementazione Keccak.
hmac hmac (modello) HMAC (Keyed-Hash Message Authentication Code): il modello hmac può essere composto con qualsiasi algoritmo o implementazione SHA utilizzando hmac(<sha-alg>) o hmac(<sha-impl>).
stdrng drbg_pr_hmac_sha1, drbg_pr_hmac_sha256, drbg_pr_hmac_sha384, drbg_pr_hmac_sha512 Crea un'istanza di HMAC_DRBG con la funzione hash denominata e con la resistenza alle previsioni abilitata: sono inclusi i controlli di integrità. Gli utenti di questa interfaccia ricevono le proprie istanze DRBG.
stdrng drbg_nopr_hmac_sha1, drbg_nopr_hmac_sha256, drbg_nopr_hmac_sha384, drbg_nopr_hmac_sha512 Come gli algoritmi di drbg_pr_*, ma con la resistenza alle previsioni disabilitata. Il codice viene condiviso con la variante resistente alle previsioni. Nella versione del kernel 5.10, il DRBG a priorità massima è drbg_nopr_hmac_sha256. Nella versione del kernel 5.15 e successive, è drbg_pr_hmac_sha512.
jitterentropy_rng jitterentropy_rng No Jitter RNG, versione 2.2.0 (kernel versione 6.1 e versioni precedenti) o versione 3.4.0 (kernel versione 6.6 e successive). Gli utenti di questa interfaccia ricevono le proprie istanze Jitter RNG. Non riutilizzano le istanze usate dai DRBG.
xcbc(aes) xcbc-aes-neon, xcbc-aes-ce No
xctr(aes) xctr-aes-neon, xctr-aes-ce No Presente solo nella versione del kernel 5.15 e successive.
cbcmac(aes) cbcmac-aes-neon, cbcmac-aes-ce No
essiv(cbc(aes),sha256) essiv-cbc-aes-sha256-neon, essiv-cbc-aes-sha256-ce No

Crea il modulo dall'origine

Per Android 14 e versioni successive (incluso android-mainline), crea il modulo fips140.ko dal codice sorgente utilizzando i comandi seguenti.

  • Crea con Bazel:

    tools/bazel run //common:fips140_dist
    
  • Crea con build.sh (legacy):

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

Questi comandi eseguono una build completa che include il kernel e il modulo fips140.ko con i contenuti del digest HMAC-SHA256 incorporati.

Indicazioni per l'utente finale

Indicazioni per l'ufficiale di crittografia

Per utilizzare il modulo kernel, il sistema operativo deve essere limitato alla modalità operativa con un singolo operatore. Questa operazione viene gestita automaticamente da Android tramite l'hardware di gestione della memoria nel processore.

Il modulo kernel non può essere installato separatamente; è incluso nel firmware del dispositivo e viene caricato automaticamente all'avvio. Funziona solo con una modalità operativa approvata.

L'ufficiale di crittografia può avviare i test automatici in qualsiasi momento riavviando il dispositivo.

Indicazioni per l'utente

Gli utenti del modulo kernel sono altri componenti del kernel che devono usare algoritmi di crittografia. Il modulo kernel non fornisce logica aggiuntiva nell'uso degli algoritmi e non archivia parametri oltre il tempo necessario per eseguire un'operazione crittografica.

L'utilizzo degli algoritmi ai fini della conformità FIPS è limitato agli algoritmi approvati. Per soddisfare il requisito di "indicatore di servizio" FIPS 140-3, il modulo fornisce una funzione fips140_is_approved_service che indica se un algoritmo è approvato.

Errori di diagnostica automatica

In caso di errore di autotest, il modulo kernel fa "panic" il kernel e il dispositivo non continua ad avviarsi. Se il riavvio del dispositivo non risolve il problema, il dispositivo deve avviarsi in modalità di ripristino per risolvere il problema eseguendo di nuovo il flash del dispositivo.


  1. È previsto che le implementazioni AES-GCM del modulo possano essere "approvate da algoritmo", ma non "approvate dal modulo". Possono essere convalidati, ma AES-GCM non può essere considerato un algoritmo approvato dal punto di vista del modulo FIPS. Questo perché i requisiti dei moduli FIPS per GCM non sono compatibili con le implementazioni di GCM che non generano IV propri.