Jak technicznie działa szyfrowanie Marshmallow?

14

Właśnie zainstalowałem Marshmallow na Nexusie 5 poprzez wypychaną aktualizację. Nie wiem, jak działa szyfrowanie. Mam dobrą wiedzę techniczną na temat szyfrowania na komputerach. Chciałbym zdobyć podobną wiedzę na temat Androida 6.

Oto co zrobiłem i jak się pomyliłem. Po przywróceniu ustawień fabrycznych ustawiłem kod PIN, a następnie zaszyfrowałem urządzenie. Podczas uruchamiania poprosił mnie o mój PIN, który był oczekiwany. Następnie usunąłem kod PIN i ponownie uruchomiłem urządzenie. Podczas uruchamiania nie prosi o podanie kodu PIN, ale urządzenie nadal zgłaszało się jako zaszyfrowane w menu ustawień. To drugie mnie dezorientuje, ponieważ spodziewałem się, że PIN odblokuje klucz deszyfrujący.

Pytania:

  • Skąd pochodzi klucz deszyfrujący w przypadku szyfrowania bez kodu PIN? Zakładam, że jest przechowywany na układzie podobnym do TPM, czy to prawda? Jeśli tak, co powstrzymuje hakera przed zażądaniem tego klucza z układu? Czy sprawdza skrót oprogramowania układowego? Coś jeszcze? Szczegóły techniczne byłyby bardzo mile widziane.
  • Czy w przypadku szyfrowania za pomocą kodu PIN jest on używany jako dodatkowy token dostępu do klucza deszyfrującego? Czy też proces odszyfrowywania działa dokładnie tak, jakby nie było kodu PIN.

TL; DL odpowiedź:

Klucz deszyfrujący jest odblokowany za pomocą wszystkich następujących elementów:

  • PIN (lub hasło itp.) Lub hasło domyślne, jeśli go nie ma
  • TEE (generator sygnatur wspierany sprzętowo, który używa kluczy, których nie można wyodrębnić)
  • Sól (łatwo dostępna, ale zapobiegająca atakom tęczowych tabel)
marcv81
źródło
Dzięki. Nawet jeśli dotyczy Lollipopa, jest to prawidłowa odpowiedź, o ile mi wiadomo. Pomyślałem, że istnieje różnica między M i L, ponieważ nie pamiętam, że mogłem skonfigurować szyfrowanie bez hasła na L lub móc usunąć mój PIN po szyfrowaniu.
marcv81,

Odpowiedzi:

15

Cytuję z Androidem Instrukcji tutaj , ale:

UWAGA:

Źródło, którego użyłem, nie jest bezpośrednio związane z Marshmallow, ale dotyczy Lollipopa i wyższych.

TL: DR

Po prostu odpowiem teraz na pytania PO. Szczegóły techniczne zostaną podane poniżej.

  1. Domyślny klucz szyfrowania pochodzi ze źródła sprzętowego (układ podobny do TPM) i domyślne hasło AOSP zdefiniowane jak default_passwordw cryptfs.cpliku źródłowym, patrz poniżej.

  2. Tak, nie tylko domyślne, ale każde hasło jest przekształcane w klucz i jest przechowywane na chipie podobnym do TPM, zwanym TEE (skrót od „Trusted Execution Environment”, dalsze szczegóły znajdują się poniżej).

  3. Haker z dostępem UART / JTAG do układów scalonych w SoC urządzenia może technicznie uzyskać dostęp do klucza TEE lub niestandardowe jądro może wyciec te informacje do hakera. Niektóre trzyliterowe agencje w teoriach spiskowych mogą ewentualnie współpracować z OEM, aby wykorzystać te niepewne jądra w urządzeniach produkcyjnych, ale nie postawiłbym za tym wielu sklepów. Ponownie zapoznaj się z ostatnią sekcją tej odpowiedzi, aby uzyskać dodatkowe informacje.

Jedyną rzeczą, która powstrzymuje hakera przed uzyskaniem dostępu do klucza, jest sama ilość wysiłku wymaganego do tego.

  1. Sprawdzanie skrótu (sumowania) oprogramowania układowego (nazywanego przez Google „Verified Boot” ) jest w rzeczywistości domyślnie wykonywane na Lollipop i powyżej (i jest dostępne od JellyBean 4.3), przez moduł jądra o nazwie dm-verity. Jest to jednak niezależne od statusu szyfrowania.

Źródło: Przewodnik bezpieczeństwa AOSP tutaj .

  1. Informacje o procesie odszyfrowywania systemu za pomocą niestandardowego hasła można znaleźć poniżej. Po prostu powiem ci tutaj, że hasło użytkownika jest zaangażowane zarówno w tworzenie, jak i używanie klucza szyfrowania.

Przegląd

Przy pierwszym uruchomieniu urządzenie tworzy losowo wygenerowany 128-bitowy klucz główny, a następnie hashuje go domyślnym hasłem i zapisaną solą. Domyślne hasło to: „default_password” Jednak wynikowy skrót jest także podpisywany przez TEE (taki jak TrustZone), który używa skrótu podpisu do szyfrowania klucza głównego.

Domyślne hasło można znaleźć w projekcie cryptfs.c w systemie Android Open Source pliku .

Gdy użytkownik ustawi kod PIN / hasło lub hasło w urządzeniu, tylko klucz 128-bitowy jest ponownie szyfrowany i zapisywany. (tj. zmiany kodu PIN / hasła / wzoru użytkownika NIE powodują ponownego szyfrowania partycji danych użytkownika).

Uruchamianie zaszyfrowanego urządzenia z domyślnym szyfrowaniem

Tak dzieje się, gdy uruchamiasz zaszyfrowane urządzenie bez hasła. Ponieważ urządzenia z Androidem 5.0 są szyfrowane przy pierwszym uruchomieniu, nie powinno być ustawionego hasła i dlatego jest to domyślny stan szyfrowania.

  1. Wykryj zaszyfrowane / dane bez hasła

Wykryj, że urządzenie z Androidem jest szyfrowane, ponieważ nie można zamontować danych / jednej z flag encryptablelubforceencrypt jest ustawiony.

voldustawia vold.decryptna trigger_default_encryption, co uruchamia defaultcryptousługę. trigger_default_encryptionsprawdza typ szyfrowania, aby sprawdzić, czy / dane są szyfrowane za pomocą hasła lub bez niego.

  1. Odszyfruj / dane

Tworzy dm-crypturządzenie na urządzeniu blokowym, aby urządzenie było gotowe do użycia.

  1. Mount / data

voldnastępnie montuje odszyfrowaną partycję real / data, a następnie przygotowuje nową partycję. Ustawia właściwość vold.post_fs_data_donena, 0a następnie ustawia vold.decryptna trigger_post_fs_data. To powoduje init.rcuruchomienie post-fs-datapoleceń. Utworzą wszystkie niezbędne katalogi lub łącza, a następnie ustawią vold.post_fs_data_donena 1.

Po voldwidzi 1 w tej nieruchomości, to ustawia właściwość vold.decryptdo: trigger_restart_framework. Powoduje init.rcto mainponowne uruchomienie usług w klasie, a także uruchomienie usług w klasie late_start po raz pierwszy od rozruchu.

  1. Uruchom framework

Teraz framework uruchamia wszystkie swoje usługi przy użyciu odszyfrowanych danych / i system jest gotowy do użycia.

Uruchamianie zaszyfrowanego urządzenia bez domyślnego szyfrowania

Tak dzieje się, gdy uruchamiasz zaszyfrowane urządzenie, które ma ustawione hasło. Hasło urządzenia może być kodem PIN, wzorem lub hasłem.

  1. Wykryj zaszyfrowane urządzenie za pomocą hasła

Wykryj, że urządzenie z Androidem jest szyfrowane, ponieważ flaga ro.crypto.state = "encrypted"

voldustawia się vold.decryptna, trigger_restart_min_frameworkponieważ / dane są szyfrowane hasłem.

  1. Zamontuj tmpfs

initustawia pięć właściwości, aby zapisać początkowe opcje montowania podane dla / data z parametrami przekazanymi z init.rc. voldużywa tych właściwości do skonfigurowania mapowania kryptograficznego:

ro.crypto.fs_type

ro.crypto.fs_real_blkdev

ro.crypto.fs_mnt_point

ro.crypto.fs_options

ro.crypto.fs_flags (8-cyfrowy numer szesnastkowy ASCII poprzedzony przez 0x)

  1. Uruchom framework, aby poprosić o hasło

Framework uruchamia się i widzi, że vold.decryptjest ustawiony na trigger_restart_min_framework. Mówi to ramie, że uruchamia się natmpfs /data dysku i musi uzyskać hasło użytkownika.

Najpierw jednak musi się upewnić, że dysk został poprawnie zaszyfrowany. Wysyła polecenie cryptfs cryptocompletedo vold. voldzwraca 0, jeśli szyfrowanie zakończyło się pomyślnie, -1 w przypadku błędu wewnętrznego lub -2, jeśli szyfrowanie nie zostało zakończone pomyślnie. voldokreśla to, wyszukując metadane krypto dlaCRYPTO_ENCRYPTION_IN_PROGRESS flagi. Jeśli jest ustawiony, proces szyfrowania został przerwany i na urządzeniu nie ma dostępnych danych.

Jeśli voldzwróci błąd, interfejs użytkownika powinien wyświetlać użytkownikowi komunikat o konieczności ponownego uruchomienia i przywrócenia ustawień fabrycznych urządzenia oraz dać użytkownikowi przycisk do naciśnięcia, aby to zrobić.

  1. Odszyfruj dane za pomocą hasła

Po cryptfs cryptocompletepomyślnym zakończeniu środowisko wyświetla interfejs użytkownika z prośbą o hasło do dysku. Kontrole UI hasło wysyłając polecenia cryptfs checkpwdo vold. Jeśli hasło jest prawidłowe (co jest określane przez pomyślne zamontowanie odszyfrowanego /dataw tymczasowej lokalizacji, a następnie odmontowanie go), vold zapisuje nazwę odszyfrowanego urządzenia blokowego we właściwości ro.crypto.fs_crypto_blkdevi zwraca status 0 do interfejsu użytkownika. Jeśli hasło jest niepoprawne, zwraca -1 do interfejsu użytkownika.

  1. Zatrzymaj framework

Interfejs użytkownika wyświetla kryptograficzną grafikę rozruchową, a następnie wywołuje komendę vold cryptfs restart. voldustawia właściwość vold.decryptdo trigger_reset_main, co powoduje init.rczrobić class_reset main. To zatrzymuje wszystkie usługi w mainklasie, co pozwala na tmpfs /dataodmontowanie.

  1. Mount / data

voldnastępnie montuje odszyfrowaną /datapartycję rzeczywistą i przygotowuje nową partycję (która mogła nigdy nie zostać przygotowana, jeśli została zaszyfrowana opcją czyszczenia, która nie jest obsługiwana w pierwszej wersji). Ustawia właściwość vold.post_fs_data_donena, 0a następnie ustawia vold.decryptna trigger_post_fs_data. To powoduje init.rcjego uruchomienie post-fs-data commands. Utworzą wszystkie niezbędne katalogi lub łącza, a następnie ustawią vold.post_fs_data_donena 1. Gdy voldzobaczysz 1w tej właściwości, ustawia właściwość vold.decryptna trigger_restart_framework. Powoduje init.rcto mainponowne uruchomienie usług w klasie, a także uruchomienie usług w klasie late_startpo raz pierwszy od rozruchu.

  1. Rozpocznij pełne środowisko

Teraz platforma uruchamia wszystkie swoje usługi przy użyciu odszyfrowanego systemu plików / danych, a system jest gotowy do użycia.

Przechowywanie zaszyfrowanego klucza

Zaszyfrowany klucz jest przechowywany w metadanych kryptograficznych. Tworzenie kopii zapasowych sprzętu jest realizowane za pomocą funkcji podpisywania w środowisku Trusted Execution Environment (TEE). Wcześniej szyfrowaliśmy klucz główny za pomocą klucza generowanego przez zastosowanie scrypthasła użytkownika i przechowywanej soli.

Aby uczynić klucz odpornym na ataki z pudełka, rozszerzamy ten algorytm, podpisując wynikowy klucz przechowywanym kluczem TEE. Otrzymana sygnatura jest następnie zamieniana na klucz o odpowiedniej długości przez kolejne zastosowanie scrypt. Ten klucz jest następnie używany do szyfrowania i deszyfrowania klucza głównego. Aby przechowywać ten klucz:

  1. Wygeneruj losowy 16-bajtowy klucz szyfrowania dysku (DEK) i 16-bajtową sól.
  2. Zastosuj scryptdo hasła użytkownika i soli, aby utworzyć 32-bajtowy klucz pośredni 1 (IK1).
  3. Wypełnij IK1 zerowymi bajtami do wielkości klucza prywatnego powiązanego ze sprzętem (HBK). W szczególności wpisujemy jako: 00 || IK1 || 00..00; jeden bajt zerowy, 32 bajty IK1, 223 bajty zerowe.
  4. Znak wyściełany IK1 z HBK, aby uzyskać 256-bajtowy IK2.
  5. Zastosuj scryptdo IK2 i soli (ta sama sól co w kroku 2), aby utworzyć 32-bajtowy IK3.
  6. Użyj pierwszych 16 bajtów IK3 jako KEK, a ostatnich 16 bajtów jako IV.
  7. Zaszyfruj DEK za pomocą AES_CBC, za pomocą klucza KEK i wektora inicjalizacji IV.
Tamoghna Chowdhury
źródło
Co z Androidem N? Koledzy założyli, że szyfrowanie w systemie Android 7 jest słabsze, ponieważ start urządzenia nie jest chroniony jak wcześniej, a zatem atakujący mógłby mieć łatwiej niż wcześniej, czy uważasz, że to prawda?
David,
@David, który wykracza poza zakres tego pytania, zadaj inne pytanie na temat Androida Nougat.
Tamoghna Chowdhury,
Jak mogę odszyfrować partycję DATA w trybie odzyskiwania? via init.recovery. <ro.hardware> .rc
Benny
@Benny, proszę zadać właściwe pytanie na ten temat
Tamoghna Chowdhury,