Šifrování celého disku je proces kódování všech uživatelských dat v zařízení Android pomocí zašifrovaného klíče. Jakmile je zařízení zašifrováno, všechna uživatelem vytvořená data jsouautomaticky zašifrována před jejich uložením na disk a všechna čteníautomaticky dešifrují data před jejich vrácením volajícímu procesu.
Šifrování celého disku bylo do systému Android zavedeno ve verzi 4.4, ale Android 5.0 představil tyto nové funkce:
- Vytvořil rychlé šifrování, které šifruje pouze použité bloky na datovém oddílu, aby první spuštění netrvalo dlouho. V současné době podporují rychlé šifrování pouze souborové systémy ext4 a f2fs.
- Přidal příznak forceencryptfstab pro šifrování při prvním spuštění.
- Přidána podpora pro vzory a šifrování bez hesla.
- Přidáno hardwarově podporované ukládání šifrovacího klíče pomocí možnosti podepisování v prostředí Trusted Execution Environment (TEE) (například v TrustZone). Další podrobnosti naleznete v části Ukládání šifrovacího klíče.
Upozornění: Zařízení aktualizovaná na systém Android 5.0 a potézašifrovaná mohou být obnovením továrních dat vrácena do nezašifrovaného stavu. Nová zařízení se systémem Android 5.0zašifrovaná při prvním spuštění nelze vrátit do nezašifrovaného stavu.
- Jak funguje šifrování celého disku systému Android
- Toky
- Zašifrování nového zařízení pomocí forceencrypt
- Šifrování existujícího zařízení
- Spuštění zašifrovaného zařízení s výchozím šifrováním
- Spuštění šifrovaného zařízení bez výchozího šifrování
- Závada
- Uložení šifrovacího klíče
- Změna hesla
- Vlastnosti šifrování
- Vlastnosti
- init vlastnosti
- Akce init
Jak funguje šifrování celého disku systému Android
Šifrování celého disku systému Android je založeno na dm-crypt, což je funkce jádra, která funguje na blokové vrstvě zařízení. Díky tomu šifrování funguje s kartami Embedded MultiMediaCard (eMMC) a podobnými zařízeními flash, která se jádru prezentují jako bloková zařízení. Šifrování není možné u systému YAFFS, který komunikuje přímo s čipem rawNAND flash. 
Šifrovací algoritmus je 128 Advanced Encryption Standard (AES) s řetězením šifrových bloků (CBC) a ESSIV:SHA256. Hlavní klíč je šifrován128bitovým AES prostřednictvím volání knihovny OpenSSL. Pro klíč je nutné použít 128 bitů nebo více (256 bitů je volitelných).
Poznámka: Výrobci OEM mohou pro šifrování hlavního klíče použít 128 bitů nebo více.
V systému Android 5.0 jsou k dispozici čtyři druhy stavů šifrování:
- výchozí
- PIN
- heslo
- vzor
Při prvním spuštění zařízení vytvoří náhodně vygenerovaný 128bitový hlavní klíča poté jej zahesluje pomocí výchozího hesla a uložené soli. Výchozí heslo je: „default_password „Výsledný hash je však také podepsán prostřednictvím TEE (například TrustZone),který používá hash podpisu k zašifrování hlavního klíče.
Výchozí heslo můžete najít definované v souboru cryptfs.cpp projektu Android Open Source.
Když uživatel v zařízení nastaví PIN/pass nebo heslo, znovu se zašifruje a uloží pouze 128bitový klíč. (Tj. uživatelské změny PIN/pasu/vzoru NEzpůsobí zašifrování uživatelských dat.) Všimněte si, že na spravovaném zařízení mohou platit omezení týkající se PIN, vzoru nebo hesla.
Šifrování je spravováno pomocí init a vold.init volá vold a vold nastavuje vlastnosti pro spouštění událostí v init. Ostatní části systémuse také dívají na vlastnosti, aby mohly provádět úkoly, jako je hlášení stavu, dotaz na heslo nebo výzva k obnovení továrního nastavení v případě fatální chyby. Pro vyvoláníšifrovacích funkcí v vold systém používá příkazy cryptfs nástroje příkazového řádkuvdc: checkpw,restart, enablecrypto, changepw,cryptocomplete, verifypw, setfield,getfield, mountdefaultencrypted, getpwtype,getpw a clearpw.
Pro zašifrování, dešifrování nebo vymazání /data nesmí být /data připojen. Aby však bylo možné zobrazit jakékoli uživatelské rozhraní (UI), musí se spustit framework a ten vyžaduje spuštění /data. Aby se tato hádanka vyřešila, je na /data připojen dočasný souborový systém, který umožňuje systému Android v případě potřeby vyzvat k zadání hesla, zobrazit průběh nebo navrhnout vymazání dat. Přináší to však omezení, že pro přepnutí z dočasného souborového systému na skutečný souborový systém /data musí systém zastavit všechny procesy s otevřenými soubory na dočasném souborovém systému a tyto procesy znovu spustit na skutečném souborovém systému /data. Za tímto účelem musí být všechny služby v jedné ze tří skupin: core, main alate_start. 
-  core: Po spuštění se nikdy nevypíná.
-  main: Vypnutí a opětovné spuštění po zadání hesla disku.
-  late_start: Nespustí se, dokud se nerozšifruje a nepřipojí/data.
Pro spuštění těchto akcí se nastavují různé řetězce vlastnosti vold.decrypt. k ukončení a opětovnému spuštění služeb slouží příkazy init:
-  class_reset: Zastaví službu, ale umožní její opětovné spuštění pomocí class_start.
-  class_start: Restartuje službu.
-  class_stop: Zastaví službu a přidá příznakSVC_DISABLED. Zastavené služby neodpovídají naclass_start.
Toky
Pro šifrované zařízení existují čtyři toky. Zařízení je zašifrováno pouze jednoua poté následuje normální spouštěcí tok.
- Zašifrovat dříve nezašifrované zařízení:
- Zašifrujte nové zařízení pomocí forceencrypt: Povinné šifrování při prvním spuštění (počínaje systémem Android L).
- Zašifrovat existující zařízení:
- Zašifrovat existující zařízení:
- Zašifrovat existující zařízení: Šifrování z podnětu uživatele (Android K a starší).
 
- Zašifrujte nové zařízení pomocí 
- Zavedení zašifrovaného zařízení:
- Spuštění šifrovaného zařízení bez hesla: Spuštění šifrovaného zařízení, které nemá nastavené heslo (relevantní pro zařízení se systémem Android 5.0 a novějším).
- Spuštění šifrovaného zařízení s heslem: Spuštění šifrovaného zařízení, které má nastavené heslo.
 
Kromě těchto toků se může stát, že se zařízení nepodaří zašifrovat /data. každý z toků je podrobně vysvětlen níže. 
Zašifrování nového zařízení pomocí forceencrypt
Toto je normální první spuštění pro systém Android 5.0.0 zařízení.
-  Detekce nešifrovaného souborového systému s příznakem forceencrypt/datanení šifrován, ale musí být, protože to nařizuje příznakforceencrypt. odpojení/data.
-  Spustit šifrování /datavold.decrypt = "trigger_encryption"spustíinit.rc,což způsobí, ževoldzašifruje/databez hesla (nastaveno žádné, protože by se mělo jednat o nové zařízení.)
-  Mount tmpfs
voldpřipojí tmpfs/data(pomocí volby tmpfs zro.crypto.tmpfs_options) a nastaví vlastnostvold.encrypt_progressna 0.voldpředpřipraví tmpfs/datapro zavedení šifrovaného systému a nastaví vlastnostvold.decryptna:trigger_restart_min_framework
-  Vyvolá rámec pro zobrazení průběhu
Protože zařízení nemá prakticky žádná data k šifrování, ukazatel průběhu se často ve skutečnosti nezobrazí, protože šifrování probíhá velmi rychle. Více podrobností o uživatelském rozhraní průběhu naleznete v částiŠifrování existujícího zařízení. 
-  Když je /datazašifrováno, sejměte frameworkvoldnastavívold.decryptnatrigger_default_encryption, čímž se spustí službadefaultcrypto. (Tím se spustí níže uvedený tok pro připojování adefaultně zašifrovaných uživatelských dat.)trigger_default_encryptionkontroluje typ šifrování, aby zjistil, zda je/datazašifrován s heslem nebo bez hesla. Protože zařízení se systémem Android 5.0 jsou při prvním spuštění šifrována, nemělo by být nastaveno žádné heslo; proto dešifrujeme a připojíme/data.
-  Mount /datainitpak připojí/datana tmpfs RAMDisk pomocíparametrů, které převezme odro.crypto.tmpfs_options, který je nastaven vinit.rc.
-  Spustí framework
Nastaví voldnatrigger_restart_framework, kterýpokračuje v obvyklém zaváděcím procesu.
Šifrování existujícího zařízení
Toto se stane, když zašifrujete nešifrované zařízení se systémem Android K nebo starším, které bylo převedeno na systém L.
Tento proces je iniciován uživatelem a v kódu se označuje jako „šifrování na místě“. Když uživatel zvolí šifrování zařízení, uživatelské rozhraní se ujistí, že je baterie plně nabitá a síťový adaptér je připojen, aby byl dostatek energie pro dokončení procesu šifrování.
Upozornění: Pokud se zařízení vybije a vypne se před dokončením šifrování, data souborů zůstanou v částečně zašifrovaném stavu. Zařízení musíbýt obnoveno do továrního nastavení a všechna data jsou ztracena.
Pro zapnutí šifrování na místě vold spustí smyčku pro čtení každéhosektoru reálného blokového zařízení a následný zápis do kryptografického blokového zařízení. vold Před čtením a zápisem kontroluje, zda je sektor používán, což značně urychluje šifrování na novém zařízení, které má málo nebo žádná data. 
Stav zařízení: Nastavte ro.crypto.state = "unencrypted"a proveďte spouštěč on nonencrypted init pro pokračování zavádění.
-  Zkontrolujte heslo
Uživatelské rozhraní zavolá volds příkazemcryptfs enablecrypto inplacekdepasswdje heslo uživatele k zamykací obrazovce.
-  Sundejte framework
voldkontroluje chyby, vrátí -1, pokud nemůže šifrovat, a vypíše důvod do protokolu. Pokud může šifrovat, nastaví vlastnostvold.decryptnatrigger_shutdown_framework. To způsobí, žeinit.rczastaví služby ve třídáchlate_startamain.
- Vytvoří kryptografickou patičku
- Vytvoří drobečkový soubor
- Restartuje
- Zjistí drobečkový soubor
-  Spustí šifrování /datavoldpak nastaví kryptografické mapování, které vytvoří virtuální kryptografické blokové zařízení, které se mapuje na skutečné blokové zařízení, ale šifruje každý sektor při zápisu a dešifruje každý sektor při čtení.voldpak vytvoří a vypíše kryptografická metadata.
-  Během šifrování připojí tmpfs
voldtmpfs/data(pomocí volby tmpfszro.crypto.tmpfs_options) a nastaví vlastnostvold.encrypt_progressna 0.voldpřipraví tmpfs/datapro zavedení šifrovaného systému a nastaví vlastnostvold.decryptna:trigger_restart_min_framework
-  Vyvolá framework pro zobrazení průběhu
trigger_restart_min_frameworkzpůsobí, žeinit.rcspustí třídu služebmain. Když framework vidí, ževold.encrypt_progressje nastaven na 0, vyvolá rozhraní progress barUI, které se každých pět sekund dotazuje na tuto vlastnost a aktualizuje ukazatel průběhu.šifrovací smyčka aktualizujevold.encrypt_progresspokaždé, když zašifruje další procento oddílu.
-  Když je /datazašifrován, aktualizuje kryptografickou patičkuKdyž je /dataúspěšně zašifrován,voldzruší příznakENCRYPTION_IN_PROGRESSv metadatech.Když je zařízení úspěšně odemčeno, heslo je poté použito k zašifrování hlavního klíče a je aktualizována kryptografická patička. Pokud se restart z nějakého důvodu nezdaří, voldnastaví vlastnostvold.encrypt_progressnaerror_reboot_faileda uživatelské rozhraní by mělo zobrazit zprávu vyzývající uživatele ke stisknutí tlačítka pro restart. Neočekává se, že by k tomu někdy došlo.
Spuštění zašifrovaného zařízení s výchozím šifrováním
Toto se stane, když spustíte zašifrované zařízení bez hesla. protože zařízení se systémem Android 5.0 jsou při prvním spuštění zašifrována, nemělo by být nastaveno žádné heslo, a proto je toto výchozí stav šifrování.
- Detekovat šifrované /databez heslaZjistí, že zařízení se systémem Android je šifrované, protože /datanelze připojit a je nastaven jeden z příznakůencryptableneboforceencrypt.voldnastavívold.decryptnatrigger_default_encryption, čímž se spustí službadefaultcrypto.trigger_default_encryptionzkontroluje typ šifrování a zjistí, zda je/datašifrováno s heslem nebo bez hesla.
-  Dešifruje /data
Vytvoří zařízení dm-cryptnad blokovým zařízením, takže zařízeníje připraveno k použití.
-  Připojí /data
voldpak připojí dešifrovaný skutečný oddíl/dataa poté připraví nový oddíl. Nastaví vlastnostvold.post_fs_data_donena 0 a poté nastavívold.decryptnatrigger_post_fs_data. To způsobí, žeinit.rcspustí své příkazypost-fs-data. Ty vytvoří všechny potřebné adresářenebo odkazy a pak nastavívold.post_fs_data_donena 1.Jakmile volduvidí v této vlastnosti 1, nastaví vlastnostvold.decryptna:trigger_restart_framework.To způsobí, žeinit.rcznovu spustí služby ve tříděmaina také poprvé od zavedení systému spustí služby ve třídělate_start.
-  Spustit framework
Nyní framework spustí všechny své služby pomocí dešifrovaného /dataa systém je připraven k použití.
Spuštění šifrovaného zařízení bez výchozího šifrování
Toto se stane, když spustíte šifrované zařízení, které má nastavenéheslo. Heslem zařízení může být pin, vzor nebo heslo.
- Detekce šifrovaného zařízení s heslem
Zjistí, že zařízení se systémem Android je šifrované, protože příznak ro.crypto.state = "encrypted"voldnastavívold.decryptnatrigger_restart_min_framework, protože/datajezašifrované s heslem.
-  Připojení tmpfs
initnastaví pět vlastností pro uložení počátečních možností připojení daných pro/datas parametry předanými zinit.rc.voldpoužívá tyto vlastnosti k nastavení kryptografického mapování:-  ro.crypto.fs_type
-  ro.crypto.fs_real_blkdev
-  ro.crypto.fs_mnt_point
-  ro.crypto.fs_options
-  ro.crypto.fs_flags(ASCII osmimístné šestnáctkové číslo, kterému předchází 0x)
 
-  
-  Spustí framework, aby se zeptal na heslo
Spustí se framework a vidí, že vold.decryptje nastaveno natrigger_restart_min_framework. To frameworku říká, že se spouští na disku tmpfs/dataa potřebuje získat uživatelské heslo.Nejprve se však musí ujistit, že disk byl správně zašifrován. Odešle příkaz cryptfs cryptocompletenavold.voldvrátí 0, pokud bylo šifrování úspěšně dokončeno, -1 při vnitřní chybě nebo-2, pokud šifrování nebylo úspěšně dokončeno. Příkazvoldto zjistí tak, že v kryptografických metadatech vyhledá příznakCRYPTO_ENCRYPTION_IN_PROGRESS. Pokud je nastaven, proces šifrování byl přerušen a na zařízení jsou nousable data. Pokudvoldvrátí chybu, uživatelské rozhraní by mělo zobrazit zprávu pro uživatele, aby restartoval a obnovil tovární nastavení zařízení, a dát uživateli tlačítko, které má za tímto účelem stisknout.
-  Dešifrování dat pomocí hesla
Pokud je cryptfs cryptocompleteúspěšné, rámec zobrazí uživatelské rozhraní s dotazem na heslo disku. Uživatelské rozhraní zkontroluje heslo odesláním příkazucryptfs checkpwnavold. Pokud je heslo správné (což se zjistí úspěšným připojením dešifrovaného/datana dočasné místo a jeho následným odmontováním),volduloží název dešifrovaného blokového zařízení do vlastnostiro.crypto.fs_crypto_blkdeva vrátí uživatelskému rozhraní stav 0. Pokud je heslo nesprávné, vrátí uživatelskému rozhraní stav -1.
-  Zastavit framework
Uživatelské rozhraní zobrazí grafiku zavádění šifrování a poté zavolá volds příkazemcryptfs restart. Příkazvoldnastaví vlastnostvold.decryptnatrigger_reset_main, což způsobí, žeinit.rcprovedeclass_reset main. Tím se zastaví všechny službyv hlavní třídě, což umožní odmountovat tmpfs/data.
-  Mount /datavoldpak připojí dešifrovaný skutečný oddíl/dataa připraví nový oddíl (který nemusel být nikdy připraven, pokud byl šifrován pomocí volby wipe, která není v první verzi podporována). Nastaví vlastnostvold.post_fs_data_donena 0 a poté nastavívold.decryptnatrigger_post_fs_data. To způsobí, žeinit.rcspustí své příkazypost-fs-data. Ty vytvoří všechny potřebné adresáře nebo odkazy a poté nastaví hodnotuvold.post_fs_data_donena 1. Jakmilevolduvidí v této vlastnosti 1, nastaví vlastnostvold.decryptnatrigger_restart_framework. To způsobí, žeinit.rcznovu spustí služby ve tříděmaina také poprvé od zavedení systému spustí služby ve třídělate_start.
-  Spustit celý framework
Nyní framework spustí všechny své služby pomocí dešifrovaného /datasouborového systému a systém je připraven k použití.
Závada
Zařízení, kterému se nedaří dešifrovat, může mít několik důvodů. Zařízení začíná běžnou sérií kroků pro spuštění:
- Detekovat zašifrované zařízení s heslem
- Mountovat tmpfs
- Spustit framework a vyzvat k zadání hesla
Ale po otevření frameworku může zařízení narazit na některé chyby:
- Heslo odpovídá, ale nelze dešifrovat data
- Uživatel zadá 30krát špatné heslo
Pokud se tyto chyby nevyřeší, vyzve uživatele k továrnímu vymazání:
Pokud vold zjistí chybu během procesu šifrování a pokud ještě nebyla zničena žádná data a framework je spuštěn, vold nastaví vlastnost vold.encrypt_progress na error_not_encrypted.Uživatelské rozhraní vyzve uživatele k restartu a upozorní ho, že proces šifrovánínebyl nikdy zahájen. Pokud k chybě dojde až poté, co byl framework stržen, ale ještě předtím, než se zobrazí uživatelské rozhraní s ukazatelem průběhu, vold restartuje systém. Pokud se restart nepodaří, nastaví vold.encrypt_progress naerror_shutting_down a vrátí -1; nebude však nic, co by chybu zachytilo. To se neočekává.
Pokud vold zjistí chybu během procesu šifrování, nastavívold.encrypt_progress na error_partially_encrypteda vrátí -1. V případě, že vold zjistí chybu během procesu šifrování, nastaví vold.encrypt_progress na error_partially_encrypteda vrátí -1. Uživatelské rozhraní by pak mělo zobrazit zprávu, že se šifrování nezdařilo, a poskytnout uživateli tlačítko pro obnovení továrního nastavení zařízení. 
Uložení šifrovacího klíče
Šifrovací klíč je uložen v kryptografických metadatech. Hardwarové zálohování jeimplementováno pomocí podepisovací schopnosti prostředí Trusted Execution Environment (TEE). dříve jsme hlavní klíč šifrovali klíčem vygenerovaným aplikací scrypt na heslo uživatele a uloženou sůl. Aby byl klíč odolný proti útokům mimo schránku, rozšířili jsme tento algoritmus o podepisování výsledného klíče uloženým klíčem TEE. Výsledný podpis se pak ještě jednou aplikací scryptu změní na klíč vhodné délky. Tento klíč je pak použit k zašifrování a dešifrování hlavního klíče. Uložení tohoto klíče:
- Vygenerujte náhodný 16bajtový šifrovací klíč disku (DEK) a 16bajtovou sůl.
- Aplikujte scrypt na uživatelské heslo a sůl a vytvořte 32bajtový meziklíč 1 (IK1).
- Podložíme IK1 nulou bajtů do velikosti hardwarově vázaného soukromého klíče (HBK). konkrétně podložíme jako: 00 || IK1 || 00..00; jeden nulový bajt, 32 bajtů IK1, 223nulových bajtů.
- Podložením IK1 pomocí HBK vznikne 256bajtový IK2.
- Použijeme scrypt na IK2 a sůl (stejná sůl jako v kroku 2) a vytvoříme 32bajtový IK3.
- Prvních 16 bajtů IK3 použijte jako KEK a posledních 16 bajtů jako IV.
- Šifrujte DEK pomocí AES_CBC s klíčem KEK a inicializačním vektorem IV.
Změna hesla
Když se uživatel rozhodne změnit nebo odstranit své heslo v nastavení, uživatelské rozhraní odešle příkaz cryptfs changepw na vold avold znovu zašifruje hlavní klíč disku s novým heslem.
Vlastnosti šifrování
vold a init spolu komunikují nastavením vlastností. Zde je seznam dostupných vlastností pro šifrování.
Vlastnosti
| Vlastnost | Popis | 
|---|---|
| vold.decrypt trigger_encryption | Šifrování disku bez hesla. | 
| vold.decrypt trigger_default_encryption | Zkontrolujte, zda je jednotka zašifrovaná bez hesla. pokud ano, dešifrujte ji a připojte, jinak nastavte vold.decryptna hodnotu trigger_restart_min_framework. | 
| vold.decrypt trigger_reset_main | Nastaví vold na vypnutí uživatelského rozhraní s dotazem na heslo disku. | 
| vold.decrypt trigger_post_fs_data | Nastaví vold na přípravu /datas potřebnými adresáři atd. | 
| vold.decrypt trigger_restart_framework | Nastaví vold, aby spustil skutečný framework a všechny služby. | 
| vold.decrypt trigger_shutdown_framework | Nastaví vold, aby vypnul celý framework a spustil šifrování. | 
| vold.decrypt trigger_restart_min_framework | Nastaví vold pro spuštění uživatelského rozhraní lišty průběhu šifrování nebo výzvy k zadání hesla, v závislosti na hodnotě ro.crypto.state. | 
| vold.encrypt_progress | Při spuštění frameworku,pokud je tato vlastnost nastavena, vstoupí do režimu uživatelského rozhraní progress baru. | 
| vold.encrypt_progress 0 to 100 | Uživatelské rozhraní progress baru by mělo zobrazovat nastavenou procentuální hodnotu. | 
| vold.encrypt_progress error_partially_encrypted | Uživatelské rozhraní s ukazatelem průběhu by mělo zobrazit zprávu, že se šifrování nezdařilo, a poskytnout uživateli možnost továrního obnovení zařízení. | 
| vold.encrypt_progress error_reboot_failed | Uživatelské rozhraní s ukazatelem průběhu by mělo zobrazit zprávu, že šifrování bylo dokončeno, a poskytnout uživateli tlačítko pro restart zařízení. Tato chyba se neočekává. | 
| vold.encrypt_progress error_not_encrypted | Uživatelské rozhraní panelu průběhu by mělozobrazit zprávu, že došlo k chybě, nebyla zašifrována ani ztracena žádná data, a dát uživateli tlačítko pro restartování systému. | 
| vold.encrypt_progress error_shutting_down | Uživatelské rozhraní panelu průběhu neběží, takže není jasné, kdo bude na tuto chybu reagovat. A stejně by k ní nemělo nikdy dojít. | 
| vold.post_fs_data_done 0 | Nastaveno voldtěsně před nastavenímvold.decryptnatrigger_post_fs_data. | 
| vold.post_fs_data_done 1 | Nastaveno init.rcneboinit.rctěsně po dokončení úlohypost-fs-data. | 
init vlastnosti
| Vlastnosti | Popis | 
|---|---|
| ro.crypto.fs_crypto_blkdev | Nastavuje se příkazem voldcheckpwpro pozdější použití příkazemvoldrestart. | 
| ro.crypto.state unencrypted | Nastaveno pomocí initpro sdělení, že tento systém běží s nešifrovaným/data ro.crypto.state encrypted. Nastavenoinit, aby říkalo, že tento systém běží se zašifrovaným/data. | 
| 
 | Těchto pět vlastností nastaví init, když se pokusí připojit/datas parametry předanými zinit.rc. Používá jevoldk nastavení kryptografického mapování. | 
| ro.crypto.tmpfs_options | Nastavuje je init.rcs parametry, které má init použít při připojování souborového systému tmpfs/data. | 
Akce init
.
