Full-Disk Encryption är en process där alla användardata på en Android-enhet kodas med en krypterad nyckel. När en enhet är krypterad krypteras alla data som skapats av användaren automatiskt innan de läggs in på disken och alla lästa data dekrypteras automatiskt innan de returneras till den anropande processen.
Full-disk-kryptering infördes i Android i 4.4, men med Android 5.0 infördes följande nya funktioner:
- Skapad snabb kryptering, som endast krypterar använda block på datapartitionen för att undvika att den första uppstarten tar lång tid. Endast ext4- och f2fs-filsystemen har för närvarande stöd för snabb kryptering.
- Lagt till flaggan
forceencrypt
fstab för att kryptera vid första uppstart. - Har lagt till stöd för mönster och kryptering utan lösenord.
- Har lagts till hårdvarubaserad lagring av krypteringsnyckeln med hjälp av TEE-signeringsfunktionen (Trusted Execution Environment) (t.ex. i en TrustZone). Se Lagring av den krypterade nyckeln för mer information.
Försiktighet: Enheter som uppgraderats till Android 5.0 och sedan krypterats kan återställas till okrypterat tillstånd genom återställning av fabriksdata. Nya Android 5.0-enheter som krypteras vid den första uppstarten kan inte återställas till okrypterat tillstånd.
- Hur Android-kryptering av full disk fungerar
- Flöden
- Kryptera en ny enhet med forceencrypt
- Kryptera en befintlig enhet
- Start av en krypterad enhet med standardkryptering
- Starta en krypterad enhet utan standardkryptering
- Fel
- Lagring av den krypterade nyckeln
- Ändra lösenordet
- Krypteringsegenskaper
- Vold properties
- init properties
- Init actions
Hur Android-kryptering av full disk fungerar
Android-kryptering av full disk är baserad på dm-crypt
, som är en kärnfunktion som fungerar på blockenhetens lager. Därför fungerar krypteringen med Embedded MultiMediaCard (eMMC) och liknande flash-enheter som presenterar sig för kärnan som blockenheter. Kryptering är inte möjlig med YAFFS, som talar direkt till ett råNAND-flashchip.
Krypteringsalgoritmen är AES (128 Advanced Encryption Standard) med CBC-kedjorering (Ccipher-block chaining) och ESSIV:SHA256. Huvudnyckeln krypteras med 128-bitars AES via anrop till OpenSSL-biblioteket. Du måste använda 128 bitar eller mer för nyckeln (256 är valfritt).
Anmärkning: OEM:er kan använda 128 bitar eller mer för att kryptera huvudnyckeln.
I Android 5.0-versionen finns det fyra typer av krypteringstillstånd:
- standard
- PIN
- lösenord
- mönster
När enheten startas upp första gången skapas en slumpmässigt genererad 128-bitars huvudnyckel och den hashasheras sedan med ett standardlösenord och lagrat salt. Standardlösenordet är: ”default_password ”Den resulterande hashen signeras dock också genom en TEE (t.ex. TrustZone), som använder en hash av signaturen för att kryptera huvudnyckeln.
Det standardlösenordet finns definierat i Android Open Source Project cryptfs.cppfile.
När användaren ställer in PIN-koden/passet eller lösenordet på enheten, är det bara den 128-bitariga nyckeln som återkrypteras och lagras. (dvs. ändringar av användarens PIN/pass/mönster orsakar INTE återkryptering av användardata.) Observera att hanterade enheter kan vara föremål för PIN-, mönster- eller lösenordsbegränsningar.
Kryptering hanteras av init
och vold
.init
anropar vold
, och Vold ställer in egenskaper för att utlösa händelser i init. Andra delar av systemet tittar också på egenskaperna för att utföra uppgifter som att rapportera status, be om ett lösenord eller uppmana till fabriksåterställning i händelse av ett dödligt fel. För att åberopa krypteringsfunktioner i vold
använder systemet kommandoradsverktygetvdc
s cryptfs
-kommandon: checkpw
,restart
, enablecrypto
, changepw
,cryptocomplete
, verifypw
, setfield
,getfield
, mountdefaultencrypted
, getpwtype
,getpw
och clearpw
.
För att kryptera, dekryptera eller radera /data
får /data
inte vara monterad. Men för att kunna visa något användargränssnitt måste ramverket starta och ramverket kräver att /data
körs. För att lösa detta problem monteras ett tillfälligt filsystem på /data
, vilket gör det möjligt för Android att efterfråga lösenord, visa framsteg eller föreslå en datautplåning vid behov. Det innebär dock den begränsningen att för att växla från det tillfälliga filsystemet till det riktiga /data
-filsystemet måste systemet stoppa alla processer med öppna filer på det tillfälliga filsystemet och starta om dessa processer på det riktiga /data
-filsystemet. För att göra detta måste alla tjänster finnas i en av tre grupper: core
, main
ochlate_start
.
-
core
: Stängs aldrig av efter start. -
main
: Stängs av och startas sedan om efter att disklösenordet har angetts. -
late_start
: Startar inte förrän efter att/data
har dekrypterats och monterats.
För att utlösa dessa åtgärder sätts egenskapen vold.decrypt
till olika strängar.För att avbryta och starta om tjänsterna är init
-kommandona:
-
class_reset
: Stoppar en tjänst, men gör det möjligt att starta om den med class_start. -
class_start
: Startar om en tjänst. -
class_stop
: Stoppar en tjänst och lägger till enSVC_DISABLED
-flagga. Stoppade tjänster svarar inte påclass_start
.
Flöden
Det finns fyra flöden för en krypterad enhet. En enhet krypteras bara en gång och följer sedan ett normalt startflöde.
- Kryptera en tidigare okrypterad enhet:
- Kryptera en ny enhet med
forceencrypt
: Obligatorisk kryptering vid första uppstart (med början i Android L). - Kryptera en befintlig enhet: Användarinitierad kryptering (Android K och tidigare).
- Kryptera en ny enhet med
- Starta upp en krypterad enhet:
- Starta en krypterad enhet utan lösenord: Starta upp en krypterad enhet som inte har något inställt lösenord (relevant för enheter med Android 5.0 och senare).
- Starta en krypterad enhet med ett lösenord: Startar en krypterad enhet som har ett inställt lösenord.
Förutom dessa flöden kan enheten också misslyckas med att kryptera /data
.Varje flöde förklaras i detalj nedan.
Kryptera en ny enhet med forceencrypt
Detta är den normala första uppstarten för en Android 5.0-enhet.
- Upptäck okrypterat filsystem med
forceencrypt
-flagg/data
är inte krypterat men måste vara det eftersomforceencrypt
kräver det.Montera bort/data
. - Börja kryptera
/data
vold.decrypt = "trigger_encryption"
utlöserinit.rc
,vilket kommer att fåvold
att kryptera/data
utan lösenord.(Inget är inställt eftersom detta ska vara en ny enhet.) - Mount tmpfs
vold
monterar en tmpfs/data
(med hjälp av tmpfs-alternativen frånro.crypto.tmpfs_options
) och sätter egenskapenvold.encrypt_progress
till 0.vold
förbereder tmpfs/data
för uppstart av ett krypterat system och sätter egenskapenvold.decrypt
till:trigger_restart_min_framework
- Ta fram ramverket för att visa framstegen
Om enheten praktiskt taget inte har några data att kryptera kommer framstegen ofta inte att visas eftersom krypteringen sker så snabbt. Se Kryptera en befintlig enhet för mer information om framstegsindikatorn.
- När
/data
är krypterad tar du ner ramverketvold
sättervold.decrypt
tilltrigger_default_encryption
vilket startar tjänstendefaultcrypto
. (Detta startar flödet nedan för montering av en standardkrypterad användardata.)trigger_default_encryption
kontrollerar krypteringstypen för att se om/data
är krypterad med eller utan lösenord. Eftersom Android 5.0-enheter krypteras vid den första uppstarten bör det inte finnas något lösenord; därför dekrypterar vi och monterar/data
. - Mount
/data
init
monterar sedan/data
på en tmpfs RAMDisk med hjälp avparametrar som den hämtar frånro.crypto.tmpfs_options
, som är inställd iinit.rc
. - Starta ramverk
Sätt
vold
tilltrigger_restart_framework
, vilketfortsätter den vanliga uppstartsprocessen.
Kryptera en befintlig enhet
Detta är vad som händer när du krypterar en okrypterad Android K- eller tidigare enhet som har migrerats till L.
Denna process är användarinitierad och kallas ”inplace encryption” i koden. När användaren väljer att kryptera en enhet ser användargränssnittet till att batteriet är fulladdat och att nätadaptern är inkopplad så att det finns tillräckligt med kraft för att slutföra krypteringsprocessen.
Varning: Om enheten får slut på ström och stängs av innan den har avslutatkrypteringen lämnas fildata kvar i ett delvis krypterat tillstånd. Enheten måste fabriksåterställas och alla data går förlorade.
För att möjliggöra inplace-kryptering startar vold
en slinga för att läsa varje sektor i den riktiga blockenheten och sedan skriva den till kryptoblockenheten. vold
kontrollerar om en sektor är i bruk innan den läses och skrivs, vilket gör krypteringen mycket snabbare på en ny enhet som har lite eller inga data.
Enhetens status: Ställ in ro.crypto.state = "unencrypted"
och kör utlösaren on nonencrypted
init
för att fortsätta att starta upp.
- Kontrollera lösenord
UI anropar
vold
med kommandotcryptfs enablecrypto inplace
därpasswd
är användarens låsskärmslösenord. - Ta ner ramverket
vold
kontrollerar om det finns några fel, returnerar -1 om den inte kan kryptera och skriver ut en orsak i loggen. Om den kan kryptera, ställer den in egenskapenvold.decrypt
tilltrigger_shutdown_framework
. Detta fårinit.rc
att stoppa tjänsterna i klassernalate_start
ochmain
. - Skapa en kryptofot
- Skapa en brödtextfil
- Reboot
- Detektera brödtextfil
- Startar kryptering
/data
vold
ställer sedan in kryptokartläggningen, vilket skapar en virtuell kryptoblockenhet som motsvarar den verkliga blockenheten men krypterar varje sektor när den skrivs och dekrypterar varje sektor när den läses.vold
skapar och skriver sedan ut kryptometadata. - Medan den krypterar monterar mount tmpfs
vold
en tmpfs/data
(med hjälp av tmpfs-alternativen frånro.crypto.tmpfs_options
) och ställer in egenskapenvold.encrypt_progress
till 0.vold
förbereder tmpfs/data
för att kunna starta upp ett krypterat system och ställer in egenskapenvold.decrypt
till:trigger_restart_min_framework
- Ta fram ramverket för att visa framstegen
trigger_restart_min_framework
föranlederinit.rc
att starta klassenmain
av tjänster. När ramverket ser attvold.encrypt_progress
är satt till 0, tar det upp förloppsindikatornUI, som frågar efter den egenskapen var femte sekund och uppdaterar en förloppsindikator.Krypteringsslingan uppdaterarvold.encrypt_progress
varje gång den krypterar ytterligare en procent av partitionen. - När
/data
är krypterad, uppdaterar du kryptofotenNär
/data
är krypterad med framgång, rensarvold
flagganENCRYPTION_IN_PROGRESS
i metadata.När enheten är upplåst används lösenordet för att kryptera huvudnyckeln och kryptofoten uppdateras.
Om omstarten misslyckas av någon anledning sätter
vold
egenskapenvold.encrypt_progress
tillerror_reboot_failed
och användargränssnittet bör visa ett meddelande där användaren uppmanas att trycka på en knapp för att starta om. Detta förväntas aldrig inträffa.
Start av en krypterad enhet med standardkryptering
Det här är vad som händer när du startar upp en krypterad enhet utan lösenord.Eftersom Android 5.0-enheter krypteras vid den första uppstarten bör det inte finnas något setpassword och därför är detta standardkrypteringstillstånd.
- Detektera krypterad
/data
utan lösenordDetektera att Android-enheten är krypterad eftersom
/data
inte kan monteras och någon av flaggornaencryptable
ellerforceencrypt
är inställd.vold
sättervold.decrypt
tilltrigger_default_encryption
, vilket startar tjänstendefaultcrypto
.trigger_default_encryption
kontrollerar krypteringstypen för att se om/data
är krypterad med eller utan lösenord. - Dekrypterar /data
Skapa
dm-crypt
-enheten över blockenheten så att enhetenär redo att användas. - Mount /data
vold
monterar sedan den dekrypterade riktiga/data
-partitionenoch förbereder sedan den nya partitionen. Den ställer in egenskapenvold.post_fs_data_done
till 0 och ställer sedan invold.decrypt
tilltrigger_post_fs_data
. Detta fårinit.rc
att köra sinapost-fs-data
-kommandon. De kommer att skapa alla nödvändiga katalogereller länkar och sedan sättavold.post_fs_data_done
till 1.När
vold
ser 1 i den egenskapen, sätter den egenskapenvold.decrypt
till:trigger_restart_framework.
Detta fårinit.rc
att starta tjänster i klassmain
igen och även starta tjänster i klasslate_start
för första gången sedan uppstarten. - Starta ramverk
Nu startar ramverket alla sina tjänster med hjälp av den avkrypterade
/data
, och systemet är redo att användas.
Starta en krypterad enhet utan standardkryptering
Detta är vad som händer när du startar upp en krypterad enhet som har ett setpassword. Enhetens lösenord kan vara en pin, ett mönster eller ett lösenord.
- Upptäck krypterad enhet med lösenord
Detekterar att Android-enheten är krypterad eftersom flaggan
ro.crypto.state = "encrypted"
vold
sättervold.decrypt
tilltrigger_restart_min_framework
eftersom/data
ärkrypterad med ett lösenord. - Montera tmpfs
init
ställer in fem egenskaper för att spara de initiala monteringsalternativen som getts för/data
med parametrar som överförs fråninit.rc
.vold
använder dessa egenskaper för att ställa in kryptomappningen:-
ro.crypto.fs_type
-
ro.crypto.fs_real_blkdev
-
ro.crypto.fs_mnt_point
-
ro.crypto.fs_options
-
ro.crypto.fs_flags
(ASCII 8-siffrigt hexatalsnummer föregånget av 0x)
-
- Starta ramverket för att be om lösenord
Ramenverket startar och ser att
vold.decrypt
är inställt påtrigger_restart_min_framework
. Detta talar om för ramverket att det startar på en tmpfs/data
-disk och att det måste ta reda på användarens lösenord.Först måste det dock se till att disken har krypterats på rätt sätt. Den skickar kommandot
cryptfs cryptocomplete
tillvold
.vold
returnerar 0 om krypteringen slutfördes framgångsrikt, -1 vid internt fel, eller-2 om krypteringen inte slutfördes framgångsrikt.vold
fastställer detta genom att leta i kryptometadata efterCRYPTO_ENCRYPTION_IN_PROGRESS
flaggen. Om det är inställt avbröts krypteringsprocessen och det finns nousable data på enheten. Omvold
returnerar ett fel bör användargränssnittet visa ett meddelande till användaren om att starta om och fabriksåterställa enheten och ge användaren en knapp att trycka på för att göra det. - Avkryptera data med lösenord
När
cryptfs cryptocomplete
är framgångsrik visar ramverket ett användargränssnitt som frågar efter disklösenordet. Användargränssnittet kontrollerar lösenordet genom att skicka kommandotcryptfs checkpw
tillvold
. Om lösenordet är korrekt (vilket fastställs genom att framgångsrikt montera den dekrypterade/data
på en tillfällig plats och sedan montera bort den) spararvold
namnet på den dekrypterade blockenheten i egenskapenro.crypto.fs_crypto_blkdev
och returnerar status 0 till användargränssnittet. Om lösenordet är felaktigt returnerar den -1 till UI. - Stoppa ramverket
UI sätter upp en kryptostartgrafik och anropar sedan
vold
med kommandotcryptfs restart
.vold
sätter egenskapenvold.decrypt
tilltrigger_reset_main
, vilket fårinit.rc
att göraclass_reset main
. Detta stoppar alla tjänster i huvudklassen, vilket gör att tmpfs/data
kan avmonteras. - Mount
/data
vold
monterar sedan den dekrypterade riktiga/data
-partitionen och förbereder den nya partitionen (som kanske aldrig har förberetts om den krypterades med alternativet wipe, som inte stöds i första versionen). Den sätter egenskapenvold.post_fs_data_done
till 0 och däreftervold.decrypt
tilltrigger_post_fs_data
. Detta fårinit.rc
att köra sinapost-fs-data
kommandon. De kommer att skapa alla nödvändiga kataloger eller länkar och sedan sättavold.post_fs_data_done
till 1. Närvold
ser 1 i den egenskapen sätter den egenskapenvold.decrypt
tilltrigger_restart_framework
. Detta fårinit.rc
att starta tjänster i klassmain
igen och även starta tjänster i klasslate_start
för första gången sedan uppstarten. - Starta hela ramverket
Nu startar ramverket alla sina tjänster med hjälp av det dekrypterade
/data
filesystemet, och systemet är redo att användas.
Fel
En enhet som misslyckas med att dekryptera kan ha flera orsaker. Enheten börjar med den normala serien av steg för att starta upp:
- Detektera krypterad enhet med ett lösenord
- Montera tmpfs
- Starta ramverket för att fråga efter lösenord
Men efter att ramverket har öppnats kan enheten stöta på några fel:
- Lösenordet matchar men kan inte dekryptera data
- Användaren anger fel lösenord 30 gånger
Om dessa fel inte löses uppmanas användaren till fabriksrensning:
Om vold
upptäcker ett fel under krypteringsprocessen och om inga data har förstörts ännu och ramverket är igång, ställer vold
in egenskapen vold.encrypt_progress
till error_not_encrypted
.Användargränssnittet uppmanar användaren att starta om och meddelar att krypteringsprocessen aldrig påbörjades. Om felet inträffar efter det att ramverket har rivits ned, men innan användargränssnittet för förloppsindikatorn är uppe, startar vold
om systemet. Om omstarten misslyckas sätts vold.encrypt_progress
till error_shutting_down
och returnerar -1; men det kommer inte att finnas något för att fånga upp felet. Detta förväntas inte hända.
Om vold
upptäcker ett fel under krypteringsprocessen, sätter denvold.encrypt_progress
till error_partially_encrypted
och returnerar -1. Användargränssnittet bör då visa ett meddelande om att krypteringen misslyckades och ge användaren en knapp för att fabriksåterställa enheten.
Lagring av den krypterade nyckeln
Den krypterade nyckeln lagras i kryptometadata. Hårdvarubackning genomförs med hjälp av Trusted Execution Environment’s (TEE) signeringsförmåga.Tidigare krypterade vi huvudnyckeln med en nyckel som genererades genom att tillämpa scrypt på användarens lösenord och det lagrade saltet. För att göra nyckeln motståndskraftig mot attacker utanför boxen utökar vi denna algoritm genom att signera den resulterande nyckeln med en lagrad TEE-nyckel. Den resulterande signaturen omvandlas sedan till en nyckel av lämplig längd genom ytterligare en tillämpning av scrypt. Denna nyckel används sedan för att kryptera och dekryptera huvudnyckeln. För att lagra denna nyckel:
- Generera en slumpmässig 16-byte disk-krypteringsnyckel (DEK) och ett 16-byte salt.
- Använd scrypt på användarlösenordet och saltet för att skapa 32-byte intermediatnyckel 1 (IK1).
- Padda IK1 med noll byte till storleken på den hårdvarubundna privata nyckeln (HBK): 00 || IK1 || 00..00; en nollbyte, 32 IK1-byte, 223 nollbyte.
- Sign fyller IK1 med HBK för att producera 256 byte IK2.
- Använd scrypt på IK2 och salt (samma salt som i steg 2) för att producera 32-byte IK3.
- Använd de första 16 bytena av IK3 som KEK och de sista 16 bytena som IV.
- Kryptera DEK med AES_CBC, med nyckeln KEK och initialiseringsvektorn IV.
Ändra lösenordet
När en användare väljer att ändra eller ta bort sitt lösenord i inställningar skickar användargränssnittetkommandot cryptfs changepw
till vold
, ochvold
krypterar diskhuvudnyckeln på nytt med det nya lösenordet.
Krypteringsegenskaper
vold
och init
kommunicerar med varandra genom att ställa in egenskaper. Här är en lista över tillgängliga egenskaper för kryptering.
Vold properties
Property | Description |
---|---|
vold.decrypt trigger_encryption |
Kryptera enheten utan lösenord. |
vold.decrypt trigger_default_encryption |
Kontrollera enheten för att se om den är krypterad utan lösenord.Om den är det ska du dekryptera och montera den, annars ska du ange vold.decrypt till trigger_restart_min_framework. |
vold.decrypt trigger_reset_main |
Sätts av vold för att stänga av användargränssnittet som frågar efter diskens lösenord. |
vold.decrypt trigger_post_fs_data |
Sätts av vold för att förbereda /data med nödvändiga kataloger, et al. |
vold.decrypt trigger_restart_framework |
Satt av vold för att starta det riktiga ramverket och alla tjänster. |
vold.decrypt trigger_shutdown_framework |
Satt av vold för att stänga av hela ramverket för att starta kryptering. |
vold.decrypt trigger_restart_min_framework |
Inställs av vold för att starta en förloppsindikator för kryptering eller för att begära lösenord, beroende på värdet på ro.crypto.state . |
vold.encrypt_progress |
När ramverket startar, om den här egenskapen är inställd, startas läget för förloppsindikatorn. |
vold.encrypt_progress 0 to 100 |
Förloppsindikatorn ska visa det inställda procentvärdet. |
vold.encrypt_progress error_partially_encrypted |
Förloppsindikatorns användargränssnitt bör visa ett meddelande om att krypteringen misslyckades och ge användaren möjlighet att göra en fabriksåterställning av enheten. |
vold.encrypt_progress error_reboot_failed |
Förloppsindikatorns användargränssnitt bör visa ett meddelande om att krypteringen är slutförd och ge användaren en knapp för att starta om enheten. Detta fel förväntas inte inträffa. |
vold.encrypt_progress error_not_encrypted |
Förloppsindikatorns användargränssnitt bör visa ett meddelande om att ett fel inträffade, att inga data krypterades eller förlorades och ge användaren en knapp för att starta om systemet. |
vold.encrypt_progress error_shutting_down |
Förloppsindikatorns användargränssnitt körs inte, så det är oklart vem som kommer att svara på detta fel. Och det borde aldrig hända ändå. |
vold.post_fs_data_done 0 |
Sätts av vold strax innan vold.decrypt sätts till trigger_post_fs_data . |
vold.post_fs_data_done 1 |
Sätts av init.rc eller init.rc strax efter att ha avslutat uppgiften post-fs-data . |
init properties
Property | Description |
---|---|
ro.crypto.fs_crypto_blkdev |
Inställs av vold -kommandot checkpw för senare användning av vold -kommandot restart . |
ro.crypto.state unencrypted |
Satt av init för att säga att det här systemet körs med en okrypterad /data ro.crypto.state encrypted . Ställs in av init för att säga att det här systemet körs med en krypterad /data . |
|
Dessa fem egenskaper ställs in av init när den försöker montera /data med parametrar som skickas in från init.rc . vold använder dessa för att ställa in kryptomappningen. |
ro.crypto.tmpfs_options |
Sätts av init.rc med de alternativ som init ska använda när det monterar filsystemet tmpfs /data . |