La crittografia completa del disco è il processo di codifica di tutti i dati utente su un dispositivo Android utilizzando un chiave criptata. Una volta che un dispositivo è criptato, tutti i dati creati dagli utenti vengono con crittografia automatica prima di eseguirne il commit su disco e di tutte le letture decriptare automaticamente i dati prima di restituirli al processo di chiamata.
La crittografia completa del disco è stata introdotta su Android 4.4, ma Android 5.0 ha introdotto queste nuove funzionalità:
- È stata creata una crittografia rapida, che cripta solo i blocchi utilizzati sulla partizione dei dati evitando che il primo avvio richieda troppo tempo. Solo i file system ext4 e f2fs supportano attualmente la crittografia rapida.
- È stato aggiunto
forceencrypt
fstab per eseguire la crittografia al primo avvio. - Aggiunto il supporto per pattern e crittografia senza password.
- È stata aggiunta l'archiviazione con supporto hardware della chiave di crittografia utilizzando Attendibile Funzionalità di firma TEE (Execution Environment) (ad esempio in un TrustZone). Per ulteriori informazioni, consulta Conservare la chiave criptata i dettagli.
Attenzione:dispositivi su cui è stato eseguito l'upgrade ad Android 5.0 e versioni successive criptato potrebbe essere restituito a uno stato non criptato tramite il ripristino dei dati di fabbrica. Nuovo Android 5.0 i dispositivi criptati al primo avvio non possono essere restituiti allo stato non criptato.
Come funziona la crittografia dell'intero disco di Android
La crittografia dell'intero disco di Android si basa su dm-crypt
, che è un kernel
che funziona a livello di dispositivi a blocchi. A causa di
questa funzionalità, la crittografia funziona con Embedded MultiMediaCard (eMMC) e
dispositivi Flash simili che si presentano al kernel come blocchi
dispositivi mobili. La crittografia non è possibile con YAFFS, che comunica direttamente con un
Chip Flash NAND.
L'algoritmo di crittografia è il 128 Advanced Encryption Standard (AES) con CBC (cipher-block chaining) ed ESSIV:SHA256. La chiave master è criptata con AES a 128 bit tramite chiamate alla libreria OpenSSL. Devi usare almeno 128 bit per la chiave (256 è facoltativo).
Nota:gli OEM possono usare una versione a 128 bit o superiore per criptare la chiave master.
In Android 5.0 esistono quattro tipi di stati della crittografia:
- predefinito
- PIN
- password
- pattern
Al primo avvio, il dispositivo crea una chiave master a 128 bit generata in modo casuale e lo sottopone ad hashing con una password predefinita e il sale memorizzato. La password predefinita è: "password_predefinita" Tuttavia, l'hash risultante viene anche firmato tramite un TEE (come TrustZone), che utilizza un hash della firma per criptare la chiave master.
Puoi trovare la password predefinita definita nel progetto open source Android cryptfs.cpp .
Quando l'utente imposta il PIN/pass o la password sul dispositivo, solo la chiave a 128 bit viene ricriptata e archiviata. (ad esempio, le modifiche a PIN/pass/pattern dell'utente NON causano nuova crittografia dei dati utente.) Tieni presente che dispositivo gestito potrebbero essere soggetti a restrizioni relative a PIN, sequenza o password.
La crittografia è gestita da init
e vold
.
init
chiama vold
e vold imposta le proprietà da attivare
eventi in init. Altre parti del sistema
controllare anche le proprietà per svolgere attività come
segnalare lo stato, richiedere una
la password o richiedere il ripristino dei dati di fabbrica in caso di errore irreversibile. Per richiamare
funzionalità di crittografia in vold
, il sistema usa lo strumento a riga di comando
Comandi cryptfs
di vdc
: checkpw
,
restart
, enablecrypto
, changepw
,
cryptocomplete
, verifypw
, setfield
getfield
, mountdefaultencrypted
, getpwtype
,
getpw
e clearpw
.
Per criptare, decriptare o cancellare i dati di /data
, /data
non deve essere montato. Tuttavia, per mostrare qualsiasi interfaccia utente (UI), il
il framework deve iniziare e richiede /data
per l'esecuzione. A
risolvere questo enigma, un file system temporaneo viene montato su /data
.
In questo modo Android può richiedere le password, mostrare i progressi o suggerire dati
cancellarli se necessario. ma pone il limite che, per passare dalla
file system temporaneo al file system /data
vero, il sistema deve
interrompi ogni processo con file aperti sul file system temporaneo e riavviali
processi sul file system /data
reale. Per farlo, tutti i servizi
deve far parte di uno di tre gruppi: core
, main
e
late_start
.
core
: non spegnere mai dopo l'avvio.main
: arresta e riavvia dopo l'inserimento della password del disco.late_start
: l'avvio non verrà avviato prima che/data
sia stato decriptato e montato.
Per attivare queste azioni, la proprietà vold.decrypt
è impostata su
varie stringhe.
Per terminare e riavviare i servizi, i comandi init
sono:
class_reset
: arresta un servizio, ma ne consente il riavvio con class_start.class_start
: riavvia un servizio.class_stop
: interrompe un servizio e aggiunge un flagSVC_DISABLED
. I servizi interrotti non rispondono aclass_start
.
Flussi
Esistono quattro flussi per un dispositivo criptato. Un dispositivo viene criptato una sola volta seguendo un normale flusso di avvio.
- Criptare un dispositivo non criptato in precedenza:
- Cripta un nuovo dispositivo con
forceencrypt
: crittografia obbligatoria al primo avvio (a partire da Android L). - Crittografia di un dispositivo esistente: crittografia avviata dall'utente (Android K e versioni precedenti).
- Cripta un nuovo dispositivo con
- Avvia un dispositivo criptato:
- Avvio di un dispositivo criptato senza password: l'avvio di un dispositivo criptato che non abbia una password impostata (per i dispositivi con Android 5.0 e versioni successive).
- Avvio di un dispositivo criptato con una password: l'avvio di un dispositivo criptato che ha una password impostata.
Oltre a questi flussi, il dispositivo può anche non riuscire a criptare /data
.
Ciascun flusso è spiegato in dettaglio di seguito.
Cripta un nuovo dispositivo con forceencrypt
Si tratta del normale primo avvio di un dispositivo Android 5.0.
- Rileva il file system non criptato con flag
forceencrypt
/data
non è criptato, ma deve esserlo perché è richiesto daforceencrypt
. Smonta/data
. - Avvia la crittografia di
/data
vold.decrypt = "trigger_encryption"
attivainit.rc
, che comporterà la crittografia di/data
da parte divold
senza password. Non è impostata nessuna opzione perché dovrebbe essere un nuovo dispositivo. - Montaggio tmpfs
vold
monta un tmpfs/data
(utilizzando le opzioni tmpfs daro.crypto.tmpfs_options
) e imposta la proprietàvold.encrypt_progress
su 0.vold
prepara il file tmpfs/data
per l'avvio di un sistema criptato e imposta il valore proprietàvold.decrypt
a:trigger_restart_min_framework
- Apri la struttura per mostrare i progressi
Poiché il dispositivo non ha praticamente dati da criptare, la barra di avanzamento spesso non appaiono perché la crittografia avviene molto rapidamente. Consulta Cripta un dispositivo esistente per ulteriori informazioni i dettagli dell'interfaccia utente di avanzamento.
- Quando
/data
è criptato, rimuovi il frameworkvold
impostavold.decrypt
sutrigger_default_encryption
che avvia la Serviziodefaultcrypto
. (Questo avvia il flusso di seguito per il montaggio di un dati utente criptati predefiniti).trigger_default_encryption
controlla tipo di crittografia per vedere se/data
è criptato con o senza un password. Poiché i dispositivi Android 5.0 sono criptati al primo avvio, dovrebbero non impostare alcuna password; pertanto decriptiamo e mettiamo in mostra/data
. - Montaggio
/data
init
quindi monta/data
su un RAMDisk tmpfs utilizzando i parametri che acquisisce daro.crypto.tmpfs_options
, impostati trainit.rc
. - Framework iniziale
vold
impostavold.decrypt
sutrigger_restart_framework
, che continua con il solito avvio e il processo di sviluppo.
Criptare un dispositivo esistente
Ecco cosa succede quando cripti un Android K non criptato o una versione precedente dispositivo di cui è stata eseguita la migrazione a L.
Questa procedura viene avviata dall'utente ed è denominata "crittografia in loco" in il codice. Quando un utente sceglie di criptare un dispositivo, la UI fa in modo che la batteria sia completamente carica e che l'alimentatore CA sia collegato in modo che ci sia abbastanza per completare il processo di crittografia.
Avviso:se il dispositivo si scarica e si spegne prima della fine la crittografia, i dati dei file vengono lasciati in uno stato parzialmente criptato. Il dispositivo deve ripristinare i dati di fabbrica e perdere tutti i dati.
Per abilitare la crittografia in loco, vold
avvia un loop per leggere ogni
settore del blocco reale e quindi scrivilo
al dispositivo di crypto block. vold
controlla se un settore è in
da utilizzare prima di leggerli e scriverli, il che rende
la crittografia molto più velocemente su un nuovo dispositivo con pochi o nessun dato.
Stato del dispositivo: imposta ro.crypto.state = "unencrypted"
ed esegui il trigger on nonencrypted
init
per continuare l'avvio.
- Verifica password
La UI chiama
vold
con il comandocryptfs enablecrypto inplace
dovepasswd
è la password della schermata di blocco dell'utente. - Rimuovere la struttura
vold
verifica la presenza di errori, restituisce -1 se non può criptare e visualizza un motivo nel log. Se può eseguire la crittografia, imposta la proprietàvold.decrypt
atrigger_shutdown_framework
. Questo fa sì cheinit.rc
interrompi i servizi nelle classilate_start
emain
. - Creare un piè di pagina di crittografia
- Creare un file breadcrumb
- Riavvia
- Rileva file breadcrumb
- Avvia la crittografia di
/data
vold
configura quindi la crypto mapping, che crea un dispositivo a blocchi di criptovalute virtuale. che mappa sul dispositivo a blocchi ma cripta ogni settore mentre è scritto, e decripta ogni settore man mano che viene letto.vold
quindi crea e scrive i metadati delle criptovalute. - Durante la crittografia, monta tmpfs
vold
monta un tmpfs/data
(utilizzando le opzioni tmpfs) daro.crypto.tmpfs_options
) e imposta la proprietàvold.encrypt_progress
a 0.vold
prepara il file tmpfs/data
per l'avvio di un sistema criptato e l'impostazione della proprietàvold.decrypt
a:trigger_restart_min_framework
- Apri la struttura per mostrare i progressi
trigger_restart_min_framework
causainit.rc
a avviare la classe di servizimain
. Quando il framework rileva che Il valorevold.encrypt_progress
è impostato su 0 e viene visualizzata la barra di avanzamento. UI, che esegue query su tale proprietà ogni cinque secondi e aggiorna una barra di avanzamento. Il loop di crittografia si aggiornavold.encrypt_progress
ogni volta cripta un'altra percentuale della partizione. - Quando
/data
è criptato, aggiorna il piè di pagina delle criptovaluteQuando
/data
viene criptato correttamente,vold
cancella il flagENCRYPTION_IN_PROGRESS
nei metadati.Quando il dispositivo viene sbloccato, la password viene utilizzata per crittografare la chiave master e il piè di pagina di crittografia viene aggiornato.
Se il riavvio non riesce per qualche motivo,
vold
imposta la proprietà Davold.encrypt_progress
aerror_reboot_failed
e nell'interfaccia utente dovrebbe essere visualizzato un messaggio che chiede all'utente di premere un pulsante riavvio. Non è previsto che questo accada.
Avvio di un dispositivo criptato con la crittografia predefinita
Questo è ciò che succede quando avvii un dispositivo criptato senza password. Poiché i dispositivi Android 5.0 vengono criptati al primo avvio, non è necessario impostare per cui si tratta dello stato della crittografia predefinita.
- Rileva
/data
criptato senza passwordRileva che il dispositivo Android è criptato perché
/data
non può essere montato e uno dei flagencryptable
oforceencrypt
impostato.vold
impostavold.decrypt
sutrigger_default_encryption
, che avvia il Serviziodefaultcrypto
.trigger_default_encryption
controlla il tipo di crittografia per verificare se/data
è criptato con o senza password. - Decripta /data
Crea il dispositivo
dm-crypt
sul dispositivo a blocchi in modo che il dispositivo pronto per l'uso. - Montaggio /data
vold
monta quindi la partizione/data
reale decriptata e poi prepara la nuova partizione. Imposta la proprietàvold.post_fs_data_done
su 0, poi impostavold.decrypt
atrigger_post_fs_data
. Questo causa l'esecuzione diinit.rc
i suoi comandipost-fs-data
. Creerà tutte le directory necessarie o link e poi impostavold.post_fs_data_done
su 1.Quando
vold
vede il numero 1 in quella proprietà, imposta la proprietàvold.decrypt
a:trigger_restart_framework.
Questo causa l'avvio di servizi da parte diinit.rc
nella classemain
e avviare anche servizi nella classelate_start
per il primo tempo dall'avvio. - Framework iniziale
Ora il framework avvia tutti i servizi utilizzando l'oggetto
/data
decriptato, e il sistema è pronto per essere utilizzato.
Avvio di un dispositivo criptato senza crittografia predefinita
Ecco cosa succede quando avvii un dispositivo criptato password. La password del dispositivo può essere un PIN, una sequenza o una password.
- Rilevare i dispositivi criptati con una password
Rileva che il dispositivo Android è criptato perché il flag
ro.crypto.state = "encrypted"
vold
impostavold.decrypt
sutrigger_restart_min_framework
perché/data
è criptato con una password. - Montaggio tmpfs
init
imposta cinque proprietà per salvare le opzioni di montaggio iniziale specificato per/data
con parametri passati dainit.rc
.vold
utilizza le seguenti proprietà per configurare la crypto mapping:ro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags
(numero esadecimale di 8 cifre ASCII preceduto da 0x)
- Inizia il framework per richiedere la password
Il framework si avvia e vede che
vold.decrypt
è impostato sutrigger_restart_min_framework
. Questo indica al framework che su un disco tmpfs/data
e deve ottenere la password dell'utente.Prima, però, deve assicurarsi che il disco sia criptato correttamente. it invia il comando
cryptfs cryptocomplete
avold
.vold
restituisce 0 se la crittografia è stata completata correttamente, -1 in caso di errore interno oppure -2 se la crittografia non è stata completata correttamente.vold
determina cercando i metadati di crittografia perCRYPTO_ENCRYPTION_IN_PROGRESS
flag. Se impostato, il processo di crittografia è stato interrotto e non utilizzabili sul dispositivo. Sevold
restituisce un errore, la UI deve mostrare un messaggio all'utente per riavviare il dispositivo e ripristinare i dati di fabbrica e restituire all'utente un pulsante su cui premere per farlo. - Decriptare i dati con password
Una volta ottenuta l'approvazione di
cryptfs cryptocomplete
, il framework mostra una UI che richiede la password del disco. La UI controlla la password invio del comandocryptfs checkpw
avold
. Se sia corretta (determinata montando correttamente/data
decriptato in una posizione temporanea e poi smontato),vold
salva il nome del dispositivo a blocchi decriptato nella proprietàro.crypto.fs_crypto_blkdev
e restituisce lo stato 0 alla UI. Se la password non è corretta, viene restituito -1 all'interfaccia utente. - Interrompi framework
La UI mostra la grafica di un avvio di crittografia e quindi chiama
vold
con il comandocryptfs restart
.vold
imposta la proprietà Davold.decrypt
atrigger_reset_main
, il che causainit.rc
per fareclass_reset main
. Tutti i servizi verranno interrotti nella classe main, il che consente di smontare il file tmpfs/data
. - Montaggio
/data
vold
monta quindi la partizione/data
reale decriptata e prepara la nuova partizione (che potrebbe non essere mai stata preparata è stato criptato con l'opzione di cancellazione, che non è supportata inizialmente ). Imposta la proprietàvold.post_fs_data_done
su 0 e poi impostavold.decrypt
sutrigger_post_fs_data
. Questo causainit.rc
per eseguire i suoi comandipost-fs-data
. Loro creare le directory o i link necessari e quindi impostare Davold.post_fs_data_done
a 1. Quandovold
vede il numero 1 in questa proprietà, imposta la proprietàvold.decrypt
sutrigger_restart_framework
. Questo causa l'avvio diinit.rc
di nuovo nella classemain
e avviano anche servizi nella classelate_start
per la prima volta dall'avvio. - Inizia il framework completo
Ora il framework avvia tutti i servizi utilizzando il file
/data
decriptato ed è pronto per l'uso.
Errore
Un dispositivo che non riesce a decriptare potrebbe risultare errato per diversi motivi. Il dispositivo inizia con la normale serie di passaggi per l'avvio:
- Rileva il dispositivo criptato con una password
- Monta tmpfs
- Avvia framework per richiedere la password
Tuttavia, dopo l'apertura del framework, il dispositivo potrebbe riscontrare alcuni errori:
- La password corrisponde, ma non può decriptare i dati
- L'utente inserisce la password errata 30 volte
Se questi errori non vengono risolti, chiedi all'utente di eliminare i dati di fabbrica:
Se vold
rileva un errore durante il processo di crittografia e se
nessun dato è stato ancora eliminato e il framework è attivo, vold
imposta
vold.encrypt_progress
a error_not_encrypted
della proprietà.
La UI richiede all'utente di riavviare e avvisa del processo di crittografia
non è mai iniziato. Se l'errore si verifica dopo la rimozione del framework,
prima che l'UI della barra di avanzamento sia attiva, vold
riavvierà il sistema. Se
se il riavvio non va a buon fine, imposta vold.encrypt_progress
su
error_shutting_down
e restituisce -1; ma non ci sarà nulla
per individuare l'errore. Ciò non è previsto.
Se vold
rileva un errore durante il processo di crittografia, imposta
Da vold.encrypt_progress
a error_partially_encrypted
e restituisce -1. La UI dovrebbe quindi visualizzare un messaggio che indica che la crittografia
non è andato a buon fine e fornisci all'utente un pulsante per ripristinare i dati di fabbrica del dispositivo.
Archiviazione della chiave criptata
La chiave criptata è archiviata nei metadati crittografici. Il supporto hardware è implementato utilizzando la funzionalità di firma TEE (Trusted Execution Environment). In precedenza, la chiave master era criptata con una chiave generata dall'applicazione della crittografia alla password dell'utente e al sale memorizzato. Per rendere la chiave resiliente contro gli attacchi esterni, estendiamo questo algoritmo firmando la chiave risultante con una chiave TEE memorizzata. La firma risultante viene quindi trasformata in un chiave di lunghezza con un'altra applicazione di scrypt. Questa chiave viene poi utilizzata per criptare e decriptare la chiave master. Per memorizzare questa chiave:
- Genera una chiave di crittografia del disco (DEK) casuale a 16 byte e un sale di 16 byte.
- Applica scrypt alla password dell'utente e al sale per produrre un testo intermedio da 32 byte chiave 1 (IK1).
- Crea un pad IK1 con zero byte, in base alla dimensione della chiave privata associata all'hardware (HBK). Nello specifico, la tastiera indica: 00 || IK1 || 00..00; un byte zero, 32 IK1 byte, 223 zero byte.
- Firma IK1 riempito con HBK per produrre un IK2 da 256-byte.
- Applicare scrypt a IK2 e sale (stesso sale del passaggio 2) per produrre IK3 da 32 byte.
- Usa i primi 16 byte di IK3 come KEK e gli ultimi 16 byte come IV.
- Cripta DEK con AES_CBC, con la chiave KEK e il vettore di inizializzazione IV.
Modifica della password
Quando un utente sceglie di modificare o rimuovere la propria password nelle impostazioni, la UI invia
il comando cryptfs changepw
per vold
e
vold
ricripta la chiave master del disco con la nuova password.
Proprietà della crittografia
vold
e init
comunicano tra loro tramite
dell'impostazione delle proprietà. Ecco un elenco delle proprietà disponibili per la crittografia.
Proprietà vold
Proprietà | Descrizione |
---|---|
vold.decrypt trigger_encryption |
Cripta l'unità senza password. |
vold.decrypt trigger_default_encryption |
Controlla l'unità per vedere se è criptata senza password.
Se lo è, decriptalo e montalo,
altrimenti imposta vold.decrypt su trigger_restart_min_framework. |
vold.decrypt trigger_reset_main |
Impostato da vold per arrestare l'UI che richiede la password del disco. |
vold.decrypt trigger_post_fs_data |
Impostato da vold per preparare /data con le directory necessarie, et al. |
vold.decrypt trigger_restart_framework |
Impostato per iniziare il framework reale e tutti i servizi. |
vold.decrypt trigger_shutdown_framework |
Impostalo per vold per arrestare l'intero framework e avviare la crittografia. |
vold.decrypt trigger_restart_min_framework |
Impostalo per vold per avviare
nella barra di avanzamento per la crittografia
richiedere la password, a seconda
il valore di ro.crypto.state . |
vold.encrypt_progress |
All'avvio del framework, Se questa proprietà è impostata, inserisci la modalità UI della barra di avanzamento. |
vold.encrypt_progress 0 to 100 |
L'interfaccia utente della barra di avanzamento mostra il valore percentuale impostato. |
vold.encrypt_progress error_partially_encrypted |
Nella UI della barra di avanzamento dovrebbe essere visualizzato un messaggio che indica che la crittografia non è riuscita. offri all'utente la possibilità di ripristinare i dati di fabbrica del dispositivo. |
vold.encrypt_progress error_reboot_failed |
L'interfaccia utente della barra di avanzamento dovrebbe mostrare un messaggio con scritto "Crittografia" completato e assegna all'utente un pulsante per riavviare il dispositivo. Questo errore che non si verifichi. |
vold.encrypt_progress error_not_encrypted |
L'interfaccia utente della barra di avanzamento visualizza un messaggio che indica un errore è successo, nessun dato è stato criptato ha perso e offre all'utente un pulsante per riavviare il sistema. |
vold.encrypt_progress error_shutting_down |
L'UI della barra di avanzamento non è in esecuzione, quindi non è chiaro chi risponderà a questo errore. E non dovrebbe mai succedere comunque. |
vold.post_fs_data_done 0 |
Impostato da vold poco prima di impostare vold.decrypt
a trigger_post_fs_data . |
vold.post_fs_data_done 1 |
Impostato da init.rc o
init.rc subito dopo aver completato l'attività post-fs-data . |
proprietà init
Proprietà | Descrizione |
---|---|
ro.crypto.fs_crypto_blkdev |
Impostato dal comando vold checkpw per un uso successivo
dal comando vold restart . |
ro.crypto.state unencrypted |
Impostato da init per indicare che il sistema è in esecuzione con una connessione non criptata
/data ro.crypto.state encrypted . Impostato da init per pronunciare
questo sistema è in esecuzione con un file /data criptato. |
|
Queste cinque proprietà sono impostate
init quando prova a montare /data con parametri passati da
init.rc . vold li utilizza per configurare il crypto mapping. |
ro.crypto.tmpfs_options |
Impostato da init.rc con le opzioni init da usare quando
il montaggio del file system /data tmpfs. |
Azioni di inizializzazione
on post-fs-data on nonencrypted on property:vold.decrypt=trigger_reset_main on property:vold.decrypt=trigger_post_fs_data on property:vold.decrypt=trigger_restart_min_framework on property:vold.decrypt=trigger_restart_framework on property:vold.decrypt=trigger_shutdown_framework on property:vold.decrypt=trigger_encryption on property:vold.decrypt=trigger_default_encryption