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 la certificazione FIPS se il prodotto che esegue il kernel GKI lo richiede.

Prima di poter utilizzare le routine crittografiche devono essere soddisfatti in particolare i seguenti requisiti FIPS 140-3:

  • Il modulo deve verificare la propria integrità prima di rendere disponibili gli algoritmi crittografici.
  • Il modulo deve esercitare e verificare i propri algoritmi crittografici approvati utilizzando test automatici a risposta nota prima di renderli disponibili.

Perché un modulo del kernel separato

La convalida FIPS 140-3 si basa sull'idea che una volta certificato un modulo basato su software o hardware, non viene mai modificato. Se modificato, deve essere ricertificato. Ciò non corrisponde facilmente ai processi di sviluppo software in uso oggi e, come risultato di questo requisito, i moduli software FIPS sono generalmente progettati per essere il più strettamente concentrati possibile sui componenti crittografici, per garantire che le modifiche non correlate alla crittografia vengano apportate. non richiedono una rivalutazione della crittografia.

Il kernel GKI è destinato ad essere aggiornato regolarmente durante l'intero ciclo di vita supportato. Ciò rende impossibile che l'intero kernel si trovi all'interno dei limiti del modulo FIPS, poiché tale modulo dovrebbe essere ricertificato ad ogni aggiornamento del kernel. Definire il "modulo FIPS" come un sottoinsieme dell'immagine del kernel attenuerebbe questo problema ma non lo risolverebbe, poiché il contenuto binario del "modulo FIPS" cambierebbe comunque molto più frequentemente del necessario.

Prima della versione 6.1 del kernel, un'altra considerazione era che GKI veniva compilato con LTO (Link Time Optimization) abilitato, poiché LTO era un prerequisito per Control Flow Integrity che è un'importante funzionalità di sicurezza.

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

Quando utilizzare il modulo

Il kernel GKI stesso contiene codice che dipende dalle routine di crittografia anch'esse incluse nel modulo del kernel FIPS 140-3. Pertanto, le routine crittografiche integrate non vengono effettivamente spostate dal kernel GKI ma piuttosto copiate nel modulo. Quando il modulo viene caricato, le routine crittografiche integrate vengono cancellate dalla CryptoAPI Linux e sostituite da quelle trasportate dal modulo.

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

Come distribuire il modulo

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

  • Aggiungi il nome del modulo a BOARD_VENDOR_RAMDISK_KERNEL_MODULES . Ciò fa sì che il modulo venga copiato sul ramdisk del fornitore.
  • Aggiungi il nome del modulo a BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD . Ciò fa sì che il nome del modulo venga aggiunto a modules.load sulla destinazione. modules.load contiene l'elenco dei moduli caricati da init all'avvio del dispositivo.

L'autocontrollo dell'integrità

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. Ciò avviene dopo che il caricatore del modulo Linux ha già apportato le consuete modifiche come l'elaborazione del riposizionamento ELF e l'applicazione di patch alternative per gli errata della CPU in quelle sezioni. Vengono eseguiti i seguenti passaggi aggiuntivi per garantire che il digest possa essere riprodotto correttamente:

  • Le rilocazioni ELF vengono conservate all'interno del modulo in modo che possano essere applicate in senso inverso all'ingresso dell'HMAC.
  • Tutte le altre patch di codice sono disabilitate per il modulo, comprese le chiavi statiche e quindi i tracepoint e gli hook del fornitore.

Gli autotest a risposta nota

Tutti gli algoritmi implementati coperti dai requisiti FIPS 140-3 devono eseguire un autotest a risposta nota prima di essere utilizzati. Secondo la 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 vengano testate sia la crittografia che la decrittografia.

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

Algoritmi inclusi nel modulo

Tutti gli algoritmi inclusi nel modulo FIPS 140-3 sono elencati di seguito. Questo vale per i rami android12-5.10 , android13-5.10 , android13-5.15 , android14-5.15 e android14-6.1 , anche se le differenze tra le versioni del kernel vengono annotate dove appropriato.

Algoritmo Implementazioni Approvabile Definizione
aes aes-generic , aes-arm64 , aes-ce , libreria AES Cifratura a blocchi AES semplice, senza modalità operativa: sono supportate tutte le dimensioni delle chiavi (128 bit, 192 bit e 256 bit). Tutte le implementazioni diverse dall'implementazione della libreria possono essere composte con una modalità operativa tramite 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 di testo cifrato: la convenzione utilizzata è CS3 ; gli ultimi due blocchi di testo cifrato 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: sono supportate tutte le dimensioni delle chiavi AES. 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 con 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 , sha224-ce Funzione hash crittografico SHA-224: il codice è condiviso con SHA-256.
sha256 sha256-generic , sha256-arm64 , sha256-ce , libreria SHA-256 Funzione hash crittografico SHA-256: a SHA-256 viene fornita un'interfaccia di libreria oltre alla tradizionale interfaccia CryptoAPI. Questa interfaccia della libreria utilizza un'implementazione diversa.
sha384 sha384-generic , sha384-arm64 , sha384-ce Funzione hash crittografico SHA-384: il codice è condiviso con SHA-512.
sha512 sha512-generic , sha512-arm64 , sha512-ce Funzione hash crittografico SHA-512
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 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 drbg_nopr_hmac_sha1 , drbg_nopr_hmac_sha256 , drbg_nopr_hmac_sha384 , drbg_nopr_hmac_sha512 Uguali agli algoritmi drbg_pr_* , ma con la resistenza alla previsione disabilitata. Il codice è condiviso con la variante resistente alla previsione. Nella versione del kernel 5.10, il DRBG con la priorità più alta è drbg_nopr_hmac_sha256 . Nella versione del kernel 5.15 e successive, è drbg_pr_hmac_sha512 .
jitterentropy_rng jitterentropy_rng NO Versione 2.2.0 di Jitter RNG : 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) 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

Costruisci il modulo dal sorgente

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

  • Costruisci con Bazel:

    tools/bazel run //common:fips140_dist
    
  • Costruisci 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 digest HMAC-SHA256 incorporati al suo interno.

Guida per l'utente finale

Guida del Crypto Officer

Per utilizzare il modulo kernel, il sistema operativo deve essere limitato a una modalità operativa a singolo operatore. Questo viene gestito automaticamente da Android utilizzando l'hardware di gestione della memoria nel processore.

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

Il Crypto Officer può far eseguire gli autotest in qualsiasi momento riavviando il dispositivo.

Guida per l'utente

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

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

Errori di autotest

In caso di fallimento del test automatico, il modulo del kernel provoca il panico del kernel e il dispositivo non continua l'avvio. Se il riavvio del dispositivo non risolve il problema, il dispositivo deve avviarsi in modalità di ripristino per correggere il problema eseguendo nuovamente il flashing del dispositivo.


  1. Si prevede che le implementazioni AES-GCM del modulo possano essere "approvate dall'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 del modulo FIPS per GCM sono incompatibili con le implementazioni GCM che non generano i propri IV.