Criptarea integrală a discului este procesul de codificare a tuturor datelor utilizatorului pe un dispozitiv Android folosind o cheie criptată. Odată ce un dispozitiv este criptat, toate datele create de utilizator suntcriptate automat înainte de a le trimite pe disc și toate datele citite sunt decriptate automat înainte de a le returna procesului de apelare.
Criptarea completă a discului a fost introdusă în Android în versiunea 4.4, dar Android 5.0 a introdusaceste noi caracteristici:
- Criptare rapidă creată, care criptează numai blocurile utilizate pe partiția de datepentru a evita ca prima pornire să dureze mult timp. Doar sistemele de fișiere ext4 și f2fssusțin în prezent criptarea rapidă.
- A adăugat steagul
forceencryptfstab pentru a cripta la prima pornire. - A adăugat suport pentru modele și criptare fără parolă.
- A adăugat stocarea cu suport hardware a cheii de criptare folosind capacitatea de semnare a Trusted Execution Environment (TEE) (cum ar fi într-o TrustZone). Consultați Stocarea cheii de criptare pentru mai multe detalii.
Atenție: Dispozitivele actualizate la Android 5.0 și apoi criptate pot fi readuse la o stare necriptată prin resetarea datelor din fabrică. Dispozitivele noi cu Android 5.0criptate la prima pornire nu pot fi readuse la o stare necriptată.
- Cum funcționează criptarea completă a discului Android
- Fluxuri
- Criptarea unui dispozitiv nou cu forceencrypt
- Criptarea unui dispozitiv existent
- Începutul unui dispozitiv criptat cu criptare implicită
- Începerea unui dispozitiv criptat fără criptare implicită
- Eșec
- Stocarea cheii criptate
- Schimbarea parolei
- Proprietăți de criptare
- Proprietăți de criptare
- init proprietăți
- Acțiuni init
Cum funcționează criptarea completă a discului Android
Criptarea completă a discului Android se bazează pe dm-crypt, care este o caracteristică a nucleului care funcționează la nivelul dispozitivului de bloc. Din acest motiv, criptarea funcționează cu Embedded MultiMediaCard (eMMC) șidispozitive flash similare care se prezintă în fața nucleului ca dispozitive de tip bloc. Criptarea nu este posibilă cu YAFFS, care vorbește direct cu un cip flash NAND brut.
Algoritmul de criptare este 128 Advanced Encryption Standard (AES) cu înlănțuire de blocuri de cifru (CBC) și ESSIV:SHA256. Cheia principală este criptată cu AES pe 128 de biți prin apeluri la biblioteca OpenSSL. Trebuie să folosiți 128 de biți sau mai mult pentru cheie (256 fiind opțional).
Nota: OEM-urile pot folosi 128 de biți sau mai mult pentru a cripta cheia principală.
În versiunea Android 5.0, există patru tipuri de stări de criptare:
- default
- PIN
- parolă
- pattern
La prima pornire, dispozitivul creează o cheie principală de 128 de biți generată aleatoriuși apoi o criptează cu o parolă implicită și o sare stocată. Parola implicită este: „default_password „Cu toate acestea, hash-ul rezultat este, de asemenea, semnat prin intermediul unui TEE (cum ar fi TrustZone), care utilizează un hash al semnăturii pentru a cripta cheia principală.
Puteți găsi parola implicită definită în fișierul cryptfs.cpp al proiectului Android Open Source Project.
Când utilizatorul setează PIN-ul/passul sau parola pe dispozitiv, numai cheia de 128 de biți este recriptată și stocată. (adică modificările de PIN/pașaport/model ale utilizatorului NU cauzează re-criptarea datelor utilizatorului.) Rețineți că dispozitivele gestionate pot face obiectul unor restricții de PIN, model sau parolă.
Criptarea este gestionată de init și vold.init apelează vold, iar vold stabilește proprietăți pentru a declanșa evenimente în init. Alte părți ale sistemului se uită, de asemenea, la proprietăți pentru a efectua sarcini cum ar fi raportarea stării, solicitarea unei parole sau solicitarea de resetare din fabrică în cazul unei erori fatale. Pentru a invoca caracteristicile de criptare din vold, sistemul utilizează comenzile cryptfs ale instrumentului de linie de comandăvdc: checkpw,restart, enablecrypto, changepw,cryptocomplete, verifypw, setfield,getfield, mountdefaultencrypted, getpwtype,getpw și clearpw.
Pentru a cripta, decripta sau șterge /data, /datanu trebuie să fie montat. Cu toate acestea, pentru a afișa orice interfață cu utilizatorul (UI), cadrul trebuie să pornească, iar cadrul necesită ca /data să funcționeze. Pentru a rezolva această enigmă, un sistem de fișiere temporar este montat pe /data.Acest lucru îi permite lui Android să solicite parole, să afișeze progresul sau să sugereze o ștergere de date, după caz. Aceasta impune însă limitarea că, pentru a trece de la sistemul de fișiere temporar la adevăratul sistem de fișiere /data, sistemul trebuie să oprească fiecare proces cu fișiere deschise pe sistemul de fișiere temporar și să repornească aceste procese pe adevăratul sistem de fișiere /data. Pentru a face acest lucru, toate serviciile trebuie să fie într-unul din cele trei grupuri: core, main șilate_start.
-
core: Nu se oprește niciodată după pornire. -
main: Se opresc și apoi repornesc după introducerea parolei de disc. -
late_start: Nu pornește decât după ce/dataa fost decriptat și montat.
Pentru a declanșa aceste acțiuni, proprietatea vold.decrypt este setată pe diferite șiruri de caractere. pentru a opri și reporni serviciile, comenzile init sunt:
-
class_reset: Oprește un serviciu, dar permite repornirea lui cu class_start. -
class_start: Repornește un serviciu. -
class_stop: Oprește un serviciu și adaugă un indicatorSVC_DISABLED. Serviciile oprite nu răspund laclass_start.
Fluxuri
Există patru fluxuri pentru un dispozitiv criptat. Un dispozitiv este criptat doar o singură datăși apoi urmează un flux normal de pornire.
- Criptează un dispozitiv necriptat anterior:
- Criptează un dispozitiv nou cu
forceencrypt: Criptare obligatorie la prima pornire (începând cu Android L). - Criptarea unui dispozitiv existent: Criptare inițiată de utilizator (Android K și versiunile anterioare).
- Criptează un dispozitiv nou cu
- Încearcă un dispozitiv criptat:
- Demararea unui dispozitiv criptat fără parolă: Pornirea unui dispozitiv criptat care nu are o parolă setată (relevant pentru dispozitivele cu Android 5.0 și ulterior).
- Starting an encrypted device with a password: Booting an encrypted device that has a set password.
În plus față de aceste fluxuri, dispozitivul poate, de asemenea, să nu reușească să cripteze /data.Fiecare dintre fluxuri este explicat în detaliu mai jos.
Criptarea unui dispozitiv nou cu forceencrypt
Aceasta este prima pornire normală pentru un dispozitiv Android 5.0 dispozitiv.
- Detectează sistemul de fișiere necriptat cu steagul
forceencrypt/datanu este criptat, dar trebuie să fie pentru căforceencrypto impune.demontează/data. - Începeți criptarea
/datavold.decrypt = "trigger_encryption"declanșeazăinit.rc,ceea ce va face cavoldsă cripteze/datafără parolă.(None este setat pentru că acesta ar trebui să fie un dispozitiv nou.) - Mount tmpfs
voldmontează un tmpfs/data(folosind opțiunile tmpfs dinro.crypto.tmpfs_options) și setează proprietateavold.encrypt_progressla 0.voldpregătește tmpfs-ul/datapentru pornirea unui sistem criptat și setează proprietateavold.decryptla:trigger_restart_min_framework - Aduceți cadrul pentru a arăta progresul
Pentru că dispozitivul nu are practic nici un fel de date de criptat, bara de progres deseori nu va apărea de fapt, deoarece criptarea are loc foarte repede. ConsultațiCriptarea unui dispozitiv existent pentru mai multe detalii despre interfața de progres.
- Când
/dataeste criptat, scoateți cadrulvoldseteazăvold.decryptlatrigger_default_encryptioncare pornește serviciuldefaultcrypto. (Aceasta pornește fluxul de mai jos pentru montarea unor date de utilizator criptate adefault.)trigger_default_encryptionverifică tipul de criptare pentru a vedea dacă/dataeste criptat cu sau fără parolă. Deoarece dispozitivele Android 5.0 sunt criptate la prima pornire, nu ar trebui să fie setată nici o parolă; prin urmare, decriptăm și montăm/data. - Mount
/datainitapoi montează/datape un RAMDisk tmpfs folosind parametrii pe care îi preia de laro.crypto.tmpfs_options, care este setat îninit.rc. - Start framework
Stabilește
voldlatrigger_restart_framework, carecontinuă procesul obișnuit de pornire.
Criptarea unui dispozitiv existent
Acesta este ceea ce se întâmplă când criptați un dispozitiv Android K sau anterior necriptat care a fost migrat la L.
Acest proces este inițiat de utilizator și este denumit în cod „criptare in situ”. Când un utilizator selectează să cripteze un dispozitiv, interfața de utilizare se asigură că bateria este complet încărcată și că adaptorul de curent alternativ este conectat, astfel încât să existe suficientă putere pentru a finaliza procesul de criptare.
Atenție: Dacă dispozitivul rămâne fără energie și se oprește înainte de a termina criptarea, datele fișierelor rămân într-o stare parțial criptată. Dispozitivul trebuie să fie resetat din fabrică și toate datele sunt pierdute.
Pentru a activa criptarea pe loc, vold pornește o buclă pentru a citi fiecare sector al dispozitivului de bloc real și apoi îl scrie în dispozitivul de bloc criptografic. vold verifică dacă un sector este în uz înainte de a-l citi și scrie, ceea ce face ca criptarea să fie mult mai rapidă pe un dispozitiv nou care are puține sau deloc date.
Starea dispozitivului: Setați ro.crypto.state = "unencrypted"și executați on nonencrypted init declanșatorul on nonencrypted init pentru a continua pornirea.
- Verificați parola
Interfața de utilizator apelează
voldcu comandacryptfs enablecrypto inplaceundepasswdeste parola ecranului de blocare a utilizatorului. - Scoateți cadrul
voldverifică dacă există erori, returnează -1 dacă nu poate cripta și tipărește un motiv în jurnal. Dacă poate cripta, setează proprietateavold.decryptlatrigger_shutdown_framework. Acest lucru face cainit.rcsă oprească serviciile din claselelate_startșimain. - Creează un subsol de criptare
- Creează un fișier breadcrumb
- Reboot
- Detectă fișierul breadcrumb
- Începe să cripteze
/datavold, apoi setează corespondența de criptare, care creează un dispozitiv de bloc criptografic virtual care se mapează pe dispozitivul de bloc real, dar criptează fiecare sector pe măsură ce este scris și decriptează fiecare sector pe măsură ce este citit.voldapoi creează și scrie metadatele criptografice. - În timp ce criptează, mount tmpfs
voldmontează un tmpfs/data(folosind opțiunile tmpfs de laro.crypto.tmpfs_options) și setează proprietateavold.encrypt_progressla 0.voldpregătește tmpfs/datapentru pornirea unui sistem criptat și setează proprietateavold.decryptla:trigger_restart_min_framework - Aduceți cadrul pentru a arăta progresul
trigger_restart_min_frameworkcauzeazăinit.rcsă pornească clasa de serviciimain. Când cadrul vede căvold.encrypt_progresseste setat la 0, aduce la suprafață bara de progresUI, care interoghează această proprietate la fiecare cinci secunde și actualizează o bară de progres.Bucla de criptare actualizeazăvold.encrypt_progressde fiecare dată când criptează încă un procent din partiție. - Când
/dataeste criptat, actualizează subsolul criptoCând
/dataeste criptat cu succes,voldșterge stegulețulENCRYPTION_IN_PROGRESSdin metadate.Când dispozitivul este deblocat cu succes, parola este apoi utilizată pentru a cripta cheia principală și se actualizează subsolul criptografic.
Dacă repornirea eșuează din anumite motive,
voldsetează proprietateavold.encrypt_progresslaerror_reboot_failed, iar interfața de utilizare ar trebui să afișeze un mesaj prin care se cere utilizatorului să apese un buton pentru a reporni. Nu se așteaptă ca acest lucru să se întâmple vreodată.
Începutul unui dispozitiv criptat cu criptare implicită
Aceasta este ceea ce se întâmplă atunci când porniți un dispozitiv criptat fără parolă.Deoarece dispozitivele Android 5.0 sunt criptate la prima pornire, nu ar trebui să existe nici un setpassword și, prin urmare, aceasta este starea de criptare implicită.
- Detectează
/datacriptat/datafără parolăDetectați că dispozitivul Android este criptat deoarece
/datanu poate fi montat și unul dintre stegulețeleencryptablesauforceencrypteste setat.voldSeteazăvold.decryptlatrigger_default_encryption, care pornește serviciuldefaultcrypto.trigger_default_encryptionverifică tipul de criptare pentru a vedea dacă/dataeste criptat cu sau fără parolă. - Decrypt /data
Creează dispozitivul
dm-cryptpeste dispozitivul de bloc, astfel încât dispozitivul este gata de utilizare. - Mount /data
voldapoi montează partiția reală/datadecriptată și apoi pregătește noua partiție. Setează proprietateavold.post_fs_data_donela 0 și apoi seteazăvold.decryptlatrigger_post_fs_data. Acest lucru face cainit.rcsă execute comenzilepost-fs-data. Acestea vor crea toate directoarele sau legăturile necesare și apoi vor setavold.post_fs_data_donela 1.După ce
voldvede 1 în această proprietate, stabilește proprietateavold.decryptla:trigger_restart_framework.Acest lucru face cainit.rcsă pornească din nou serviciile din clasamainși, de asemenea, să pornească serviciile din clasalate_startpentru prima dată de la pornire. - Start framework
Acum framework-ul pornește toate serviciile sale folosind
/datadecriptat,iar sistemul este gata de utilizare.
Începerea unui dispozitiv criptat fără criptare implicită
Aceasta se întâmplă când porniți un dispozitiv criptat care are o parolă setată. Parola dispozitivului poate fi un pin, un model sau o parolă.
- Detectează dispozitivul criptat cu o parolă
Detectează că dispozitivul Android este criptat deoarece steagul
ro.crypto.state = "encrypted"voldseteazăvold.decryptlatrigger_restart_min_frameworkdeoarece/dataestecriptat cu o parolă. - Montează tmpfs
initsetează cinci proprietăți pentru a salva opțiunile inițiale de montare date pentru/datacu parametrii trecuți de lainit.rc.voldutilizează aceste proprietăți pentru a configura maparea criptografică:-
ro.crypto.fs_type -
ro.crypto.fs_real_blkdev -
ro.crypto.fs_mnt_point -
ro.crypto.fs_options -
ro.crypto.fs_flags(număr hexagonal ASCII de 8 cifre precedat de 0x)
-
- Pornește cadrul pentru a solicita parola
Cadrul pornește și vede că
vold.decrypteste setat latrigger_restart_min_framework. Acest lucru îi spune cadrului că pornește pe un disc tmpfs/datași că trebuie să obțină parola utilizatorului.În primul rând, însă, trebuie să se asigure că discul a fost criptat corespunzător. Aceasta trimite comanda
cryptfs cryptocompletelavold.voldreturnează 0 dacă criptarea a fost finalizată cu succes, -1 la o eroare internă sau-2 dacă criptarea nu a fost finalizată cu succes.volddetermină acest lucru căutând în metadatele criptografice steagulCRYPTO_ENCRYPTION_IN_PROGRESS. Dacă acesta este setat, procesul de criptare a fost întrerupt și există date care pot fi citite pe dispozitiv. Dacăvoldreturnează o eroare, interfața de utilizare ar trebui să afișeze un mesaj către utilizator pentru a reporni și a reseta din fabrică dispozitivul și să ofere utilizatorului un buton pe care să îl apese pentru a face acest lucru. - Decriptarea datelor cu parolă
După ce
cryptfs cryptocompleteare succes, cadrul afișează o interfață de utilizare care cere parola discului. UI verifică parola prin trimiterea comenziicryptfs checkpwlavold. Dacă parola este corectă (ceea ce se determină prin montarea cu succes a discului decriptat/dataîntr-o locație temporară, apoi prin demontarea acestuia),voldsalvează numele dispozitivului decriptat în bloc în proprietatearo.crypto.fs_crypto_blkdevși returnează starea 0 către UI. Dacă parola este incorectă, returnează -1 către UI. - Stop framework
UI afișează un grafic de pornire criptografic și apoi apelează
voldcu comandacryptfs restart.voldsetează proprietateavold.decryptlatrigger_reset_main, ceea ce face cainit.rcsă facăclass_reset main. Acest lucru oprește toate serviciile din clasa principală, ceea ce permite ca tmpfs/datasă fie demontat. - Mount
/datavoldmontează apoi partiția reală decriptată/datași pregătește noua partiție (care este posibil să nu fi fost niciodată pregătită dacă a fost criptată cu opțiunea wipe, care nu este suportată în prima versiune). Setează proprietateavold.post_fs_data_donela 0 și apoi seteazăvold.decryptlatrigger_post_fs_data. Acest lucru face cainit.rcsă execute comenzile salepost-fs-data. Acestea vor crea toate directoarele sau legăturile necesare și apoi vor setavold.post_fs_data_donela 1. Odată cevoldvede 1 în acea proprietate, setează proprietateavold.decryptlatrigger_restart_framework. Acest lucru face cainit.rcsă pornească din nou serviciile din clasamainși, de asemenea, să pornească serviciile din clasalate_startpentru prima dată de la pornire. - Start full framework
Acum framework-ul pornește toate serviciile sale folosind sistemul de fișiere decriptat
/data, iar sistemul este gata de utilizare.
Eșec
Un dispozitiv care nu reușește să decripteze poate fi în neregulă din câteva motive. Dispozitivulîncepe cu seria normală de pași pentru a porni:
- Detectă dispozitivul criptat cu o parolă
- Montează tmpfs
- Pornește cadrul pentru a solicita parola
Dar după ce se deschide cadrul, dispozitivul poate întâmpina unele erori:
- Parola se potrivește, dar nu poate decripta datele
- Utilizatorul introduce o parolă greșită de 30 de ori
Dacă aceste erori nu sunt rezolvate, solicită utilizatorului ștergerea din fabrică:
Dacă vold detectează o eroare în timpul procesului de criptare și dacă nu au fost distruse încă date și cadrul este în funcțiune, vold setează proprietatea vold.encrypt_progress la error_not_encrypted.UI solicită utilizatorului să repornească și îl avertizează că procesul de criptare nu a început niciodată. În cazul în care eroarea apare după ce cadrul a fost distrus, dar înainte ca bara de progres să fie ridicată, vold va reporni sistemul. În cazul în care repornirea eșuează, setează vold.encrypt_progress laerror_shutting_down și returnează -1; dar nu va exista nimic care să surprindă eroarea. Nu este de așteptat să se întâmple acest lucru.
Dacă vold detectează o eroare în timpul procesului de criptare, seteazăvold.encrypt_progress la error_partially_encryptedși returnează -1. UI ar trebui apoi să afișeze un mesaj care să spună că criptarea a eșuat și să ofere un buton pentru ca utilizatorul să reseteze dispozitivul din fabrică.
Stocarea cheii criptate
Cheia criptată este stocată în metadatele criptografice. Susținerea hardware esteimplementată prin utilizarea capacității de semnare a Trusted Execution Environment (TEE). anterior, am criptat cheia principală cu o cheie generată prin aplicarea scrypt la parola utilizatorului și la sarea stocată. Pentru a face cheia rezistentă la atacurile off-box, extindem acest algoritm prin semnarea cheii rezultate cu o cheie TEE stocată. Semnătura rezultată este apoi transformată într-o cheie de lungime corespunzătoare prin încă o aplicare a scrypt. Această cheie este apoi utilizată pentru a cripta și decripta cheia principală. Pentru a stoca această cheie:
- Generați o cheie aleatorie de criptare a discului de 16 octeți (DEK) și o sare de 16 octeți.
- Aplicați scrypt la parola utilizatorului și la sare pentru a produce cheia intermediară 1 (IK1) de 32 de octeți.
- Paduplați IK1 cu zero octeți până la dimensiunea cheii private legate de hardware (HBK). în mod specific, pad-ul este următorul: 00 || IK1 || IK1 || 00..00; un octet zero, 32 de octeți IK1, 223 de octeți zero.
- Semnul a umplut IK1 cu HBK pentru a produce IK2 de 256 de octeți.
- Aplicați scrypt la IK2 și sare (aceeași sare ca la pasul 2) pentru a produce un IK3 de 32 de octeți.
- Utilizați primii 16 octeți din IK3 ca KEK și ultimii 16 octeți ca IV.
- Criptează DEK cu AES_CBC, cu cheia KEK și vectorul de inițializare IV.
Schimbarea parolei
Când un utilizator alege să își schimbe sau să își elimine parola din setări, interfața utilizator trimite comanda cryptfs changepw la vold, iarvold recriptează cheia principală a discului cu noua parolă.
Proprietăți de criptare
vold și init comunică între ele prin stabilirea de proprietăți. Iată o listă a proprietăților disponibile pentru criptare.
Proprietăți de criptare
| Proprietate | Descriere |
|---|---|
vold.decrypt trigger_encryption |
Criptează unitatea fără parolă. |
vold.decrypt trigger_default_encryption |
Controlați unitatea pentru a vedea dacă este criptată fără parolă. dacă este, decriptați-o și montați-o, altfel setați vold.decrypt la trigger_restart_min_framework. |
vold.decrypt trigger_reset_main |
Setat de vold pentru a închide interfața utilizator care cere parola discului. |
vold.decrypt trigger_post_fs_data |
Setat de vold pentru a pregăti /data cu directoarele necesare, et al. |
vold.decrypt trigger_restart_framework |
Setat de vold pentru a porni cadrul real și toate serviciile. |
vold.decrypt trigger_shutdown_framework |
Setat de vold pentru a opri cadrul complet pentru a începe criptarea. |
vold.decrypt trigger_restart_min_framework |
Setat de vold pentru a porni bara de progres UI pentru criptare sau pentru a solicita parola, în funcție de valoarea lui ro.crypto.state. |
vold.encrypt_progress |
Când cadrul pornește, dacă această proprietate este setată, intră în modul UI al barei de progres. |
vold.encrypt_progress 0 to 100 |
Interfața UI a barei de progres trebuie să afișeze valoarea procentuală setată. |
vold.encrypt_progress error_partially_encrypted |
Unitatea de interfață a barei de progres ar trebui să afișeze un mesaj care să spună că criptarea a eșuat și să ofere utilizatorului o opțiune de resetare automată a dispozitivului. |
vold.encrypt_progress error_reboot_failed |
Unitatea de interfață a barei de progres ar trebui să afișeze un mesaj care să spună că criptarea s-a finalizat și să ofere utilizatorului un buton pentru a reporni dispozitivul. Nu se așteaptă ca această eroare să se întâmple. |
vold.encrypt_progress error_not_encrypted |
Interfața de utilizare a barei de progres ar trebui să afișeze un mesaj care să spună că s-a produs o eroare, că nu au fost criptate sau pierdute date și să ofere utilizatorului un buton pentru a reporni sistemul. |
vold.encrypt_progress error_shutting_down |
Interfața de utilizare a barei de progres nu funcționează, deci nu este clar cine va răspunde la această eroare. Și oricum nu ar trebui să se întâmple niciodată. |
vold.post_fs_data_done 0 |
Setați de vold chiar înainte de a seta vold.decrypt la trigger_post_fs_data. |
vold.post_fs_data_done 1 |
Setați de init.rc sau init.rc chiar după ce ați terminat sarcina post-fs-data. |
init proprietăți
| Proprietate | Descriere |
|---|---|
ro.crypto.fs_crypto_blkdev |
Stabilit de comanda vold checkpwpentru a fi utilizat ulterior de comanda vold restart. |
ro.crypto.state unencrypted |
Stabilit de init pentru a spune că acest sistem funcționează cu un /data ro.crypto.state encrypted necriptat. Setate de init pentru a spune că acest sistem rulează cu un /data criptat. |
|
|
Aceste cinci proprietăți sunt setate de init atunci când încearcă să monteze /data cu parametrii trecuți din init.rc. vold le folosește pentru a configura maparea criptografică. |
ro.crypto.tmpfs_options |
Stabilite de init.rc cu opțiunile pe care init ar trebui să le folosească atunci când montează sistemul de fișiere tmpfs /data. |
Acțiuni init
.