Weryfikowany rozruch wymaga weryfikacji kryptograficznej całego kodu wykonywalnego i danych, które są częścią wersji Androida uruchamianej przed użyciem. Obejmuje to jądro (wczytane z partycji boot
), drzewo urządzenia (wczytane z partycji dtbo
), partycję system
, partycję vendor
itd.
Małe partycje, takie jak boot
i dtbo
, które są odczytywane tylko raz, są zwykle weryfikowane przez załadowanie całego zawartości do pamięci i obliczenie jej wartości skrótu. Następnie obliczona wartość funkcji haszowania jest porównywana z oczekiwaną wartością funkcji haszowania. Jeśli wartości się nie zgadzają, Android nie wczyta pliku.
Więcej informacji znajdziesz w artykule Proces uruchamiania.
Większe partycje, które nie mieszczą się w pamięci (np. systemy plików), mogą używać drzewa haszowania, w którym weryfikacja jest ciągłym procesem, który odbywa się podczas wczytywania danych do pamięci. W tym przypadku skrót główny drzewa skrótów jest obliczany w czasie wykonywania i porównywany z oczekiwaną wartością skrótu głównego. Android zawiera sterownik dm-verity, który weryfikuje większe partycje. Jeśli w jakimś momencie obliczony hash root nie będzie zgodny z oczekiwaną wartością hasha roota, dane nie zostaną użyte, a Android przejdzie w stan błędu. Więcej informacji znajdziesz w artykule Uszkodzenie pliku dm-verity.
Oczekiwane wartości hasz są zwykle przechowywane na końcu lub na początku każdej zweryfikowanej partycji, w dedykowanej partycji lub w obu tych miejscach. Co ważne, te wartości skrótu są podpisane (bezpośrednio lub pośrednio) przez zaufanego głównego urzędu certyfikacji. Na przykład implementacja AVB obsługuje oba podejścia. Więcej informacji znajdziesz w artykule Weryfikacja podczas uruchamiania na Androidzie.
Ochrona przed przywróceniem
Nawet w przypadku całkowicie bezpiecznego procesu aktualizacji możliwe jest, że nietrwały exploit jądra Androida ręcznie zainstaluje starszą, bardziej podatną na ataki wersję Androida, uruchomi ją ponownie, a następnie użyje tej wersji Androida do zainstalowania trwałego exploita. W ten sposób atakujący staje się właścicielem urządzenia i może zrobić z nim wszystko, w tym wyłączyć aktualizacje.
Ochrona przed tą klasą ataków nosi nazwę Rollback Protection (ochrona przed cofaniem). Ochrona przed cofnięciem jest zwykle realizowana przez wykorzystanie pamięci z możliwością wykrycia manipulacji, aby zapisać najnowszą wersję Androida i odmówić uruchomienia Androida, jeśli jest ona starsza niż zapisana wersja. Wersje są zwykle śledzone na podstawie partycji.
Więcej informacji o tym, jak AVB obsługuje zabezpieczenia przed cofnięciem zmian, znajdziesz w pliku README.
Obsługa błędów weryfikacji
Weryfikacja może się nie udać podczas uruchamiania (np. gdy obliczony hasz na partycji boot
nie pasuje do oczekiwanego hasza) lub podczas działania (np. gdy dm-verity napotka błąd weryfikacji na partycji system
). Jeśli weryfikacja nie powiedzie się podczas uruchamiania, urządzenie nie uruchomi się, a użytkownik będzie musiał wykonać czynności mające na celu przywrócenie urządzenia.
Jeśli weryfikacja nie powiedzie się w czasie działania, proces będzie nieco bardziej skomplikowany. Jeśli urządzenie korzysta z dm-verity, powinno być skonfigurowane w trybie restart
. W trybie restart
, jeśli wystąpi błąd weryfikacji, urządzenie zostanie natychmiast ponownie uruchomione z określoną flagą wskazującą przyczynę. Bootloader powinien zauważyć ten flagę i przełączyć dm-verity na tryb błędu we/wy (eio
) i pozostać w tym trybie do momentu zainstalowania nowej aktualizacji.
Podczas uruchamiania w trybie eio
na urządzeniu wyświetla się ekran z błędem informujący użytkownika o wykryciu uszkodzenia i możliwym nieprawidłowym działaniu urządzenia. Ten ekran będzie widoczny, dopóki użytkownik go nie zamknie. W trybie eio
sterownik dm-verity nie uruchamia ponownie urządzenia, jeśli wystąpi błąd weryfikacji. Zamiast tego zwracany jest błąd EIO, a aplikacja musi obsłużyć ten błąd.
Chodzi o to, aby uruchomić narzędzie do aktualizacji systemu (aby można było zainstalować nowy system operacyjny bez błędów) lub aby użytkownik mógł przenieść jak najwięcej danych z urządzenia. Po zainstalowaniu nowego systemu operacyjnego program ładujący wykryje nowo zainstalowany system i powróci do trybu restart
.