Wdrażanie DM-verity

Android 4.4 i nowsze obsługują weryfikację podczas uruchamiania funkcji jądra device-mapper-verity (dm-verity), która zapewnia sprawdzanie integralności blokowanych urządzeń. DM-verity pomaga zapobiegać trwałym rootkitom który może zachować uprawnienia roota i naruszać urządzenia. Ten pomaga użytkownikom Androida mieć pewność, że podczas uruchamiania urządzenia jest to to samo w takiej postaci, w jakiej była ostatnio używana.

Potencjalnie szkodliwe aplikacje z uprawnieniami administratora mogą się ukrywać przed lub w inny sposób zamaskować się. Oprogramowanie do roota może Dzieje się tak, ponieważ często mają one większe uprawnienia niż detektory, oprogramowanie „kłamstwa” programy wykrywające.

Funkcja DM-Verity pozwala przyjrzeć się urządzeniu blokowemu, czyli bazowej pamięci masowej. warstwa systemu plików i określić, czy jest ona zgodna z oczekiwaniami konfiguracji. Służy do tego kryptograficzne drzewo haszujące. Dla każdego bloku (zwykle 4k), jest dostępny hasz SHA256.

Ponieważ wartości hash są przechowywane w drzewie stron, tylko tagi najwyższego poziomu „root” hasz musi być zaufany w celu weryfikacji reszty drzewa. Zdolność do modyfikowanie dowolnego z bloków byłoby równoważne złamaniu skrótu kryptograficznego. Poniższy schemat przedstawia tę strukturę.

tabela z haszowaniem-dm-werity

Rysunek 1. Tabela haszująca dm-verity

partycja rozruchowa zawiera klucz publiczny, który musi zostać zweryfikowany. przez producenta urządzenia. Ten klucz jest używany do weryfikacji podpisu dla tego hasza i potwierdzić, że partycja systemowa urządzenia jest chroniona bez zmian.

Operacja

W jądrze działa ochrona dm-verity. Jeśli więc oprogramowanie roota zaatakuje system zachowa dostęp do systemu. Aby temu zaradzić większość producentów weryfikuje jądro za pomocą klucza wypalonego w urządzeniu. Po wyjściu urządzenia z fabryki nie można zmienić tego kluczyka.

Producenci używają tego klucza do weryfikowania podpisu na pierwszym poziomie. program rozruchowy, który z kolei weryfikuje podpis na kolejnych poziomach, w programie rozruchowym aplikacji, a ostatecznie w jądrze. Każdy producent chcący korzystać ze zweryfikowanych rozruch powinien obejmować metodę weryfikacji integralności jądra systemu. Jeśli jądro zostało zweryfikowane, może sprawdzać urządzenie blokowe i sprawdź, czy został zamontowany.

Jednym ze sposobów weryfikacji urządzenia blokowego jest bezpośrednie zaszyfrowanie jego zawartości i porównanie do wartości przedpłaconej. Jednak próba zweryfikowania całego urządzenia blokowego może przez dłuższy czas i zużywają dużo energii. Urządzenia zajęłyby przez długi czas uruchamiania, a następnie znacznie się rozładowuje przed użyciem.

Zamiast tego usługa DM-verity weryfikuje bloki pojedynczo i tylko wtedy, gdy dostęp. Podczas odczytu do pamięci blok jest równolegle szyfrowany. Hasz to i weryfikowanie drzewa. A ponieważ czytanie tych informacji jest tak kosztowne, , czas oczekiwania związany z weryfikacją na poziomie bloku wynosi raczej nominalny.

Jeśli weryfikacja się nie powiedzie, urządzenie wygeneruje błąd wejścia-wyjścia, który wskazuje blok. nie można odczytać. Wygląda na to, że system plików jest uszkodzony. nie jest oczekiwany.

Aplikacje mogą kontynuować pracę bez danych wynikowych, na przykład kiedy te wyniki nie są wymagane dla głównej funkcji aplikacji. Pamiętaj jednak: jeśli aplikacja nie będzie mogła kontynuować pracy bez tych danych, zakończy się niepowodzeniem.

Przekaż dalej korektę błędu

Android 7.0 lub nowszy poprawia niezawodność dm-verity w przypadku błędu przekazywania korekty (FEC). Implementacja AOSP rozpoczyna się od wspólnego tagu Reed-Solomon poprawiający błędy i stosuje technikę zwaną przeplatywaniem, aby zmniejszyć iloraz danych i zwiększyć liczbę uszkodzonych bloków, które można odzyskać. Więcej informacji o FEC znajdziesz na stronie ściśle wymuszana weryfikacja podczas uruchamiania z korektą błędów;

Implementacja

Podsumowanie

  1. Wygeneruj obraz systemu ext4.
  2. Wygeneruj drzewo haszujące dla tego obrazu.
  3. Utwórz tabelę dm-verity dla tego drzewa haszu.
  4. Podpisz tabelę dm-verity, aby wygenerować tabelę. podpis.
  5. Łączenie w pakiety podpisu tabeli i tabeli dm-verity do metadanych prawdziwości.
  6. Połącz obraz systemu, metadane weryfikacji i drzewo haszu.

Zapoznaj się z artykułem Projekty Chromium – weryfikacja podczas uruchamiania. gdzie znajdziesz szczegółowy opis drzewa haszowania i tabeli dm-verity.

Generowanie drzewa skrótu

Jak opisano we wprowadzeniu, drzewo skrótu jest integralną częścią dm-verity. narzędzie cryptsetup za pomocą którego można wygenerować drzewo skrótu. Zgodny jest też tutaj zdefiniowany:

<your block device name> <your block device name> <block size> <block size> <image size in blocks> <image size in blocks + 8> <root hash> <salt>

Aby utworzyć hasz, obraz systemu w warstwie 0 jest dzielony na 4 tys. bloków, z których każdy ma przypisany hasz SHA256. Warstwa 1 jest tworzona przez łączenie tylko tych haszów SHA256. do formatu 4K bloków, uzyskując w ten sposób znacznie mniejszy obraz. Powstała warstwa 2 z zaszyfrowanymi SHA256 warstwy 1.

Jest to możliwe, dopóki hasze SHA256 poprzedniej warstwy nie zmieszczą się w jednym miejscu. blokować. Po otrzymaniu skrótu SHA256 tego bloku otrzymasz hasz główny drzewa.

Rozmiar drzewa haszu (i odpowiadającego mu wykorzystanie miejsca na dysku) różni się w zależności od rozmiaru zweryfikowanej partycji. W praktyce rozmiar drzewa haszującego zwykle wynosi małe, często poniżej 30 MB.

Jeśli w warstwie znajduje się bryła, która nie jest całkowicie wypełniona naturalnie przez z poprzedniej warstwy, musisz wypełnić ją zerami, aby uzyskać oczekiwany 4K. Dzięki temu będziesz wiedzieć, że drzewo skrótu nie zostało usunięte i jest uzupełniono o puste dane.

Aby wygenerować drzewo haszowania, połącz hasze warstwy 2 z tymi, które są powiązane z warstwą. 1, w warstwie 3 hasze są przekazywane do warstwy 2 itd. Napisz wszystko na dysk. Zwróć uwagę, że nie odnosi się to do warstwy 0 skrótu głównego.

Podsumowując, ogólny algorytm tworzenia drzewa haszującego wygląda tak:

  1. Wybierz losową sól (kodowanie szesnastkowe).
  2. Rozdziel obraz systemu na bloki 4K.
  3. Dla każdego bloku pobierz jego (z zaburzaniem) hasz SHA256.
  4. Połącz te hasze, aby utworzyć poziom
  5. Dodaj do poziomu 0 s do granicy bloku 4K.
  6. Połącz poziom z drzewem haszu.
  7. Powtarzaj kroki 2–6, używając poprzedniego poziomu jako źródła dla następnego, aż masz tylko jeden hasz.

Wynikiem tego działania jest pojedynczy hasz, który jest haszem głównym. To i Twoja sól są używane podczas tworzenia tabeli mapowania DCM.

Tworzę tabelę mapowania DSM-verity

Utwórz tabelę mapowania dm-verity, która identyfikuje urządzenie blokujące (lub miejsce docelowe). dla jądra i lokalizację drzewa haszu (to ta sama wartość). Ten mapowanie jest używane do generowania i uruchamiania fstab. Tabela określa też, rozmiar bloków oraz element hash_start, lokalizacja początkowa drzewa haszowania; (zwłaszcza jego numer bloku od początku zdjęcia).

Zobacz konfigurację kryptografii dla szczegółowy opis pól tabeli mapowania wartości docelowej

Podpisywanie tabeli DS-verity

Podpisz tabelę dm-verity, aby utworzyć podpis tabeli. Podczas weryfikacji partycjonowanie, podpis tabeli jest najpierw weryfikowany. Jest to wykonywane w przypadku klucza na obraz rozruchowy w stałym miejscu. Klucze są zwykle zawarte w sekcji producentów systemów do automatycznego umieszczania na urządzeniach lokalizacji.

Aby zweryfikować partycję za pomocą tej kombinacji podpisu i klucza:

  1. Dodaj klucz RSA-2048 w formacie zgodnym z libmincrypt /boot partycja o /verity_key. Określ lokalizację klucza używanego do weryfikacji drzewo hasza.
  2. W obszarze fstab odpowiedniego wpisu dodaj verify do flag fs_mgr.

Łączenie podpisu tabeli z metadanymi

Połącz podpis tabeli i tabelę dm-verity w metadanych dotyczących weryfikacji. Całość blok metadanych jest objęty wersjami, więc można go rozszerzyć, na przykład dodać dodać podpis lub zmienić kolejność.

W ramach kontroli z każdym zestawem metadanych tabeli kojarzona jest magiczna liczba i łatwiej zidentyfikować tabelę. Ponieważ długość jest podawana w systemie ext4 w nagłówku obrazu, umożliwia wyszukiwanie metadanych bez wiedzy treści danych.

Dzięki temu możesz się upewnić, że nie została wybrana opcja weryfikacji niezweryfikowanej partycji. Jeśli tak, brak tej magicznej liczby spowoduje przerwanie procesu weryfikacji. Ten numer przypomina:
0xb001b001

Wartości bajtów w formacie szesnastkowym:

  • pierwszy bajt = b0
  • drugi bajt = 01
  • trzeci bajt = b0
  • czwarty bajt = 01

Poniższy diagram przedstawia zestawienie metadanych dotyczących wiarygodności:

<magic number>|<version>|<signature>|<table length>|<table>|<padding>
\-------------------------------------------------------------------/
\----------------------------------------------------------/   |
                            |                                  |
                            |                                 32K
                       block content

Te pola metadanych są opisane w tabeli.

Tabela 1. Pola metadanych Verity

Pole Cel Rozmiar Wartość
magiczna liczba używane przez fs_mgr do sprawdzenia poprawności 4 bajty 0xb001b001
Wersja używane do wersji bloku metadanych 4 bajty obecnie 0
podpis podpis tabeli w formie dopełnionej PKCS1.5 256 bajtów
długość tabeli długość tabeli dm-verity w bajtach 4 bajty
stół opisana wcześniej tabela dm-verity Długość tabeli (bajty)
padding ta struktura jest dopełniona do 32 kB długości 0

Optymalizuję dm-verity

Aby uzyskać najlepszą wydajność przy użyciu DSM:

  • W jądrze włącz NEON SHA-2 dla ARMv7 i SHA-2 dla architektur ARMv8.
  • Eksperymentuj z różnymi funkcjami odczytu z wyprzedzeniem i prefetch_cluster ustawień, aby znaleźć najlepszą konfigurację dla urządzenia.