Š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.decrypt na 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 /data s 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 vold těsně před nastavením vold.decrypt na trigger_post_fs_data. |
vold.post_fs_data_done 1 |
Nastaveno init.rc nebo init.rc těsně po dokončení úlohy post-fs-data. |
init vlastnosti
| Vlastnosti | Popis |
|---|---|
ro.crypto.fs_crypto_blkdev |
Nastavuje se příkazem vold checkpw pro pozdější použití příkazem vold restart. |
ro.crypto.state unencrypted |
Nastaveno pomocí init pro sdělení, že tento systém běží s nešifrovaným /data ro.crypto.state encrypted. Nastaveno init, aby říkalo, že tento systém běží se zašifrovaným /data. |
|
|
Těchto pět vlastností nastaví init, když se pokusí připojit /data s parametry předanými z init.rc. Používá je vold k nastavení kryptografického mapování. |
ro.crypto.tmpfs_options |
Nastavuje je init.rc s parametry, které má init použít při připojování souborového systému tmpfs /data. |
Akce init
.