Modulo crittografico GKI certificabile FIPS 140-3

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

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

  • Il modulo deve verificare la propria integrità prima di creare algoritmi crittografici disponibili.
  • Il modulo deve esercitare e verificare i propri algoritmi crittografici approvati utilizzando autotest con risposta nota 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 hardware o software non viene mai modificato. Se modificata, deve essere viene rinnovata. Questo non corrisponde facilmente ai processi di sviluppo software attualmente in uso e, a causa di questo requisito, i moduli software FIPS sono generalmente progettati per essere il più possibile incentrati sui componenti crittografici, per garantire che le modifiche non correlate alla crittografia non richiedano una rivalutazione della crittografia.

Il kernel GKI deve essere aggiornato regolarmente per l'intera durata supportata. Ciò rende non fattibile che l'intero kernel rientri nel confine del modulo FIPS, poiché un modulo di questo tipo dovrebbe essere sottoposto a nuova certificazione a ogni aggiornamento del kernel. Definire il "modulo FIPS" come un sottoinsieme dell'immagine del kernel attenuarebbe questo problema, ma non lo risolverebbe, poiché i contenuti binari del "modulo FIPS" cambierebbero comunque molto più di frequente del necessario.

Prima della versione del kernel 6.1, un'altra considerazione era che GKI era compilato LTO (ottimizzazione del tempo di collegamento) attivato, in quanto LTO era un prerequisito del controllo Integrità del flusso, che è una funzionalità di sicurezza importante.

Pertanto, tutto il codice coperto dai requisiti FIPS 140-3 viene pacchettizzato in un modulo kernel separato fips140.ko che si basa solo su interfacce esposte dal sorgente del kernel GKI da cui è stato creato. Ciò significa 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 corretti eventuali problemi nel codice del modulo stesso.

Quando utilizzare il modulo

Il kernel GKI stesso contiene codice che dipende dalle routine di crittografia che sono anche pacchettizzate nel modulo del kernel FIPS 140-3. Pertanto, le routine di crittografia predefinite non vengono rimosse dal kernel GKI, ma vengono copiate nel modulo. Quando il modulo viene caricato, le routine di crittografia integrate vengono ritirate da CryptoAPI di Linux e sostituite da quelle del modulo.

Ciò significa che il modulo fips140.ko è del tutto facoltativo e rende ha senso implementarla se è richiesta la certificazione FIPS 140-3. A parte questo, il modulo non fornisce funzionalità aggiuntive e se lo carichi inutilmente influiranno solo sui tempi di avvio, senza offrire alcun vantaggio.

Come eseguire il deployment del modulo

Il modulo può essere incorporato nella build Android seguendo i seguenti passaggi:

  • Aggiungi il nome del modulo a BOARD_VENDOR_RAMDISK_KERNEL_MODULES. Questo fa sì che da copiare nel ramdisk del fornitore.
  • Aggiungi il nome del modulo a BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD. Questo fa sì che il nome del modulo venga aggiunto a modules.load nel target. modules.load contiene l'elenco dei moduli caricati da init all'avvio del dispositivo.

Il controllo di integrità autonomo

Il modulo del kernel FIPS 140-3 prende il digest HMAC-SHA256 delle proprie sezioni .code e .rodata al momento del caricamento del modulo e lo confronta con il digest registrato nel modulo. Questo avviene dopo che il caricatore di moduli Linux ha già apportato le solite modifiche, come l'elaborazione del trasferimento ELF e le patching alternative per gli errori della CPU in queste sezioni. Le seguenti vengono eseguiti ulteriori passaggi per garantire la riproduzione del digest correttamente:

  • I trasferimenti ELF vengono conservati all'interno del modulo in modo che possano essere applicati invertire l'input di HMAC.
  • Il modulo annulla eventuali patch di codice apportate dal kernel per lo stack di chiamate dinamico ombra. Nello specifico, il modulo sostituisce tutte le istruzioni che push o pop dallo stack di chiamate shadow con le istruzioni del codice di autenticazione del puntatore (PAC) presenti inizialmente.
  • Tutte le altre patch del codice sono disabilitate per il modulo, incluse le chiavi statiche e quindi tracepoint e hook dei fornitori.

I test di autovalutazione con risposta nota

Tutti gli algoritmi implementati che sono coperti dai requisiti FIPS 140-3 devono eseguire una diagnostica automatica a risposta nota prima di essere utilizzata. In base allo standard FIPS 140-3 Indicazioni per l'implementazione 10.3.A, un singolo vettore di test per algoritmo che utilizza una qualsiasi delle lunghezze della chiave supportate è sufficiente per le crittografie, purché siano testate sia la crittografia che la decrittografia.

CryptoAPI di Linux ha un concetto di priorità dell'algoritmo, in cui possono coesistere diverse implementazioni (ad esempio una che utilizza istruzioni di crittografia speciali e una di riserva per le CPU che non le implementano) dello stesso algoritmo. È quindi necessario testare tutte le implementazioni dello stesso dell'algoritmo. Questo è necessario perché CryptoAPI di Linux consente di aggirare la selezione in base alla priorità e di selezionare un algoritmo con priorità inferiore.

Algoritmi inclusi nel modulo

Di seguito sono elencati tutti gli algoritmi inclusi nel modulo FIPS 140-3. Si applica a android12-5.10, android13-5.10, android13-5.15, Rami del kernel android14-5.15, android14-6.1 e android15-6.6, però le differenze tra le versioni del kernel vengono indicate ove appropriato.

Algoritmo Implementazioni Approvabile Definizione
aes aes-generic, aes-arm64, aes-ce, libreria AES Cifratura a blocchi AES senza modalità di funzionamento: sono supportate tutte le dimensioni delle chiavi (128 bit, 192 bit 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 kernel 6.1 e precedenti, sono supportate tutte le dimensioni delle chiavi AES; nel kernel 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 delle chiavi deboli 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 IV a 96 bit. Come per tutte le altre modalità AES in questo modulo, è compito dell'utente chiamante fornire gli 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 di 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 di hash crittografica SHA-256: oltre all'interfaccia CryptoAPI standard, è fornita un'interfaccia della libreria per SHA-256. Questa interfaccia della 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 di hash crittografica SHA-512
sha3-224 sha3-224-generic Funzione hash crittografica SHA3-224. Presente solo nella versione del 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 di Keccak.
sha3-512 sha3-512-generic Come sopra, ma con una lunghezza del digest di 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 HMAC_DRBG istanziato con la funzione hash con nome e con la resistenza alla previsione abilitata: sono inclusi i controlli di integrità. Gli utenti di questa interfaccia ottengono le proprie istanze DRBG.
stdrng drbg_nopr_hmac_sha1, drbg_nopr_hmac_sha256, drbg_nopr_hmac_sha384, drbg_nopr_hmac_sha512 Gli stessi algoritmi di drbg_pr_*, ma con la resistenza alla previsione disattivata. Il codice è 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 utilizzate 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

Compila il modulo dal codice sorgente

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

  • Crea con Bazel:

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

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

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

Indicazioni per gli utenti finali

Guida per gli addetti alla crittografia

Per utilizzare il modulo kernel, il sistema operativo deve essere limitato a una con un singolo operatore. Questa operazione viene gestita automaticamente da Android utilizzando 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 in una modalità di funzionamento approvata.

L'addetto alla crittografia può eseguire i test di autodiagnosi in qualsiasi momento riavviando il dispositivo.

Indicazioni per l'utente

Gli utenti di un modulo kernel sono altri componenti del kernel che devono usare algoritmi crittografici. Il modulo kernel non fornisce logica aggiuntiva l'uso degli algoritmi e non memorizza alcun parametro oltre il tempo necessarie per eseguire un'operazione crittografica.

L'utilizzo degli algoritmi ai fini della conformità FIPS è limitato agli algoritmi approvati. Per soddisfare il requisito dell'"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 guasto del test di autodiagnosi, il modulo del kernel provoca un panico del kernel e il dispositivo non continua l'avvio. Se il riavvio del dispositivo non risolva il problema, il dispositivo deve avviarsi in modalità Recovery per correggere problema eseguendo di nuovo il flash del dispositivo.


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