Google is committed to advancing racial equity for Black communities. See how.
Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Crittografia dell'intero disco

La crittografia dell'intero disco è il processo di codifica di tutti i dati utente su un dispositivo Android utilizzando una chiave crittografata. Una volta che un dispositivo è crittografato, tutti i dati creati dall'utente vengono automaticamente crittografati prima di salvarli sul disco e tutte le letture decrittografano automaticamente i dati prima di restituirli al processo chiamante.

La crittografia dell'intero disco è stata introdotta in Android in 4.4, ma Android 5.0 ha introdotto queste nuove funzionalità:

  • Creazione di una crittografia rapida, che crittografa solo i blocchi utilizzati sulla partizione dati per evitare che il primo avvio richieda molto tempo. Solo i filesystem ext4 e f2fs attualmente supportano la crittografia veloce.
  • Aggiunto il flag forceencrypt fstab per crittografare al primo avvio.
  • Aggiunto supporto per pattern e crittografia senza password.
  • Aggiunta dell'archiviazione supportata da hardware della chiave di crittografia utilizzando la funzionalità di firma TEE (Trusted Execution Environment) (come in una TrustZone). Vedere Archiviazione della chiave crittografata per maggiori dettagli.

Attenzione: i dispositivi aggiornati ad Android 5.0 e quindi crittografati potrebbero tornare a uno stato non crittografato mediante il ripristino dei dati di fabbrica. I nuovi dispositivi Android 5.0 crittografati al primo avvio non possono essere riportati a uno stato non crittografato.

Come funziona la crittografia dell'intero disco di Android

La crittografia dell'intero disco di Android si basa su dm-crypt , una funzionalità del kernel che funziona a livello di dispositivo a blocchi. Per questo motivo, la crittografia funziona con Embedded MultiMediaCard ( eMMC) e dispositivi flash simili che si presentano al kernel come dispositivi a blocchi. La crittografia non è possibile con YAFFS, che parla direttamente con un chip flash NAND grezzo.

L'algoritmo di crittografia è 128 Advanced Encryption Standard (AES) con cipher-block chaining (CBC) ed ESSIV: SHA256. La chiave master è crittografata con AES a 128 bit tramite chiamate alla libreria OpenSSL. È necessario utilizzare 128 bit o più per la chiave (con 256 opzionale).

Nota: gli OEM possono utilizzare 128 bit o superiore per crittografare la chiave master.

Nella versione di Android 5.0, ci sono quattro tipi di stati di crittografia:

  • predefinito
  • PIN
  • parola d'ordine
  • modello

Al primo avvio, il dispositivo crea una chiave master a 128 bit generata in modo casuale, quindi l'ha hash con una password predefinita e sale memorizzato. La password predefinita è: "default_password" Tuttavia, l'hash risultante viene firmato anche tramite un TEE (come TrustZone), che utilizza un hash della firma per crittografare la chiave master.

Puoi trovare la password predefinita definita nel file cryptfs.cpp di Android Open Source Project.

Quando l'utente imposta il PIN / pass o la password sul dispositivo, solo la chiave a 128 bit viene nuovamente crittografata e archiviata. (Ad esempio, le modifiche al PIN / pass / pattern utente NON causano la ricodifica dei dati utente.) Si noti che il dispositivo gestito può essere soggetto a restrizioni relative a PIN, pattern o password.

La crittografia è gestita da init e vold . init chiama vold e vold imposta le proprietà per attivare gli eventi in init. Altre parti del sistema esaminano anche le proprietà per svolgere attività come segnalare lo stato, chiedere una password o richiedere il ripristino delle impostazioni di fabbrica in caso di errore irreversibile. Per richiamare le funzionalità di crittografia in vold , il sistema utilizza lo strumento da riga di comando vdc 's cryptfs comandi: checkpw , restart , enablecrypto , changepw , cryptocomplete , verifypw , setfield , getfield , mountdefaultencrypted , getpwtype , getpw e clearpw .

Per crittografare, decrittografare o cancellare /data , /data non deve essere montata. Tuttavia, per mostrare qualsiasi interfaccia utente (UI), il framework deve essere avviato e il framework richiede /data per essere eseguito. Per risolvere questo enigma, un filesystem temporaneo viene montato su /data . Ciò consente ad Android di richiedere password, mostrare lo stato di avanzamento o suggerire una cancellazione dei dati secondo necessità. Impone la limitazione che per passare dal filesystem temporaneo al filesystem true /data , il sistema deve arrestare ogni processo con file aperti sul filesystem temporaneo e riavviare quei processi sul filesystem reale /data . A tale scopo, tutti i servizi devono essere in uno dei tre gruppi: core , main e late_start .

  • core : non spegnere mai dopo l'avvio.
  • main : spegne e riavvia dopo aver immesso la password del disco.
  • late_start : non si avvia fino a quando /data è stata decrittografata e montata.

Per attivare queste azioni, la proprietà vold.decrypt è impostata su varie stringhe . Per uccidere 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 : arresta un servizio e aggiunge un flag SVC_DISABLED . I servizi interrotti non rispondono a class_start .

Flussi

Esistono quattro flussi per un dispositivo crittografato. Un dispositivo viene crittografato una sola volta e quindi segue un normale flusso di avvio.

  • Crittografa un dispositivo precedentemente non crittografato:
    • Crittografa un nuovo dispositivo con forceencrypt : crittografia obbligatoria al primo avvio (a partire da Android L).
    • Crittografa un dispositivo esistente: crittografia avviata dall'utente (Android K e versioni precedenti).
  • Avvia un dispositivo crittografato:
    • Avvio di un dispositivo crittografato senza password: avvio di un dispositivo crittografato che non ha una password impostata (rilevante per i dispositivi con Android 5.0 e versioni successive).
    • Avvio di un dispositivo crittografato con una password: avvio di un dispositivo crittografato con una password impostata.

Oltre a questi flussi, il dispositivo può anche non crittografare /data . Ciascuno dei flussi è spiegato in dettaglio di seguito.

Crittografa un nuovo dispositivo con forceencrypt

Questo è il normale primo avvio di un dispositivo Android 5.0.

  1. Rileva il filesystem non crittografato con il flag forceencrypt

    /data non è crittografata ma deve esserlo perché forceencrypt impone. Smonta /data .

  2. Avvia crittografia /data

    vold.decrypt = "trigger_encryption" attiva init.rc , che farà sì che vold crittografi /data senza password. (Nessuno è impostato perché dovrebbe essere un nuovo dispositivo.)

  3. Montare tmpfs

    vold monta un tmpfs /data (utilizzando le opzioni tmpfs da ro.crypto.tmpfs_options ) e imposta la proprietà vold.encrypt_progress a 0. vold prepara tmpfs /data per l'avvio di un sistema crittografato e imposta la proprietà vold.decrypt su: trigger_restart_min_framework

  4. Visualizza la struttura per mostrare i progressi

    Poiché il dispositivo non ha praticamente dati da crittografare, la barra di avanzamento spesso non viene effettivamente visualizzata perché la crittografia avviene così rapidamente. Vedere Crittografare un dispositivo esistente per ulteriori dettagli sull'interfaccia utente di avanzamento.

  5. Quando /data è crittografata, rimuovere il framework

    vold imposta vold.decrypt su trigger_default_encryption che avvia il servizio defaultcrypto . (Ciò avvia il flusso di seguito per il montaggio di dati utente crittografati predefiniti.) trigger_default_encryption controlla il tipo di crittografia per vedere se /data è crittografata con o senza password. Poiché i dispositivi Android 5.0 sono crittografati al primo avvio, non dovrebbe essere impostata alcuna password; quindi decifriamo e montiamo /data .

  6. Montare /data

    init quindi monta /data su un RAMDisk tmpfs usando i parametri che raccoglie da ro.crypto.tmpfs_options , che è impostato in init.rc

  7. Avvia framework

    Imposta vold su trigger_restart_framework , che continua il normale processo di avvio.

Crittografa un dispositivo esistente

Questo è ciò che accade quando si crittografa un dispositivo Android K non crittografato o un dispositivo precedente che è stato migrato a L.

Questo processo viene avviato dall'utente e nel codice viene indicato come "crittografia sul posto". Quando un utente sceglie di crittografare un dispositivo, l'interfaccia utente si assicura che la batteria sia completamente carica e l'adattatore CA sia collegato in modo che ci sia alimentazione sufficiente per completare il processo di crittografia.

Avvertenza: se il dispositivo si esaurisce e si spegne prima che abbia terminato la crittografia, i dati del file vengono lasciati in uno stato parzialmente crittografato. Il dispositivo deve essere ripristinato alle impostazioni di fabbrica e tutti i dati vengono persi.

Per abilitare la crittografia sul posto, vold avvia un ciclo per leggere ogni settore del dispositivo a blocchi reale e quindi scriverlo sul dispositivo a blocchi crittografici. vold controlla se un settore è in uso prima di leggerlo e scriverlo, il che rende la crittografia molto più veloce su un nuovo dispositivo che ha pochi o nessun dato.

Stato del dispositivo : impostare ro.crypto.state = "unencrypted" ed eseguire il trigger di init on nonencrypted per continuare l'avvio.

  1. Controlla la password

    L'interfaccia utente chiama vold con il comando cryptfs enablecrypto inplace cui passwd è la password della schermata di blocco dell'utente.

  2. Abbatti la struttura

    vold verifica la presenza di errori, restituisce -1 se non è in grado di crittografare e stampa un motivo nel registro. Se può crittografare, imposta la proprietà vold.decrypt su trigger_shutdown_framework . Questo fa sì che init.rc interrompa i servizi nelle classi late_start e main .

  3. Crea un footer crittografico
  4. Crea un file breadcrumb
  5. Riavvia
  6. Rileva file breadcrumb
  7. Avvia crittografia /data

    vold imposta quindi la mappatura crittografica, che crea un dispositivo di blocco crittografico virtuale che mappa sul dispositivo a blocchi reale ma crittografa ogni settore mentre viene scritto e decrittografa ogni settore mentre viene letto. vold quindi crea e scrive i metadati crittografici.

  8. Mentre sta crittografando, monta tmpfs

    vold monta un tmpfs /data (utilizzando le opzioni tmpfs da ro.crypto.tmpfs_options ) e imposta la proprietà vold.encrypt_progress su 0. vold prepara tmpfs /data per l'avvio di un sistema crittografato e imposta la proprietà vold.decrypt su: trigger_restart_min_framework

  9. Visualizza la struttura per mostrare i progressi

    trigger_restart_min_framework fa sì che init.rc avvii la classe main di servizi. Quando il framework vold.encrypt_progress che vold.encrypt_progress è impostato su 0, visualizza l'interfaccia utente della barra di avanzamento, che interroga quella proprietà ogni cinque secondi e aggiorna una barra di avanzamento. Il ciclo di crittografia aggiorna vold.encrypt_progress ogni volta che crittografa un'altra percentuale della partizione.

  10. Quando /data è crittografata, aggiorna il piè di pagina della crittografia

    Quando /data viene crittografata con successo, vold cancella il flag ENCRYPTION_IN_PROGRESS nei metadati.

    Quando il dispositivo viene sbloccato con successo, la password viene utilizzata per crittografare la chiave master e il footer crittografico viene aggiornato.

    Se il riavvio non riesce per qualche motivo, vold imposta la proprietà vold.encrypt_progress su error_reboot_failed e l'interfaccia utente dovrebbe visualizzare un messaggio che chiede all'utente di premere un pulsante per riavviare. Questo non dovrebbe mai accadere.

Avvio di un dispositivo crittografato con crittografia predefinita

Questo è ciò che accade quando avvii un dispositivo crittografato senza password. Poiché i dispositivi Android 5.0 sono crittografati al primo avvio, non dovrebbe esserci alcuna password impostata e quindi questo è lo stato di crittografia predefinito .

  1. Rileva /data crittografati senza password

    Rileva che il dispositivo Android è crittografato perché /data non può essere montata e uno dei flag encryptable o forceencrypt è impostato.

    vold imposta vold.decrypt su trigger_default_encryption , che avvia il servizio defaultcrypto . trigger_default_encryption controlla il tipo di crittografia per vedere se /data è crittografata con o senza password.

  2. Decifrare / dati

    Crea il dispositivo dm-crypt sul dispositivo a blocchi in modo che il dispositivo sia pronto per l'uso.

  3. Montare / dati

    vold quindi monta la partizione reale /data decrittografata e quindi prepara la nuova partizione. Imposta la proprietà vold.post_fs_data_done su 0 e quindi imposta vold.decrypt su trigger_post_fs_data . Questo fa sì che init.rc esegua i suoi comandi post-fs-data . vold.post_fs_data_done tutte le directory o i collegamenti necessari e quindi imposteranno vold.post_fs_data_done su 1.

    Una volta che vold vede l'1 in quella proprietà, imposta la proprietà vold.decrypt su: trigger_restart_framework. Ciò fa sì che init.rc avvii nuovamente i servizi nella classe main e anche i servizi nella classe late_start per la prima volta dall'avvio.

  4. Avvia framework

    Ora il framework avvia tutti i suoi servizi utilizzando i /data decrittografati e il sistema è pronto per l'uso.

Avvio di un dispositivo crittografato senza crittografia predefinita

Questo è ciò che accade quando avvii un dispositivo crittografato con una password impostata. La password del dispositivo può essere un PIN, una sequenza o una password.

  1. Rileva il dispositivo crittografato con una password

    Rileva che il dispositivo Android è crittografato perché il flag ro.crypto.state = "encrypted"

    vold imposta vold.decrypt su trigger_restart_min_framework perché /data è crittografata con una password.

  2. Montare tmpfs

    init imposta cinque proprietà per salvare le opzioni di montaggio iniziali fornite per /data con i parametri passati da init.rc vold utilizza queste proprietà per impostare la mappatura crittografica:

    1. ro.crypto.fs_type
    2. ro.crypto.fs_real_blkdev
    3. ro.crypto.fs_mnt_point
    4. ro.crypto.fs_options
    5. ro.crypto.fs_flags (numero esadecimale ASCII a 8 cifre preceduto da 0x)
  3. Avvia framework per richiedere la password

    Il framework si avvia e vede che vold.decrypt è impostato su trigger_restart_min_framework . Questo dice al framework che si sta avviando su un tmpfs /data disk e ha bisogno di ottenere la password dell'utente.

    Per prima cosa, tuttavia, è necessario assicurarsi che il disco sia stato crittografato correttamente. Invia il comando cryptfs cryptocomplete a vold . vold restituisce 0 se la crittografia è stata completata correttamente, -1 in caso di errore interno o -2 se la crittografia non è stata completata correttamente. vold determina ciò cercando nei metadati crypto il flag CRYPTO_ENCRYPTION_IN_PROGRESS . Se è impostato, il processo di crittografia è stato interrotto e non ci sono dati utilizzabili sul dispositivo. Se vold restituisce un errore, l'interfaccia utente dovrebbe visualizzare un messaggio all'utente per riavviare e ripristinare le impostazioni di fabbrica del dispositivo e fornire all'utente un pulsante da premere per farlo.

  4. Decifra i dati con la password

    Una volta che cryptfs cryptocomplete esito positivo, il framework visualizza un'interfaccia utente che richiede la password del disco. L'interfaccia utente controlla la password inviando il comando cryptfs checkpw a vold . Se la password è corretta (che viene determinata montando correttamente i /data decrittografati in una posizione temporanea, quindi smontandola), vold salva il nome del dispositivo a blocchi decrittografato nella proprietà ro.crypto.fs_crypto_blkdev e restituisce lo stato 0 all'interfaccia utente . Se la password non è corretta, restituisce -1 all'interfaccia utente.

  5. Stop framework

    L'interfaccia utente cryptfs restart un grafico di avvio crittografico e quindi chiama vold con il comando cryptfs restart . vold imposta la proprietà vold.decrypt su trigger_reset_main , che fa sì che init.rc class_reset main . Ciò interrompe tutti i servizi nella classe principale, il che consente di smontare tmpfs /data .

  6. Montare /data

    vold quindi monta la partizione reale /data decrittografata e prepara la nuova partizione (che potrebbe non essere mai stata preparata se fosse stata crittografata con l'opzione wipe, che non è supportata nella prima versione). Imposta la proprietà vold.post_fs_data_done su 0 e quindi imposta vold.decrypt su trigger_post_fs_data . Questo fa sì che init.rc esegua i suoi comandi post-fs-data . vold.post_fs_data_done tutte le directory oi collegamenti necessari e quindi imposteranno vold.post_fs_data_done su 1. Una volta che vold vede l'1 in quella proprietà, imposta la proprietà vold.decrypt su trigger_restart_framework . Ciò fa sì che init.rc avvii nuovamente i servizi nella classe main e anche i servizi nella classe late_start per la prima volta dall'avvio.

  7. Avvia framework completo

    Ora il framework avvia tutti i suoi servizi utilizzando il file system decrittografato /data e il sistema è pronto per l'uso.

Fallimento

Un dispositivo che non riesce a decrittografare potrebbe essere storto per alcuni motivi. Il dispositivo si avvia con la normale serie di passaggi per l'avvio:

  1. Rileva il dispositivo crittografato con una password
  2. Montare tmpfs
  3. Avvia framework per richiedere la password

Ma dopo l'apertura del framework, il dispositivo può riscontrare alcuni errori:

  • La password corrisponde ma non può decrittografare i dati
  • L'utente immette una password errata 30 volte

Se questi errori non vengono risolti, richiedere all'utente di cancellare i dati di fabbrica :

Se vold rileva un errore durante il processo di crittografia e se nessun dato è stato ancora distrutto e il framework è vold.encrypt_progress , vold imposta la proprietà vold.encrypt_progress su error_not_encrypted . L'interfaccia utente richiede all'utente di riavviare e avvisa che il processo di crittografia non è mai stato avviato. Se l'errore si verifica dopo che il framework è stato abbattuto, ma prima che l'interfaccia utente della barra di avanzamento sia vold , vold riavvierà il sistema. Se il riavvio fallisce, imposta vold.encrypt_progress su error_shutting_down e restituisce -1; ma non ci sarà nulla per rilevare l'errore. Questo non dovrebbe accadere.

Se vold rileva un errore durante il processo di crittografia, imposta vold.encrypt_progress su error_partially_encrypted e restituisce -1. L'interfaccia utente dovrebbe quindi visualizzare un messaggio che informa che la crittografia non è riuscita e fornire un pulsante per consentire all'utente di ripristinare le impostazioni di fabbrica del dispositivo.

Archiviazione della chiave crittografata

La chiave crittografata viene archiviata nei metadati crittografici. Il supporto hardware viene implementato utilizzando la funzionalità di firma TEE (Trusted Execution Environment). In precedenza, abbiamo crittografato la chiave principale con una chiave generata applicando scrypt alla password dell'utente e al salt memorizzato. Per rendere la chiave resiliente contro gli attacchi off-box, estendiamo questo algoritmo firmando la chiave risultante con una chiave TEE memorizzata. La firma risultante viene quindi trasformata in una chiave di lunghezza appropriata da un'altra applicazione di scrypt. Questa chiave viene quindi utilizzata per crittografare e decrittografare la chiave master. Per memorizzare questa chiave:

  1. Genera una chiave di crittografia del disco (DEK) casuale a 16 byte e sale a 16 byte.
  2. Applicare scrypt alla password utente e al salt per produrre la chiave intermedia 1 (IK1) a 32 byte.
  3. Pad IK1 con zero byte alla dimensione della chiave privata associata all'hardware (HBK). Nello specifico, inseriamo come: 00 || IK1 || 00..00; uno zero byte, 32 IK1 byte, 223 zero byte.
  4. Firma IK1 imbottito con HBK per produrre IK2 a 256 byte.
  5. Applica lo scrypt a IK2 e sale (lo stesso sale del passaggio 2) per produrre IK3 a 32 byte.
  6. Usa i primi 16 byte di IK3 come KEK e gli ultimi 16 byte come IV.
  7. Crittografa DEK con AES_CBC, con chiave KEK e vettore di inizializzazione IV.

Modifica della password

Quando un utente sceglie di modificare o rimuovere la propria password nelle impostazioni, l'interfaccia utente invia il comando cryptfs changepw a vold e vold crittografa nuovamente la chiave master del disco con la nuova password.

Proprietà di crittografia

vold e init comunicano tra loro impostando le proprietà. Di seguito è riportato un elenco delle proprietà disponibili per la crittografia.

Proprietà Vold

Proprietà Descrizione
vold.decrypt trigger_encryption Crittografa l'unità senza password.
vold.decrypt trigger_default_encryption Controlla l'unità per vedere se è crittografata senza password. Se lo è, decodificalo e vold.decrypt , altrimenti imposta vold.decrypt su trigger_restart_min_framework.
vold.decrypt trigger_reset_main Impostato da vold per chiudere l'interfaccia utente 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 da vold per avviare il framework reale e tutti i servizi.
vold.decrypt trigger_shutdown_framework Impostato da vold per chiudere l'intero framework per avviare la crittografia.
vold.decrypt trigger_restart_min_framework Impostato da vold per avviare l'interfaccia utente della barra di avanzamento per la crittografia o per richiedere la password, a seconda del valore di ro.crypto.state .
vold.encrypt_progress All'avvio del framework, se questa proprietà è impostata, accedere alla modalità UI della barra di avanzamento.
vold.encrypt_progress 0 to 100 L'interfaccia utente della barra di avanzamento dovrebbe visualizzare il valore percentuale impostato.
vold.encrypt_progress error_partially_encrypted L'interfaccia utente della barra di avanzamento dovrebbe visualizzare un messaggio che la crittografia non è riuscita e dare all'utente un'opzione per ripristinare le impostazioni di fabbrica del dispositivo.
vold.encrypt_progress error_reboot_failed L'interfaccia utente della barra di avanzamento dovrebbe visualizzare un messaggio che dice che la crittografia è stata completata e fornire all'utente un pulsante per riavviare il dispositivo. Questo errore non dovrebbe verificarsi.
vold.encrypt_progress error_not_encrypted L'interfaccia utente della barra di avanzamento dovrebbe visualizzare un messaggio che informa che si è verificato un errore, nessun dato è stato crittografato o perso e fornire all'utente un pulsante per riavviare il sistema.
vold.encrypt_progress error_shutting_down L'interfaccia utente della barra di avanzamento non è in esecuzione, quindi non è chiaro chi risponderà a questo errore. E comunque non dovrebbe mai accadere.
vold.post_fs_data_done 0 Impostato da vold appena prima di impostare vold.decrypt su trigger_post_fs_data .
vold.post_fs_data_done 1 Impostato da init.rc o init.rc subito dopo aver terminato 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 dire che questo sistema è in esecuzione con un /data ro.crypto.state encrypted . Impostato da init per dire che questo sistema è in esecuzione con un /data crittografato.

ro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags

Queste cinque proprietà vengono impostate da init quando tenta di montare /data con i parametri passati da init.rc vold utilizza per configurare la mappatura crittografica.
ro.crypto.tmpfs_options Impostato da init.rc con le opzioni che init dovrebbe usare durante il montaggio del filesystem tmpfs /data .

Iniziare azioni

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