Strażnik dostępu

Podsystem Gatekeeper przeprowadza uwierzytelnianie wzoru lub hasła urządzenia w zaufanym środowisku wykonawczym (TEE). Gatekeeper rejestruje i weryfikuje hasła za pomocą obsługiwanego sprzętowo klucza tajnego. Dodatkowo Gatekeeper ogranicza liczbę kolejnych nieudanych prób weryfikacji i musi odmawiać obsługi żądań na podstawie określonego limitu czasu i określonej liczby kolejnych nieudanych prób.

Gdy użytkownicy weryfikują swoje hasła, Gatekeeper generuje token uwierzytelniania podpisany kluczem HMAC używanym podczas uruchamiania, który jest dostępny tylko dla bezpiecznych komponentów. Ten token jest wysyłany do Keystore opartego na sprzęcie. Oznacza to, że token uwierzytelniania Gatekeeper powiadamia Keystore, że klucze powiązane z uwierzytelnianiem (np. klucze utworzone przez aplikacje) mogą być używane przez aplikacje.

Architektura

Usługa Gatekeeper obejmuje 3 główne komponenty:

  • gatekeeperd (demon Gatekeeper) – usługa C++ Binder w Androidzie, która zawiera niezależną od platformy logikę implementującą interfejs IGateKeeperService AIDL na podstawie podstawowej implementacji IGatekeeper specyficznej dla dostawcy.
  • Usługa warstwy abstrakcji sprzętu (HAL) Gatekeeper – implementacja interfejsu IGatekeeper AIDL specyficzna dla dostawcy. Ta usługa HAL działa w Androidzie, ale podstawowe funkcje Gatekeepera muszą działać w bezpiecznym środowisku, więc zwykle komunikuje się z aplikacją TA Gatekeeper.
  • Zaufana aplikacja Gatekeeper (TA) – implementacja specyficzna dla dostawcy, która działa w środowisku TEE i przeprowadza weryfikację hasła lub wzoru.

LockSettingsService wysyła żądanie (za pomocą interfejsu Binder), które dociera do demona gatekeeperd w systemie operacyjnym Android. Demon gatekeeperd wysyła żądanie do usługi IGatekeeper HAL, która z kolei dociera do odpowiednika Gatekeeper TA w TEE:

Procedura dla podmiotu kontrolującego dostęp

Rysunek 1. Ogólny przepływ danych w przypadku uwierzytelniania za pomocą GateKeeper.

Demon gatekeeperd zapewnia interfejsom API platformy Android dostęp do HAL i uczestniczy w zgłaszaniu do magazynu kluczy uwierzytelniania urządzenia. Demon gatekeeperd działa w osobnym procesie i jest oddzielony od serwera systemowego.

Implementacja HAL

Demon gatekeeperd używa interfejsu HAL IGatekeeper do interakcji z podstawowym zaufanym środowiskiem wykonawczym Gatekeeper w celu uwierzytelniania hasła. Implementacja Gatekeeper TA musi umożliwiać podpisywanie (rejestrowanie) i weryfikowanie obiektów binarnych. Wszystkie implementacje muszą być zgodne ze standardowym formatem tokena uwierzytelniającego (HardwareAuthToken) generowanego po każdej udanej weryfikacji hasła. Szczegółowe informacje o treści i semantyce HardwareAuthToken znajdziesz w definicji HardwareAuthToken.aidl.

Implementacje HAL dostawców muszą implementować funkcje enrollverify:IGatekeeper

  • Metoda enroll przyjmuje obiekt hasła, podpisuje go i zwraca podpis jako uchwyt. Zwrócony obiekt blob (z wywołania funkcji enroll) musi mieć strukturę pokazaną w sekcji system/gatekeeper/include/gatekeeper/password_handle.h.
  • Funkcja verify musi porównać podpis wygenerowany przez podane hasło i upewnić się, że pasuje on do zarejestrowanego uchwytu hasła.

Klucz używany do rejestracji i weryfikacji nigdy nie może się zmieniać i powinien być możliwy do ponownego wygenerowania przy każdym uruchomieniu urządzenia.

Trusty i inne implementacje

System operacyjny Trusty to zaufany system operacyjny open source firmy Google przeznaczony do środowisk TEE. Zawiera on zatwierdzoną implementację usługi Gatekeeper. Jednak każdy system operacyjny TEE może implementować Gatekeepera, o ile TEE ma dostęp do trwałego klucza obsługiwanego sprzętowo i bezpiecznego zegara monotonicznego działającego w trybie zawieszenia.

Trusty używa wewnętrznego systemu IPC do bezpośredniej komunikacji klucza tajnego między KeyMint (wcześniej Keymaster) a implementacją Trusty usługi Gatekeeper (Trusty Gatekeeper). Ten udostępniony klucz tajny służy do podpisywania tokenów AuthToken wysyłanych do usługi Keystore w celu dostarczania atestów weryfikacji hasła. Trusty Gatekeeper przy każdym użyciu wysyła do KeyMint prośbę o klucz. Nie przechowuje ani nie buforuje wartości. Implementacje mogą udostępniać ten klucz tajny w dowolny sposób, który nie zagraża bezpieczeństwu.

Klucz HMAC używany do rejestrowania i weryfikowania haseł jest wyprowadzany i przechowywany wyłącznie w usłudze Gatekeeper.

Android udostępnia ogólną implementację C++ usługi Gatekeeper, która wymaga jedynie dodania procedur specyficznych dla urządzenia. Na tej implementacji opiera się Trusty. Aby wdrożyć usługę TEE Gatekeeper z kodem specyficznym dla urządzenia w przypadku środowiska TEE, zapoznaj się z funkcjami i komentarzami w system/gatekeeper/include/gatekeeper/gatekeeper.h. Główne obowiązki związane z wdrożeniem zgodnym z zasadami obejmują:

  • Zgodność z IGatekeeper HAL.
  • Zwrócone tokeny uwierzytelniające muszą być sformatowane zgodnie ze specyfikacją HardwareAuthToken (opisaną w sekcji Uwierzytelnianie).
  • Usługa TEE Gatekeeper musi mieć możliwość udostępniania klucza HMAC usłudze KeyMint, albo żądając klucza za pomocą komunikacji IPC w TEE na żądanie, albo utrzymując w każdej chwili prawidłową pamięć podręczną wartości.

Bezpieczne identyfikatory użytkowników (SID)

Identyfikator SID użytkownika to reprezentacja użytkownika w TEE (nie jest ściśle powiązany z identyfikatorem użytkownika Androida). Identyfikator SID jest generowany za pomocą kryptograficznego generatora liczb pseudolosowych (PRNG) za każdym razem, gdy użytkownik rejestruje nowe hasło bez podawania poprzedniego. Jest to tzw. ponowna rejestracja niezaufanego urządzenia, która zwykle następuje tylko wtedy, gdy użytkownik po raz pierwszy ustawia hasło lub wzór.

Zaufana ponowna rejestracja następuje, gdy użytkownik poda prawidłowe, poprzednie hasło, np. podczas zmiany hasła. W takim przypadku identyfikator SID użytkownika jest przenoszony do nowego uchwytu hasła, co pozwala zachować klucze powiązane z tym identyfikatorem.

Identyfikator SID użytkownika jest uwzględniany w uwierzytelnianiu HMAC wraz z hasłem w uchwycie hasła, gdy hasło jest zarejestrowane.

Identyfikatory SID użytkowników są uwzględniane w wartości HardwareAuthToken zwracanej przez funkcję verify() i powiązane ze wszystkimi kluczami Keystore powiązanymi z uwierzytelnianiem (szczegółowe informacje o formacie HardwareAuthToken i Keystore znajdziesz w sekcji Uwierzytelnianie).

Pamiętaj, że niezaufane wywołanie funkcji enroll() zmienia identyfikator SID użytkownika, więc wywołanie sprawia, że klucze powiązane z tym hasłem stają się bezużyteczne. Jeśli atakujący przejmą kontrolę nad systemem Android, mogą zmienić hasło do urządzenia, ale w tym procesie zniszczą klucze chronione przez roota.

Ograniczanie liczby żądań

Usługa Gatekeeper musi mieć możliwość bezpiecznego ograniczania prób siłowego odgadnięcia danych logowania użytkownika. Jak pokazano w GatekeeperVerifyResponse.aidl, HAL umożliwia zwracanie czasu oczekiwania w milisekundach. Limit czasu informuje klienta, aby nie wywoływał ponownie usługi Gatekeeper, dopóki nie upłynie limit czasu. Usługa Gatekeeper nie powinna obsługiwać żądań, jeśli wystąpiło oczekiwanie na przekroczenie limitu czasu.

Przed zweryfikowaniem hasła użytkownika usługa Gatekeeper musi zapisać licznik nieudanych prób. Jeśli weryfikacja hasła się powiedzie, licznik nieudanych prób powinien zostać wyczyszczony. Zapobiega to atakom, które uniemożliwiają ograniczanie przepustowości przez wyłączenie wbudowanej pamięci MMC (eMMC) po wydaniu wywołania verify. Funkcja enroll weryfikuje też hasło użytkownika (jeśli zostało podane) i musi być ograniczana w ten sam sposób.

Jeśli urządzenie obsługuje licznik niepowodzeń, zdecydowanie zalecamy zapisywanie go w bezpiecznej pamięci. Jeśli urządzenie nie obsługuje szyfrowania opartego na plikach lub jeśli bezpieczna pamięć jest zbyt wolna, implementacje mogą bezpośrednio używać bloku pamięci chronionej przed powtórzeniem (RPMB).