Il kernel GKI include un modulo kernel Linux denominato fips140.ko che
rispetta i requisiti FIPS 140-3 per i moduli software di crittografia.
Questo modulo può essere inviato per la certificazione FIPS se il prodotto che esegue il
kernel GKI lo richiede.
Prima di poter utilizzare le routine di crittografia, devono essere soddisfatti in particolare i seguenti requisiti FIPS 140-3:
- Il modulo deve controllare la propria integrità prima di rendere disponibili gli algoritmi crittografici.
- Il modulo deve esercitare e verificare gli algoritmi crittografici approvati utilizzando autotest degli algoritmi crittografici prima di renderli disponibili.
Perché un modulo kernel separato
La convalida FIPS 140-3 si basa sull'idea che una volta certificato un modulo software o hardware, non viene mai modificato. Se modificato, deve essere ricertificato. Questo non corrisponde facilmente ai processi di sviluppo software in uso oggi e, di conseguenza, i moduli software FIPS sono generalmente progettati per concentrarsi il più possibile sui componenti crittografici, in modo da garantire che le modifiche non correlate alla crittografia non richiedano una rivalutazione della crittografia.
Il kernel GKI deve essere aggiornato regolarmente per tutta la sua durata supportata. In questo modo, è impossibile che l'intero kernel si trovi all'interno del limite del modulo FIPS, in quanto un modulo di questo tipo dovrebbe essere ricertificato a ogni aggiornamento del kernel. Definire il "modulo FIPS" come sottoinsieme dell'immagine del kernel mitigherebbe questo problema, ma non lo risolverebbe, poiché i contenuti binari del "modulo FIPS" cambierebbero comunque molto più spesso del necessario.
Prima della versione kernel 6.1, un'altra considerazione era che GKI veniva compilato con LTO (Link Time Optimization) abilitato, perché LTO era un prerequisito per l'integrità del flusso di controllo, una funzionalità di sicurezza importante.
Pertanto, tutto il codice coperto dai requisiti FIPS 140-3 è incluso
in un modulo del kernel separato fips140.ko che si basa solo su interfacce
stabili esposte dall'origine del kernel GKI da cui è stato creato. Ciò
significa che il modulo può essere utilizzato con diverse release GKI della stessa
generazione e che deve essere aggiornato e inviato nuovamente per la certificazione solo
se sono stati risolti problemi nel codice contenuto nel modulo stesso.
Quando utilizzare il modulo
Il kernel GKI stesso contiene codice che dipende dalle routine crittografiche che sono anche incluse nel modulo del kernel FIPS 140-3. Pertanto, le routine di crittografia integrate non vengono effettivamente spostate dal kernel GKI, ma vengono copiate nel modulo. Quando il modulo viene caricato, le routine di crittografia integrate vengono annullate dalla CryptoAPI di Linux e sostituite da quelle del modulo.
Ciò significa che il modulo fips140.ko è completamente facoltativo e ha senso implementarlo solo se la certificazione FIPS 140-3 è un requisito. A parte questo,
il modulo non fornisce funzionalità aggiuntive e il suo caricamento non necessario
probabilmente influirà solo sul tempo di avvio, senza fornire alcun vantaggio.
Come eseguire il deployment del modulo
Il modulo può essere incorporato nella build Android seguendo questi passaggi:
- Aggiungi il nome del modulo a
BOARD_VENDOR_RAMDISK_KERNEL_MODULES. In questo modo, il modulo viene 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 amodules.loadsulla destinazione.modules.loadcontiene l'elenco dei moduli caricati dainitall'avvio del dispositivo.
Autocontrollo dell'integrità
Il modulo kernel FIPS 140-3 acquisisce 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. Ciò avviene dopo che il caricatore di moduli Linux ha
già apportato le modifiche consuete, come l'elaborazione del riposizionamento ELF e
l'applicazione di patch alternative per gli errata della CPU a queste sezioni. Per garantire che il digest possa essere riprodotto correttamente, vengono eseguiti i seguenti passaggi aggiuntivi:
- Le rilocazioni ELF vengono conservate all'interno del modulo in modo che possano essere applicate in senso inverso all'input dell'HMAC.
- Il modulo inverte le patch di codice apportate dal kernel per Dynamic Shadow Call Stack. In particolare, il modulo sostituisce qualsiasi istruzione che inserisce o estrae dallo stack di chiamate ombra le istruzioni del codice di autenticazione del puntatore (PAC) presenti originariamente.
- Tutte le altre patch del codice sono disattivate per il modulo, incluse le chiavi statiche e quindi anche i punti di traccia e gli hook del fornitore.
L'algoritmo crittografico esegue autotest
Il modulo del kernel FIPS 140-3 soddisfa i requisiti di autotest dell'algoritmo crittografico di FIPS 140-3 implementando test con risposta nota. I test implementati variano in base all'algoritmo e sono conformi alla guida all'implementazione FIPS 140-3 10.3.A.
In genere, è necessario un solo vettore di test per algoritmo. I test automatici dell'algoritmo crittografico FIPS sono progettati per convalidare solo la funzionalità di base. I test completi vengono eseguiti separatamente utilizzando il Cryptographic Algorithm Validation Program (CAVP) e la suite di test crittografici del kernel upstream.
Quando un algoritmo ha più implementazioni accessibili all'utente o utilizzate dai servizi del modulo, FIPS 140-3 richiede che tutte queste implementazioni vengano sottoposte ad autotest. Ciò è pertinente alla strategia di integrazione tradizionalmente utilizzata
dalla CryptoAPI di Linux, in cui ogni algoritmo può avere più implementazioni
accessibili agli utenti. Ad esempio, nel kernel android16-6.12, SHA-256 ha tre implementazioni: sha256-generic, sha256-arm64 e sha256-ce. Sulle CPU con
le estensioni di crittografia ARMv8, sha256-ce viene utilizzato per impostazione predefinita, ma gli utenti possono comunque
accedere esplicitamente alle altre. Pertanto, il modulo esegue l'autotest di tutte e tre
le implementazioni.
Nel kernel android17-6.18 e versioni successive, alcuni algoritmi utilizzano una strategia di integrazione più semplice. Ad esempio, nel kernel android17-6.18, SHA-256 ha una singola implementazione sha256-lib che seleziona automaticamente il codice appropriato per la CPU al tempo di caricamento del modulo. Pertanto, il modulo esegue solo l'autodiagnosi
sha256-lib.
Algoritmi inclusi nel modulo
Tutti gli algoritmi inclusi nel modulo FIPS 140-3 sono elencati di seguito.
Ciò vale per i rami del kernel android12-5.10, android13-5.10, android13-5.15,
android14-5.15, android14-6.1, android15-6.6, android16-6.12 e
android17-6.18, anche se le differenze tra le versioni del kernel sono
indicate ove opportuno.
| Algoritmo | Implementazioni | Approvabile | Definizione |
|---|---|---|---|
aes |
aes-generic, aes-arm64, aes-ce, libreria AES |
Sì | Cifratura a blocchi AES semplice, senza modalità di funzionamento: sono supportate tutte le dimensioni delle chiavi (128 bit, 192 bit e 256 bit). Tutte le implementazioni diverse da quella della libreria possono essere composte con una modalità di funzionamento tramite un modello. |
cmac(aes) |
cmac (modello), cmac-aes-neon, cmac-aes-ce |
Sì | AES-CMAC: sono supportate tutte le dimensioni delle chiavi AES. Il modello cmac può essere composto con qualsiasi implementazione di aes utilizzando cmac(. Le altre implementazioni sono autonome. |
ecb(aes) |
ecb (modello), ecb-aes-neon, ecb-aes-neonbs, ecb-aes-ce |
Sì | AES-ECB: sono supportate tutte le dimensioni delle chiavi AES. Il modello ecb può essere composto con qualsiasi implementazione di aes utilizzando ecb(. Le altre implementazioni sono autonome. |
cbc(aes) |
cbc (modello), cbc-aes-neon, cbc-aes-neonbs, cbc-aes-ce |
Sì | AES-CBC: sono supportate tutte le dimensioni delle chiavi AES. Il modello cbc può essere composto con qualsiasi implementazione di aes utilizzando cbc(. Le altre implementazioni sono autonome. |
cts(cbc(aes)) |
cts (modello), cts-cbc-aes-neon, cts-cbc-aes-ce |
Sì | AES-CBC-CTS o AES-CBC con furto di testo non criptato: la convenzione utilizzata è CS3; gli ultimi due blocchi di testo non criptato vengono scambiati in modo incondizionato. Sono supportate tutte le dimensioni delle chiavi AES. Il modello cts può essere composto con qualsiasi implementazione di cbc utilizzando cts(. Le altre implementazioni sono autonome. |
ctr(aes) |
ctr (modello), ctr-aes-neon, ctr-aes-neonbs, ctr-aes-ce |
Sì | AES-CTR: sono supportate tutte le dimensioni delle chiavi AES. Il modello ctr può essere composto con qualsiasi implementazione di aes utilizzando ctr(. Le altre implementazioni sono autonome. |
xts(aes) |
xts (modello), xts-aes-neon, xts-aes-neonbs, xts-aes-ce |
Sì | AES-XTS: nel kernel 6.1 e versioni precedenti, sono supportate tutte le dimensioni delle chiavi AES; nel kernel 6.6 e versioni successive, sono supportati solo AES-128 e AES-256. Il modello xts può essere composto con qualsiasi implementazione di ecb(aes) utilizzando xts(. 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 |
No 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, il chiamante è responsabile della fornitura dei vettori di inizializzazione. Il modello gcm può essere composto da qualsiasi implementazione di ctr(aes) e ghash utilizzando gcm_base(. Le altre implementazioni sono autonome. |
sha1 |
Kernel 6.12 e versioni precedenti: sha1-generic, sha1-ce |
Sì | La funzione di hash crittografica SHA-1. Rimosso nel kernel 6.18 e versioni successive. |
sha224 |
Kernel 6.18 e versioni successive: sha224-lib. Kernel 6.12 e versioni precedenti: sha224-generic, sha224-arm64, sha224-ce |
Sì | Funzione hash crittografica SHA-224: il codice è condiviso con SHA-256. |
sha256 |
Kernel 6.18 e versioni successive: sha256-lib. Kernel 6.12 e versioni precedenti: sha256-generic, sha256-arm64, sha256-ce, libreria SHA-256 |
Sì | Funzione hash crittografica SHA-256. |
sha384 |
Kernel 6.18 e versioni successive: sha384-lib. Kernel 6.12 e versioni precedenti: sha384-generic, sha384-arm64, sha384-ce |
Sì | Funzione hash crittografica SHA-384: il codice è condiviso con SHA-512. |
sha512 |
Kernel 6.18 e versioni successive: sha512-lib. Kernel 6.12 e versioni precedenti: sha512-generic, sha512-arm64, sha512-ce |
Sì | Funzione di hash crittografica SHA-512. |
sha3-224 |
Kernel 6.6 e versioni successive: sha3-224-generic |
Sì | Funzione hash crittografica SHA3-224. |
sha3-256 |
Kernel 6.6 e versioni successive: sha3-256-generic |
Sì | Come il precedente, ma con lunghezza del digest di 256 bit (SHA3-256). Tutte le lunghezze del digest utilizzano la stessa implementazione di Keccak. |
sha3-384 |
Kernel 6.6 e versioni successive: sha3-384-generic |
Sì | Come il precedente, ma con lunghezza del digest di 384 bit (SHA3-384). Tutte le lunghezze del digest utilizzano la stessa implementazione di Keccak. |
sha3-512 |
Kernel 6.6 e versioni successive: sha3-512-generic |
Sì | Come il precedente, ma con lunghezza del digest di 512 bit (SHA3-512). Tutte le lunghezze del digest utilizzano la stessa implementazione di Keccak. |
hmac |
hmac (modello) |
Sì | Keyed-hash message authentication code (HMAC): il modello hmac può essere composto con qualsiasi algoritmo o implementazione SHA utilizzando hmac( o hmac(. |
stdrng |
Tutti i kernel: drbg_pr_hmac_sha256, drbg_pr_hmac_sha384, drbg_pr_hmac_sha512. Kernel 6.6 e versioni precedenti: drbg_pr_hmac_sha1 |
Sì | HMAC_DRBG istanziato con la funzione hash denominata e con la resistenza alla previsione abilitata: sono inclusi i controlli di integrità. Gli utenti di questa interfaccia ottengono le proprie istanze DRBG. |
stdrng |
Tutti i kernel: drbg_nopr_hmac_sha256, drbg_nopr_hmac_sha384, drbg_nopr_hmac_sha512. Kernel 6.6 e versioni precedenti: drbg_nopr_hmac_sha1 |
Sì | Uguale agli algoritmi drbg_pr_*, ma con la resistenza alla previsione disattivata. Il codice viene condiviso con la variante resistente alla previsione. Nel kernel 5.10, il DRBG con la priorità più alta è drbg_nopr_hmac_sha256. Nel kernel 5.15 e versioni successive, è drbg_pr_hmac_sha512. |
jitterentropy_rng |
jitterentropy_rng |
No | Jitter RNG, versione 2.2.0 (versione kernel 6.1 e precedenti) o versione 3.4.0 (versione kernel 6.6 e successive). Gli utenti di questa interfaccia ottengono le proprie istanze Jitter RNG. Non riutilizzano le istanze utilizzate dai DRBG. |
xcbc(aes) |
xcbc-aes-neon, xcbc-aes-ce |
No | |
xctr(aes) |
Kernel 5.15 e versioni successive: xctr-aes-neon, xctr-aes-ce |
No | |
cbcmac(aes) |
cbcmac-aes-neon, cbcmac-aes-ce |
No | |
essiv(cbc(aes),sha256) |
essiv-cbc-aes-sha256-neon, essiv-cbc-aes-sha256-ce |
No |
1. Le implementazioni AES-GCM del modulo possono essere approvate dall'algoritmo, ma non 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 del modulo FIPS per GCM sono incompatibili con le implementazioni GCM che non generano i propri IV.
Crea il modulo dal codice sorgente
Per Android 14 e versioni successive (incluso
android-mainline), crea il modulo fips140.ko dall'origine utilizzando i
seguenti comandi.
Crea con Bazel:
tools/bazel run //common:fips140_distCrea con
build.sh(legacy):BUILD_CONFIG=common/build.config.gki.aarch64.fips140 build/build.sh
Questi comandi eseguono una build completa, inclusi il kernel e il modulo fips140.ko, con i contenuti del digest HMAC-SHA256 incorporati.
Indicazioni per l'utente finale
Guida per il responsabile delle criptovalute
Per utilizzare il modulo del kernel, il sistema operativo deve essere limitato a una singola modalità operativa. Questa operazione viene gestita automaticamente da Android utilizzando l'hardware di gestione della memoria nel processore.
Il modulo del 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ò far eseguire gli autotest in qualsiasi momento riavviando il dispositivo.
Indicazioni per l'utente
L'utente del modulo del kernel sono altri componenti del kernel che devono utilizzare algoritmi crittografici. Il modulo del kernel non fornisce logica aggiuntiva nell'utilizzo degli algoritmi e non archivia parametri oltre il tempo necessario per eseguire un'operazione di crittografia.
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 esito negativo dell'autotest, il modulo del kernel causa un errore irreversibile del kernel e il dispositivo non continua l'avvio. Se il riavvio del dispositivo non risolve il problema, è necessario avviare il dispositivo in modalità di ripristino per correggere il problema eseguendo nuovamente il flashing del dispositivo.