Wznów po restarcie

W Androidzie 11 aktualizacje OTA można stosować za pomocą mechanizmów aktualizacji A/B lub wirtualnej aktualizacji A/B w połączeniu z metodami klasy RecoverySystem. Po ponownym uruchomieniu urządzenia w celu zastosowania aktualizacji OTA funkcja Resume-on-Reboot (RoR) odblokowuje pamięć szyfrowaną za pomocą danych logowania.

Chociaż w Androidzie 11 partnerzy mogą połączyć ten proces z funkcją systemu OTA, która stosuje aktualizacje, gdy urządzenie ma być nieaktywne, w Androidzie 12 nie potrzebują dodatkowej funkcji systemu OTA. Proces RoR zapewnia użytkownikom większe bezpieczeństwo i wygodę, ponieważ aktualizacje mogą być przeprowadzane w czasie, gdy urządzenie jest nieaktywne. Z kolei funkcje aktualizacji wieloklientowych i opartych na serwerze w Androidzie 12 zapewniają bezpieczeństwo na poziomie sprzętu urządzenia.

Aby funkcja android.hardware.reboot_escrow obsługiwała RoR na Androidzie 11, musisz przyznać jej uprawnienia do urządzenia. Nie musisz tego robić, aby włączyć RoR na serwerze na Androidzie 12 i nowszych wersjach, ponieważ nie korzystają one z warstwy HAL.

Tło

Od Androida 7 system ten obsługuje bezpośredni rozruch, który umożliwia uruchamianie aplikacji na urządzeniu, zanim użytkownik odblokuje pamięć CE. Wdrożenie obsługi bezpośredniego rozruchu zapewniło użytkownikom większą wygodę przed wprowadzeniem czynnika wiedzy o ekranie blokady (LSKF) po rozruchu.

RoR umożliwia odblokowanie pamięci CE wszystkich aplikacji na urządzeniu, w tym tych, które nie obsługują bezpośredniego uruchamiania, gdy po aktualizacji OTA nastąpi ponowne uruchomienie. Dzięki tej funkcji użytkownicy mogą otrzymywać powiadomienia ze wszystkich zainstalowanych aplikacji po ponownym uruchomieniu urządzenia.

Model zagrożeń

Implementacja RoR musi zapewniać, że gdy urządzenie trafi w ręce osoby atakującej, odzyskanie zaszyfrowanych danych CE użytkownika będzie niezwykle trudne, nawet jeśli urządzenie jest włączone, pamięć CE jest odblokowana, a urządzenie jest odblokowywane przez użytkownika po otrzymaniu aktualizacji OTA. Odporność na ataki wewnętrzne musi być skuteczna nawet wtedy, gdy atakujący uzyska dostęp do kluczy kryptograficznych podpisywania transmisji.

W szczególności pamięć CE nie może być odczytywana przez osobę atakującą, która ma fizyczny dostęp do urządzenia i dysponuje tymi możliwościami oraz ograniczeniami:

Uprawnienia

  • Może używać klucza podpisywania dowolnego dostawcy lub firmy do podpisywania dowolnych wiadomości.
  • Może spowodować otrzymanie przez urządzenie aktualizacji OTA.
  • Może modyfikować działanie dowolnego sprzętu (np. procesora aplikacji lub pamięci flash) z wyjątkiem przypadków opisanych poniżej w sekcji Ograniczenia. (Jednak taka modyfikacja wiąże się z co najmniej godzinnym opóźnieniem i wyłączeniem zasilania, które powoduje usunięcie zawartości pamięci RAM).

Ograniczenia

  • Nie można modyfikować działania sprzętu odpornego na manipulacje (np. układu Titan M).
  • Nie można odczytać pamięci RAM aktywnego urządzenia.
  • Nie może odgadywać danych logowania użytkownika (kodu PIN, wzoru, hasła) ani w inny sposób powodować ich wpisywania.

Rozwiązanie

System aktualizacji RoR w Androidzie 12 zapewnia ochronę przed bardzo zaawansowanymi atakami, a hasła i kody PIN na urządzeniu pozostają na nim – nigdy nie są wysyłane na serwery Google ani na nich przechowywane. Poniżej znajdziesz omówienie procesu, który zapewnia podobny poziom bezpieczeństwa jak w przypadku sprzętowego systemu RoR na poziomie urządzenia:

  • Android stosuje ochronę kryptograficzną w przypadku danych przechowywanych na urządzeniu.
  • Wszystkie dane są chronione przez klucze przechowywane w zaufanym środowisku wykonawczym (TEE).
  • Środowisko TEE udostępnia klucze tylko wtedy, gdy uruchomiony system operacyjny przejdzie uwierzytelnianie kryptograficzne (zweryfikowany rozruch).
  • Usługa RoR działająca na serwerach Google zabezpiecza dane CE, przechowując tajny klucz, który można pobrać tylko przez ograniczony czas. Działa to w całym ekosystemie Androida.
  • Kryptograficzny klucz chroniony kodem PIN użytkownika służy do odblokowywania urządzenia i odszyfrowywania pamięci CE.
    • Gdy zaplanowane jest ponowne uruchomienie w nocy, Android prosi użytkownika o wpisanie kodu PIN, a następnie oblicza syntetyczne hasło (SP).
    • Następnie dwukrotnie szyfruje SP: raz za pomocą klucza K_s przechowywanego w pamięci RAM, a drugi raz za pomocą klucza K_k przechowywanego w TEE.
    • Podwójnie zaszyfrowany SP jest przechowywany na dysku, a SP jest usuwany z pamięci RAM. Oba klucze są nowo wygenerowane i używane tylko podczas jednego ponownego uruchomienia.
  • Gdy nadejdzie czas ponownego uruchomienia, Android powierzy K_s serwerowi. Paragon z K_k jest szyfrowany przed zapisaniem na dysku.
  • Po ponownym uruchomieniu Android używa K_k do odszyfrowania paragonu, a następnie wysyła go na serwer, aby pobrać K_s.
    • K_kK_s służą do odszyfrowywania SP przechowywanego na dysku.
    • Android używa SP do odblokowania pamięci CE i umożliwienia normalnego uruchamiania aplikacji.
    • Elementy K_kK_s zostaną odrzucone.

Aktualizacje, które chronią Twój telefon, mogą być przeprowadzane w dogodnym dla Ciebie czasie, np. gdy śpisz.

Odtwarzanie kodu PIN karty SIM

W określonych warunkach kod PIN karty SIM jest weryfikowany z pamięci podręcznej. Ten proces nazywa się odtwarzaniem kodu PIN karty SIM.

Karta SIM z włączonym kodem PIN musi też po ponownym uruchomieniu bez nadzoru przejść bezproblemową weryfikację kodu PIN (powtórzenie kodu PIN karty SIM), aby przywrócić łączność komórkową (wymaganą do połączeń telefonicznych, SMS-ów i usług transmisji danych). Kod PIN karty SIM i odpowiadające mu informacje o karcie SIM (ICCID i numer gniazda karty SIM) są przechowywane razem w bezpieczny sposób. Zapisany kod PIN można pobrać i użyć do weryfikacji dopiero po pomyślnym ponownym uruchomieniu bez udziału użytkownika. Jeśli urządzenie jest zabezpieczone, kod PIN karty SIM jest przechowywany z kluczami chronionymi przez LSKF. Jeśli karta SIM ma włączony kod PIN, interakcja z serwerem RoR wymaga połączenia Wi-Fi w przypadku aktualizacji OTA i serwerowego RoR, co zapewnia podstawową funkcjonalność (z łącznością komórkową) po ponownym uruchomieniu.

Kod PIN do karty SIM jest ponownie szyfrowany i przechowywany za każdym razem, gdy użytkownik go włączy, zweryfikuje lub zmodyfikuje. Kod PIN karty SIM zostanie odrzucony, jeśli wystąpi którykolwiek z tych przypadków:

  • Karta SIM zostanie usunięta lub zresetowana.
  • Użytkownik wyłącza kod PIN.
  • Nastąpił restart nieinicjowany przez RoR.

Zapisany kod PIN karty SIM można użyć tylko raz po ponownym uruchomieniu zainicjowanym przez RoR i tylko przez bardzo krótki czas (20 sekund) – jeśli dane karty SIM są zgodne. Przechowywany kod PIN karty SIM nigdy nie opuszcza aplikacji TelephonyManager i nie może być pobierany przez moduły zewnętrzne.

Wskazówki dotyczące implementacji

W Androidzie 12 funkcje RoR oparte na wielu klientach i serwerach zapewniają partnerom mniejsze obciążenie podczas przesyłania aktualizacji OTA. Niezbędne aktualizacje mogą być przeprowadzane w dogodnych okresach przestoju urządzenia, np. w godzinach snu.

Aby aktualizacje OTA w tym czasie nie przerywały pracy użytkowników, zastosuj tryb ciemny, który ogranicza emisję światła. Aby to zrobić, w programie rozruchowym urządzenia wyszukaj ciąg znaków reason unattended. Jeśli unattended ma wartość true, włącz tryb ciemny na urządzeniu. Pamiętaj, że to na producencie OEM spoczywa odpowiedzialność za ograniczenie emisji dźwięku i światła.

Jeśli przechodzisz na Androida 12 lub wprowadzasz na rynek urządzenia z Androidem 12, nie musisz nic robić, aby wdrożyć nową funkcję RoR.

W przypadku przepływu obejmującego wielu klientów występuje jedno nowe wywołanie, isPreparedForUnattendedUpdate, pokazane poniżej:

@RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
            android.Manifest.permission.REBOOT})
public static boolean isPreparedForUnattendedUpdate(@NonNull Context context)

Nie musisz tego wdrażać, ponieważ interfejs HAL jest przestarzały od Androida 12.

TelephonyManager

Klient OTA wywołuje interfejs API systemu TelephonyManager, gdy w Androidzie 12 zbliża się ponowne uruchomienie. Ten interfejs API przenosi wszystkie kody PIN w pamięci podręcznej ze stanu AVAILABLE do stanu REBOOT_READY. Interfejs TelephonyManager API systemu jest chroniony przez istniejące uprawnienie REBOOT w pliku manifestu.

 /**
    * The unattended reboot was prepared successfully.
    * @hide
    */
   @SystemApi
   public static final int PREPARE_UNATTENDED_REBOOT_SUCCESS = 0;

   /**
    * The unattended reboot was prepared, but the user will need to manually
    * enter the PIN code of at least one SIM card present in the device.
    * @hide
    */
   @SystemApi
   public static final int PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED = 1;

   /**
    * The unattended reboot was not prepared due to generic error.
    * @hide
    */
   @SystemApi
   public static final int PREPARE_UNATTENDED_REBOOT_ERROR = 2;

   /** @hide */
   @Retention(RetentionPolicy.SOURCE)
   @IntDef(prefix = {"PREPARE_UNATTENDED_REBOOT_"},
           value = {
                   PREPARE_UNATTENDED_REBOOT_SUCCESS,
                   PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED,
                   PREPARE_UNATTENDED_REBOOT_ERROR
           })
   public @interface PrepareUnattendedRebootResult {}

   /**
    * Prepare TelephonyManager for an unattended reboot. The reboot is
    * required to be done shortly after the API is invoked.
    *
    * Requires system privileges.
    *
    * <p>Requires Permission:
    *   {@link android.Manifest.permission#REBOOT}
    *
    * @return {@link #PREPARE_UNATTENDED_REBOOT_SUCCESS} in case of success.
    * {@link #PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED} if the device contains
    * at least one SIM card for which the user needs to manually enter the PIN
    * code after the reboot. {@link #PREPARE_UNATTENDED_REBOOT_ERROR} in case
    * of error.
    * @hide
    */
   @SystemApi
   @RequiresPermission(android.Manifest.permission.REBOOT)
   @PrepareUnattendedRebootResult
   public int prepareForUnattendedReboot()

Interfejs TelephonyManager API jest używany przez uprzywilejowane pliki APK.

Testowanie

Aby przetestować nowy interfejs API, wykonaj to polecenie:

    adb shell cmd phone unattended-reboot

To polecenie działa tylko wtedy, gdy powłoka jest uruchomiona jako root (adb root).

Tylko Android 11

Pozostała część tej strony dotyczy Androida 11.

Od lipca 2020 r. implementacje RoR HAL dzielą się na 2 kategorie:

  1. Jeśli sprzęt SoC obsługuje trwałość pamięci RAM po ponownym uruchomieniu, producenci OEM mogą użyć domyślnej implementacji w AOSP (domyślne przechowywanie pamięci RAM).
  2. Jeśli sprzęt urządzenia lub układ SoC obsługuje bezpieczną enklawę sprzętową (oddzielny koprocesor zabezpieczeń z własną pamięcią RAM i ROM), musi dodatkowo spełniać te wymagania:
    • wykrywać ponowne uruchomienie głównego procesora;
    • musi mieć źródło zegara sprzętowego, które jest zachowywane po ponownym uruchomieniu. Oznacza to, że enklawa musi być w stanie wykryć ponowne uruchomienie i wyłączyć timer ustawiony przed ponownym uruchomieniem.
    • Obsługa przechowywania klucza depozytowego w pamięci RAM/ROM enklawy, tak aby nie można go było odzyskać w wyniku ataków offline. Klucz RoR musi być przechowywany w taki sposób, aby osoby z wewnątrz organizacji ani atakujący nie mogli go odzyskać.

Domyślna ochrona pamięci RAM

AOSP ma implementację RoR HAL korzystającą z pamięci RAM. Aby ta funkcja działała, producenci OEM muszą zadbać o to, aby ich układy SoC obsługiwały trwałość pamięci RAM podczas ponownego uruchamiania. Niektóre układy SoC nie są w stanie zachować zawartości pamięci RAM po ponownym uruchomieniu, dlatego przed włączeniem tego domyślnego HAL producenci OEM powinni skonsultować się z partnerami w zakresie układów SoC. W następnej sekcji znajdziesz kanoniczne odniesienie do tego zagadnienia.

Przebieg aktualizacji OTA z użyciem RoR

Aplikacja klienta OTA na telefonie musi mieć uprawnienia Manifest.permission.REBOOTManifest.permission.RECOVERY, aby wywoływać metody niezbędne do wdrożenia RoR. Po spełnieniu tego warunku aktualizacja przebiega w ten sposób:

  1. Aplikacja kliencka OTA pobiera aktualizację.
  2. Aplikacja klienta OTA wywołuje funkcję RecoverySystem#prepareForUnattendedUpdate, która powoduje wyświetlenie użytkownikowi prośby o podanie kodu PIN, wzoru lub hasła na ekranie blokady podczas następnego odblokowywania.
  3. Użytkownik odblokowuje urządzenie na ekranie blokady i jest ono gotowe do zastosowania aktualizacji.
  4. Aplikacja kliencka OTA wywołuje funkcję RecoverySystem#rebootAndApply, która natychmiast powoduje ponowne uruchomienie urządzenia.

Po zakończeniu tego procesu urządzenie uruchomi się ponownie, a mechanizm RoR odblokuje zaszyfrowaną pamięć danych logowania (CE). Dla aplikacji wygląda to jak normalne odblokowanie przez użytkownika, więc otrzymują one wszystkie sygnały, takie jak ACTION_LOCKED_BOOT_COMPLETEDACTION_BOOT_COMPLETED, które zwykle otrzymują.

Modyfikowanie konfiguracji usług

Produkt oznaczony jako obsługujący funkcję RoR na Androidzie 11 musi zawierać implementację HAL RebootEscrow i plik XML znacznika funkcji. Domyślna implementacja dobrze sprawdza się na urządzeniach, które używają ciepłego ponownego uruchamiania (gdy podczas ponownego uruchamiania zasilanie pamięci DRAM jest włączone).

Znacznik funkcji ponownego uruchamiania depozytu

Musi też być obecny znacznik funkcji:

PRODUCT_COPY_FILES += \
    frameworks/native/data/etc/android.hardware.reboot_escrow.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.reboot_escrow.xml

Domyślna implementacja HAL ponownego uruchamiania z depozytem

Aby użyć domyślnej implementacji, musisz zarezerwować 65536 bajtów (0x10000). Nigdy nie zapisuj tych bajtów w pamięci trwałej, aby zachować właściwości zabezpieczeń.

Zmiany w drzewie urządzeń jądra systemu Linux

W drzewie urządzeń jądra systemu Linux musisz zarezerwować pamięć dla regionu pmem. W tym przykładzie znak 0x50000000 jest zarezerwowany:

  reserved-memory {
    my_reservation@0x50000000 {
      no-map;
      reg = <0x50000000 0x10000>;
    }
  }

  reboot_escrow@0 {
    compatible = "pmem-region";
    reg = <0x50000000 0x10000>;
  };

Sprawdź, czy w katalogu bloków znajduje się nowe urządzenie o nazwie takiej jak /dev/block/pmem0 (np. pmem1 lub pmem2).

Zmiany w pliku Device.mk

Zakładając, że nowe urządzenie z poprzedniego kroku ma nazwę pmem0, musisz się upewnić, że do pliku vendor/<oem>/<product>/device.mk zostały dodane te nowe wpisy:

# Resume on Reboot support
PRODUCT_PROPERTY_OVERRIDES += \
    ro.rebootescrow.device=/dev/block/pmem0
PRODUCT_PACKAGES += \
    android.hardware.rebootescrow-service.default
Reguły SELinux

Dodaj te nowe wpisy do file_contexts na urządzeniu:

/dev/block/pmem0  u:object_r:rebootescrow_device:s0
/vendor/bin/hw/android\.hardware\.rebootescrow-service\.default  u:object_r:hal_rebootescrow_default_exec:s0